Description of problem: We have a WebService that we use to automatically enroll new users. This WebService makes use of the OrganizationService to create the user, link it to the correct groups and to define the attributes of its profile. When deploying the portal in a cluster we face an issue: if the user is synchronized and that the user tries to login during the synchronization or after but on the other node it takes a while for the user to have its new rights / properties being available. In order to avoid this kind of problem we want to invalidate the IDM cache at login time. To do that we retrieve the service org.exoplatform.services.organization.idm.PicketLinkIDMCacheService from the ExoContainerContext / PortalContainer then we call the method invalidate(String) on the following 2 namespaces: - "idm_realm_portal/USERS/<username>" - "idm_realm_portal/ATTRIBUTES/<username>" However it does not work. Indeed we can notice that calling the method printCaches() after calling the invalidate we can still see the cache entries for the users we wanted to invalidate. When debugging we notice the following code in the class AbstractInfinispanCacheProvider private String getNamespaceForFqn(String ns) { if (ns == null) { return NULL_NS_NODE; } else { // Better to check with indexOf first because of performance reasons, as replaceAll is expensive and '/' is used only in unit tests if (ns.indexOf('/') != -1) { ns = ns.replaceAll("/", "_"); } } return ns; } The line of code: ns = ns.replaceAll("/", "_"); changes the value of the namespace we request to invalidate replacing all '/' with '_'. Even if the comment says that '/' characters are only used in unit test, the keys that are stored in the cache actually contains cache. So if we want to invalidate the root user the namespace we request to invalidate is: idm_realm_portal/USERS/root The generated key that is removed from the cache is: /NODE_MAIN_ROOT_API/idm_realm_portal_USERS_root While the key that is stored in the cach is: /NODE_MAIN_ROOT_API/idm_realm_portal/USERS/root In the debugger if I compensate the replaceAll moving the value back from idm_realm_portal_USERS_root to idm_realm_portal/USERS/root then the cache invalidation works. Version-Release number of selected component (if applicable): - JPP 6.0
I've commited the fix to Picketlink IDM here https://github.com/picketlink/picketlink-idm/commit/0735c6b6ba0b31f63747976b4738a92dfb27e033 . It will be available in next version of Picketlink IDM (Likely version 1.4.4.Final) With this fix, it's not possible to have realm names with character "/" in name, but this doesn't affect GateIn/JPP anyway because here are realm names without "/" character. If you want to try the fix rigt now before official Picketlink IDM release, you can test with latest SNAPSHOT. So you will just need to: - Checkout latest 1.4 branch from https://github.com/picketlink/picketlink-idm/tree/1.4 - Build it with "mvn clean install" - Copy file picketlink-idm-cache/target/picketlink-idm-cache-1.4.4.Final-SNAPSHOT.jar to GATEIN_HOME/modules/org/picketlink/idm/main/ to replace the current file picketlink-idm-cache-*.jar (you will also need to update file name in GATEIN_HOME/modules/org/picketlink/idm/main/module.xml) - Now you can invalidate records in cache by calling the JMX "invalidate" operation with arguments like "idm_realm_portal/USERS/root" or "idm_realm_portal/ATTRIBUTES/root"
Fixed. Requires PLIDM release and upgrading it in 3.6.x branch
PLIDM upgraded to 1.4.4 in 3.6.x branch.
Verified using PicketLinkIDMCacheService MBean.
This issue is quite similar to https://bugzilla.redhat.com/show_bug.cgi?id=1032440 and has defacto same cause. I think that same "Doc text" could be shared for this issue as for 1032440. So I just copy-pasted the already existing text from 1032440 (Sending flag requires_doc_text flag to ? so Jared can doublecheck and confirm)