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

davsclaus pushed a commit to branch CAMEL-26198-ldap-dircontext
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 8aaa07675c5f26ef090e1e2e7568d331152af122
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Nov 3 00:11:51 2026 +0100

    CAMEL-26198: camel-ldap - fail clearly when a DirContext bean was closed or 
is missing, and fix the embedded ApacheDS of the ITs
    
    The producer closes the DirContext after each search (CAMEL-1583), so a
    singleton InitialDirContext bean failed on the next exchange with a
    NoInitialContextException. The producer now tells it saw the same closed
    bean again and fails with an IllegalStateException that says to use a
    prototype scoped bean or a Hashtable/Map bean. The docs and the option
    description say a DirContext bean is closed after each use, and the
    credentials example binds the environment instead of a singleton context.
    
    A dirContextName with no bean in the registry gave an NPE in the search;
    it now fails with a NoSuchBeanException naming the bean.
    
    The test DirectoryExtension replaced the TLS key of the admin entry
    without the tlsKeyInfo object class, which ApacheDS 2.0.0.AM27 rejects
    (ERR_277), so the ITs failed in beforeAll. ApacheDS already generates a
    2048-bit key, so the workaround for old Java 8 releases is removed.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../org/apache/camel/catalog/components/ldap.json  |   2 +-
 .../apache/camel/catalog/docs/ldap-component.adoc  |  12 +-
 .../org/apache/camel/component/ldap/ldap.json      |   2 +-
 .../camel-ldap/src/main/docs/ldap-component.adoc   |  12 +-
 .../apache/camel/component/ldap/LdapEndpoint.java  |   7 +-
 .../apache/camel/component/ldap/LdapProducer.java  |  16 ++
 .../component/ldap/LdapProducerDirContextTest.java | 187 +++++++++++++++++++++
 .../server/core/integ5/DirectoryExtension.java     |  29 ----
 .../builder/endpoint/StaticEndpointBuilders.java   |  18 +-
 .../endpoint/dsl/LdapEndpointBuilderFactory.java   |  16 +-
 10 files changed, 249 insertions(+), 52 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ldap.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ldap.json
index 9511ea5f92bd..8ca68a3e2c54 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ldap.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ldap.json
@@ -32,7 +32,7 @@
     "producerOut": { "carriers": [ "list" ], "javaType": 
"java.util.List<javax.naming.directory.SearchResult>", "description": "The 
entries found under the base DN: a List of SearchResult, empty when none match, 
all the pages of them with pageSize" }
   },
   "properties": {
-    "dirContextName": { "index": 0, "kind": "path", "displayName": "Dir 
Context Name", "group": "producer", "label": "", "required": true, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Name of either a javax.naming.directory.DirContext, or java.util.Hashtable, or 
Map bean to lookup in the registry. If the bean is either a Hashtable or Map 
then a new javax.naming.directory.DirContext insta [...]
+    "dirContextName": { "index": 0, "kind": "path", "displayName": "Dir 
Context Name", "group": "producer", "label": "", "required": true, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Name of either a javax.naming.directory.DirContext, or java.util.Hashtable, or 
Map bean to lookup in the registry. If the bean is either a Hashtable or Map 
then a new javax.naming.directory.DirContext insta [...]
     "base": { "index": 1, "kind": "parameter", "displayName": "Base", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "ou=system", "description": "The base DN for searches." },
     "pageSize": { "index": 2, "kind": "parameter", "displayName": "Page Size", 
"group": "producer", "label": "", "required": false, "type": "integer", 
"javaType": "java.lang.Integer", "deprecated": false, "autowired": false, 
"secret": false, "description": "When specified the ldap module uses paging to 
retrieve all results (most LDAP Servers throw an exception when trying to 
retrieve more than 1000 entries in one query). To be able to use this a 
LdapContext (subclass of DirContext) has t [...]
     "returnedAttributes": { "index": 3, "kind": "parameter", "displayName": 
"Returned Attributes", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Comma-separated list of 
attributes that should be set in each entry of the result" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/ldap-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/ldap-component.adoc
index 7238a2d0bf7f..9b1bb8ebc6bf 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/ldap-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/ldap-component.adoc
@@ -117,6 +117,15 @@ The component then creates a new `DirContext` for each 
message, as the prototype
 The preceding example declares a regular Sun-based LDAP `DirContext`
 that connects anonymously to a locally hosted LDAP server.
 
+The producer closes the `DirContext` after each search. A `DirContext` bean 
must therefore be prototype scoped
+(`scope="prototype"` in Spring, `@Dependent` in Quarkus), so the registry 
gives a new instance for each message.
+A singleton `InitialDirContext` bean works for the first message only; the 
next message fails with an
+`IllegalStateException` that says the bean was closed. To share one bean, bind 
a `Hashtable` or `Map` with the
+environment of the `DirContext` instead, as in the YAML example, and the 
component creates and closes
+a new `DirContext` for each message.
+
+If no bean is found in the registry for the name in the URI, the message fails 
with a `NoSuchBeanException`.
+
 [NOTE]
 ====
 `DirContext` objects are *not* required to support concurrency by contract. It 
is therefore important to manage the directory context's lifecycle 
appropriately. In the Spring framework, `prototype` scoped objects are 
instantiated each time they are looked up to ensure concurrency and avoid 
sharing the same context between multiple threads.
@@ -212,8 +221,9 @@ props.setProperty(Context.SECURITY_AUTHENTICATION, 
"simple");
 props.setProperty(Context.SECURITY_PRINCIPAL, "cn=Manager");
 props.setProperty(Context.SECURITY_CREDENTIALS, "secret");
 
+// bind the environment (a Properties is a Hashtable), so a new DirContext is 
created for each message
 DefaultRegistry reg = new DefaultRegistry();
-reg.bind("myldap", new InitialLdapContext(props, null));
+reg.bind("myldap", props);
 
 from("direct:start").to("ldap:myldap?base=ou=test");
 ----
diff --git 
a/components/camel-ldap/src/generated/resources/META-INF/org/apache/camel/component/ldap/ldap.json
 
b/components/camel-ldap/src/generated/resources/META-INF/org/apache/camel/component/ldap/ldap.json
index 9511ea5f92bd..8ca68a3e2c54 100644
--- 
a/components/camel-ldap/src/generated/resources/META-INF/org/apache/camel/component/ldap/ldap.json
+++ 
b/components/camel-ldap/src/generated/resources/META-INF/org/apache/camel/component/ldap/ldap.json
@@ -32,7 +32,7 @@
     "producerOut": { "carriers": [ "list" ], "javaType": 
"java.util.List<javax.naming.directory.SearchResult>", "description": "The 
entries found under the base DN: a List of SearchResult, empty when none match, 
all the pages of them with pageSize" }
   },
   "properties": {
-    "dirContextName": { "index": 0, "kind": "path", "displayName": "Dir 
Context Name", "group": "producer", "label": "", "required": true, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Name of either a javax.naming.directory.DirContext, or java.util.Hashtable, or 
Map bean to lookup in the registry. If the bean is either a Hashtable or Map 
then a new javax.naming.directory.DirContext insta [...]
+    "dirContextName": { "index": 0, "kind": "path", "displayName": "Dir 
Context Name", "group": "producer", "label": "", "required": true, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Name of either a javax.naming.directory.DirContext, or java.util.Hashtable, or 
Map bean to lookup in the registry. If the bean is either a Hashtable or Map 
then a new javax.naming.directory.DirContext insta [...]
     "base": { "index": 1, "kind": "parameter", "displayName": "Base", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "ou=system", "description": "The base DN for searches." },
     "pageSize": { "index": 2, "kind": "parameter", "displayName": "Page Size", 
"group": "producer", "label": "", "required": false, "type": "integer", 
"javaType": "java.lang.Integer", "deprecated": false, "autowired": false, 
"secret": false, "description": "When specified the ldap module uses paging to 
retrieve all results (most LDAP Servers throw an exception when trying to 
retrieve more than 1000 entries in one query). To be able to use this a 
LdapContext (subclass of DirContext) has t [...]
     "returnedAttributes": { "index": 3, "kind": "parameter", "displayName": 
"Returned Attributes", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Comma-separated list of 
attributes that should be set in each entry of the result" },
diff --git a/components/camel-ldap/src/main/docs/ldap-component.adoc 
b/components/camel-ldap/src/main/docs/ldap-component.adoc
index 7238a2d0bf7f..9b1bb8ebc6bf 100644
--- a/components/camel-ldap/src/main/docs/ldap-component.adoc
+++ b/components/camel-ldap/src/main/docs/ldap-component.adoc
@@ -117,6 +117,15 @@ The component then creates a new `DirContext` for each 
message, as the prototype
 The preceding example declares a regular Sun-based LDAP `DirContext`
 that connects anonymously to a locally hosted LDAP server.
 
+The producer closes the `DirContext` after each search. A `DirContext` bean 
must therefore be prototype scoped
+(`scope="prototype"` in Spring, `@Dependent` in Quarkus), so the registry 
gives a new instance for each message.
+A singleton `InitialDirContext` bean works for the first message only; the 
next message fails with an
+`IllegalStateException` that says the bean was closed. To share one bean, bind 
a `Hashtable` or `Map` with the
+environment of the `DirContext` instead, as in the YAML example, and the 
component creates and closes
+a new `DirContext` for each message.
+
+If no bean is found in the registry for the name in the URI, the message fails 
with a `NoSuchBeanException`.
+
 [NOTE]
 ====
 `DirContext` objects are *not* required to support concurrency by contract. It 
is therefore important to manage the directory context's lifecycle 
appropriately. In the Spring framework, `prototype` scoped objects are 
instantiated each time they are looked up to ensure concurrency and avoid 
sharing the same context between multiple threads.
@@ -212,8 +221,9 @@ props.setProperty(Context.SECURITY_AUTHENTICATION, 
"simple");
 props.setProperty(Context.SECURITY_PRINCIPAL, "cn=Manager");
 props.setProperty(Context.SECURITY_CREDENTIALS, "secret");
 
+// bind the environment (a Properties is a Hashtable), so a new DirContext is 
created for each message
 DefaultRegistry reg = new DefaultRegistry();
-reg.bind("myldap", new InitialLdapContext(props, null));
+reg.bind("myldap", props);
 
 from("direct:start").to("ldap:myldap?base=ou=test");
 ----
diff --git 
a/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapEndpoint.java
 
b/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapEndpoint.java
index 9c41bef75c94..dfdd13914757 100644
--- 
a/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapEndpoint.java
+++ 
b/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapEndpoint.java
@@ -87,9 +87,10 @@ public class LdapEndpoint extends DefaultEndpoint {
      * Name of either a {@link javax.naming.directory.DirContext}, or {@link 
java.util.Hashtable}, or {@link Map} bean
      * to lookup in the registry. If the bean is either a Hashtable or Map 
then a new
      * {@link javax.naming.directory.DirContext} instance is created for each 
use. If the bean is a
-     * {@link javax.naming.directory.DirContext} then the bean is used as 
given. The latter may not be possible in all
-     * situations where the {@link javax.naming.directory.DirContext} must not 
be shared, and in those situations it can
-     * be better to use {@link java.util.Hashtable} or {@link Map} instead.
+     * {@link javax.naming.directory.DirContext} then the bean is used as 
given, and it is closed after each use, so the
+     * bean must be prototype scoped (a new instance for each lookup). A 
singleton
+     * {@link javax.naming.directory.InitialDirContext} bean works for one 
exchange only, so in those situations use
+     * {@link java.util.Hashtable} or {@link Map} instead.
      */
     public void setDirContextName(String dirContextName) {
         this.dirContextName = dirContextName;
diff --git 
a/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapProducer.java
 
b/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapProducer.java
index 5a2544aaeb3a..d5112a2bc418 100644
--- 
a/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapProducer.java
+++ 
b/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapProducer.java
@@ -22,6 +22,7 @@ import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 
+import javax.naming.InitialContext;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.directory.DirContext;
@@ -47,6 +48,8 @@ public class LdapProducer extends DefaultProducer {
     private final SearchControls searchControls;
     private final String searchBase;
     private final Integer pageSize;
+    // the last InitialContext this producer closed, to tell when the registry 
gives the same (closed) bean again
+    private volatile DirContext lastClosedContext;
 
     public LdapProducer(LdapEndpoint endpoint, String remaining, String base, 
int scope, Integer pageSize,
                         String returnedAttributes) {
@@ -89,6 +92,10 @@ public class LdapProducer extends DefaultProducer {
         } finally {
             if (dirContext != null) {
                 dirContext.close();
+                if (dirContext instanceof InitialContext) {
+                    // an InitialContext cannot be used after it is closed
+                    lastClosedContext = dirContext;
+                }
             }
         }
     }
@@ -111,11 +118,20 @@ public class LdapProducer extends DefaultProducer {
             Hashtable hash = new Hashtable((Map) context);
             answer = new InitialDirContext(hash);
         } else if (context instanceof DirContext) {
+            if (context == lastClosedContext) {
+                throw new IllegalStateException(
+                        "The DirContext bean: " + remaining + " was closed 
after the previous exchange, as the producer"
+                                                + " closes the DirContext 
after each search. Use a bean with prototype scope"
+                                                + " (a new DirContext for each 
lookup), or a Hashtable or Map bean with the"
+                                                + " environment of the 
DirContext, so a new DirContext is created for each exchange");
+            }
             answer = (DirContext) context;
         } else if (context != null) {
             String msg = "Found bean: " + remaining + " in Registry of type: " 
+ context.getClass().getName()
                          + " expected type was: " + DirContext.class.getName();
             throw new NoSuchBeanException(msg);
+        } else {
+            throw new NoSuchBeanException(remaining, 
DirContext.class.getName());
         }
         return answer;
     }
diff --git 
a/components/camel-ldap/src/test/java/org/apache/camel/component/ldap/LdapProducerDirContextTest.java
 
b/components/camel-ldap/src/test/java/org/apache/camel/component/ldap/LdapProducerDirContextTest.java
new file mode 100644
index 000000000000..69fcf025e677
--- /dev/null
+++ 
b/components/camel-ldap/src/test/java/org/apache/camel/component/ldap/LdapProducerDirContextTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.camel.component.ldap;
+
+import java.lang.reflect.Proxy;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchResult;
+import javax.naming.spi.InitialContextFactory;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.NoSuchBeanException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Tests how the producer gets the DirContext from the registry and closes it, 
with a fake DirContext.
+ */
+public class LdapProducerDirContextTest extends CamelTestSupport {
+
+    private static final AtomicInteger CREATED = new AtomicInteger();
+    private static final AtomicInteger CLOSED = new AtomicInteger();
+
+    @BeforeEach
+    void resetCounters() {
+        CREATED.set(0);
+        CLOSED.set(0);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:start").to("ldap:ldapserver?base=ou=system");
+                from("direct:missing").to("ldap:noSuchBean?base=ou=system");
+            }
+        };
+    }
+
+    @Test
+    void hashtableBeanCreatesAndClosesContextForEachExchange() {
+        context.getRegistry().bind("ldapserver", environment());
+
+        assertEquals(1, search().size());
+        assertEquals(1, search().size());
+
+        assertEquals(2, CREATED.get());
+        assertEquals(2, CLOSED.get());
+    }
+
+    @Test
+    void singletonInitialDirContextBeanFailsClearlyAfterItWasClosed() throws 
Exception {
+        context.getRegistry().bind("ldapserver", new 
InitialDirContext(environment()));
+
+        assertEquals(1, search().size());
+        assertEquals(1, CLOSED.get());
+
+        CamelExecutionException e = 
assertThrows(CamelExecutionException.class, this::search);
+        IllegalStateException cause = 
assertInstanceOf(IllegalStateException.class, e.getCause());
+        assertTrue(cause.getMessage().contains("The DirContext bean: 
ldapserver was closed"), cause.getMessage());
+        assertTrue(cause.getMessage().contains("prototype scope"), 
cause.getMessage());
+    }
+
+    @Test
+    void dirContextBeanThatIsNotAnInitialContextIsUsedForEachExchange() {
+        // a DirContext such as com.sun.jndi.ldap.LdapCtx connects again after 
it is closed
+        context.getRegistry().bind("ldapserver", fakeDirContext());
+
+        assertEquals(1, search().size());
+        assertEquals(1, search().size());
+
+        assertEquals(2, CLOSED.get());
+    }
+
+    @Test
+    void missingBeanFailsWithNoSuchBeanException() {
+        CamelExecutionException e = assertThrows(CamelExecutionException.class,
+                () -> template.requestBody("direct:missing", 
"(objectClass=*)"));
+        NoSuchBeanException cause = 
assertInstanceOf(NoSuchBeanException.class, e.getCause());
+        assertEquals("noSuchBean", cause.getName());
+    }
+
+    private List<?> search() {
+        return template.requestBody("direct:start", "(objectClass=*)", 
List.class);
+    }
+
+    private static Hashtable<String, String> environment() {
+        Hashtable<String, String> env = new Hashtable<>();
+        env.put(Context.INITIAL_CONTEXT_FACTORY, 
FakeContextFactory.class.getName());
+        return env;
+    }
+
+    private static DirContext fakeDirContext() {
+        CREATED.incrementAndGet();
+        return (DirContext) 
Proxy.newProxyInstance(LdapProducerDirContextTest.class.getClassLoader(),
+                new Class<?>[] { DirContext.class }, (proxy, method, args) -> {
+                    switch (method.getName()) {
+                        case "search":
+                            return new ListEnumeration(
+                                    List.of(new SearchResult("uid=test", null, 
new BasicAttributes())));
+                        case "close":
+                            CLOSED.incrementAndGet();
+                            return null;
+                        case "hashCode":
+                            return System.identityHashCode(proxy);
+                        case "equals":
+                            return proxy == args[0];
+                        case "toString":
+                            return "FakeDirContext";
+                        default:
+                            throw new 
UnsupportedOperationException(method.getName());
+                    }
+                });
+    }
+
+    public static class FakeContextFactory implements InitialContextFactory {
+
+        @Override
+        public Context getInitialContext(Hashtable<?, ?> environment) {
+            return fakeDirContext();
+        }
+    }
+
+    private static final class ListEnumeration implements 
NamingEnumeration<SearchResult> {
+
+        private final Iterator<SearchResult> it;
+
+        ListEnumeration(List<SearchResult> list) {
+            this.it = list.iterator();
+        }
+
+        @Override
+        public SearchResult next() {
+            return it.next();
+        }
+
+        @Override
+        public boolean hasMore() {
+            return it.hasNext();
+        }
+
+        @Override
+        public void close() {
+            // noop
+        }
+
+        @Override
+        public boolean hasMoreElements() {
+            return it.hasNext();
+        }
+
+        @Override
+        public SearchResult nextElement() {
+            return it.next();
+        }
+    }
+}
diff --git 
a/components/camel-ldap/src/test/java/org/apache/directory/server/core/integ5/DirectoryExtension.java
 
b/components/camel-ldap/src/test/java/org/apache/directory/server/core/integ5/DirectoryExtension.java
index d94b418578c1..2832944a1865 100644
--- 
a/components/camel-ldap/src/test/java/org/apache/directory/server/core/integ5/DirectoryExtension.java
+++ 
b/components/camel-ldap/src/test/java/org/apache/directory/server/core/integ5/DirectoryExtension.java
@@ -20,20 +20,12 @@ import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.UUID;
 
-import org.apache.directory.api.ldap.model.entry.DefaultModification;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.entry.Modification;
-import org.apache.directory.api.ldap.model.entry.ModificationOperation;
-import org.apache.directory.api.ldap.model.exception.LdapException;
-import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.api.util.FileUtils;
-import org.apache.directory.server.constants.ServerDNConstants;
 import org.apache.directory.server.core.api.DirectoryService;
 import org.apache.directory.server.core.api.changelog.ChangeLog;
 import org.apache.directory.server.core.factory.DefaultDirectoryServiceFactory;
 import org.apache.directory.server.core.factory.DirectoryServiceFactory;
 import org.apache.directory.server.core.factory.PartitionFactory;
-import org.apache.directory.server.core.security.TlsKeyGenerator;
 import org.apache.directory.server.ldap.LdapServer;
 import org.junit.jupiter.api.extension.AfterAllCallback;
 import org.junit.jupiter.api.extension.AfterEachCallback;
@@ -96,7 +88,6 @@ public class DirectoryExtension implements BeforeAllCallback, 
AfterAllCallback,
             }
             // Apply the class LDIFs
             DSAnnotationProcessor.applyLdifs(description, 
classDirectoryService);
-            updateTlsKey(classDirectoryService);
 
             // check if it has a LdapServerBuilder, then use the DS created 
above
             classLdapServer = 
ServerAnnotationProcessor.createLdapServer(description, classDirectoryService);
@@ -117,7 +108,6 @@ public class DirectoryExtension implements 
BeforeAllCallback, AfterAllCallback,
             if (methodDirectoryService != null) {
                 // Apply all the LDIFs
                 DSAnnotationProcessor.applyLdifs(classDescription, 
methodDirectoryService);
-                updateTlsKey(methodDirectoryService);
                 directoryService = methodDirectoryService;
             } else if (classDirectoryService != null) {
                 directoryService = classDirectoryService;
@@ -202,25 +192,6 @@ public class DirectoryExtension implements 
BeforeAllCallback, AfterAllCallback,
                 dirService.revert(revision);
             }
         }
-
-        private void updateTlsKey(DirectoryService ds) throws LdapException {
-            // Update TLS key for tests. Newer Java 8 releases consider RSA 
keys
-            // with less than 1024 bits as insecure and such are disabled by 
default, see
-            // 
http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html
-            Entry adminEntry = ds.getAdminSession().lookup(new 
Dn(ServerDNConstants.ADMIN_SYSTEM_DN));
-            TlsKeyGenerator.addKeyPair(adminEntry, 
TlsKeyGenerator.CERTIFICATE_PRINCIPAL_DN,
-                    TlsKeyGenerator.CERTIFICATE_PRINCIPAL_DN, "RSA", 1024);
-            Modification mod1 = new DefaultModification(
-                    ModificationOperation.REPLACE_ATTRIBUTE,
-                    adminEntry.get(TlsKeyGenerator.PRIVATE_KEY_AT));
-            Modification mod2 = new DefaultModification(
-                    ModificationOperation.REPLACE_ATTRIBUTE,
-                    adminEntry.get(TlsKeyGenerator.PUBLIC_KEY_AT));
-            Modification mod3 = new DefaultModification(
-                    ModificationOperation.REPLACE_ATTRIBUTE,
-                    adminEntry.get(TlsKeyGenerator.USER_CERTIFICATE_AT));
-            ds.getAdminSession().modify(adminEntry.getDn(), mod1, mod2, mod3);
-        }
     }
 
     @Override
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
index b6304de7d42b..623b7b0a0a11 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
@@ -11419,10 +11419,11 @@ public class StaticEndpointBuilders {
      * java.util.Hashtable, or Map bean to lookup in the registry. If the bean
      * is either a Hashtable or Map then a new 
javax.naming.directory.DirContext
      * instance is created for each use. If the bean is a
-     * javax.naming.directory.DirContext then the bean is used as given. The
-     * latter may not be possible in all situations where the
-     * javax.naming.directory.DirContext must not be shared, and in those
-     * situations it can be better to use java.util.Hashtable or Map instead.
+     * javax.naming.directory.DirContext then the bean is used as given, and it
+     * is closed after each use, so the bean must be prototype scoped (a new
+     * instance for each lookup). A singleton
+     * javax.naming.directory.InitialDirContext bean works for one exchange
+     * only, so in those situations use java.util.Hashtable or Map instead.
      * 
      * @param path dirContextName
      * @return the dsl builder
@@ -11445,10 +11446,11 @@ public class StaticEndpointBuilders {
      * java.util.Hashtable, or Map bean to lookup in the registry. If the bean
      * is either a Hashtable or Map then a new 
javax.naming.directory.DirContext
      * instance is created for each use. If the bean is a
-     * javax.naming.directory.DirContext then the bean is used as given. The
-     * latter may not be possible in all situations where the
-     * javax.naming.directory.DirContext must not be shared, and in those
-     * situations it can be better to use java.util.Hashtable or Map instead.
+     * javax.naming.directory.DirContext then the bean is used as given, and it
+     * is closed after each use, so the bean must be prototype scoped (a new
+     * instance for each lookup). A singleton
+     * javax.naming.directory.InitialDirContext bean works for one exchange
+     * only, so in those situations use java.util.Hashtable or Map instead.
      * 
      * @param componentName to use a custom component name for the endpoint
      * instead of the default name
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LdapEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LdapEndpointBuilderFactory.java
index d1a82502c443..ab1d6e9311ac 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LdapEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LdapEndpointBuilderFactory.java
@@ -204,10 +204,10 @@ public interface LdapEndpointBuilderFactory {
          * bean is either a Hashtable or Map then a new
          * javax.naming.directory.DirContext instance is created for each use.
          * If the bean is a javax.naming.directory.DirContext then the bean is
-         * used as given. The latter may not be possible in all situations 
where
-         * the javax.naming.directory.DirContext must not be shared, and in
-         * those situations it can be better to use java.util.Hashtable or Map
-         * instead.
+         * used as given, and it is closed after each use, so the bean must be
+         * prototype scoped (a new instance for each lookup). A singleton
+         * javax.naming.directory.InitialDirContext bean works for one exchange
+         * only, so in those situations use java.util.Hashtable or Map instead.
          * 
          * @param path dirContextName
          * @return the dsl builder
@@ -231,10 +231,10 @@ public interface LdapEndpointBuilderFactory {
          * bean is either a Hashtable or Map then a new
          * javax.naming.directory.DirContext instance is created for each use.
          * If the bean is a javax.naming.directory.DirContext then the bean is
-         * used as given. The latter may not be possible in all situations 
where
-         * the javax.naming.directory.DirContext must not be shared, and in
-         * those situations it can be better to use java.util.Hashtable or Map
-         * instead.
+         * used as given, and it is closed after each use, so the bean must be
+         * prototype scoped (a new instance for each lookup). A singleton
+         * javax.naming.directory.InitialDirContext bean works for one exchange
+         * only, so in those situations use java.util.Hashtable or Map instead.
          * 
          * @param componentName to use a custom component name for the endpoint
          * instead of the default name

Reply via email to