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

amichair pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/aries-rsa.git

commit c7ac876fddaff587bf253739a1cd8a28beabc31a
Author: Amichai Rothman <[email protected]>
AuthorDate: Sun Mar 29 20:27:35 2026 +0300

    ARIES-2216 Better-define the exported service properties that define a 
unique endpoint
---
 .../aries/rsa/core/RemoteServiceAdminCore.java     | 35 +++++++++++++++++-----
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git 
a/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java 
b/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
index d89d8991..7748468c 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/RemoteServiceAdminCore.java
@@ -31,6 +31,7 @@ import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -305,9 +306,20 @@ public class RemoteServiceAdminCore implements 
RemoteServiceAdmin {
     }
 
     /**
-     * Converts the given properties map into one that can be used as a map 
key itself.
-     * For example, if a value is an array, it is converted into a list so 
that the
-     * equals method will compare it properly.
+     * Creates a unique key from the given exported service properties.
+     * <p>
+     * This key is used to store and lookup export registrations for a service,
+     * and so determines when a service export already exists for the given
+     * properties or whether a new one needs to be created.
+     * <p>
+     * The key must be comparable using the {@code equals} method so it can be 
used as
+     * a map key. Specifically, array values are converted into lists so they 
can be compared.
+     * <p>
+     * Custom service properties that are not RSA/distribution properties are 
ignored
+     * since they do not affect the export and should not cause a new endpoint 
to be
+     * created. It is not well-defined which properties are unique to and 
endpoint and
+     * which are not, but we do our best - currently we include the 
objectClass,
+     * service.* and config-type prefixed properties in the key.
      *
      * @param properties a properties map
      * @return a map that represents the given map, but can be safely used as 
a map key itself
@@ -315,14 +327,21 @@ public class RemoteServiceAdminCore implements 
RemoteServiceAdmin {
     private Map<String, Object> makeKey(Map<String, Object> properties) {
         // FIXME: we should also make logically equal values actually compare 
as equal
         // (e.g. String+ values should be normalized)
+        List<String> configTypes = 
StringPlus.normalize(properties.get(Constants.SERVICE_EXPORTED_CONFIGS));
         Map<String, Object> converted = new HashMap<>(properties.size());
         for (Map.Entry<String, Object> entry : properties.entrySet()) {
-            Object val = entry.getValue();
-            // convert arrays into lists so that they can be compared via 
equals()
-            if (val instanceof Object[]) {
-                val = Arrays.asList((Object[])val);
+            String k = entry.getKey().toLowerCase(Locale.ROOT);
+            // a heuristic for which service properties affect the exported 
endpoint and
+            // which do not (and should reuse an existing endpoint and not 
create a new one)
+            if (k.equals("objectclass") || k.startsWith("service.")
+                   || (configTypes != null && 
configTypes.stream().anyMatch(k::startsWith))) {
+                Object val = entry.getValue();
+                // convert arrays into lists so that they can be compared via 
equals()
+                if (val instanceof Object[]) {
+                    val = Arrays.asList((Object[]) val);
+                }
+                converted.put(k, val);
             }
-            converted.put(entry.getKey(), val);
         }
         return converted;
     }

Reply via email to