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

baedke pushed a commit to branch issue/oak-6756
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git


The following commit(s) were added to refs/heads/issue/oak-6756 by this push:
     new 44c79ad8ff OAK-6756: Convert oak-auth-external to OSGi R7 annotations
44c79ad8ff is described below

commit 44c79ad8ff7f125e5000a900bf413cc51ce4ed76
Author: Manfred Baedke <manfred.bae...@gmail.com>
AuthorDate: Wed Mar 20 15:55:13 2024 +0100

    OAK-6756: Convert oak-auth-external to OSGi R7 annotations
    
    done.
---
 oak-auth-external/pom.xml                          |   6 +-
 .../external/impl/DefaultSyncConfigImpl.java       | 353 ++++++++++++---------
 .../external/impl/DefaultSyncHandler.java          |  21 +-
 .../external/impl/ExternalIDPManagerImpl.java      |  15 +-
 .../external/impl/ExternalLoginModuleFactory.java  | 121 +++----
 .../external/impl/SyncManagerImpl.java             |  15 +-
 .../principal/ExternalPrincipalConfiguration.java  |  88 +++--
 .../external/impl/jmx/SynMBeanImplOSGiTest.java    |   1 +
 8 files changed, 354 insertions(+), 266 deletions(-)

diff --git a/oak-auth-external/pom.xml b/oak-auth-external/pom.xml
index d8f9d0b85f..581d7014fc 100644
--- a/oak-auth-external/pom.xml
+++ b/oak-auth-external/pom.xml
@@ -70,13 +70,13 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.jaas</artifactId>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.component.annotations</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.scr.annotations</artifactId>
+            <artifactId>org.apache.felix.jaas</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git 
a/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfigImpl.java
 
b/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfigImpl.java
index 2a6ab154f6..07adb49fbe 100644
--- 
a/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfigImpl.java
+++ 
b/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfigImpl.java
@@ -20,140 +20,80 @@ package 
org.apache.jackrabbit.oak.spi.security.authentication.external.impl;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
 import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
 import 
org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncConfig;
 import org.jetbrains.annotations.NotNull;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
 
 /**
  * {@code DefaultSyncConfig} defines how users and groups from an external 
source are synced into the repository using
  * the {@link DefaultSyncHandler}.
  */
-@Component(
-        label = "Apache Jackrabbit Oak Default Sync Handler",
-        name = 
"org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler",
-        configurationFactory = true,
-        metatype = true,
-        ds = false
-)
 public class DefaultSyncConfigImpl extends DefaultSyncConfig {
 
     /**
-     * @see #getName()
+     * @see DefaultSyncConfig#getName()
      */
-    public static final String PARAM_NAME_DEFAULT = 
DefaultSyncConfig.DEFAULT_NAME;
-
-    /**
-     * @see #getName()
-     */
-    @Property(
-            label = "Sync Handler Name",
-            description = "Name of this sync configuration. This is used to 
reference this handler by the login modules.",
-            value = PARAM_NAME_DEFAULT
-    )
     public static final String PARAM_NAME = "handler.name";
-
     /**
-     * @see DefaultSyncConfig.User#getExpirationTime()
+     * @see DefaultSyncConfig#getName()
      */
-    public static final String PARAM_USER_EXPIRATION_TIME_DEFAULT = "1h";
+    public static final String PARAM_NAME_DEFAULT = 
DefaultSyncConfig.DEFAULT_NAME;
 
     /**
      * @see DefaultSyncConfig.User#getExpirationTime()
      */
-    @Property(
-            label = "User Expiration Time",
-            description = "Duration until a synced user gets expired (eg. '1h 
30m' or '1d').",
-            value = PARAM_USER_EXPIRATION_TIME_DEFAULT
-    )
     public static final String PARAM_USER_EXPIRATION_TIME = 
"user.expirationTime";
-
     /**
-     * @see DefaultSyncConfig.User#getAutoMembership()
+     * @see DefaultSyncConfig.User#getExpirationTime()
      */
-    public static final String[] PARAM_USER_AUTO_MEMBERSHIP_DEFAULT = {};
+    public static final String PARAM_USER_EXPIRATION_TIME_DEFAULT = "1h";
 
     /**
      * @see DefaultSyncConfig.User#getAutoMembership()
      */
-    @Property(
-            label = "User auto membership",
-            description = "List of groups that a synced user is added to 
automatically",
-            value = {},
-            cardinality = Integer.MAX_VALUE
-    )
     public static final String PARAM_USER_AUTO_MEMBERSHIP = 
"user.autoMembership";
-
     /**
-     * @see DefaultSyncConfig.User#getPropertyMapping()
+     * @see DefaultSyncConfig.User#getAutoMembership()
      */
-    public static final String[] PARAM_USER_PROPERTY_MAPPING_DEFAULT = 
{"rep:fullname=cn"};
+    public static final String[] PARAM_USER_AUTO_MEMBERSHIP_DEFAULT = {};
 
     /**
      * @see DefaultSyncConfig.User#getPropertyMapping()
      */
-    @Property(
-            label = "User property mapping",
-            description = "List mapping definition of local properties from 
external ones. eg: 'profile/email=mail'." +
-                    "Use double quotes for fixed values. eg: 
'profile/nt:primaryType=\"nt:unstructured\"",
-            value = {"rep:fullname=cn"},
-            cardinality = Integer.MAX_VALUE
-    )
     public static final String PARAM_USER_PROPERTY_MAPPING = 
"user.propertyMapping";
-
     /**
-     * @see DefaultSyncConfig.User#getPathPrefix()
+     * @see DefaultSyncConfig.User#getPropertyMapping()
      */
-    public static final String PARAM_USER_PATH_PREFIX_DEFAULT = "";
+    public static final String[] PARAM_USER_PROPERTY_MAPPING_DEFAULT = 
{"rep:fullname=cn"};
 
     /**
      * @see DefaultSyncConfig.User#getPathPrefix()
      */
-    @Property(
-            label = "User Path Prefix",
-            description = "The path prefix used when creating new users.",
-            value = PARAM_USER_PATH_PREFIX_DEFAULT
-    )
     public static final String PARAM_USER_PATH_PREFIX = "user.pathPrefix";
-
     /**
-     * @see DefaultSyncConfig.User#getMembershipExpirationTime()
+     * @see DefaultSyncConfig.User#getPathPrefix()
      */
-    public static final String PARAM_USER_MEMBERSHIP_EXPIRATION_TIME_DEFAULT = 
"1h";
+    public static final String PARAM_USER_PATH_PREFIX_DEFAULT = "";
 
     /**
      * @see DefaultSyncConfig.User#getMembershipExpirationTime()
      */
-    @Property(
-            label = "User Membership Expiration",
-            description = "Time after which membership expires (eg. '1h 30m' 
or '1d'). Note however, that a membership sync is aways bound to a sync of the 
user.",
-            value = PARAM_USER_MEMBERSHIP_EXPIRATION_TIME_DEFAULT
-    )
     public static final String PARAM_USER_MEMBERSHIP_EXPIRATION_TIME = 
"user.membershipExpTime";
-
     /**
-     * @see DefaultSyncConfig.User#getMembershipNestingDepth()
+     * @see DefaultSyncConfig.User#getMembershipExpirationTime()
      */
-    public static final int PARAM_USER_MEMBERSHIP_NESTING_DEPTH_DEFAULT = 0;
+    public static final String PARAM_USER_MEMBERSHIP_EXPIRATION_TIME_DEFAULT = 
"1h";
 
     /**
      * @see DefaultSyncConfig.User#getMembershipNestingDepth()
      */
-    @Property(
-            label = "User membership nesting depth",
-            description = "Returns the maximum depth of group nesting when 
membership relations are synced. " +
-                    "A value of 0 effectively disables group membership 
lookup. A value of 1 only adds the direct " +
-                    "groups of a user. This value has no effect when syncing 
individual groups only when syncing a " +
-                    "users membership ancestry.",
-            intValue = PARAM_USER_MEMBERSHIP_NESTING_DEPTH_DEFAULT
-    )
     public static final String PARAM_USER_MEMBERSHIP_NESTING_DEPTH = 
"user.membershipNestingDepth";
-
     /**
-     * @see DefaultSyncConfig.User#getDynamicMembership()
+     * @see DefaultSyncConfig.User#getMembershipNestingDepth()
      */
-    public static final boolean PARAM_USER_DYNAMIC_MEMBERSHIP_DEFAULT = false;
+    public static final int PARAM_USER_MEMBERSHIP_NESTING_DEPTH_DEFAULT = 0;
 
     /**
      * Configuration option to enable dynamic group membership. If enabled the
@@ -168,18 +108,11 @@ public class DefaultSyncConfigImpl extends 
DefaultSyncConfig {
      *
      * @see DefaultSyncConfig.User#getDynamicMembership()
      */
-    @Property(
-            label = "User Dynamic Membership",
-            description = "If enabled membership of external identities (user) 
is no longer fully reflected " +
-                    "within the repositories user management.",
-            boolValue = PARAM_USER_DYNAMIC_MEMBERSHIP_DEFAULT
-    )
     public static final String PARAM_USER_DYNAMIC_MEMBERSHIP = 
"user.dynamicMembership";
-    
     /**
-     * @see DefaultSyncConfig.User#getEnforceDynamicMembership()
+     * @see DefaultSyncConfig.User#getDynamicMembership()
      */
-    public static final boolean PARAM_USER_ENFORCE_DYNAMIC_MEMBERSHIP_DEFAULT 
= false;
+    public static final boolean PARAM_USER_DYNAMIC_MEMBERSHIP_DEFAULT = false;
 
     /**
      * Configuration option to enforce dynamic group membership upon user 
sync. If enabled the
@@ -187,127 +120,241 @@ public class DefaultSyncConfigImpl extends 
DefaultSyncConfig {
      *
      * @see DefaultSyncConfig.User#getDynamicMembership()
      */
-    @Property(
-            label = "User Enforce Dynamic Membership",
-            description = "If enabled dynamic membership will be enforced for 
previously synchronized users. Note, that this option has no effect if 'dynamic 
membership' is disabled.",
-            boolValue = PARAM_USER_ENFORCE_DYNAMIC_MEMBERSHIP_DEFAULT
-    )
     public static final String PARAM_USER_ENFORCE_DYNAMIC_MEMBERSHIP = 
"user.enforceDynamicMembership";
-
     /**
-     * @see User#getDisableMissing()
+     * @see DefaultSyncConfig.User#getDynamicMembership()
      */
-    public static final boolean PARAM_DISABLE_MISSING_USERS_DEFAULT = false;
+    public static final boolean PARAM_USER_ENFORCE_DYNAMIC_MEMBERSHIP_DEFAULT 
= false;
 
     /**
      * @see User#getDisableMissing()
      */
-    @Property(
-        label = "Disable missing users",
-        description = "If true, users that no longer exist on the external 
provider will be locally disabled, " +
-            "and re-enabled if they become valid again. If false (default) 
they will be removed.",
-        boolValue = false
-    )
     public static final String PARAM_DISABLE_MISSING_USERS = 
"user.disableMissing";
-
     /**
-     * @see DefaultSyncConfig.Group#getExpirationTime()
+     * @see User#getDisableMissing()
      */
-    public static final String PARAM_GROUP_EXPIRATION_TIME_DEFAULT = "1d";
+    public static final boolean PARAM_DISABLE_MISSING_USERS_DEFAULT = false;
 
     /**
      * @see DefaultSyncConfig.Group#getExpirationTime()
      */
-    @Property(
-            label = "Group Expiration Time",
-            description = "Duration until a synced group expires (eg. '1h 30m' 
or '1d').",
-            value = PARAM_GROUP_EXPIRATION_TIME_DEFAULT
-    )
     public static final String PARAM_GROUP_EXPIRATION_TIME = 
"group.expirationTime";
-
     /**
-     * @see DefaultSyncConfig.Group#getAutoMembership()
+     * @see DefaultSyncConfig.Group#getExpirationTime()
      */
-    public static final String[] PARAM_GROUP_AUTO_MEMBERSHIP_DEFAULT = {};
+    public static final String PARAM_GROUP_EXPIRATION_TIME_DEFAULT = "1d";
 
     /**
      * @see DefaultSyncConfig.Group#getAutoMembership()
      */
-    @Property(
-            label = "Group auto membership",
-            description = "List of groups that a synced group is added to 
automatically",
-            value = {},
-            cardinality = Integer.MAX_VALUE
-    )
     public static final String PARAM_GROUP_AUTO_MEMBERSHIP = 
"group.autoMembership";
-
     /**
-     * @see DefaultSyncConfig.Group#getPropertyMapping()
+     * @see DefaultSyncConfig.Group#getAutoMembership()
      */
-    public static final String[] PARAM_GROUP_PROPERTY_MAPPING_DEFAULT = {};
+    public static final String[] PARAM_GROUP_AUTO_MEMBERSHIP_DEFAULT = {};
 
     /**
      * @see DefaultSyncConfig.Group#getPropertyMapping()
      */
-    @Property(
-            label = "Group property mapping",
-            description = "List mapping definition of local properties from 
external ones.",
-            value = {},
-            cardinality = Integer.MAX_VALUE
-    )
     public static final String PARAM_GROUP_PROPERTY_MAPPING = 
"group.propertyMapping";
-
     /**
-     * @see DefaultSyncConfig.Group#getPathPrefix()
+     * @see DefaultSyncConfig.Group#getPropertyMapping()
      */
-    public static final String PARAM_GROUP_PATH_PREFIX_DEFAULT = "";
+    public static final String[] PARAM_GROUP_PROPERTY_MAPPING_DEFAULT = {};
 
     /**
      * @see DefaultSyncConfig.Group#getPathPrefix()
      */
-    @Property(
-            label = "Group Path Prefix",
-            description = "The path prefix used when creating new groups.",
-            value = PARAM_GROUP_PATH_PREFIX_DEFAULT
-    )
     public static final String PARAM_GROUP_PATH_PREFIX = "group.pathPrefix";
-
     /**
-     * @see DefaultSyncConfig.Group#getDynamicGroups()
+     * @see DefaultSyncConfig.Group#getPathPrefix()
      */
-    public static final boolean PARAM_GROUP_DYNAMIC_GROUPS_DEFAULT = false;
-    
+    public static final String PARAM_GROUP_PATH_PREFIX_DEFAULT = "";
+
     /**
      * @see DefaultSyncConfig.Group#getDynamicGroups()
      */
-    @Property(
-            label = "Dynamic Groups",
-            description = "If enabled external identity groups are 
synchronized as dynamic groups i.e. members/membership " +
-                    "is resolved dynamically by a DynamicMembershipProvider. 
Note: currently this option only takes effect " +
-                    "if 'User Dynamic Membership' is enabled.",
-            boolValue = PARAM_GROUP_DYNAMIC_GROUPS_DEFAULT
-    )
     public static final String PARAM_GROUP_DYNAMIC_GROUPS = 
"group.dynamicGroups";
-
     /**
-     * Default value for {@link #PARAM_ENABLE_RFC7613_USERCASE_MAPPED_PROFILE}
+     * @see DefaultSyncConfig.Group#getDynamicGroups()
      */
-    public static final boolean 
PARAM_ENABLE_RFC7613_USERCASE_MAPPED_PROFILE_DEFAULT = false;
+    public static final boolean PARAM_GROUP_DYNAMIC_GROUPS_DEFAULT = false;
 
     /**
      * @see Authorizable#isApplyRFC7613UsernameCaseMapped()
      */
-    @Property(
-            label = "RFC7613 Username Normalization Profile",
-            description = "Enable the UsercaseMappedProfile defined in RFC7613 
for username normalization.",
-            boolValue = PARAM_ENABLE_RFC7613_USERCASE_MAPPED_PROFILE_DEFAULT
-    )
     public static final String PARAM_ENABLE_RFC7613_USERCASE_MAPPED_PROFILE = 
"enableRFC7613UsercaseMappedProfile";
+    /**
+     * @see Authorizable#isApplyRFC7613UsernameCaseMapped()
+     */
+    public static final boolean 
PARAM_ENABLE_RFC7613_USERCASE_MAPPED_PROFILE_DEFAULT = false;
 
     private static final long MILLIS_PER_HOUR = 60 * 60 * 1000L;
     private static final ConfigurationParameters.Milliseconds ONE_HOUR = 
ConfigurationParameters.Milliseconds.of(MILLIS_PER_HOUR);
     private static final ConfigurationParameters.Milliseconds ONE_DAY = 
ConfigurationParameters.Milliseconds.of(24 * MILLIS_PER_HOUR);
 
+    @ObjectClassDefinition(
+            id = 
"org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler",
+            name = "Apache Jackrabbit Oak Default Sync Handler"
+    )
+    @interface Configuration {
+        /**
+         * @see DefaultSyncConfig#getName()
+         */
+        @AttributeDefinition(
+                name = "Sync Handler Name",
+                description = "Name of this sync configuration. This is used 
to reference this handler by the login modules."
+        )
+        String handler_name() default PARAM_NAME_DEFAULT;
+
+        /**
+         * @see DefaultSyncConfig.User#getExpirationTime()
+         */
+        @AttributeDefinition(
+                name = "User Expiration Time",
+                description = "Duration until a synced user gets expired (eg. 
'1h 30m' or '1d')."
+        )
+        String user_expirationTime() default 
PARAM_USER_EXPIRATION_TIME_DEFAULT;
+
+        /**
+         * @see DefaultSyncConfig.User#getAutoMembership()
+         */
+        @AttributeDefinition(
+                name = "User auto membership",
+                description = "List of groups that a synced user is added to 
automatically",
+                cardinality = Integer.MAX_VALUE
+        )
+        String[] user_autoMembership();
+
+        /**
+         * @see DefaultSyncConfig.User#getPropertyMapping()
+         */
+        @AttributeDefinition(
+                name = "User property mapping",
+                description = "List mapping definition of local properties 
from external ones. eg: 'profile/email=mail'." +
+                        "Use double quotes for fixed values. eg: 
'profile/nt:primaryType=\"nt:unstructured\"",
+                cardinality = Integer.MAX_VALUE
+        )
+        String[] user_propertyMapping() default {"rep:fullname=cn"};
+
+        /**
+         * @see DefaultSyncConfig.User#getPathPrefix()
+         */
+        @AttributeDefinition(
+                name = "User Path Prefix",
+                description = "The path prefix used when creating new users."
+        )
+        String user_pathPrefix() default PARAM_USER_PATH_PREFIX_DEFAULT;
+
+        /**
+         * @see DefaultSyncConfig.User#getMembershipExpirationTime()
+         */
+        @AttributeDefinition(
+                name = "User Membership Expiration",
+                description = "Time after which membership expires (eg. '1h 
30m' or '1d'). Note however, that a membership sync is aways bound to a sync of 
the user."
+        )
+        String user_membershipExpTime() default 
PARAM_USER_MEMBERSHIP_EXPIRATION_TIME_DEFAULT;
+
+        /**
+         * @see DefaultSyncConfig.User#getMembershipNestingDepth()
+         */
+        @AttributeDefinition(
+                name = "User membership nesting depth",
+                description = "Returns the maximum depth of group nesting when 
membership relations are synced. " +
+                        "A value of 0 effectively disables group membership 
lookup. A value of 1 only adds the direct " +
+                        "groups of a user. This value has no effect when 
syncing individual groups only when syncing a " +
+                        "users membership ancestry."
+        )
+        int user_membershipNestingDepth() default 
PARAM_USER_MEMBERSHIP_NESTING_DEPTH_DEFAULT;
+
+        /**
+         * @see DefaultSyncConfig.User#getDynamicMembership()
+         */
+        @AttributeDefinition(
+                name = "User Dynamic Membership",
+                description = "If enabled membership of external identities 
(user) is no longer fully reflected " +
+                        "within the repositories user management."
+        )
+        boolean user_dynamicMembership() default 
PARAM_USER_DYNAMIC_MEMBERSHIP_DEFAULT;
+
+        /**
+         * @see DefaultSyncConfig.User#getDynamicMembership()
+         */
+        @AttributeDefinition(
+                name = "User Enforce Dynamic Membership",
+                description = "If enabled dynamic membership will be enforced 
for previously synchronized users. Note, that this option has no effect if 
'dynamic membership' is disabled."
+        )
+        boolean user_enforceDynamicMembership() default 
PARAM_USER_ENFORCE_DYNAMIC_MEMBERSHIP_DEFAULT;
+
+        /**
+         * @see User#getDisableMissing()
+         */
+        @AttributeDefinition(
+                name = "Disable missing users",
+                description = "If true, users that no longer exist on the 
external provider will be locally disabled, " +
+                        "and re-enabled if they become valid again. If false 
(default) they will be removed."
+        )
+        boolean user_disableMissing() default 
PARAM_DISABLE_MISSING_USERS_DEFAULT;
+
+        /**
+         * @see DefaultSyncConfig.Group#getExpirationTime()
+         */
+        @AttributeDefinition(
+                name = "Group Expiration Time",
+                description = "Duration until a synced group expires (eg. '1h 
30m' or '1d')."
+        )
+        String group_expirationTime() default 
PARAM_GROUP_EXPIRATION_TIME_DEFAULT;
+
+        /**
+         * @see DefaultSyncConfig.Group#getAutoMembership()
+         */
+        @AttributeDefinition(
+                name = "Group auto membership",
+                description = "List of groups that a synced group is added to 
automatically",
+                cardinality = Integer.MAX_VALUE
+        )
+        String[] group_autoMembership();
+
+        /**
+         * @see DefaultSyncConfig.Group#getPropertyMapping()
+         */
+        @AttributeDefinition(
+                name = "Group property mapping",
+                description = "List mapping definition of local properties 
from external ones.",
+                cardinality = Integer.MAX_VALUE
+        )
+        String[] group_propertyMapping();
+
+        /**
+         * @see DefaultSyncConfig.Group#getPathPrefix()
+         */
+        @AttributeDefinition(
+                name = "Group Path Prefix",
+                description = "The path prefix used when creating new groups."
+        )
+        String group_pathPrefix() default PARAM_GROUP_PATH_PREFIX_DEFAULT;
+
+        /**
+         * @see DefaultSyncConfig.Group#getDynamicGroups()
+         */
+        @AttributeDefinition(
+                name = "Dynamic Groups",
+                description = "If enabled external identity groups are 
synchronized as dynamic groups i.e. members/membership " +
+                        "is resolved dynamically by a 
DynamicMembershipProvider. Note: currently this option only takes effect " +
+                        "if 'User Dynamic Membership' is enabled."
+        )
+        boolean group_dynamicGroups() default 
PARAM_GROUP_DYNAMIC_GROUPS_DEFAULT;
+
+        /**
+         * @see Authorizable#isApplyRFC7613UsernameCaseMapped()
+         */
+        @AttributeDefinition(
+                name = "RFC7613 Username Normalization Profile",
+                description = "Enable the UsercaseMappedProfile defined in 
RFC7613 for username normalization."
+        )
+        boolean enableRFC7613UsercaseMappedProfile() default 
PARAM_ENABLE_RFC7613_USERCASE_MAPPED_PROFILE_DEFAULT;
+    }
+
     /**
      * Creates a new LDAP provider configuration based on the properties store 
in the given parameters.
      * @param params the configuration parameters.
diff --git 
a/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandler.java
 
b/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandler.java
index d2051aa4c1..9d24a042a0 100644
--- 
a/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandler.java
+++ 
b/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandler.java
@@ -17,11 +17,10 @@
 package org.apache.jackrabbit.oak.spi.security.authentication.external.impl;
 
 import org.apache.jackrabbit.guava.common.collect.Iterators;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.ConfigurationPolicy;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Service;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
 import org.apache.jackrabbit.api.security.user.Authorizable;
 import org.apache.jackrabbit.api.security.user.Group;
 import org.apache.jackrabbit.api.security.user.UserManager;
@@ -40,6 +39,7 @@ import 
org.apache.jackrabbit.oak.spi.whiteboard.AbstractServiceTracker;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.osgi.framework.BundleContext;
+import org.osgi.service.metatype.annotations.Designate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -59,9 +59,16 @@ import java.util.Set;
  */
 @Component(
         // note that the metatype information is generated from 
DefaultSyncConfig
-        policy = ConfigurationPolicy.REQUIRE
+        configurationPolicy = ConfigurationPolicy.REQUIRE,
+        service = {
+                SyncHandler.class,
+                AutoMembershipAware.class
+        }
+)
+@Designate(
+        ocd = DefaultSyncConfigImpl.Configuration.class,
+        factory = true
 )
-@Service
 public class DefaultSyncHandler implements SyncHandler, AutoMembershipAware {
 
     /**
diff --git 
a/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalIDPManagerImpl.java
 
b/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalIDPManagerImpl.java
index a7d74ea962..9662084750 100644
--- 
a/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalIDPManagerImpl.java
+++ 
b/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalIDPManagerImpl.java
@@ -16,10 +16,6 @@
  */
 package org.apache.jackrabbit.oak.spi.security.authentication.external.impl;
 
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard;
 import 
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityProvider;
 import 
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityProviderManager;
@@ -27,14 +23,21 @@ import 
org.apache.jackrabbit.oak.spi.whiteboard.AbstractServiceTracker;
 import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Deactivate;
 
 /**
  * {@code ExternalIDPManagerImpl} is used to manage registered external 
identity provider. This class automatically
  * tracks the IDPs that are registered via OSGi but can also be used in 
non-OSGi environments by manually adding and
  * removing the providers.
  */
-@Component(immediate = true)
-@Service
+@Component(
+        immediate = true,
+        service = {
+                ExternalIdentityProviderManager.class
+        }
+)
 public class ExternalIDPManagerImpl extends 
AbstractServiceTracker<ExternalIdentityProvider> implements 
ExternalIdentityProviderManager {
 
     /**
diff --git 
a/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.java
 
b/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.java
index cebec28580..678079a44d 100644
--- 
a/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.java
+++ 
b/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.java
@@ -22,15 +22,6 @@ import javax.security.auth.spi.LoginModule;
 
 import org.apache.jackrabbit.guava.common.collect.ImmutableMap;
 import org.apache.felix.jaas.LoginModuleFactory;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.ConfigurationPolicy;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.jackrabbit.oak.api.ContentRepository;
 import org.apache.jackrabbit.oak.commons.jmx.JmxUtil;
 import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard;
@@ -45,6 +36,16 @@ import org.apache.jackrabbit.oak.spi.whiteboard.Registration;
 import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -53,62 +54,66 @@ import org.slf4j.LoggerFactory;
  * via OSGi config.
  */
 @Component(
-        label = "Apache Jackrabbit Oak External Login Module",
-        metatype = true,
-        policy = ConfigurationPolicy.REQUIRE,
-        configurationFactory = true
+        configurationPolicy = ConfigurationPolicy.REQUIRE,
+        service = {
+                LoginModuleFactory.class,
+                SyncHandlerMapping.class
+        }
+)
+@Designate(
+        ocd = ExternalLoginModuleFactory.Configuration.class,
+        factory = true
 )
-@Service
 public class ExternalLoginModuleFactory implements LoginModuleFactory, 
SyncHandlerMapping {
 
-    private static final Logger log = 
LoggerFactory.getLogger(ExternalLoginModuleFactory.class);
-
-    @SuppressWarnings("UnusedDeclaration")
-    @Property(
-            intValue = 150,
-            label = "JAAS Ranking",
-            description = "Specifying the ranking (i.e. sort order) of this 
login module entry. The entries are sorted " +
-                    "in a descending order (i.e. higher value ranked 
configurations come first)."
-    )
-    public static final String JAAS_RANKING = LoginModuleFactory.JAAS_RANKING;
-
-    @SuppressWarnings("UnusedDeclaration")
-    @Property(
-            value = "SUFFICIENT",
-            label = "JAAS Control Flag",
-            description = "Property specifying whether or not a LoginModule is 
REQUIRED, REQUISITE, SUFFICIENT or " +
-                    "OPTIONAL. Refer to the JAAS configuration documentation 
for more details around the meaning of " +
-                    "these flags."
-    )
-    public static final String JAAS_CONTROL_FLAG = 
LoginModuleFactory.JAAS_CONTROL_FLAG;
-
-    @SuppressWarnings("UnusedDeclaration")
-    @Property(
-            label = "JAAS Realm",
-            description = "The realm name (or application name) against which 
the LoginModule  is be registered. If no " +
-                    "realm name is provided then LoginModule is registered 
with a default realm as configured in " +
-                    "the Felix JAAS configuration."
-    )
-    public static final String JAAS_REALM_NAME = 
LoginModuleFactory.JAAS_REALM_NAME;
-
-    @Property(
-            label = "Identity Provider Name",
-            description = "Name of the identity provider (for example: 
'ldap')."
+    @ObjectClassDefinition(
+            id = 
"org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModuleFactory",
+            name = "Apache Jackrabbit Oak External Login Module"
     )
-    public static final String PARAM_IDP_NAME = 
SyncHandlerMapping.PARAM_IDP_NAME;
+    @interface Configuration {
+        @AttributeDefinition(
+                name = "JAAS Ranking",
+                description = "Specifying the ranking (i.e. sort order) of 
this login module entry. The entries are sorted " +
+                        "in a descending order (i.e. higher value ranked 
configurations come first)."
+        )
+        int jaas_ranking() default 150;
+
+        @AttributeDefinition(
+                name = "JAAS Control Flag",
+                description = "Property specifying whether or not a 
LoginModule is REQUIRED, REQUISITE, SUFFICIENT or " +
+                        "OPTIONAL. Refer to the JAAS configuration 
documentation for more details around the meaning of " +
+                        "these flags."
+        )
+        String jaas_controlFlag() default "SUFFICIENT";
+
+        @AttributeDefinition(
+                name = "JAAS Realm",
+                description = "The realm name (or application name) against 
which the LoginModule  is be registered. If no " +
+                        "realm name is provided then LoginModule is registered 
with a default realm as configured in " +
+                        "the Felix JAAS configuration."
+        )
+        String jaas_realmName();
+
+        @AttributeDefinition(
+                name = "Identity Provider Name",
+                description = "Name of the identity provider (for example: 
'ldap')."
+        )
+        String idp_name();
+
+        @AttributeDefinition(
+                name = "Sync Handler Name",
+                description = "Name of the sync handler."
+        )
+        String sync_handlerName() default DefaultSyncConfig.DEFAULT_NAME;
+    }
 
-    @Property(
-            value = DefaultSyncConfig.DEFAULT_NAME,
-            label = "Sync Handler Name",
-            description = "Name of the sync handler."
-    )
-    public static final String PARAM_SYNC_HANDLER_NAME = 
SyncHandlerMapping.PARAM_SYNC_HANDLER_NAME;
+    private static final Logger log = 
LoggerFactory.getLogger(ExternalLoginModuleFactory.class);
 
-    @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = 
ReferencePolicy.DYNAMIC)
-    private SecurityProvider securityProvider;
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = 
ReferencePolicy.DYNAMIC)
+    private volatile SecurityProvider securityProvider;
 
-    @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = 
ReferencePolicy.DYNAMIC)
-    private ContentRepository contentRepository;
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = 
ReferencePolicy.DYNAMIC)
+    private volatile ContentRepository contentRepository;
 
     @Reference
     private SyncManager syncManager;
diff --git 
a/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/SyncManagerImpl.java
 
b/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/SyncManagerImpl.java
index 3599618f6c..5b3e337675 100644
--- 
a/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/SyncManagerImpl.java
+++ 
b/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/SyncManagerImpl.java
@@ -17,10 +17,6 @@
 
 package org.apache.jackrabbit.oak.spi.security.authentication.external.impl;
 
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard;
 import 
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncHandler;
 import 
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncManager;
@@ -28,14 +24,21 @@ import 
org.apache.jackrabbit.oak.spi.whiteboard.AbstractServiceTracker;
 import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Deactivate;
 
 /**
  * {@code SyncManagerImpl} is used to manage registered sync handlers. This 
class automatically
  * tracks the SyncHandlers that are registered via OSGi but can also be used 
in non-OSGi environments by manually
  * adding and removing the handlers.
  */
-@Component(immediate = true)
-@Service
+@Component(
+        immediate = true,
+        service = {
+                SyncManager.class
+        }
+)
 public class SyncManagerImpl extends AbstractServiceTracker<SyncHandler> 
implements SyncManager {
 
     /**
diff --git 
a/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java
 
b/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java
index 0e31a70945..222fd291f4 100644
--- 
a/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java
+++ 
b/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java
@@ -17,13 +17,6 @@
 package 
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.principal;
 
 import org.apache.jackrabbit.guava.common.collect.ImmutableList;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.PropertyOption;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.jackrabbit.api.security.principal.PrincipalManager;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
@@ -51,6 +44,13 @@ import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import org.osgi.service.metatype.annotations.Option;
 
 import java.security.Principal;
 import java.util.Collections;
@@ -58,7 +58,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import static 
org.apache.jackrabbit.oak.spi.security.RegistrationConstants.OAK_SECURITY_NAME;
 import static 
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalIdentityConstants.PARAM_PROTECT_EXTERNAL_IDENTITIES;
 import static 
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalIdentityConstants.VALUE_PROTECT_EXTERNAL_IDENTITIES_PROTECTED;
 import static 
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalIdentityConstants.VALUE_PROTECT_EXTERNAL_IDENTITIES_NONE;
@@ -75,34 +74,57 @@ import static 
org.apache.jackrabbit.oak.spi.security.authentication.external.imp
  * @see <a href="https://issues.apache.org/jira/browse/OAK-4101";>OAK-4101</a>
  */
 @Component(
-        metatype = true,
-        label = "Apache Jackrabbit Oak External PrincipalConfiguration",
-        immediate = true
+        immediate = true,
+        service = {
+                PrincipalConfiguration.class,
+                SecurityConfiguration.class
+        }
+)
+@Designate(
+        ocd = ExternalPrincipalConfiguration.Configuration.class
 )
-@Service({PrincipalConfiguration.class, SecurityConfiguration.class})
-@Properties({
-        @Property(name = ExternalIdentityConstants.PARAM_PROTECT_EXTERNAL_IDS,
-                label = "External Identity Protection",
-                description = "If disabled rep:externalId properties won't be 
properly protected (backwards compatible behavior). NOTE: for security reasons 
it is strongly recommend to keep the protection enabled!",
-                boolValue = 
ExternalIdentityConstants.DEFAULT_PROTECT_EXTERNAL_IDS),
-        @Property(name = PARAM_PROTECT_EXTERNAL_IDENTITIES,
-                label = "External User and Group Protection",
+public class ExternalPrincipalConfiguration extends ConfigurationBase 
implements PrincipalConfiguration {
+
+    @ObjectClassDefinition(
+            id = 
"org.apache.jackrabbit.oak.spi.security.authentication.external.impl.principal.ExternalPrincipalConfiguration",
+            name = "Apache Jackrabbit Oak External PrincipalConfiguration"
+    )
+    @interface Configuration {
+        @AttributeDefinition(
+                name = "External Identity Protection",
+                description = "If disabled rep:externalId properties won't be 
properly protected (backwards compatible behavior). NOTE: for security reasons 
it is strongly recommend to keep the protection enabled!"
+        )
+        boolean protectExternalId() default 
ExternalIdentityConstants.DEFAULT_PROTECT_EXTERNAL_IDS;
+
+        @AttributeDefinition(
+                name = "External User and Group Protection",
                 description = "If 'None' is selected the synchronized external 
users/groups won't be protected (backwards compatible behavior) and can be 
edited like local users/groups. NOTE: in order to avoid having inconsistencies 
between the IDP that defines the external identities and local synced 
identities it is recommend to enable the protection. With option 'Warn' the 
protection is disabled but warnings will be logged.",
                 options = {
-                    @PropertyOption(name = 
VALUE_PROTECT_EXTERNAL_IDENTITIES_NONE, value = 
VALUE_PROTECT_EXTERNAL_IDENTITIES_NONE),
-                    @PropertyOption(name = 
VALUE_PROTECT_EXTERNAL_IDENTITIES_WARN, value = 
VALUE_PROTECT_EXTERNAL_IDENTITIES_WARN),
-                    @PropertyOption(name = 
VALUE_PROTECT_EXTERNAL_IDENTITIES_PROTECTED, value = 
VALUE_PROTECT_EXTERNAL_IDENTITIES_PROTECTED)
-                }),
-        @Property(name = 
ExternalIdentityConstants.PARAM_SYSTEM_PRINCIPAL_NAMES, 
-                label = "System Principal Names", 
-                description = "Names of additional 'SystemUserPrincipal' 
instances that are excluded from the protection check. Note that this 
configuration does not grant the required permission to perform the 
operation.", 
-                value = {}, 
-                cardinality = 10),
-        @Property(name = OAK_SECURITY_NAME,
-                propertyPrivate= true, 
-                value = 
"org.apache.jackrabbit.oak.spi.security.authentication.external.impl.principal.ExternalPrincipalConfiguration")
-})
-public class ExternalPrincipalConfiguration extends ConfigurationBase 
implements PrincipalConfiguration {
+                        @Option(
+                                label = VALUE_PROTECT_EXTERNAL_IDENTITIES_NONE,
+                                value = VALUE_PROTECT_EXTERNAL_IDENTITIES_NONE
+                        ),
+                        @Option(
+                                label = VALUE_PROTECT_EXTERNAL_IDENTITIES_WARN,
+                                value = VALUE_PROTECT_EXTERNAL_IDENTITIES_WARN
+                        ),
+                        @Option(
+                                label = 
VALUE_PROTECT_EXTERNAL_IDENTITIES_PROTECTED,
+                                value = 
VALUE_PROTECT_EXTERNAL_IDENTITIES_PROTECTED
+                        )
+                }
+        )
+        String protectExternalIdentities();
+
+        @AttributeDefinition(
+                name = "System Principal Names",
+                description = "Names of additional 'SystemUserPrincipal' 
instances that are excluded from the protection check. Note that this 
configuration does not grant the required permission to perform the operation.",
+                cardinality = 10
+        )
+        String[] systemPrincipalNames();
+
+        String oak_security_name() default 
"org.apache.jackrabbit.oak.spi.security.authentication.external.impl.principal.ExternalPrincipalConfiguration";
+    }
     
     private SyncConfigTracker syncConfigTracker;
     private SyncHandlerMappingTracker syncHandlerMappingTracker;
diff --git 
a/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SynMBeanImplOSGiTest.java
 
b/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SynMBeanImplOSGiTest.java
index 0b3bfa05d7..5f3d1e73a1 100644
--- 
a/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SynMBeanImplOSGiTest.java
+++ 
b/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SynMBeanImplOSGiTest.java
@@ -93,6 +93,7 @@ public class SynMBeanImplOSGiTest extends 
ExternalLoginTestBase {
     public void testContentRepositoryAndSecurityProviderServices() throws 
Exception {
         context.registerService(ContentRepository.class, 
getContentRepository());
         context.registerService(SecurityProvider.class, getSecurityProvider());
+        context.registerInjectActivateService(externalLoginModuleFactory);
         assertSyncBeanRegistration(externalLoginModuleFactory, true);
     }
 


Reply via email to