CAMEL-11743: camel-ldap - Make it possible to use ENV when configuring DirContext
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/b7481fb7 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/b7481fb7 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/b7481fb7 Branch: refs/heads/master Commit: b7481fb7209a7914980c267d3751747d13f7b4af Parents: 439f853 Author: Claus Ibsen <davscl...@apache.org> Authored: Sun Sep 3 16:25:03 2017 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Sun Sep 3 16:25:03 2017 +0200 ---------------------------------------------------------------------- .../src/main/docs/ldap-component.adoc | 2 +- .../camel/component/ldap/LdapEndpoint.java | 6 +- .../camel/component/ldap/LdapProducer.java | 24 +++- .../camel/component/ldap/LdapRouteTwoTest.java | 142 +++++++++++++++++++ 4 files changed, 169 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/b7481fb7/components/camel-ldap/src/main/docs/ldap-component.adoc ---------------------------------------------------------------------- diff --git a/components/camel-ldap/src/main/docs/ldap-component.adoc b/components/camel-ldap/src/main/docs/ldap-component.adoc index ec7f452..51f7b91 100644 --- a/components/camel-ldap/src/main/docs/ldap-component.adoc +++ b/components/camel-ldap/src/main/docs/ldap-component.adoc @@ -58,7 +58,7 @@ with the following path and query parameters: [width="100%",cols="2,5,^1,2",options="header"] |======================================================================= | Name | Description | Default | Type -| **dirContextName** | *Required* Name of javax.naming.directory.DirContext bean to lookup in the registry. | | String +| **dirContextName** | *Required* 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 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. | | String |======================================================================= #### Query Parameters (5 parameters): http://git-wip-us.apache.org/repos/asf/camel/blob/b7481fb7/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapEndpoint.java ---------------------------------------------------------------------- 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 131c1b3..7ba8138 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 @@ -17,6 +17,7 @@ package org.apache.camel.component.ldap; import java.net.URISyntaxException; +import java.util.Map; import javax.naming.directory.SearchControls; import org.apache.camel.Consumer; @@ -78,7 +79,10 @@ public class LdapEndpoint extends DefaultEndpoint { } /** - * Name of {@link javax.naming.directory.DirContext} bean to lookup in the registry. + * 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. */ public void setDirContextName(String dirContextName) { this.dirContextName = dirContextName; http://git-wip-us.apache.org/repos/asf/camel/blob/b7481fb7/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapProducer.java ---------------------------------------------------------------------- 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 cbde266..8e1e67b 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 @@ -18,10 +18,13 @@ package org.apache.camel.component.ldap; import java.util.ArrayList; import java.util.Arrays; +import java.util.Hashtable; import java.util.List; +import java.util.Map; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.naming.ldap.Control; @@ -30,6 +33,7 @@ import javax.naming.ldap.PagedResultsControl; import javax.naming.ldap.PagedResultsResponseControl; import org.apache.camel.Exchange; +import org.apache.camel.NoSuchBeanException; import org.apache.camel.impl.DefaultProducer; /** @@ -85,7 +89,7 @@ public class LdapProducer extends DefaultProducer { } } - protected DirContext getDirContext() { + protected DirContext getDirContext() throws NamingException { // Obtain our ldap context. We do this by looking up the context in our registry. // Note though that a new context is expected each time. Therefore if spring is // being used then use prototype="scope". If you do not then you might experience @@ -93,8 +97,22 @@ public class LdapProducer extends DefaultProducer { // On the other hand if you have a DirContext that is able to support concurrency // then using the default singleton scope is entirely sufficient. Most DirContext // classes will require prototype scope though. - DirContext dirContext = (DirContext) getEndpoint().getCamelContext().getRegistry().lookupByName(remaining); - return dirContext; + // if its a Map/Hashtable then we create a new context per time + + DirContext answer = null; + Object context = getEndpoint().getCamelContext().getRegistry().lookupByName(remaining); + if (context instanceof Hashtable) { + answer = new InitialDirContext((Hashtable<?, ?>) context); + } else if (context instanceof Map) { + Hashtable hash = new Hashtable((Map) context); + answer = new InitialDirContext(hash); + } else if (context instanceof DirContext) { + answer = (DirContext) context; + } else if (context != null) { + String msg = "Found bean: " + remaining + " in Registry of type: " + answer.getClass().getName() + " expected type was: " + DirContext.class.getName(); + throw new NoSuchBeanException(msg); + } + return answer; } private List<SearchResult> simpleSearch(DirContext ldapContext, String searchFilter) throws NamingException { http://git-wip-us.apache.org/repos/asf/camel/blob/b7481fb7/components/camel-ldap/src/test/java/org/apache/camel/component/ldap/LdapRouteTwoTest.java ---------------------------------------------------------------------- diff --git a/components/camel-ldap/src/test/java/org/apache/camel/component/ldap/LdapRouteTwoTest.java b/components/camel-ldap/src/test/java/org/apache/camel/component/ldap/LdapRouteTwoTest.java new file mode 100644 index 0000000..b262b69 --- /dev/null +++ b/components/camel-ldap/src/test/java/org/apache/camel/component/ldap/LdapRouteTwoTest.java @@ -0,0 +1,142 @@ +/** + * 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.util.Collection; +import java.util.Hashtable; +import javax.naming.directory.SearchResult; + +import org.apache.camel.CamelContext; +import org.apache.camel.Endpoint; +import org.apache.camel.Exchange; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.impl.SimpleRegistry; +import org.apache.directory.api.util.Network; +import org.apache.directory.server.annotations.CreateLdapServer; +import org.apache.directory.server.annotations.CreateTransport; +import org.apache.directory.server.core.annotations.ApplyLdifFiles; +import org.apache.directory.server.core.integ.AbstractLdapTestUnit; +import org.apache.directory.server.core.integ.FrameworkRunner; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +@RunWith(FrameworkRunner.class) +@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP")}) +@ApplyLdifFiles("org/apache/camel/component/ldap/LdapRouteTest.ldif") +public class LdapRouteTwoTest extends AbstractLdapTestUnit { + + private CamelContext camel; + private ProducerTemplate template; + private int port; + + @Before + public void setup() throws Exception { + // you can assign port number in the @CreateTransport annotation + port = super.getLdapServer().getPort(); + + // use ENV variables + Hashtable<String, String> env = new Hashtable(); + env.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory"); + env.put("java.naming.provider.url", Network.ldapLoopbackUrl(ldapServer.getPort())); + env.put("java.naming.security.principal", "uid=admin,ou=system"); + env.put("java.naming.security.credentials", "secret"); + env.put("java.naming.security.authentication", "simple"); + + SimpleRegistry reg = new SimpleRegistry(); + reg.put("localhost:" + port, env); + camel = new DefaultCamelContext(reg); + template = camel.createProducerTemplate(); + } + + @After + public void tearDown() throws Exception { + camel.stop(); + } + + @Test + public void testLdapRouteStandardTwo() throws Exception { + camel.addRoutes(createRouteBuilder("ldap:localhost:" + port + "?base=ou=system")); + camel.start(); + + Endpoint endpoint = camel.getEndpoint("direct:start"); + Exchange exchange = endpoint.createExchange(); + // then we set the LDAP filter on the in body + exchange.getIn().setBody("(!(ou=test1))"); + + // now we send the exchange to the endpoint, and receives the response from Camel + Exchange out = template.send(endpoint, exchange); + Collection<SearchResult> searchResults = defaultLdapModuleOutAssertions(out); + + assertFalse(contains("uid=test1,ou=test,ou=system", searchResults)); + assertTrue(contains("uid=test2,ou=test,ou=system", searchResults)); + assertTrue(contains("uid=testNoOU,ou=test,ou=system", searchResults)); + assertTrue(contains("uid=tcruise,ou=actors,ou=system", searchResults)); + + // call again + endpoint = camel.getEndpoint("direct:start"); + exchange = endpoint.createExchange(); + // then we set the LDAP filter on the in body + exchange.getIn().setBody("(!(ou=test1))"); + + // now we send the exchange to the endpoint, and receives the response from Camel + out = template.send(endpoint, exchange); + searchResults = defaultLdapModuleOutAssertions(out); + + assertFalse(contains("uid=test1,ou=test,ou=system", searchResults)); + assertTrue(contains("uid=test2,ou=test,ou=system", searchResults)); + assertTrue(contains("uid=testNoOU,ou=test,ou=system", searchResults)); + assertTrue(contains("uid=tcruise,ou=actors,ou=system", searchResults)); + } + + @SuppressWarnings("unchecked") + private Collection<SearchResult> defaultLdapModuleOutAssertions(Exchange out) { + // assertions of the response + assertNotNull(out); + assertNotNull(out.getOut()); + Collection<SearchResult> data = out.getOut().getBody(Collection.class); + assertNotNull("out body could not be converted to a Collection - was: " + out.getOut().getBody(), data); + return data; + } + + protected boolean contains(String dn, Collection<SearchResult> results) { + for (SearchResult result : results) { + if (result.getNameInNamespace().equals(dn)) { + return true; + } + } + + return false; + } + + protected RouteBuilder createRouteBuilder(final String ldapEndpointUrl) throws Exception { + return new RouteBuilder() { + // START SNIPPET: route + public void configure() throws Exception { + from("direct:start").to(ldapEndpointUrl); + } + // END SNIPPET: route + }; + } +}