From 84949bb51fc8f6c8eeab97789480e9055dec78c6 Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Wed, 10 Feb 2016 14:09:29 -0500 Subject: [PATCH] concurrency --- .../configuration/keycloak-server.json | 16 +++++----- .../RevisionedCacheRealmProviderFactory.java | 4 +-- .../RevisionedConnectionProviderFactory.java | 4 +-- .../LockingCacheRealmProviderFactory.java | 2 +- .../LockingConnectionProviderFactory.java | 4 +-- .../RepeatableReadWriteSkewRealmCache.java | 2 +- ...atableReadWriteSkewRealmCacheProvider.java | 12 ++++---- .../keycloak/models/jpa/ClientAdapter.java | 5 ++-- .../AuthenticationExecutionEntity.java | 3 ++ .../entities/AuthenticationFlowEntity.java | 3 ++ .../entities/AuthenticatorConfigEntity.java | 3 ++ .../models/jpa/entities/ClientEntity.java | 9 +++--- .../jpa/entities/ClientTemplateEntity.java | 3 ++ .../models/jpa/entities/CredentialEntity.java | 3 ++ .../jpa/entities/GroupAttributeEntity.java | 3 ++ .../models/jpa/entities/GroupEntity.java | 3 ++ .../jpa/entities/IdentityProviderEntity.java | 3 ++ .../IdentityProviderMapperEntity.java | 3 ++ .../jpa/entities/MigrationModelEntity.java | 3 ++ .../jpa/entities/ProtocolMapperEntity.java | 3 ++ .../models/jpa/entities/RealmEntity.java | 3 ++ .../RequiredActionProviderEntity.java | 3 ++ .../models/jpa/entities/RoleEntity.java | 8 +++++ .../jpa/entities/UserAttributeEntity.java | 3 ++ .../jpa/entities/UserConsentEntity.java | 3 ++ .../models/jpa/entities/UserEntity.java | 3 ++ .../entities/UserFederationMapperEntity.java | 3 ++ .../UserFederationProviderEntity.java | 3 ++ .../resources/META-INF/keycloak-server.json | 29 ++++++++++++++----- .../testsuite/admin/ConcurrencyTest.java | 8 +++-- .../keycloak-infinispan.xml | 6 ++++ 31 files changed, 123 insertions(+), 40 deletions(-) mode change 100644 => 100755 distribution/feature-packs/server-feature-pack/src/main/resources/content/standalone/configuration/keycloak-server.json mode change 100644 => 100755 testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json mode change 100644 => 100755 wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/content/standalone/configuration/keycloak-server.json b/distribution/feature-packs/server-feature-pack/src/main/resources/content/standalone/configuration/keycloak-server.json old mode 100644 new mode 100755 index b96d61b3cf..41dab8565d --- a/distribution/feature-packs/server-feature-pack/src/main/resources/content/standalone/configuration/keycloak-server.json +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/content/standalone/configuration/keycloak-server.json @@ -28,12 +28,6 @@ } }, - "realmCache": { - "infinispan" : { - "enabled": true - } - }, - "userSessionPersister": { "provider": "jpa" }, @@ -67,8 +61,16 @@ } }, + "realmCache": { + "provider": "infinispan-locking", + "infinispan-locking" : { + "enabled": true + } + }, + "connectionsInfinispan": { - "default" : { + "provider": "locking", + "locking": { "cacheContainer" : "java:comp/env/infinispan/Keycloak" } } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/counter/RevisionedCacheRealmProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/counter/RevisionedCacheRealmProviderFactory.java index ae7ca69058..d50eb0b885 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/counter/RevisionedCacheRealmProviderFactory.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/counter/RevisionedCacheRealmProviderFactory.java @@ -36,8 +36,6 @@ import org.keycloak.models.cache.CacheRealmProvider; import org.keycloak.models.cache.CacheRealmProviderFactory; import org.keycloak.models.cache.entities.CachedClient; import org.keycloak.models.cache.entities.CachedRealm; -import org.keycloak.models.cache.infinispan.DefaultCacheRealmProvider; -import org.keycloak.models.cache.infinispan.InfinispanRealmCache; import java.util.concurrent.ConcurrentHashMap; @@ -64,7 +62,7 @@ public class RevisionedCacheRealmProviderFactory implements CacheRealmProviderFa synchronized (this) { if (realmCache == null) { Cache cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_CACHE_NAME); - Cache counterCache = session.getProvider(InfinispanConnectionProvider.class).getCache(RevisionedConnectionProviderFactory.COUNTER_CACHE_NAME); + Cache counterCache = session.getProvider(InfinispanConnectionProvider.class).getCache(RevisionedConnectionProviderFactory.VERSION_CACHE_NAME); cache.addListener(new CacheListener()); realmCache = new RevisionedRealmCache(cache, counterCache, realmLookup); } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/counter/RevisionedConnectionProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/counter/RevisionedConnectionProviderFactory.java index 4b8c3f6d3d..845a907461 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/counter/RevisionedConnectionProviderFactory.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/counter/RevisionedConnectionProviderFactory.java @@ -26,7 +26,7 @@ import org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFa * @author Stian Thorgersen */ public class RevisionedConnectionProviderFactory extends DefaultInfinispanConnectionProviderFactory { - public static final String COUNTER_CACHE_NAME = "COUNTER_CACHE"; + public static final String VERSION_CACHE_NAME = "realmVersions"; protected static final Logger logger = Logger.getLogger(RevisionedConnectionProviderFactory.class); @@ -41,7 +41,7 @@ public class RevisionedConnectionProviderFactory extends DefaultInfinispanConnec ConfigurationBuilder counterConfigBuilder = new ConfigurationBuilder(); Configuration counterCacheConfiguration = counterConfigBuilder.build(); - cacheManager.defineConfiguration(COUNTER_CACHE_NAME, counterCacheConfiguration); + cacheManager.defineConfiguration(VERSION_CACHE_NAME, counterCacheConfiguration); } } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProviderFactory.java index 2009b670a1..f143ea3ffd 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProviderFactory.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProviderFactory.java @@ -62,7 +62,7 @@ public class LockingCacheRealmProviderFactory implements CacheRealmProviderFacto synchronized (this) { if (realmCache == null) { Cache cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_CACHE_NAME); - Cache counterCache = session.getProvider(InfinispanConnectionProvider.class).getCache(LockingConnectionProviderFactory.COUNTER_CACHE_NAME); + Cache counterCache = session.getProvider(InfinispanConnectionProvider.class).getCache(LockingConnectionProviderFactory.VERSION_CACHE_NAME); cache.addListener(new CacheListener()); realmCache = new LockingRealmCache(cache, counterCache, realmLookup); } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingConnectionProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingConnectionProviderFactory.java index f3e5f294a2..4a8dfa9fe6 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingConnectionProviderFactory.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingConnectionProviderFactory.java @@ -28,7 +28,7 @@ import org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFa * @author Stian Thorgersen */ public class LockingConnectionProviderFactory extends DefaultInfinispanConnectionProviderFactory { - public static final String COUNTER_CACHE_NAME = "COUNTER_CACHE"; + public static final String VERSION_CACHE_NAME = "realmVersions"; protected static final Logger logger = Logger.getLogger(LockingConnectionProviderFactory.class); @@ -46,7 +46,7 @@ public class LockingConnectionProviderFactory extends DefaultInfinispanConnectio counterConfigBuilder.transaction().lockingMode(LockingMode.PESSIMISTIC); Configuration counterCacheConfiguration = counterConfigBuilder.build(); - cacheManager.defineConfiguration(COUNTER_CACHE_NAME, counterCacheConfiguration); + cacheManager.defineConfiguration(VERSION_CACHE_NAME, counterCacheConfiguration); } } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/skewed/RepeatableReadWriteSkewRealmCache.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/skewed/RepeatableReadWriteSkewRealmCache.java index bb0b807112..18e5d866ef 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/skewed/RepeatableReadWriteSkewRealmCache.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/skewed/RepeatableReadWriteSkewRealmCache.java @@ -113,7 +113,7 @@ public class RepeatableReadWriteSkewRealmCache implements RealmCache { } } } catch (Exception e) { - logger.info("Failed to commit invalidate"); + logger.trace("Failed to commit invalidate"); } return rtn; } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/skewed/RepeatableReadWriteSkewRealmCacheProvider.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/skewed/RepeatableReadWriteSkewRealmCacheProvider.java index fe7d6c27c2..5ff2ff8f93 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/skewed/RepeatableReadWriteSkewRealmCacheProvider.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/skewed/RepeatableReadWriteSkewRealmCacheProvider.java @@ -221,7 +221,7 @@ public class RepeatableReadWriteSkewRealmCacheProvider implements CacheRealmProv cache.endBatch(true); logger.trace("returning new cached realm"); } catch (Exception exception) { - logger.info("failed to add to cache", exception); + logger.trace("failed to add to cache", exception); return model; } } else if (realmInvalidations.contains(id)) { @@ -256,7 +256,7 @@ public class RepeatableReadWriteSkewRealmCacheProvider implements CacheRealmProv cache.endBatch(true); logger.trace("returning new cached realm: " + cached.getName()); } catch (Exception exception) { - logger.info("failed to add to cache", exception); + logger.trace("failed to add to cache", exception); return model; } } else if (realmInvalidations.contains(cached.getId())) { @@ -340,7 +340,7 @@ public class RepeatableReadWriteSkewRealmCacheProvider implements CacheRealmProv batchEnded = true; cache.endBatch(true); } catch (Exception exception) { - logger.info("failed to add to cache", exception); + logger.trace("failed to add to cache", exception); return model; } @@ -378,7 +378,7 @@ public class RepeatableReadWriteSkewRealmCacheProvider implements CacheRealmProv batchEnded = true; cache.endBatch(true); } catch (Exception exception) { - logger.info("failed to add to cache", exception); + logger.trace("failed to add to cache", exception); return model; } @@ -416,7 +416,7 @@ public class RepeatableReadWriteSkewRealmCacheProvider implements CacheRealmProv batchEnded = true; cache.endBatch(true); } catch (Exception exception) { - logger.info("failed to add to cache", exception); + logger.trace("failed to add to cache", exception); return model; } } else if (appInvalidations.contains(id)) { @@ -452,7 +452,7 @@ public class RepeatableReadWriteSkewRealmCacheProvider implements CacheRealmProv batchEnded = true; cache.endBatch(true); } catch (Exception exception) { - logger.info("failed to add to cache", exception); + logger.trace("failed to add to cache", exception); return model; } } else if (clientTemplateInvalidations.contains(id)) { diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java index d4207d130b..311540b5c9 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java @@ -633,7 +633,7 @@ public class ClientAdapter implements ClientModel { roleEntity.setClient(entity); roleEntity.setClientRole(true); roleEntity.setRealmId(realm.getId()); - //entity.getRoles().add(roleEntity); + entity.getRoles().add(roleEntity); em.persist(roleEntity); em.flush(); return new RoleAdapter(realm, em, roleEntity); @@ -650,7 +650,7 @@ public class ClientAdapter implements ClientModel { RoleEntity role = RoleAdapter.toRoleEntity(roleModel, em); if (!role.isClientRole()) return false; - //entity.getRoles().remove(role); + entity.getRoles().remove(role); entity.getDefaultRoles().remove(role); String compositeRoleTable = JpaUtils.getTableNameForNativeQuery("COMPOSITE_ROLE", em); em.createNativeQuery("delete from " + compositeRoleTable + " where CHILD_ROLE = :role").setParameter("role", role).executeUpdate(); @@ -673,7 +673,6 @@ public class ClientAdapter implements ClientModel { for (RoleEntity entity : roles) { list.add(new RoleAdapter(realm, em, entity)); } - return list; */ TypedQuery query = em.createNamedQuery("getClientRoles", RoleEntity.class); query.setParameter("client", entity); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationExecutionEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationExecutionEntity.java index 71ecd94afe..8e759a4d1b 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationExecutionEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationExecutionEntity.java @@ -19,6 +19,8 @@ package org.keycloak.models.jpa.entities; import org.keycloak.models.AuthenticationExecutionModel; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -43,6 +45,7 @@ import javax.persistence.Table; public class AuthenticationExecutionEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @ManyToOne(fetch = FetchType.LAZY) diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationFlowEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationFlowEntity.java index 886dd4328c..402acf12b5 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationFlowEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationFlowEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; @@ -44,6 +46,7 @@ import java.util.Collection; public class AuthenticationFlowEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @ManyToOne(fetch = FetchType.LAZY) diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticatorConfigEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticatorConfigEntity.java index a35c03e4f9..9057683374 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticatorConfigEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticatorConfigEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ElementCollection; @@ -40,6 +42,7 @@ import java.util.Map; public class AuthenticatorConfigEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @Column(name="ALIAS") diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java index cc9b36aba0..15544c62ed 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CascadeType; import javax.persistence.CollectionTable; import javax.persistence.Column; @@ -53,6 +55,7 @@ public class ClientEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL private String id; @Column(name = "NAME") private String name; @@ -151,8 +154,8 @@ public class ClientEntity { @Column(name="NODE_REREG_TIMEOUT") private int nodeReRegistrationTimeout; - //@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, mappedBy = "client") - //Collection roles = new ArrayList(); + @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, mappedBy = "client") + Collection roles = new ArrayList(); @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true) @JoinTable(name="CLIENT_DEFAULT_ROLES", joinColumns = { @JoinColumn(name="CLIENT_ID")}, inverseJoinColumns = { @JoinColumn(name="ROLE_ID")}) @@ -348,7 +351,6 @@ public class ClientEntity { this.managementUrl = managementUrl; } - /* public Collection getRoles() { return roles; } @@ -356,7 +358,6 @@ public class ClientEntity { public void setRoles(Collection roles) { this.roles = roles; } - */ public Collection getDefaultRoles() { return defaultRoles; diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientTemplateEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientTemplateEntity.java index 1f27816529..280a257c23 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientTemplateEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientTemplateEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CascadeType; import javax.persistence.CollectionTable; import javax.persistence.Column; @@ -48,6 +50,7 @@ public class ClientTemplateEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL private String id; @Column(name = "NAME") private String name; diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java index 4e54c51d87..ceb284cb06 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -42,6 +44,7 @@ import javax.persistence.Table; public class CredentialEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @Column(name="TYPE") diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/GroupAttributeEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/GroupAttributeEntity.java index b784d8222b..a5dbfc4a00 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/GroupAttributeEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/GroupAttributeEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -42,6 +44,7 @@ public class GroupAttributeEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @ManyToOne(fetch= FetchType.LAZY) diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/GroupEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/GroupEntity.java index 420929abc6..9eadbc8990 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/GroupEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/GroupEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; @@ -47,6 +49,7 @@ import java.util.Collection; public class GroupEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @Column(name = "NAME") diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java index 607466349e..77ca6147ed 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ElementCollection; @@ -44,6 +46,7 @@ public class IdentityProviderEntity { @Id @Column(name="INTERNAL_ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String internalId; @ManyToOne(fetch = FetchType.LAZY) diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderMapperEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderMapperEntity.java index a7afa8d50f..2011e934f8 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderMapperEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderMapperEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ElementCollection; @@ -39,6 +41,7 @@ public class IdentityProviderMapperEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @Column(name="NAME") diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/MigrationModelEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/MigrationModelEntity.java index 148d00950f..ce4d8458e3 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/MigrationModelEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/MigrationModelEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -37,6 +39,7 @@ public class MigrationModelEntity { public static final String SINGLETON_ID = "SINGLETON"; @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL private String id; @Column(name="VERSION", length = 36) diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java index bb51ad963d..b6e30713d0 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ElementCollection; @@ -39,6 +41,7 @@ public class ProtocolMapperEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @Column(name="NAME") diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java index 87cc7e5592..da369f0cce 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CascadeType; import javax.persistence.CollectionTable; import javax.persistence.Column; @@ -53,6 +55,7 @@ import java.util.Set; public class RealmEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @Column(name="NAME", unique = true) diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredActionProviderEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredActionProviderEntity.java index 95d3373ddb..d8b43fb73e 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredActionProviderEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredActionProviderEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ElementCollection; @@ -42,6 +44,7 @@ import java.util.Map; public class RequiredActionProviderEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @Column(name="ALIAS") diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java index 6a6ca5f621..b94a7439aa 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java @@ -17,6 +17,11 @@ package org.keycloak.models.jpa.entities; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; + +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -37,6 +42,8 @@ import java.util.Collection; * @version $Revision: 1 $ */ @Entity +//@DynamicInsert +//@DynamicUpdate @Table(name="KEYCLOAK_ROLE", uniqueConstraints = { @UniqueConstraint(columnNames = { "NAME", "CLIENT_REALM_CONSTRAINT" }) }) @@ -49,6 +56,7 @@ import java.util.Collection; public class RoleEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL private String id; @Column(name = "NAME") diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserAttributeEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserAttributeEntity.java index e09c1bb64b..263757fc54 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserAttributeEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserAttributeEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ElementCollection; @@ -48,6 +50,7 @@ public class UserAttributeEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @ManyToOne(fetch= FetchType.LAZY) diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentEntity.java index a349d801a8..c1098e235c 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentEntity.java @@ -20,6 +20,8 @@ package org.keycloak.models.jpa.entities; import java.util.ArrayList; import java.util.Collection; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; @@ -51,6 +53,7 @@ public class UserConsentEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @ManyToOne(fetch= FetchType.LAZY) diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java index b1c8c046ab..d110a17eb3 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java @@ -19,6 +19,8 @@ package org.keycloak.models.jpa.entities; import org.keycloak.models.utils.KeycloakModelUtils; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; @@ -59,6 +61,7 @@ import java.util.Collection; public class UserEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @Column(name = "USERNAME") diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserFederationMapperEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserFederationMapperEntity.java index 54989f2d6f..41350f66fe 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserFederationMapperEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserFederationMapperEntity.java @@ -19,6 +19,8 @@ package org.keycloak.models.jpa.entities; import java.util.Map; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ElementCollection; @@ -41,6 +43,7 @@ public class UserFederationMapperEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @Column(name="NAME") diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserFederationProviderEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserFederationProviderEntity.java index 7b841ca364..f7cab7f8c8 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserFederationProviderEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserFederationProviderEntity.java @@ -17,6 +17,8 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Access; +import javax.persistence.AccessType; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ElementCollection; @@ -39,6 +41,7 @@ public class UserFederationProviderEntity { @Id @Column(name="ID", length = 36) + @Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL protected String id; @ManyToOne(fetch = FetchType.LAZY) diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json old mode 100644 new mode 100755 index 09782319bc..5cef402653 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json @@ -26,14 +26,6 @@ "provider": "${keycloak.userSessionPersister.provider:jpa}" }, - "userSessions": { - "provider" : "${keycloak.userSessions.provider:infinispan}" - }, - - "realmCache": { - "provider": "${keycloak.realm.cache.provider:infinispan}" - }, - "userCache": { "provider": "${keycloak.user.cache.provider:infinispan}", "mem": { @@ -41,6 +33,10 @@ } }, + "userSessions": { + "provider" : "${keycloak.userSessions.provider:infinispan}" + }, + "timer": { "provider": "basic" }, @@ -99,6 +95,23 @@ } }, + "realmCache": { + "provider": "infinispan-locking", + "infinispan-locking" : { + "enabled": true + } + }, + + "connectionsInfinispan": { + "provider": "locking", + "locking": { + "clustered": "${keycloak.connectionsInfinispan.clustered:false}", + "async": "${keycloak.connectionsInfinispan.async:true}", + "sessionsOwners": "${keycloak.connectionsInfinispan.sessionsOwners:2}" + } + }, + + "truststore": { "file": { "file": "${keycloak.truststore.file:src/main/keystore/keycloak.truststore}", diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ConcurrencyTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ConcurrencyTest.java index f3bacbaf9f..f510f04dfd 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ConcurrencyTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ConcurrencyTest.java @@ -42,13 +42,12 @@ import static org.junit.Assert.*; /** * @author Stian Thorgersen */ -@Ignore public class ConcurrencyTest extends AbstractClientTest { private static final Logger log = Logger.getLogger(ConcurrencyTest.class); - private static final int DEFAULT_THREADS = 10; - private static final int DEFAULT_ITERATIONS = 100; + private static final int DEFAULT_THREADS = 1; + private static final int DEFAULT_ITERATIONS = 5; // If enabled only one request is allowed at the time. Useful for checking that test is working. private static final boolean SYNCHRONIZED = false; @@ -146,6 +145,8 @@ public class ConcurrencyTest extends AbstractClientTest { final String clientId = ApiUtil.getCreatedId(response); response.close(); + System.out.println("*********************************************"); + run(new KeycloakRunnable() { @Override public void run(Keycloak keycloak, RealmResource realm, int threadNum, int iterationNum) { @@ -160,6 +161,7 @@ public class ConcurrencyTest extends AbstractClientTest { }); long end = System.currentTimeMillis() - start; System.out.println("createClientRole took " + end); + System.out.println("*********************************************"); } diff --git a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml old mode 100644 new mode 100755 index 57cd94b92f..74fbae372e --- a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml +++ b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml @@ -30,6 +30,9 @@ + + + @@ -87,6 +90,9 @@ + + +