You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2018/07/03 02:48:19 UTC

[1/6] james-project git commit: JAMES-2441 Extract LDAP configuration in a POJO

Repository: james-project
Updated Branches:
  refs/heads/master dca7006e4 -> 21bb9757b


JAMES-2441 Extract LDAP configuration in a POJO


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/fcd09ee0
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/fcd09ee0
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/fcd09ee0

Branch: refs/heads/master
Commit: fcd09ee0daf66ca346b2f781e4a88fbfbd937a50
Parents: dca7006
Author: benwa <bt...@linagora.com>
Authored: Wed Jun 27 10:38:13 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Mon Jul 2 16:35:49 2018 +0700

----------------------------------------------------------------------
 .../user/ldap/LdapRepositoryConfiguration.java  | 306 +++++++++++++++++++
 .../user/ldap/ReadOnlyUsersLDAPRepository.java  | 214 ++++---------
 2 files changed, 357 insertions(+), 163 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/fcd09ee0/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/LdapRepositoryConfiguration.java
----------------------------------------------------------------------
diff --git a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/LdapRepositoryConfiguration.java b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/LdapRepositoryConfiguration.java
new file mode 100644
index 0000000..fe230f0
--- /dev/null
+++ b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/LdapRepositoryConfiguration.java
@@ -0,0 +1,306 @@
+/****************************************************************
+ * 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.james.user.ldap;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+
+public class LdapRepositoryConfiguration {
+    public static final String SUPPORTS_VIRTUAL_HOSTING = "supportsVirtualHosting";
+
+    public static LdapRepositoryConfiguration from(HierarchicalConfiguration configuration) throws ConfigurationException {
+        String ldapHost = configuration.getString("[@ldapHost]", "");
+        String principal = configuration.getString("[@principal]", "");
+        String credentials = configuration.getString("[@credentials]", "");
+        String userBase = configuration.getString("[@userBase]");
+        String userIdAttribute = configuration.getString("[@userIdAttribute]");
+        String userObjectClass = configuration.getString("[@userObjectClass]");
+        // Default is to use connection pooling
+        boolean useConnectionPool = configuration.getBoolean("[@useConnectionPool]", true);
+        int connectionTimeout = configuration.getInt("[@connectionTimeout]", -1);
+        int readTimeout = configuration.getInt("[@readTimeout]", -1);
+        // Default maximum retries is 1, which allows an alternate connection to
+        // be found in a multi-homed environment
+        int maxRetries = configuration.getInt("[@maxRetries]", 1);
+        boolean supportsVirtualHosting = configuration.getBoolean(SUPPORTS_VIRTUAL_HOSTING, false);
+        // Default retry start interval is 0 second
+        long retryStartInterval = configuration.getLong("[@retryStartInterval]", 0);
+        // Default maximum retry interval is 60 seconds
+        long retryMaxInterval = configuration.getLong("[@retryMaxInterval]", 60);
+        int scale = configuration.getInt("[@retryIntervalScale]", 1000); // seconds
+
+        HierarchicalConfiguration restrictionConfig = null;
+        // Check if we have a restriction we can use
+        // See JAMES-1204
+        if (configuration.containsKey("restriction[@memberAttribute]")) {
+            restrictionConfig = configuration.configurationAt("restriction");
+        }
+        ReadOnlyLDAPGroupRestriction restriction = new ReadOnlyLDAPGroupRestriction(restrictionConfig);
+
+        //see if there is a filter argument
+        String filter = configuration.getString("[@filter]");
+
+        Optional<String> administratorId = Optional.ofNullable(configuration.getString("[@administratorId]"));
+
+        return new LdapRepositoryConfiguration(
+            ldapHost,
+            principal,
+            credentials,
+            userBase,
+            userIdAttribute,
+            userObjectClass,
+            useConnectionPool,
+            connectionTimeout,
+            readTimeout,
+            maxRetries,
+            supportsVirtualHosting,
+            retryStartInterval,
+            retryMaxInterval,
+            scale,
+            restriction,
+            filter,
+            administratorId);
+    }
+
+    /**
+     * The URL of the LDAP server against which users are to be authenticated.
+     * Note that users are actually authenticated by binding against the LDAP
+     * server using the users &quot;dn&quot; and &quot;credentials&quot;.The
+     * value of this field is taken from the value of the configuration
+     * attribute &quot;ldapHost&quot;.
+     */
+    private final String ldapHost;
+
+    /**
+     * The user with which to initially bind to the LDAP server. The value of
+     * this field is taken from the configuration attribute
+     * &quot;principal&quot;.
+     */
+    private final String principal;
+
+    /**
+     * The password/credentials with which to initially bind to the LDAP server.
+     * The value of this field is taken from the configuration attribute
+     * &quot;credentials&quot;.
+     */
+    private final String credentials;
+
+    /**
+     * This is the LDAP context/sub-context within which to search for user
+     * entities. The value of this field is taken from the configuration
+     * attribute &quot;userBase&quot;.
+     */
+    private final String userBase;
+
+    /**
+     * The value of this field is taken from the configuration attribute
+     * &quot;userIdAttribute&quot;. This is the LDAP attribute type which holds
+     * the userId value. Note that this is not the same as the email address
+     * attribute.
+     */
+    private final String userIdAttribute;
+
+    /**
+     * The value of this field is taken from the configuration attribute
+     * &quot;userObjectClass&quot;. This is the LDAP object class to use in the
+     * search filter for user nodes under the userBase value.
+     */
+    private final String userObjectClass;
+
+    // Use a connection pool. Default is true.
+    private final boolean useConnectionPool;
+
+    // The connection timeout in milliseconds.
+    // A value of less than or equal to zero means to use the network protocol's
+    // (i.e., TCP's) timeout value.
+    private final int connectionTimeout;
+
+    // The LDAP read timeout in milliseconds.
+    private final int readTimeout;
+
+    // Maximum number of times to retry a connection attempts. Default is no
+    // retries.
+    private final int maxRetries;
+    private final boolean supportsVirtualHosting;
+    private final long retryStartInterval;
+    private final long retryMaxInterval;
+    private final int scale;
+
+    /**
+     * Encapsulates the information required to restrict users to LDAP groups or
+     * roles. This object is populated from the contents of the configuration
+     * element &lt;restriction&gt;.
+     */
+    private final ReadOnlyLDAPGroupRestriction restriction;
+
+    /**
+     * The value of this field is taken from the configuration attribute &quot;filter&quot;.
+     * This is the search filter to use to find the desired user.
+     */
+    private final String filter;
+
+    /**
+     * UserId of the administrator
+     * The administrator is allowed to log in as other users
+     */
+    private final Optional<String> administratorId;
+
+    private LdapRepositoryConfiguration(String ldapHost, String principal, String credentials, String userBase, String userIdAttribute,
+                                       String userObjectClass, boolean useConnectionPool, int connectionTimeout, int readTimeout,
+                                       int maxRetries, boolean supportsVirtualHosting, long retryStartInterval, long retryMaxInterval,
+                                       int scale, ReadOnlyLDAPGroupRestriction restriction, String filter,
+                                       Optional<String> administratorId) throws ConfigurationException {
+        this.ldapHost = ldapHost;
+        this.principal = principal;
+        this.credentials = credentials;
+        this.userBase = userBase;
+        this.userIdAttribute = userIdAttribute;
+        this.userObjectClass = userObjectClass;
+        this.useConnectionPool = useConnectionPool;
+        this.connectionTimeout = connectionTimeout;
+        this.readTimeout = readTimeout;
+        this.maxRetries = maxRetries;
+        this.supportsVirtualHosting = supportsVirtualHosting;
+        this.retryStartInterval = retryStartInterval;
+        this.retryMaxInterval = retryMaxInterval;
+        this.scale = scale;
+        this.restriction = restriction;
+        this.filter = filter;
+        this.administratorId = administratorId;
+
+        checkState();
+    }
+
+    private void checkState() throws ConfigurationException {
+        if (userBase == null) {
+            throw new ConfigurationException("[@userBase] is mandatory");
+        }
+        if (userIdAttribute == null) {
+            throw new ConfigurationException("[@userIdAttribute] is mandatory");
+        }
+        if (userObjectClass == null) {
+            throw new ConfigurationException("[@userObjectClass] is mandatory");
+        }
+    }
+
+    public String getLdapHost() {
+        return ldapHost;
+    }
+
+    public String getPrincipal() {
+        return principal;
+    }
+
+    public String getCredentials() {
+        return credentials;
+    }
+
+    public String getUserBase() {
+        return userBase;
+    }
+
+    public String getUserIdAttribute() {
+        return userIdAttribute;
+    }
+
+    public String getUserObjectClass() {
+        return userObjectClass;
+    }
+
+    public boolean useConnectionPool() {
+        return useConnectionPool;
+    }
+
+    public int getConnectionTimeout() {
+        return connectionTimeout;
+    }
+
+    public int getReadTimeout() {
+        return readTimeout;
+    }
+
+    public int getMaxRetries() {
+        return maxRetries;
+    }
+
+    public boolean supportsVirtualHosting() {
+        return supportsVirtualHosting;
+    }
+
+    public long getRetryStartInterval() {
+        return retryStartInterval;
+    }
+
+    public long getRetryMaxInterval() {
+        return retryMaxInterval;
+    }
+
+    public int getScale() {
+        return scale;
+    }
+
+    public ReadOnlyLDAPGroupRestriction getRestriction() {
+        return restriction;
+    }
+
+    public String getFilter() {
+        return filter;
+    }
+
+    public Optional<String> getAdministratorId() {
+        return administratorId;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof LdapRepositoryConfiguration) {
+            LdapRepositoryConfiguration that = (LdapRepositoryConfiguration) o;
+
+            return Objects.equals(this.useConnectionPool, that.useConnectionPool)
+                && Objects.equals(this.connectionTimeout, that.connectionTimeout)
+                && Objects.equals(this.readTimeout, that.readTimeout)
+                && Objects.equals(this.maxRetries, that.maxRetries)
+                && Objects.equals(this.supportsVirtualHosting, that.supportsVirtualHosting)
+                && Objects.equals(this.retryStartInterval, that.retryStartInterval)
+                && Objects.equals(this.retryMaxInterval, that.retryMaxInterval)
+                && Objects.equals(this.scale, that.scale)
+                && Objects.equals(this.ldapHost, that.ldapHost)
+                && Objects.equals(this.principal, that.principal)
+                && Objects.equals(this.credentials, that.credentials)
+                && Objects.equals(this.userBase, that.userBase)
+                && Objects.equals(this.userIdAttribute, that.userIdAttribute)
+                && Objects.equals(this.userObjectClass, that.userObjectClass)
+                && Objects.equals(this.restriction, that.restriction)
+                && Objects.equals(this.filter, that.filter)
+                && Objects.equals(this.administratorId, that.administratorId);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(ldapHost, principal, credentials, userBase, userIdAttribute, userObjectClass, useConnectionPool,
+            connectionTimeout, readTimeout, maxRetries, supportsVirtualHosting, retryStartInterval, retryMaxInterval, scale,
+            restriction, filter, administratorId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fcd09ee0/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
----------------------------------------------------------------------
diff --git a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
index 3007d85..6f6677b 100644
--- a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
+++ b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
@@ -25,7 +25,6 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Properties;
 import java.util.Set;
 
@@ -59,6 +58,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.github.steveash.guavate.Guavate;
+import com.google.common.base.Strings;
 
 /**
  * <p>
@@ -251,96 +251,16 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
     public static final String SUPPORTS_VIRTUAL_HOSTING = "supportsVirtualHosting";
 
     /**
-     * The URL of the LDAP server against which users are to be authenticated.
-     * Note that users are actually authenticated by binding against the LDAP
-     * server using the users &quot;dn&quot; and &quot;credentials&quot;.The
-     * value of this field is taken from the value of the configuration
-     * attribute &quot;ldapHost&quot;.
-     */
-    private String ldapHost;
-
-    /**
-     * The value of this field is taken from the configuration attribute
-     * &quot;userIdAttribute&quot;. This is the LDAP attribute type which holds
-     * the userId value. Note that this is not the same as the email address
-     * attribute.
-     */
-    private String userIdAttribute;
-
-    /**
-     * The value of this field is taken from the configuration attribute
-     * &quot;userObjectClass&quot;. This is the LDAP object class to use in the
-     * search filter for user nodes under the userBase value.
-     */
-    private String userObjectClass;
-
-    /**
-     * The value of this field is taken from the configuration attribute &quot;filter&quot;.
-     * This is the search filter to use to find the desired user. 
-     */
-    private String filter;
-    
-    /**
-     * This is the LDAP context/sub-context within which to search for user
-     * entities. The value of this field is taken from the configuration
-     * attribute &quot;userBase&quot;.
-     */
-    private String userBase;
-
-    /**
-     * The user with which to initially bind to the LDAP server. The value of
-     * this field is taken from the configuration attribute
-     * &quot;principal&quot;.
-     */
-    private String principal;
-
-    /**
-     * The password/credentials with which to initially bind to the LDAP server.
-     * The value of this field is taken from the configuration attribute
-     * &quot;credentials&quot;.
-     */
-    private String credentials;
-
-    /**
-     * Encapsulates the information required to restrict users to LDAP groups or
-     * roles. This object is populated from the contents of the configuration
-     * element &lt;restriction&gt;.
-     */
-    private ReadOnlyLDAPGroupRestriction restriction;
-
-    /**
      * The context for the LDAP server. This is the connection that is built
      * from the configuration attributes &quot;ldapHost&quot;,
      * &quot;principal&quot; and &quot;credentials&quot;.
      */
     private LdapContext ldapContext;
-    private boolean supportsVirtualHosting;
-    
-    /**
-     * UserId of the administrator
-     * The administrator is allowed to log in as other users
-     */
-    private Optional<String> administratorId;
-
-    // Use a connection pool. Default is true.
-    private boolean useConnectionPool = true;
-
-    // The connection timeout in milliseconds.
-    // A value of less than or equal to zero means to use the network protocol's
-    // (i.e., TCP's) timeout value.
-    private int connectionTimeout = -1;
-
-    // The LDAP read timeout in milliseconds.
-    private int readTimeout = -1;
-
     // The schedule for retry attempts
     private RetrySchedule schedule = null;
 
-    // Maximum number of times to retry a connection attempts. Default is no
-    // retries.
-    private int maxRetries = 0;
-
     private final DomainList domainList;
+    private LdapRepositoryConfiguration ldapConfiguration;
 
     @Inject
     public ReadOnlyUsersLDAPRepository(DomainList domainList) {
@@ -351,61 +271,24 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
     /**
      * Extracts the parameters required by the repository instance from the
      * James server configuration data. The fields extracted include
-     * {@link #ldapHost}, {@link #userIdAttribute}, {@link #userBase},
-     * {@link #principal}, {@link #credentials} and {@link #restriction}.
+     * {@link LdapRepositoryConfiguration#ldapHost}, {@link LdapRepositoryConfiguration#userIdAttribute}, {@link LdapRepositoryConfiguration#userBase},
+     * {@link LdapRepositoryConfiguration#principal}, {@link LdapRepositoryConfiguration#credentials} and {@link LdapRepositoryConfiguration#restriction}.
      *
      * @param configuration
      *            An encapsulation of the James server configuration data.
      */
     @Override
     public void configure(HierarchicalConfiguration configuration) throws ConfigurationException {
-        ldapHost = configuration.getString("[@ldapHost]", "");
-        principal = configuration.getString("[@principal]", "");
-        credentials = configuration.getString("[@credentials]", "");
-        userBase = configuration.getString("[@userBase]");
-        userIdAttribute = configuration.getString("[@userIdAttribute]");
-        userObjectClass = configuration.getString("[@userObjectClass]");
-        // Default is to use connection pooling
-        useConnectionPool = configuration.getBoolean("[@useConnectionPool]", true);
-        connectionTimeout = configuration.getInt("[@connectionTimeout]", -1);
-        readTimeout = configuration.getInt("[@readTimeout]", -1);
-        // Default maximum retries is 1, which allows an alternate connection to
-        // be found in a multi-homed environment
-        maxRetries = configuration.getInt("[@maxRetries]", 1);
-        supportsVirtualHosting = configuration.getBoolean(SUPPORTS_VIRTUAL_HOSTING, false);
-        // Default retry start interval is 0 second
-        long retryStartInterval = configuration.getLong("[@retryStartInterval]", 0);
-        // Default maximum retry interval is 60 seconds
-        long retryMaxInterval = configuration.getLong("[@retryMaxInterval]", 60);
-        int scale = configuration.getInt("[@retryIntervalScale]", 1000); // seconds
-        schedule = new DoublingRetrySchedule(retryStartInterval, retryMaxInterval, scale);
-
-        HierarchicalConfiguration restrictionConfig = null;
-        // Check if we have a restriction we can use
-        // See JAMES-1204
-        if (configuration.containsKey("restriction[@memberAttribute]")) {
-            restrictionConfig = configuration.configurationAt("restriction");
-        }
-        restriction = new ReadOnlyLDAPGroupRestriction(restrictionConfig);
-
-        //see if there is a filter argument
-        filter = configuration.getString("[@filter]");
-
-        administratorId = Optional.ofNullable(configuration.getString("[@administratorId]"));
-
-        checkState();
+        configure(LdapRepositoryConfiguration.from(configuration));
     }
 
-    private void checkState() throws ConfigurationException {
-        if (userBase == null) {
-            throw new ConfigurationException("[@userBase] is mandatory");
-        }
-        if (userIdAttribute == null) {
-            throw new ConfigurationException("[@userIdAttribute] is mandatory");
-        }
-        if (userObjectClass == null) {
-            throw new ConfigurationException("[@userObjectClass] is mandatory");
-        }
+    public void configure(LdapRepositoryConfiguration configuration) {
+        ldapConfiguration = configuration;
+
+        schedule = new DoublingRetrySchedule(
+            configuration.getRetryStartInterval(),
+            configuration.getRetryMaxInterval(),
+            configuration.getScale());
     }
 
     /**
@@ -419,7 +302,12 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
     @PostConstruct
     public void init() throws Exception {
         if (LOGGER.isDebugEnabled()) {
-            LOGGER.debug(this.getClass().getName() + ".init()" + '\n' + "LDAP host: " + ldapHost + '\n' + "User baseDN: " + userBase + '\n' + "userIdAttribute: " + userIdAttribute + '\n' + "Group restriction: " + restriction + '\n' + "UseConnectionPool: " + useConnectionPool + '\n' + "connectionTimeout: " + connectionTimeout + '\n' + "readTimeout: " + readTimeout + '\n' + "retrySchedule: " + schedule + '\n' + "maxRetries: " + maxRetries + '\n');
+            LOGGER.debug(this.getClass().getName() + ".init()" + '\n' + "LDAP host: " + ldapConfiguration.getLdapHost()
+                + '\n' + "User baseDN: " + ldapConfiguration.getUserBase() + '\n' + "userIdAttribute: "
+                + ldapConfiguration.getUserIdAttribute() + '\n' + "Group restriction: " + ldapConfiguration.getRestriction()
+                + '\n' + "UseConnectionPool: " + ldapConfiguration.useConnectionPool() + '\n' + "connectionTimeout: "
+                + ldapConfiguration.getConnectionTimeout() + '\n' + "readTimeout: " + ldapConfiguration.getReadTimeout()
+                + '\n' + "retrySchedule: " + schedule + '\n' + "maxRetries: " + ldapConfiguration.getMaxRetries() + '\n');
         }
         // Setup the initial LDAP context
         updateLdapContext();
@@ -450,7 +338,7 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
      *             Propagated from underlying LDAP communication API.
      */
     protected LdapContext computeLdapContext() throws NamingException {
-        return new RetryingLdapContext(schedule, maxRetries) {
+        return new RetryingLdapContext(schedule, ldapConfiguration.getMaxRetries()) {
 
             @Override
             public Context newDelegate() throws NamingException {
@@ -462,21 +350,21 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
     protected Properties getContextEnvironment() {
         final Properties props = new Properties();
         props.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
-        props.put(Context.PROVIDER_URL, null == ldapHost ? "" : ldapHost);
-        if (null == credentials || credentials.isEmpty()) {
+        props.put(Context.PROVIDER_URL, null == ldapConfiguration.getLdapHost() ? "" : ldapConfiguration.getLdapHost());
+        if (Strings.isNullOrEmpty(ldapConfiguration.getCredentials())) {
             props.put(Context.SECURITY_AUTHENTICATION, LdapConstants.SECURITY_AUTHENTICATION_NONE);
         } else {
             props.put(Context.SECURITY_AUTHENTICATION, LdapConstants.SECURITY_AUTHENTICATION_SIMPLE);
-            props.put(Context.SECURITY_PRINCIPAL, null == principal ? "" : principal);
-            props.put(Context.SECURITY_CREDENTIALS, credentials);
+            props.put(Context.SECURITY_PRINCIPAL, null == ldapConfiguration.getPrincipal() ? "" : ldapConfiguration.getPrincipal());
+            props.put(Context.SECURITY_CREDENTIALS, ldapConfiguration.getCredentials());
         }
         // The following properties are specific to com.sun.jndi.ldap.LdapCtxFactory
-        props.put(PROPERTY_NAME_CONNECTION_POOL, Boolean.toString(useConnectionPool));
-        if (connectionTimeout > -1) {
-            props.put(PROPERTY_NAME_CONNECT_TIMEOUT, Integer.toString(connectionTimeout));
+        props.put(PROPERTY_NAME_CONNECTION_POOL, String.valueOf(ldapConfiguration.useConnectionPool()));
+        if (ldapConfiguration.getConnectionTimeout() > -1) {
+            props.put(PROPERTY_NAME_CONNECT_TIMEOUT, String.valueOf(ldapConfiguration.getConnectionTimeout()));
         }
-        if (readTimeout > -1) {
-            props.put(PROPERTY_NAME_READ_TIMEOUT, Integer.toString(readTimeout));
+        if (ldapConfiguration.getReadTimeout() > -1) {
+            props.put(PROPERTY_NAME_READ_TIMEOUT, Integer.toString(ldapConfiguration.getReadTimeout()));
         }
         return props;
     }
@@ -515,7 +403,7 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
 
     /**
      * Gets all the user entities taken from the LDAP server, as taken from the
-     * search-context given by the value of the attribute {@link #userBase}.
+     * search-context given by the value of the attribute {@link LdapRepositoryConfiguration#userBase}.
      *
      * @return A set containing all the relevant users found in the LDAP
      *         directory.
@@ -528,8 +416,8 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
         SearchControls sc = new SearchControls();
         sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
         sc.setReturningAttributes(new String[] { "distinguishedName" });
-        NamingEnumeration<SearchResult> sr = ldapContext.search(userBase, "(objectClass="
-                + userObjectClass + ")", sc);
+        NamingEnumeration<SearchResult> sr = ldapContext.search(ldapConfiguration.getUserBase(), "(objectClass="
+                + ldapConfiguration.getUserObjectClass() + ")", sc);
         while (sr.hasMore()) {
             SearchResult r = sr.next();
             result.add(r.getNameInNamespace());
@@ -565,11 +453,11 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
     }
 
     /**
-     * For a given name, this method makes ldap search in userBase with filter {@link #userIdAttribute}=name and objectClass={@link #userObjectClass}
-     * and builds {@link User} based on search result.
+     * For a given name, this method makes ldap search in userBase with filter {@link LdapRepositoryConfiguration#userIdAttribute}=name
+     * and objectClass={@link LdapRepositoryConfiguration#userObjectClass} and builds {@link User} based on search result.
      *
      * @param name
-     *            The userId which should be value of the field {@link #userIdAttribute}
+     *            The userId which should be value of the field {@link LdapRepositoryConfiguration#userIdAttribute}
      * @return A {@link ReadOnlyLDAPUser} instance which is initialized with the
      *         userId of this user and ldap connection information with which
      *         the user was searched. Return null if such a user was not found.
@@ -579,30 +467,30 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
     private ReadOnlyLDAPUser searchAndBuildUser(String name) throws NamingException {
         SearchControls sc = new SearchControls();
         sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
-        sc.setReturningAttributes(new String[] { userIdAttribute });
+        sc.setReturningAttributes(new String[] { ldapConfiguration.getUserIdAttribute() });
         sc.setCountLimit(1);
 
         String filterTemplate = "(&({0}={1})(objectClass={2})" +
-            StringUtils.defaultString(filter, "") +
+            StringUtils.defaultString(ldapConfiguration.getFilter(), "") +
             ")";
 
         String sanitizedFilter = FilterEncoder.format(
             filterTemplate,
-            userIdAttribute,
+            ldapConfiguration.getUserIdAttribute(),
             name,
-            userObjectClass);
+            ldapConfiguration.getUserObjectClass());
 
-        NamingEnumeration<SearchResult> sr = ldapContext.search(userBase, sanitizedFilter, sc);
+        NamingEnumeration<SearchResult> sr = ldapContext.search(ldapConfiguration.getUserBase(), sanitizedFilter, sc);
 
         if (!sr.hasMore()) {
             return null;
         }
 
         SearchResult r = sr.next();
-        Attribute userName = r.getAttributes().get(userIdAttribute);
+        Attribute userName = r.getAttributes().get(ldapConfiguration.getUserIdAttribute());
 
-        if (!restriction.isActivated()
-            || userInGroupsMembershipList(r.getNameInNamespace(), restriction.getGroupMembershipLists(ldapContext))) {
+        if (!ldapConfiguration.getRestriction().isActivated()
+            || userInGroupsMembershipList(r.getNameInNamespace(), ldapConfiguration.getRestriction().getGroupMembershipLists(ldapContext))) {
             return new ReadOnlyLDAPUser(userName.get().toString(), r.getNameInNamespace(), ldapContext);
         }
 
@@ -614,7 +502,7 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
      * server, so as to extract the items that are of interest to James.
      * Specifically it extracts the userId, which is extracted from the LDAP
      * attribute whose name is given by the value of the field
-     * {@link #userIdAttribute}.
+     * {@link LdapRepositoryConfiguration#userIdAttribute}.
      *
      * @param userDN
      *            The distinguished-name of the user whose details are to be
@@ -627,7 +515,7 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
      */
     private ReadOnlyLDAPUser buildUser(String userDN) throws NamingException {
       Attributes userAttributes = ldapContext.getAttributes(userDN);
-      Attribute userName = userAttributes.get(userIdAttribute);
+      Attribute userName = userAttributes.get(ldapConfiguration.getUserIdAttribute());
       return new ReadOnlyLDAPUser(userName.get().toString(), userDN, ldapContext);
     }
 
@@ -709,8 +597,8 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
         Set<String> userDNs = getAllUsersFromLDAP();
         Collection<String> validUserDNs;
 
-        if (restriction.isActivated()) {
-            Map<String, Collection<String>> groupMembershipList = restriction
+        if (ldapConfiguration.getRestriction().isActivated()) {
+            Map<String, Collection<String>> groupMembershipList = ldapConfiguration.getRestriction()
                     .getGroupMembershipLists(ldapContext);
             validUserDNs = new ArrayList<>();
 
@@ -761,12 +649,12 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
      */
     @Override
     public boolean supportVirtualHosting() {
-        return supportsVirtualHosting;
+        return ldapConfiguration.supportsVirtualHosting();
     }
 
 
     @Override
-    public String getUser(MailAddress mailAddress) throws UsersRepositoryException {
+    public String getUser(MailAddress mailAddress) {
         if (supportVirtualHosting()) {
             return mailAddress.asString();
         } else {
@@ -775,9 +663,9 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
     }
 
     @Override
-    public boolean isAdministrator(String username) throws UsersRepositoryException {
-        if (administratorId.isPresent()) {
-            return administratorId.get().equals(username);
+    public boolean isAdministrator(String username) {
+        if (ldapConfiguration.getAdministratorId().isPresent()) {
+            return ldapConfiguration.getAdministratorId().get().equals(username);
         }
         return false;
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[4/6] james-project git commit: JAMES-2441 Get ride of UnionConfigurationProvider to inject LDAP host

Posted by bt...@apache.org.
JAMES-2441 Get ride of UnionConfigurationProvider to inject LDAP host

We rather should inject the POJO first!


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/6430724b
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/6430724b
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/6430724b

Branch: refs/heads/master
Commit: 6430724b34d5c3a8e0d0ead454cc508a6e640051
Parents: fcd09ee
Author: benwa <bt...@linagora.com>
Authored: Wed Jun 27 11:06:22 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Tue Jul 3 09:47:14 2018 +0700

----------------------------------------------------------------------
 .../james/data/LdapUsersRepositoryModule.java   |  18 ++-
 .../apache/james/CassandraLdapJmapTestRule.java |  70 ++++------
 .../user/ldap/LdapRepositoryConfiguration.java  | 130 ++++++++++++++++++-
 3 files changed, 164 insertions(+), 54 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/6430724b/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java b/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java
index 6fcab3c..cab8827 100644
--- a/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java
+++ b/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java
@@ -20,15 +20,18 @@ package org.apache.james.data;
 
 import java.util.List;
 
+import org.apache.commons.configuration.ConfigurationException;
 import org.apache.james.lifecycle.api.Configurable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.user.api.UsersRepository;
+import org.apache.james.user.ldap.LdapRepositoryConfiguration;
 import org.apache.james.user.ldap.ReadOnlyUsersLDAPRepository;
 import org.apache.james.utils.ConfigurationPerformer;
 
 import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
+import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
@@ -43,22 +46,29 @@ public class LdapUsersRepositoryModule extends AbstractModule {
         Multibinder.newSetBinder(binder(), ConfigurationPerformer.class).addBinding().to(LdapUsersRepositoryConfigurationPerformer.class);
     }
 
+    @Provides
+    @Singleton
+    public LdapRepositoryConfiguration provideConfiguration(ConfigurationProvider configurationProvider) throws ConfigurationException {
+        return LdapRepositoryConfiguration.from(
+            configurationProvider.getConfiguration("usersrepository"));
+    }
+
     @Singleton
     public static class LdapUsersRepositoryConfigurationPerformer implements ConfigurationPerformer {
 
-        private final ConfigurationProvider configurationProvider;
+        private final LdapRepositoryConfiguration configuration;
         private final ReadOnlyUsersLDAPRepository usersRepository;
 
         @Inject
-        public LdapUsersRepositoryConfigurationPerformer(ConfigurationProvider configurationProvider, ReadOnlyUsersLDAPRepository usersRepository) {
-            this.configurationProvider = configurationProvider;
+        public LdapUsersRepositoryConfigurationPerformer(LdapRepositoryConfiguration configuration, ReadOnlyUsersLDAPRepository usersRepository) {
+            this.configuration = configuration;
             this.usersRepository = usersRepository;
         }
 
         @Override
         public void initModule() {
             try {
-                usersRepository.configure(configurationProvider.getConfiguration("usersrepository"));
+                usersRepository.configure(configuration);
                 usersRepository.init();
             } catch (Exception e) {
                 throw new RuntimeException(e);

http://git-wip-us.apache.org/repos/asf/james-project/blob/6430724b/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJmapTestRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJmapTestRule.java b/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJmapTestRule.java
index 3a81da6..b4b8fd0 100644
--- a/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJmapTestRule.java
+++ b/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJmapTestRule.java
@@ -21,22 +21,16 @@ package org.apache.james;
 
 import java.io.IOException;
 
-import org.apache.commons.configuration.HierarchicalConfiguration;
-import org.apache.commons.configuration.plist.PropertyListConfiguration;
-import org.apache.james.http.jetty.ConfigurationException;
+import org.apache.commons.configuration.ConfigurationException;
 import org.apache.james.modules.TestJMAPServerModule;
 import org.apache.james.server.core.configuration.Configuration;
-import org.apache.james.server.core.configuration.ConfigurationProvider;
-import org.apache.james.server.core.configuration.FileConfigurationProvider;
+import org.apache.james.user.ldap.LdapRepositoryConfiguration;
 import org.junit.rules.TemporaryFolder;
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
-import com.google.inject.Inject;
 import com.google.inject.Module;
-import com.google.inject.name.Named;
-import com.google.inject.name.Names;
 
 public class CassandraLdapJmapTestRule implements TestRule {
     private static final int LIMIT_TO_3_MESSAGES = 3;
@@ -65,12 +59,31 @@ public class CassandraLdapJmapTestRule implements TestRule {
             .build();
 
         return new GuiceJamesServer(configuration)
-            .combineWith(CassandraLdapJamesServerMain.cassandraLdapServerModule,
-                binder -> binder.bind(String.class).annotatedWith(Names.named("ldapIp")).toInstance(ldapIp))
+            .combineWith(CassandraLdapJamesServerMain.cassandraLdapServerModule)
             .overrideWith(new TestJMAPServerModule(LIMIT_TO_3_MESSAGES))
             .overrideWith(guiceModuleTestRule.getModule())
             .overrideWith(additionals)
-            .overrideWith(binder -> binder.bind(ConfigurationProvider.class).to(UnionConfigurationProvider.class));
+            .overrideWith(binder -> binder.bind(LdapRepositoryConfiguration.class)
+                .toInstance(computeConfiguration(ldapIp)));
+    }
+
+    private LdapRepositoryConfiguration computeConfiguration(String ldapIp) {
+        try {
+            return LdapRepositoryConfiguration.builder()
+                .ldapHost(ldapIp)
+                .principal("cn=admin,dc=james,dc=org")
+                .credentials("mysecretpassword")
+                .userBase("ou=People,dc=james,dc=org")
+                .userIdAttribute("uid")
+                .userObjectClass("inetOrgPerson")
+                .maxRetries(4)
+                .retryStartInterval(0)
+                .retryMaxInterval(8)
+                .scale(1000)
+                .build();
+        } catch (ConfigurationException e) {
+            throw new RuntimeException(e);
+        }
     }
 
     @Override
@@ -81,39 +94,4 @@ public class CassandraLdapJmapTestRule implements TestRule {
     public void await() {
         guiceModuleTestRule.await();
     }
-
-    private static class UnionConfigurationProvider implements ConfigurationProvider {
-        private final FileConfigurationProvider fileConfigurationProvider;
-        private final String ldapIp;
-
-        @Inject
-        public UnionConfigurationProvider(FileConfigurationProvider fileConfigurationProvider,
-            @Named("ldapIp") String ldapIp) {
-            this.fileConfigurationProvider = fileConfigurationProvider;
-            this.ldapIp = ldapIp;
-        }
-
-        @Override
-        public HierarchicalConfiguration getConfiguration(String component) throws org.apache.commons.configuration.ConfigurationException {
-            if (component.equals("usersrepository")) {
-                return ldapRepositoryConfiguration();
-            }
-            return fileConfigurationProvider.getConfiguration(component);
-        }
-
-        private HierarchicalConfiguration ldapRepositoryConfiguration() throws ConfigurationException {
-            PropertyListConfiguration configuration = new PropertyListConfiguration();
-            configuration.addProperty("[@ldapHost]", ldapIp);
-            configuration.addProperty("[@principal]", "cn=admin\\,dc=james\\,dc=org");
-            configuration.addProperty("[@credentials]", "mysecretpassword");
-            configuration.addProperty("[@userBase]", "ou=People\\,dc=james\\,dc=org");
-            configuration.addProperty("[@userIdAttribute]", "uid");
-            configuration.addProperty("[@userObjectClass]", "inetOrgPerson");
-            configuration.addProperty("[@maxRetries]", "4");
-            configuration.addProperty("[@retryStartInterval]", "0");
-            configuration.addProperty("[@retryMaxInterval]", "8");
-            configuration.addProperty("[@retryIntervalScale]", "1000");
-            return configuration;
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/6430724b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/LdapRepositoryConfiguration.java
----------------------------------------------------------------------
diff --git a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/LdapRepositoryConfiguration.java b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/LdapRepositoryConfiguration.java
index fe230f0..9546ec4 100644
--- a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/LdapRepositoryConfiguration.java
+++ b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/LdapRepositoryConfiguration.java
@@ -25,9 +25,131 @@ import java.util.Optional;
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.HierarchicalConfiguration;
 
+import com.google.common.base.Preconditions;
+
 public class LdapRepositoryConfiguration {
     public static final String SUPPORTS_VIRTUAL_HOSTING = "supportsVirtualHosting";
 
+    private static final boolean USE_CONNECTION_POOL = true;
+    private static final int NO_CONNECTION_TIMEOUT = -1;
+    private static final int NO_READ_TIME_OUT = -1;
+    private static final boolean ENABLE_VIRTUAL_HOSTING = true;
+    private static final ReadOnlyLDAPGroupRestriction NO_RESTRICTION = new ReadOnlyLDAPGroupRestriction(null);
+    private static final String NO_FILTER = null;
+    private static final Optional<String> NO_ADMINISTRATOR_ID = Optional.empty();
+
+    public static class Builder {
+        private Optional<String> ldapHost;
+        private Optional<String> principal;
+        private Optional<String> credentials;
+        private Optional<String> userBase;
+        private Optional<String> userIdAttribute;
+        private Optional<String> userObjectClass;
+        private Optional<Integer> maxRetries;
+        private Optional<Long> retryStartInterval;
+        private Optional<Long> retryMaxInterval;
+        private Optional<Integer> scale;
+
+        public Builder() {
+            ldapHost = Optional.empty();
+            principal = Optional.empty();
+            credentials = Optional.empty();
+            userBase = Optional.empty();
+            userIdAttribute = Optional.empty();
+            userObjectClass = Optional.empty();
+            maxRetries = Optional.empty();
+            retryStartInterval = Optional.empty();
+            retryMaxInterval = Optional.empty();
+            scale = Optional.empty();
+        }
+
+        public Builder ldapHost(String ldapHost) {
+            this.ldapHost = Optional.of(ldapHost);
+            return this;
+        }
+
+        public Builder principal(String principal) {
+            this.principal = Optional.of(principal);
+            return this;
+        }
+
+        public Builder credentials(String credentials) {
+            this.credentials = Optional.of(credentials);
+            return this;
+        }
+
+        public Builder userBase(String userBase) {
+            this.userBase = Optional.of(userBase);
+            return this;
+        }
+
+        public Builder userIdAttribute(String userIdAttribute) {
+            this.userIdAttribute = Optional.of(userIdAttribute);
+            return this;
+        }
+
+        public Builder userObjectClass(String userObjectClass) {
+            this.userObjectClass = Optional.of(userObjectClass);
+            return this;
+        }
+
+        public Builder maxRetries(int maxRetries) {
+            this.maxRetries = Optional.of(maxRetries);
+            return this;
+        }
+
+        public Builder retryStartInterval(long retryStartInterval) {
+            this.retryStartInterval = Optional.of(retryStartInterval);
+            return this;
+        }
+
+        public Builder retryMaxInterval(long retryMaxInterval) {
+            this.retryMaxInterval = Optional.of(retryMaxInterval);
+            return this;
+        }
+
+        public Builder scale(int scale) {
+            this.scale = Optional.of(scale);
+            return this;
+        }
+
+        public LdapRepositoryConfiguration build() throws ConfigurationException {
+            Preconditions.checkState(ldapHost.isPresent(), "'ldapHost' is mandatory");
+            Preconditions.checkState(principal.isPresent(), "'principal' is mandatory");
+            Preconditions.checkState(credentials.isPresent(), "'credentials' is mandatory");
+            Preconditions.checkState(userBase.isPresent(), "'userBase' is mandatory");
+            Preconditions.checkState(userIdAttribute.isPresent(), "'userIdAttribute' is mandatory");
+            Preconditions.checkState(userObjectClass.isPresent(), "'userObjectClass' is mandatory");
+            Preconditions.checkState(maxRetries.isPresent(), "'maxRetries' is mandatory");
+            Preconditions.checkState(retryStartInterval.isPresent(), "'retryStartInterval' is mandatory");
+            Preconditions.checkState(retryMaxInterval.isPresent(), "'retryMaxInterval' is mandatory");
+            Preconditions.checkState(scale.isPresent(), "'scale' is mandatory");
+
+            return new LdapRepositoryConfiguration(
+                ldapHost.get(),
+                principal.get(),
+                credentials.get(),
+                userBase.get(),
+                userIdAttribute.get(),
+                userObjectClass.get(),
+                USE_CONNECTION_POOL,
+                NO_CONNECTION_TIMEOUT,
+                NO_READ_TIME_OUT,
+                maxRetries.get(),
+                !ENABLE_VIRTUAL_HOSTING,
+                retryStartInterval.get(),
+                retryMaxInterval.get(),
+                scale.get(),
+                NO_RESTRICTION,
+                NO_FILTER,
+                NO_ADMINISTRATOR_ID);
+        }
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
     public static LdapRepositoryConfiguration from(HierarchicalConfiguration configuration) throws ConfigurationException {
         String ldapHost = configuration.getString("[@ldapHost]", "");
         String principal = configuration.getString("[@principal]", "");
@@ -36,13 +158,13 @@ public class LdapRepositoryConfiguration {
         String userIdAttribute = configuration.getString("[@userIdAttribute]");
         String userObjectClass = configuration.getString("[@userObjectClass]");
         // Default is to use connection pooling
-        boolean useConnectionPool = configuration.getBoolean("[@useConnectionPool]", true);
-        int connectionTimeout = configuration.getInt("[@connectionTimeout]", -1);
-        int readTimeout = configuration.getInt("[@readTimeout]", -1);
+        boolean useConnectionPool = configuration.getBoolean("[@useConnectionPool]", USE_CONNECTION_POOL);
+        int connectionTimeout = configuration.getInt("[@connectionTimeout]", NO_CONNECTION_TIMEOUT);
+        int readTimeout = configuration.getInt("[@readTimeout]", NO_READ_TIME_OUT);
         // Default maximum retries is 1, which allows an alternate connection to
         // be found in a multi-homed environment
         int maxRetries = configuration.getInt("[@maxRetries]", 1);
-        boolean supportsVirtualHosting = configuration.getBoolean(SUPPORTS_VIRTUAL_HOSTING, false);
+        boolean supportsVirtualHosting = configuration.getBoolean(SUPPORTS_VIRTUAL_HOSTING, !ENABLE_VIRTUAL_HOSTING);
         // Default retry start interval is 0 second
         long retryStartInterval = configuration.getLong("[@retryStartInterval]", 0);
         // Default maximum retry interval is 60 seconds


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[2/6] james-project git commit: JAMES-2441 Reduce poll delay in Cassandra LDAP guice tests

Posted by bt...@apache.org.
JAMES-2441 Reduce poll delay in Cassandra LDAP guice tests


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/21bb9757
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/21bb9757
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/21bb9757

Branch: refs/heads/master
Commit: 21bb9757b010460e81fe930a3f72d35bc2b199b1
Parents: 53dc38f
Author: benwa <bt...@linagora.com>
Authored: Mon Jul 2 16:45:46 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Tue Jul 3 09:47:14 2018 +0700

----------------------------------------------------------------------
 .../test/java/org/apache/james/CassandraLdapJamesServerTest.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/21bb9757/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJamesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJamesServerTest.java b/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJamesServerTest.java
index 60840da..723f357 100644
--- a/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJamesServerTest.java
+++ b/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJamesServerTest.java
@@ -19,7 +19,7 @@
 
 package org.apache.james;
 
-import static com.jayway.awaitility.Duration.FIVE_HUNDRED_MILLISECONDS;
+import static com.jayway.awaitility.Duration.ONE_HUNDRED_MILLISECONDS;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.IOException;
@@ -43,7 +43,7 @@ public class CassandraLdapJamesServerTest extends AbstractJmapJamesServerTest {
     private static final String PASSWORD = "secret";
     private static final String DOMAIN = "james.org";
     private static final String ADMIN_PASSWORD = "mysecretpassword";
-    private static Duration slowPacedPollInterval = FIVE_HUNDRED_MILLISECONDS;
+    private static Duration slowPacedPollInterval = ONE_HUNDRED_MILLISECONDS;
     private static ConditionFactory calmlyAwait = Awaitility.with()
         .pollInterval(slowPacedPollInterval)
         .and()


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[6/6] james-project git commit: JAMES-2441 Tests were not played via maven

Posted by bt...@apache.org.
JAMES-2441 Tests were not played via maven

This is due to a bad profile, that had not been removed.

Missing junit libs (!!!). The injection of UnionConfigurationProvider failed.

(Previous commits fixed this)


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ce6a5d66
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ce6a5d66
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ce6a5d66

Branch: refs/heads/master
Commit: ce6a5d66056bda0061698999d2c470cbf840bec8
Parents: 6430724
Author: benwa <bt...@linagora.com>
Authored: Wed Jun 27 11:15:40 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Tue Jul 3 09:47:14 2018 +0700

----------------------------------------------------------------------
 .../guice/cassandra-ldap-guice/pom.xml          | 28 +++++++++++---------
 1 file changed, 15 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/ce6a5d66/server/container/guice/cassandra-ldap-guice/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-ldap-guice/pom.xml b/server/container/guice/cassandra-ldap-guice/pom.xml
index afa2b4a..b7f64a7 100644
--- a/server/container/guice/cassandra-ldap-guice/pom.xml
+++ b/server/container/guice/cassandra-ldap-guice/pom.xml
@@ -98,6 +98,11 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-testing</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>james-server-util-java8</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
@@ -118,6 +123,16 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-launcher</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.vintage</groupId>
+            <artifactId>junit-vintage-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.testcontainers</groupId>
             <artifactId>testcontainers</artifactId>
             <scope>test</scope>
@@ -176,19 +191,6 @@
                 <artifactId>maven-bundle-plugin</artifactId>
                 <extensions>true</extensions>
             </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <excludes>
-                        <exclude>**/suite/*.java</exclude>
-                        <exclude>**/suite/**/*.java</exclude>
-                    </excludes>
-                    <includes>
-                        <include>${cassandra.includes}</include>
-                    </includes>
-                </configuration>
-            </plugin>
         </plugins>
     </build>
 


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[3/6] james-project git commit: JAMES-2441 Test that a user can receive emails before her first connection

Posted by bt...@apache.org.
JAMES-2441 Test that a user can receive emails before her first connection


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/dd31a821
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/dd31a821
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/dd31a821

Branch: refs/heads/master
Commit: dd31a8219d6942a74587b2df4f396bab88c26ef2
Parents: ce6a5d6
Author: benwa <bt...@linagora.com>
Authored: Wed Jun 27 11:16:28 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Tue Jul 3 09:47:14 2018 +0700

----------------------------------------------------------------------
 .../james/CassandraLdapJamesServerTest.java     | 35 ++++++++++++++++++
 .../server/CamelMailetContainerModule.java      |  4 ++-
 .../org/apache/james/utils/SpoolerProbe.java    | 37 ++++++++++++++++++++
 .../james/AbstractJmapJamesServerTest.java      |  2 +-
 4 files changed, 76 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/dd31a821/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJamesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJamesServerTest.java b/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJamesServerTest.java
index c6a8eca..60840da 100644
--- a/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJamesServerTest.java
+++ b/server/container/guice/cassandra-ldap-guice/src/test/java/org/apache/james/CassandraLdapJamesServerTest.java
@@ -19,21 +19,37 @@
 
 package org.apache.james;
 
+import static com.jayway.awaitility.Duration.FIVE_HUNDRED_MILLISECONDS;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.IOException;
 
 import org.apache.commons.net.imap.IMAPClient;
+import org.apache.james.core.Domain;
 import org.apache.james.user.ldap.LdapGenericContainer;
+import org.apache.james.utils.IMAPMessageReader;
+import org.apache.james.utils.SMTPMessageSender;
+import org.apache.james.utils.SpoolerProbe;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
 
+import com.jayway.awaitility.Awaitility;
+import com.jayway.awaitility.Duration;
+import com.jayway.awaitility.core.ConditionFactory;
+
 public class CassandraLdapJamesServerTest extends AbstractJmapJamesServerTest {
     private static final String JAMES_USER = "james-user";
     private static final String PASSWORD = "secret";
     private static final String DOMAIN = "james.org";
     private static final String ADMIN_PASSWORD = "mysecretpassword";
+    private static Duration slowPacedPollInterval = FIVE_HUNDRED_MILLISECONDS;
+    private static ConditionFactory calmlyAwait = Awaitility.with()
+        .pollInterval(slowPacedPollInterval)
+        .and()
+        .with()
+        .pollDelay(slowPacedPollInterval)
+        .await();
 
     private LdapGenericContainer ldapContainer = LdapGenericContainer.builder()
         .domain(DOMAIN)
@@ -45,6 +61,11 @@ public class CassandraLdapJamesServerTest extends AbstractJmapJamesServerTest {
     @Rule
     public RuleChain ruleChain = RuleChain.outerRule(ldapContainer).around(cassandraLdapJmap);
 
+    @Rule
+    public IMAPMessageReader imapMessageReader = new IMAPMessageReader();
+    @Rule
+    public SMTPMessageSender messageSender = new SMTPMessageSender(Domain.LOCALHOST.asString());
+
     @Override
     protected GuiceJamesServer createJamesServer() throws IOException {
         ldapContainer.start();
@@ -70,4 +91,18 @@ public class CassandraLdapJamesServerTest extends AbstractJmapJamesServerTest {
 
         assertThat(imapClient.login(JAMES_USER, PASSWORD)).isTrue();
     }
+
+    @Test
+    public void mailsShouldBeWellReceivedBeforeFirstUserConnectionWithLdap() throws Exception {
+        messageSender.connect("127.0.0.1", 1025)
+            .sendMessage("bob@any.com", JAMES_USER + "@localhost");
+
+        calmlyAwait.until(() -> server.getProbe(SpoolerProbe.class).processingFinished());
+
+        imapMessageReader.connect("127.0.0.1", 1143)
+            .login(JAMES_USER, PASSWORD)
+            .select("INBOX")
+            .awaitMessage(calmlyAwait);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/dd31a821/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
index d96d2ab..0d41d59 100644
--- a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
+++ b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
@@ -47,7 +47,9 @@ import org.apache.james.user.api.UsersRepository;
 import org.apache.james.utils.ConfigurationPerformer;
 import org.apache.james.utils.GuiceMailetLoader;
 import org.apache.james.utils.GuiceMatcherLoader;
+import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.MailetConfigurationOverride;
+import org.apache.james.utils.SpoolerProbe;
 import org.apache.mailet.MailetContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -79,7 +81,7 @@ public class CamelMailetContainerModule extends AbstractModule {
         bind(MatcherLoader.class).to(GuiceMatcherLoader.class);
 
         Multibinder.newSetBinder(binder(), MailetConfigurationOverride.class);
-
+        Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(SpoolerProbe.class);
         Multibinder.newSetBinder(binder(), ConfigurationPerformer.class).addBinding().to(MailetModuleConfigurationPerformer.class);
 
         Multibinder<CamelMailetContainerModule.TransportProcessorCheck> transportProcessorChecks = Multibinder.newSetBinder(binder(), CamelMailetContainerModule.TransportProcessorCheck.class);

http://git-wip-us.apache.org/repos/asf/james-project/blob/dd31a821/server/container/guice/mailet/src/main/java/org/apache/james/utils/SpoolerProbe.java
----------------------------------------------------------------------
diff --git a/server/container/guice/mailet/src/main/java/org/apache/james/utils/SpoolerProbe.java b/server/container/guice/mailet/src/main/java/org/apache/james/utils/SpoolerProbe.java
new file mode 100644
index 0000000..322a11b
--- /dev/null
+++ b/server/container/guice/mailet/src/main/java/org/apache/james/utils/SpoolerProbe.java
@@ -0,0 +1,37 @@
+/****************************************************************
+ * 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.james.utils;
+
+import javax.inject.Inject;
+
+import org.apache.james.mailetcontainer.impl.JamesMailSpooler;
+
+public class SpoolerProbe implements GuiceProbe {
+    private final JamesMailSpooler spooler;
+
+    @Inject
+    public SpoolerProbe(JamesMailSpooler spooler) {
+        this.spooler = spooler;
+    }
+
+    public boolean processingFinished() {
+        return spooler.getCurrentSpoolCount() == 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/dd31a821/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
index 27f01eb..fb510be 100644
--- a/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
+++ b/server/container/guice/protocols/jmap/src/test/java/org/apache/james/AbstractJmapJamesServerTest.java
@@ -51,7 +51,7 @@ public abstract class AbstractJmapJamesServerTest {
     protected static final String JAMES_SERVER_HOST = "127.0.0.1";
     protected static final int IMAP_PORT = 1143; // You need to be root (superuser) to bind to ports under 1024.
 
-    private GuiceJamesServer server;
+    protected GuiceJamesServer server;
     private SocketChannel socketChannel;
 
     @Before


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[5/6] james-project git commit: JAMES-2441 Rely on Optional in ReadOnlyUsersLDAPRepository

Posted by bt...@apache.org.
JAMES-2441 Rely on Optional in ReadOnlyUsersLDAPRepository


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/53dc38fd
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/53dc38fd
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/53dc38fd

Branch: refs/heads/master
Commit: 53dc38fdac567a8728ffef982388c6f5ade71d72
Parents: dd31a82
Author: benwa <bt...@linagora.com>
Authored: Wed Jun 27 17:33:46 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Tue Jul 3 09:47:14 2018 +0700

----------------------------------------------------------------------
 .../apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/53dc38fd/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
----------------------------------------------------------------------
diff --git a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
index 6f6677b..61c264a 100644
--- a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
+++ b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepository.java
@@ -25,6 +25,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Properties;
 import java.util.Set;
 
@@ -348,14 +349,16 @@ public class ReadOnlyUsersLDAPRepository implements UsersRepository, Configurabl
     }
 
     protected Properties getContextEnvironment() {
-        final Properties props = new Properties();
+        Properties props = new Properties();
         props.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
-        props.put(Context.PROVIDER_URL, null == ldapConfiguration.getLdapHost() ? "" : ldapConfiguration.getLdapHost());
+        props.put(Context.PROVIDER_URL, Optional.ofNullable(ldapConfiguration.getLdapHost())
+            .orElse(""));
         if (Strings.isNullOrEmpty(ldapConfiguration.getCredentials())) {
             props.put(Context.SECURITY_AUTHENTICATION, LdapConstants.SECURITY_AUTHENTICATION_NONE);
         } else {
             props.put(Context.SECURITY_AUTHENTICATION, LdapConstants.SECURITY_AUTHENTICATION_SIMPLE);
-            props.put(Context.SECURITY_PRINCIPAL, null == ldapConfiguration.getPrincipal() ? "" : ldapConfiguration.getPrincipal());
+            props.put(Context.SECURITY_PRINCIPAL, Optional.ofNullable(ldapConfiguration.getPrincipal())
+                .orElse(""));
             props.put(Context.SECURITY_CREDENTIALS, ldapConfiguration.getCredentials());
         }
         // The following properties are specific to com.sun.jndi.ldap.LdapCtxFactory


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org