From e46d688280c3442b3822d4c89bc3cab617d3e635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9cile=20Chemin?= Date: Wed, 6 Dec 2023 13:36:52 +0100 Subject: [PATCH] [BUG] :bug: Fix max time before a connection is dropped from ldap connection pool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cécile Chemin --- docs/configuration.md | 25 ++++++++++--------- docs/realm-configuration.md | 25 ++++++++++--------- .../config/LdapRealmProviderDAOImpl.java | 5 ++++ .../sugoi/store/ldap/LdapStoreBeans.java | 9 +++++++ .../insee/sugoi/ldap/utils/LdapFactory.java | 20 +++++++++------ .../ldap/utils/config/LdapConfigKeys.java | 3 ++- 6 files changed, 54 insertions(+), 33 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 7934af83..0037199d 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -27,18 +27,19 @@ Sugoi-api is a springboot app working with extension. Each extension is activate Realm can be load from different sources. -| Properties | Description | Default value | example | -|--------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------:|--------------------------:|------------------------------------:| -| fr.insee.sugoi.realm.config.type | RealmProvider type (could be ldap or file) | file | file | -| fr.insee.sugoi.realm.config.local.path | Use only if config type is file. Path to a file containing an array of realms in json format | | realms.json | -| fr.insee.sugoi.config.ldap.profils.url | Use only if config type is ldap. Ldap host and port where the realm configurations are stored | | my-ldap.url | -| fr.insee.sugoi.config.ldap.profils.port | Use only if config type is ldap. Ldap host and port where the realm configurations are stored | | 389 | -| fr.insee.sugoi.config.ldap.profils.branche | Use only if config type is ldap. Ldap subtree where configurations are stored | | | -| fr.insee.sugoi.config.ldap.profils.pattern | Use only if config type is ldap. String pattern to find realms ('{realm}' is replaced with realm's name). cn={realm} will search realm config for realm1 | cn=Profil\_{realm}\_Sugoi | cn=config\_{realm}\_WebServicesLdap | -| fr.insee.sugoi.config.ldap.profils.timeout | Timeout before failing to get profiles in milliseconds | 30000 | 30000 | -| fr.insee.sugoi.ldap.default.vlv.enabled | enable vlv searched on ldap | false | | -| fr.insee.sugoi.config.ldap.default.sortKey | attribute on which paging request will be ordered | | uid | -| fr.insee.sugoi.verify-unique-mail | indicate if a check on user email must be done before each update/creation | | true | +| Properties | Description | Default value | example | +|------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------:|--------------------------:|------------------------------------:| +| fr.insee.sugoi.realm.config.type | RealmProvider type (could be ldap or file) | file | file | +| fr.insee.sugoi.realm.config.local.path | Use only if config type is file. Path to a file containing an array of realms in json format | | realms.json | +| fr.insee.sugoi.config.ldap.profils.url | Use only if config type is ldap. Ldap host and port where the realm configurations are stored | | my-ldap.url | +| fr.insee.sugoi.config.ldap.profils.port | Use only if config type is ldap. Ldap host and port where the realm configurations are stored | | 389 | +| fr.insee.sugoi.config.ldap.profils.branche | Use only if config type is ldap. Ldap subtree where configurations are stored | | | +| fr.insee.sugoi.config.ldap.profils.pattern | Use only if config type is ldap. String pattern to find realms ('{realm}' is replaced with realm's name). cn={realm} will search realm config for realm1 | cn=Profil\_{realm}\_Sugoi | cn=config\_{realm}\_WebServicesLdap | +| fr.insee.sugoi.config.ldap.profils.timeout | Timeout before failing to get profiles in milliseconds | 30000 | 30000 | +| fr.insee.sugoi.ldap.default.vlv.enabled | enable vlv searched on ldap | false | | +| fr.insee.sugoi.config.ldap.default.sortKey | attribute on which paging request will be ordered | | uid | +| fr.insee.sugoi.config.ldap.default.max-pool-connection-age | default time before a connection is dropped from connection pool in millis | 60000 | uid | +| fr.insee.sugoi.verify-unique-mail | indicate if a check on user email must be done before each update/creation | | true | ### Reader writer configuration diff --git a/docs/realm-configuration.md b/docs/realm-configuration.md index ba373525..225e25dd 100644 --- a/docs/realm-configuration.md +++ b/docs/realm-configuration.md @@ -80,18 +80,19 @@ A list of custom key/values can be added at the end. ### Realm configuration properties -| Field name | Example | Optional | Default | Description | -|-------------------------------------| :-----------------------------------------------: |----------------------------------------------------------------------------------------:|------------------------------------------------------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| seealso_attributes | "seeAlso, otherSeeAlso" | no, set to enable seealso functionnality | | All values in the corresponding attributes will be parsed as [SeeAlso](concepts.md#SeeAlso) string to add a new attributes to a user. It can be a single attribute name or a list of attribute names separated by a comma. | -| app-managed-attribute-keys-list | "inseeGroupeDefaut, inseeGroupeApplicatif" | yes, it just allow person with app right to give (or remove) properties on an attribute | | The name of the attribute to modify | -| app-managed-attribute-patterns-list | "(.\*)\_$(application),$(application)\\$\\$(.\*)" | yes | | The pattern that the attribute value must follow | -| vlv_enabled | true or false | yes, disabled by default | | Allowed to make vlv search on ldap | -| sort_key | uid | no | | Attribute on which ordered will be done when making a paging request | -| usersMaxOutputSize | 100 | yes | fr.insee.sugoi.users.maxoutputsize | The maximum number of user outputs allowed | -| groupsMaxOutputSize | 100 | yes | fr.insee.sugoi.groups.maxoutputsize | The maximum number of grouos outputs allowed | -| applicationsMaxOutputSize | 100 | yes | fr.insee.sugoi.applications.maxoutputsize | The maximum number of applications outputs allowed | -| organizationsMaxOutputSize | 100 | yes | fr.insee.sugoi.organizations.maxoutputsize | The maximum number of organizations outputs allowed | -| group_manager_source_pattern | "uid=ASI\_$(appliname),ou=Applications,o=insee,c=fr" | | the default can be set via the instance property : fr.insee.sugoi.ldap.default.group_manager_source_pattern | Describe where the group manager of the application {appliname} should be fetch. Users belonging to this group can create, delete, add or remove users from ${appliname}'s groups. | +| Field name | Example | Optional | Default | Description | +|-------------------------------------|:----------------------------------------------------:|----------------------------------------------------------------------------------------:|--------------------------------------------------------------------------------------------------------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| seealso_attributes | "seeAlso, otherSeeAlso" | no, set to enable seealso functionnality | | All values in the corresponding attributes will be parsed as [SeeAlso](concepts.md#SeeAlso) string to add a new attributes to a user. It can be a single attribute name or a list of attribute names separated by a comma. | +| app-managed-attribute-keys-list | "inseeGroupeDefaut, inseeGroupeApplicatif" | yes, it just allow person with app right to give (or remove) properties on an attribute | | The name of the attribute to modify | +| app-managed-attribute-patterns-list | "(.\*)\_$(application),$(application)\\$\\$(.\*)" | yes | | The pattern that the attribute value must follow | +| vlv_enabled | true or false | yes, disabled by default | | Allowed to make vlv search on ldap | +| sort_key | uid | no | | Attribute on which ordered will be done when making a paging request | +| usersMaxOutputSize | 100 | yes | fr.insee.sugoi.users.maxoutputsize | The maximum number of user outputs allowed | +| groupsMaxOutputSize | 100 | yes | fr.insee.sugoi.groups.maxoutputsize | The maximum number of grouos outputs allowed | +| applicationsMaxOutputSize | 100 | yes | fr.insee.sugoi.applications.maxoutputsize | The maximum number of applications outputs allowed | +| organizationsMaxOutputSize | 100 | yes | fr.insee.sugoi.organizations.maxoutputsize | The maximum number of organizations outputs allowed | +| group_manager_source_pattern | "uid=ASI\_$(appliname),ou=Applications,o=insee,c=fr" | | the default can be set via the instance property : fr.insee.sugoi.ldap.default.group_manager_source_pattern | Describe where the group manager of the application {appliname} should be fetch. Users belonging to this group can create, delete, add or remove users from ${appliname}'s groups. | +| max_pool_connection_age | 30000 | | the default can be set via the instance property : fr.insee.sugoi.config.ldap.default.max-pool-connection-age | time before a connection is dropped from connection pool | Realm configuration properties can be set as: diff --git a/sugoi-api-ldap-config-provider/src/main/java/fr/insee/sugoi/config/LdapRealmProviderDAOImpl.java b/sugoi-api-ldap-config-provider/src/main/java/fr/insee/sugoi/config/LdapRealmProviderDAOImpl.java index 2ea8308b..108311b0 100644 --- a/sugoi-api-ldap-config-provider/src/main/java/fr/insee/sugoi/config/LdapRealmProviderDAOImpl.java +++ b/sugoi-api-ldap-config-provider/src/main/java/fr/insee/sugoi/config/LdapRealmProviderDAOImpl.java @@ -107,6 +107,9 @@ public class LdapRealmProviderDAOImpl implements RealmProvider { @Value("${fr.insee.sugoi.config.ldap.default.sortKey:}") private String defaultSortKey; + @Value("${fr.insee.sugoi.config.ldap.default.max-pool-connection-age:60000}") + private String maxPoolConnectionAge; + @Autowired UiMappingService uiMappingService; private static final Logger logger = LoggerFactory.getLogger(LdapRealmProviderDAOImpl.class); @@ -341,6 +344,7 @@ private LDAPConnectionPool ldapPoolConnection() { config.put(LdapConfigKeys.PORT, String.valueOf(port)); config.put(LdapConfigKeys.POOL_SIZE, defaultPoolSize); config.put(LdapConfigKeys.LDAP_CONNECTION_TIMEOUT, connectionTimeout); + config.put(LdapConfigKeys.MAX_POOL_CONNECTION_AGE, maxPoolConnectionAge); ldapConnectionPool = LdapFactory.getConnectionPool(config); } } @@ -361,6 +365,7 @@ private LDAPConnectionPool ldapConnectionPoolAuthenticated() { config.put(LdapConfigKeys.USERNAME, defaultUsername); config.put(LdapConfigKeys.PASSWORD, defaultPassword); config.put(LdapConfigKeys.LDAP_CONNECTION_TIMEOUT, connectionTimeout); + config.put(LdapConfigKeys.MAX_POOL_CONNECTION_AGE, maxPoolConnectionAge); ldapConnectionPool = LdapFactory.getConnectionPoolAuthenticated(config); } return ldapConnectionPool; diff --git a/sugoi-api-ldap-store-provider/src/main/java/fr/insee/sugoi/store/ldap/LdapStoreBeans.java b/sugoi-api-ldap-store-provider/src/main/java/fr/insee/sugoi/store/ldap/LdapStoreBeans.java index e0470bcf..de3542a3 100644 --- a/sugoi-api-ldap-store-provider/src/main/java/fr/insee/sugoi/store/ldap/LdapStoreBeans.java +++ b/sugoi-api-ldap-store-provider/src/main/java/fr/insee/sugoi/store/ldap/LdapStoreBeans.java @@ -84,6 +84,9 @@ public class LdapStoreBeans { "#{'${fr.insee.sugoi.ldap.default.user-mapping:username:uid,String,rw;groups:memberOf,list_group,ro;habilitations:inseeGroupeDefaut,list_habilitation,rw}'.split(';')}") private List defaultUserMapping; + @Value("${fr.insee.sugoi.config.ldap.default.max-pool-connection-age:60000}") + private String maxPoolConnectionAge; + @Value( "#{'${fr.insee.sugoi.ldap.default.organization-mapping:identifiant:uid,String,rw;address:inseeAdressePostaleDN,address,rw;organization:inseeOrganisationDN,organization,rw}'.split(';')}") private List defaultOrganizationMapping; @@ -157,6 +160,12 @@ public Map generateConfig(Realm realm, UserStorage user && !realm.getProperties().get(LdapConfigKeys.VLV_ENABLED).isEmpty() ? realm.getProperties().get(LdapConfigKeys.VLV_ENABLED).get(0) : vlvEnabled); + config.put( + LdapConfigKeys.MAX_POOL_CONNECTION_AGE, + realm.getProperties().get(LdapConfigKeys.MAX_POOL_CONNECTION_AGE) != null + && !realm.getProperties().get(LdapConfigKeys.MAX_POOL_CONNECTION_AGE).isEmpty() + ? realm.getProperties().get(LdapConfigKeys.MAX_POOL_CONNECTION_AGE).get(0) + : maxPoolConnectionAge); config.put( LdapConfigKeys.USER_OBJECT_CLASSES, userStorage.getProperties().get(LdapConfigKeys.USER_OBJECT_CLASSES) != null diff --git a/sugoi-api-ldap-utils/src/main/java/fr/insee/sugoi/ldap/utils/LdapFactory.java b/sugoi-api-ldap-utils/src/main/java/fr/insee/sugoi/ldap/utils/LdapFactory.java index 90548b3c..4b3d62c5 100644 --- a/sugoi-api-ldap-utils/src/main/java/fr/insee/sugoi/ldap/utils/LdapFactory.java +++ b/sugoi-api-ldap-utils/src/main/java/fr/insee/sugoi/ldap/utils/LdapFactory.java @@ -61,12 +61,14 @@ public static LDAPConnectionPool getConnectionPool(Map } LDAPConnection ldapConnection = new LDAPConnection( - config.get(LdapConfigKeys.URL), Integer.valueOf(config.get(LdapConfigKeys.PORT))); + config.get(LdapConfigKeys.URL), Integer.parseInt(config.get(LdapConfigKeys.PORT))); setConnectionTimeout(ldapConnection, config); - openLdapPoolConnection.put( - name, + LDAPConnectionPool ldapConnectionPool = new LDAPConnectionPool( - ldapConnection, Integer.valueOf(config.get(LdapConfigKeys.POOL_SIZE)))); + ldapConnection, Integer.parseInt(config.get(LdapConfigKeys.POOL_SIZE))); + ldapConnectionPool.setMaxConnectionAgeMillis( + Integer.parseInt(config.get(LdapConfigKeys.MAX_POOL_CONNECTION_AGE))); + openLdapPoolConnection.put(name, ldapConnectionPool); // Only put key if ldap connection correctly open openLdapPoolConnectionConfig.put(key, name); } @@ -140,14 +142,16 @@ public static LDAPConnectionPool getConnectionPoolAuthenticated( LDAPConnection ldapConnection = new LDAPConnection( config.get(LdapConfigKeys.URL), - Integer.valueOf(config.get(LdapConfigKeys.PORT)), + Integer.parseInt(config.get(LdapConfigKeys.PORT)), config.get(LdapConfigKeys.USERNAME), config.get(LdapConfigKeys.PASSWORD)); setConnectionTimeout(ldapConnection, config); - openLdapPoolConnection.put( - name, + LDAPConnectionPool ldapConnectionPool = new LDAPConnectionPool( - ldapConnection, Integer.valueOf(config.get(LdapConfigKeys.POOL_SIZE)))); + ldapConnection, Integer.parseInt(config.get(LdapConfigKeys.POOL_SIZE))); + ldapConnectionPool.setMaxConnectionAgeMillis( + Integer.parseInt(config.get(LdapConfigKeys.MAX_POOL_CONNECTION_AGE))); + openLdapPoolConnection.put(name, ldapConnectionPool); // Only put key if ldap connection correctly open openLdapPoolConnectionConfig.put(key, name); } diff --git a/sugoi-api-ldap-utils/src/main/java/fr/insee/sugoi/ldap/utils/config/LdapConfigKeys.java b/sugoi-api-ldap-utils/src/main/java/fr/insee/sugoi/ldap/utils/config/LdapConfigKeys.java index 81f2ca24..3d9abc08 100644 --- a/sugoi-api-ldap-utils/src/main/java/fr/insee/sugoi/ldap/utils/config/LdapConfigKeys.java +++ b/sugoi-api-ldap-utils/src/main/java/fr/insee/sugoi/ldap/utils/config/LdapConfigKeys.java @@ -36,7 +36,8 @@ public enum LdapConfigKeys implements RealmConfigKeys { ADDRESS_OBJECT_CLASSES("address_object_classes"), USERSTORAGE_NAME("userstorage_name"), READ_CONNECTION_AUTHENTICATED("read_connection_authenticated"), - LDAP_CONNECTION_TIMEOUT("ldap_connection_timeout"); + LDAP_CONNECTION_TIMEOUT("ldap_connection_timeout"), + MAX_POOL_CONNECTION_AGE("max_pool_connection_age"); private String name;