Replace old HotRod index annotation with new one

This commit is contained in:
Martin Kanis 2022-11-24 16:32:06 +01:00 committed by Michal Hajas
parent 9bb5b08015
commit c0e103dc95
34 changed files with 354 additions and 341 deletions

View file

@ -24,6 +24,10 @@
<groupId>org.keycloak</groupId> <groupId>org.keycloak</groupId>
<artifactId>keycloak-model-map</artifactId> <artifactId>keycloak-model-map</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-api</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.infinispan</groupId> <groupId>org.infinispan</groupId>
<artifactId>infinispan-client-hotrod</artifactId> <artifactId>infinispan-client-hotrod</artifactId>

View file

@ -19,8 +19,8 @@ package org.keycloak.models.map.storage.hotRod;
import org.keycloak.authorization.model.Policy; import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource; import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.Scope;
import org.keycloak.events.Event; import org.keycloak.events.Event;
import org.keycloak.models.AuthenticatedClientSessionModel;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
@ -53,11 +53,8 @@ public class IckleQueryMapModelCriteriaBuilder<E extends AbstractHotRodEntity, M
private final Map<String, Object> parameters; private final Map<String, Object> parameters;
private static final Pattern LIKE_PATTERN_DELIMITER = Pattern.compile("%+"); private static final Pattern LIKE_PATTERN_DELIMITER = Pattern.compile("%+");
private static final Pattern NON_ANALYZED_FIELD_REGEX = Pattern.compile("[%_\\\\]"); private static final Pattern NON_ANALYZED_FIELD_REGEX = Pattern.compile("[%_\\\\]");
// private static final Pattern ANALYZED_FIELD_REGEX = Pattern.compile("[+!^\"~*?:\\\\]"); // TODO reevaluate once https://github.com/keycloak/keycloak/issues/9295 is fixed
private static final Pattern ANALYZED_FIELD_REGEX = Pattern.compile("\\\\"); // escape "\" with extra "\"
public static final Map<SearchableModelField<?>, String> INFINISPAN_NAME_OVERRIDES = new HashMap<>(); public static final Map<SearchableModelField<?>, String> INFINISPAN_NAME_OVERRIDES = new HashMap<>();
public static final Set<SearchableModelField<?>> ANALYZED_MODEL_FIELDS = new HashSet<>(); public static final Set<SearchableModelField<?>> LOWERCASE_NORMALIZED_MODEL_FIELDS = new HashSet<>();
static { static {
INFINISPAN_NAME_OVERRIDES.put(ClientModel.SearchableFields.SCOPE_MAPPING_ROLE, "scopeMappings"); INFINISPAN_NAME_OVERRIDES.put(ClientModel.SearchableFields.SCOPE_MAPPING_ROLE, "scopeMappings");
@ -96,13 +93,19 @@ public class IckleQueryMapModelCriteriaBuilder<E extends AbstractHotRodEntity, M
} }
static { static {
// the "filename" analyzer in Infinispan works correctly for case-insensitive search with whitespaces LOWERCASE_NORMALIZED_MODEL_FIELDS.add(Policy.SearchableFields.NAME);
ANALYZED_MODEL_FIELDS.add(RoleModel.SearchableFields.DESCRIPTION); LOWERCASE_NORMALIZED_MODEL_FIELDS.add(Policy.SearchableFields.TYPE);
ANALYZED_MODEL_FIELDS.add(UserModel.SearchableFields.FIRST_NAME); LOWERCASE_NORMALIZED_MODEL_FIELDS.add(Resource.SearchableFields.NAME);
ANALYZED_MODEL_FIELDS.add(UserModel.SearchableFields.LAST_NAME); LOWERCASE_NORMALIZED_MODEL_FIELDS.add(Resource.SearchableFields.TYPE);
ANALYZED_MODEL_FIELDS.add(UserModel.SearchableFields.EMAIL); LOWERCASE_NORMALIZED_MODEL_FIELDS.add(Scope.SearchableFields.NAME);
ANALYZED_MODEL_FIELDS.add(Policy.SearchableFields.TYPE); LOWERCASE_NORMALIZED_MODEL_FIELDS.add(ClientModel.SearchableFields.CLIENT_ID);
ANALYZED_MODEL_FIELDS.add(Resource.SearchableFields.TYPE); LOWERCASE_NORMALIZED_MODEL_FIELDS.add(GroupModel.SearchableFields.NAME);
LOWERCASE_NORMALIZED_MODEL_FIELDS.add(RoleModel.SearchableFields.NAME);
LOWERCASE_NORMALIZED_MODEL_FIELDS.add(RoleModel.SearchableFields.DESCRIPTION);
LOWERCASE_NORMALIZED_MODEL_FIELDS.add(UserModel.SearchableFields.USERNAME_CASE_INSENSITIVE);
LOWERCASE_NORMALIZED_MODEL_FIELDS.add(UserModel.SearchableFields.EMAIL);
LOWERCASE_NORMALIZED_MODEL_FIELDS.add(UserModel.SearchableFields.FIRST_NAME);
LOWERCASE_NORMALIZED_MODEL_FIELDS.add(UserModel.SearchableFields.LAST_NAME);
} }
public IckleQueryMapModelCriteriaBuilder(Class<E> hotRodEntityClass, StringBuilder whereClauseBuilder, Map<String, Object> parameters) { public IckleQueryMapModelCriteriaBuilder(Class<E> hotRodEntityClass, StringBuilder whereClauseBuilder, Map<String, Object> parameters) {
@ -237,14 +240,6 @@ public class IckleQueryMapModelCriteriaBuilder<E extends AbstractHotRodEntity, M
return value; return value;
} }
public static Object sanitizeAnalyzed(Object value) {
if (value instanceof String) {
return sanitizeEachUnitAndReplaceDelimiter((String) value, IckleQueryMapModelCriteriaBuilder::sanitizeSingleUnitAnalyzed, "*");
}
return value;
}
private static String sanitizeEachUnitAndReplaceDelimiter(String value, UnaryOperator<String> sanitizeSingleUnit, String replacement) { private static String sanitizeEachUnitAndReplaceDelimiter(String value, UnaryOperator<String> sanitizeSingleUnit, String replacement) {
return LIKE_PATTERN_DELIMITER.splitAsStream(value) return LIKE_PATTERN_DELIMITER.splitAsStream(value)
.map(sanitizeSingleUnit) .map(sanitizeSingleUnit)
@ -256,18 +251,6 @@ public class IckleQueryMapModelCriteriaBuilder<E extends AbstractHotRodEntity, M
return NON_ANALYZED_FIELD_REGEX.matcher(value).replaceAll("\\\\\\\\" + "$0"); return NON_ANALYZED_FIELD_REGEX.matcher(value).replaceAll("\\\\\\\\" + "$0");
} }
private static String sanitizeSingleUnitAnalyzed(String value) {
return ANALYZED_FIELD_REGEX.matcher(value).replaceAll("\\\\\\\\"); // escape "\" with extra "\"
// .replaceAll("\\\\\\\\" + "$0"); skipped for now because Infinispan is not able to escape
// special characters for analyzed fields
// TODO reevaluate once https://github.com/keycloak/keycloak/issues/9295 is fixed
}
public static boolean isAnalyzedModelField(SearchableModelField<?> modelField) {
return ANALYZED_MODEL_FIELDS.contains(modelField);
}
/** /**
* *
* @return Ickle query that represents this QueryBuilder * @return Ickle query that represents this QueryBuilder

View file

@ -56,7 +56,7 @@ public class IckleQueryOperators {
OPERATOR_TO_EXPRESSION_COMBINATORS.put(ModelCriteriaBuilder.Operator.IN, IckleQueryOperators::in); OPERATOR_TO_EXPRESSION_COMBINATORS.put(ModelCriteriaBuilder.Operator.IN, IckleQueryOperators::in);
OPERATOR_TO_EXPRESSION_COMBINATORS.put(ModelCriteriaBuilder.Operator.EXISTS, IckleQueryOperators::exists); OPERATOR_TO_EXPRESSION_COMBINATORS.put(ModelCriteriaBuilder.Operator.EXISTS, IckleQueryOperators::exists);
OPERATOR_TO_EXPRESSION_COMBINATORS.put(ModelCriteriaBuilder.Operator.NOT_EXISTS, IckleQueryOperators::notExists); OPERATOR_TO_EXPRESSION_COMBINATORS.put(ModelCriteriaBuilder.Operator.NOT_EXISTS, IckleQueryOperators::notExists);
OPERATOR_TO_EXPRESSION_COMBINATORS.put(ModelCriteriaBuilder.Operator.ILIKE, IckleQueryOperators::iLike); OPERATOR_TO_EXPRESSION_COMBINATORS.put(ModelCriteriaBuilder.Operator.ILIKE, IckleQueryOperators::like);
OPERATOR_TO_EXPRESSION_COMBINATORS.put(ModelCriteriaBuilder.Operator.LIKE, IckleQueryOperators::like); OPERATOR_TO_EXPRESSION_COMBINATORS.put(ModelCriteriaBuilder.Operator.LIKE, IckleQueryOperators::like);
OPERATOR_TO_STRING.put(ModelCriteriaBuilder.Operator.EQ, "="); OPERATOR_TO_STRING.put(ModelCriteriaBuilder.Operator.EQ, "=");
@ -94,12 +94,6 @@ public class IckleQueryOperators {
return field + " IS NULL OR " + field + " IS EMPTY"; return field + " IS NULL OR " + field + " IS EMPTY";
} }
private static String iLike(String modelFieldName, Object[] values, Map<String, Object> parameters) {
String sanitizedValue = (String) IckleQueryMapModelCriteriaBuilder.sanitizeNonAnalyzed(values[0]);
return singleValueOperator(ModelCriteriaBuilder.Operator.ILIKE)
.combine(modelFieldName + "Lowercase", new String[] {sanitizedValue.toLowerCase()}, parameters);
}
private static String like(String modelFieldName, Object[] values, Map<String, Object> parameters) { private static String like(String modelFieldName, Object[] values, Map<String, Object> parameters) {
String sanitizedValue = (String) IckleQueryMapModelCriteriaBuilder.sanitizeNonAnalyzed(values[0]); String sanitizedValue = (String) IckleQueryMapModelCriteriaBuilder.sanitizeNonAnalyzed(values[0]);
return singleValueOperator(ModelCriteriaBuilder.Operator.LIKE) return singleValueOperator(ModelCriteriaBuilder.Operator.LIKE)

View file

@ -38,9 +38,8 @@ import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import static org.keycloak.models.map.storage.hotRod.IckleQueryMapModelCriteriaBuilder.LOWERCASE_NORMALIZED_MODEL_FIELDS;
import static org.keycloak.models.map.storage.hotRod.IckleQueryMapModelCriteriaBuilder.getFieldName; import static org.keycloak.models.map.storage.hotRod.IckleQueryMapModelCriteriaBuilder.getFieldName;
import static org.keycloak.models.map.storage.hotRod.IckleQueryMapModelCriteriaBuilder.sanitizeAnalyzed;
import static org.keycloak.models.map.storage.hotRod.IckleQueryOperators.C;
/** /**
* This class provides knowledge on how to build Ickle query where clauses for specified {@link SearchableModelField}. * This class provides knowledge on how to build Ickle query where clauses for specified {@link SearchableModelField}.
@ -98,15 +97,12 @@ public class IckleQueryWhereClauses {
Object[] values, Map<String, Object> parameters) { Object[] values, Map<String, Object> parameters) {
String fieldName = IckleQueryMapModelCriteriaBuilder.getFieldName(modelField); String fieldName = IckleQueryMapModelCriteriaBuilder.getFieldName(modelField);
if (IckleQueryMapModelCriteriaBuilder.isAnalyzedModelField(modelField) && if (op == ModelCriteriaBuilder.Operator.ILIKE && !LOWERCASE_NORMALIZED_MODEL_FIELDS.contains(modelField)) {
(op.equals(ModelCriteriaBuilder.Operator.ILIKE) || op.equals(ModelCriteriaBuilder.Operator.EQ) || op.equals(ModelCriteriaBuilder.Operator.NE))) { throw new CriterionNotSupportedException(modelField, op, "Attempt to search case-insensitively without lowercase normalizer applied on the field.");
}
String clause = C + "." + fieldName + " : '" + sanitizeAnalyzed(((String)values[0]).toLowerCase()) + "'"; if (op == ModelCriteriaBuilder.Operator.LIKE && LOWERCASE_NORMALIZED_MODEL_FIELDS.contains(modelField)) {
if (op.equals(ModelCriteriaBuilder.Operator.NE)) { throw new CriterionNotSupportedException(modelField, op, "Attempt to search case-sensitively with lowercase-normalized field.");
return "not(" + clause + ")";
}
return clause;
} }
return whereClauseProducerForModelField(modelField).produceWhereClause(fieldName, op, values, parameters); return whereClauseProducerForModelField(modelField).produceWhereClause(fieldName, op, values, parameters);

View file

@ -17,6 +17,8 @@
package org.keycloak.models.map.storage.hotRod.authSession; package org.keycloak.models.map.storage.hotRod.authSession;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -41,7 +43,7 @@ import java.util.Set;
topLevelEntity = true, topLevelEntity = true,
modelClass = "org.keycloak.sessions.RootAuthenticationSessionModel" modelClass = "org.keycloak.sessions.RootAuthenticationSessionModel"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodRootAuthenticationSessionEntity.VERSION) @ProtoDoc("schema-version: " + HotRodRootAuthenticationSessionEntity.VERSION)
public class HotRodRootAuthenticationSessionEntity extends AbstractHotRodEntity { public class HotRodRootAuthenticationSessionEntity extends AbstractHotRodEntity {
@ -62,21 +64,21 @@ public class HotRodRootAuthenticationSessionEntity extends AbstractHotRodEntity
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@ProtoField(number = 4) @ProtoField(number = 4)
public Long timestamp; public Long timestamp;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 5) @ProtoField(number = 5)
public Long expiration; public Long expiration;

View file

@ -17,6 +17,8 @@
package org.keycloak.models.map.storage.hotRod.authorization; package org.keycloak.models.map.storage.hotRod.authorization;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -35,7 +37,7 @@ import org.keycloak.models.map.storage.hotRod.common.UpdatableHotRodEntityDelega
modelClass = "org.keycloak.authorization.model.PermissionTicket", modelClass = "org.keycloak.authorization.model.PermissionTicket",
cacheName = "authz" cacheName = "authz"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodPermissionTicketEntity.VERSION) @ProtoDoc("schema-version: " + HotRodPermissionTicketEntity.VERSION)
public class HotRodPermissionTicketEntity extends AbstractHotRodEntity { public class HotRodPermissionTicketEntity extends AbstractHotRodEntity {
@ -53,47 +55,47 @@ public class HotRodPermissionTicketEntity extends AbstractHotRodEntity {
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true, sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@Basic(sortable = true)
@ProtoField(number = 4) @ProtoField(number = 4)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String owner; public String owner;
@Basic(sortable = true)
@ProtoField(number = 5) @ProtoField(number = 5)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String requester; public String requester;
@ProtoField(number = 6) @ProtoField(number = 6)
public Long createdTimestamp; public Long createdTimestamp;
@Basic(sortable = true)
@ProtoField(number = 7) @ProtoField(number = 7)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public Long grantedTimestamp; public Long grantedTimestamp;
@Basic(sortable = true)
@ProtoField(number = 8) @ProtoField(number = 8)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String resourceId; public String resourceId;
@Basic(sortable = true)
@ProtoField(number = 9) @ProtoField(number = 9)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String scopeId; public String scopeId;
@Basic(sortable = true)
@ProtoField(number = 10) @ProtoField(number = 10)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String resourceServerId; public String resourceServerId;
@Basic(sortable = true)
@ProtoField(number = 11) @ProtoField(number = 11)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String policyId; public String policyId;
public static abstract class AbstractHotRodPermissionTicketEntity extends UpdatableHotRodEntityDelegateImpl<HotRodPermissionTicketEntity> implements MapPermissionTicketEntity { public static abstract class AbstractHotRodPermissionTicketEntity extends UpdatableHotRodEntityDelegateImpl<HotRodPermissionTicketEntity> implements MapPermissionTicketEntity {

View file

@ -17,6 +17,9 @@
package org.keycloak.models.map.storage.hotRod.authorization; package org.keycloak.models.map.storage.hotRod.authorization;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.api.annotations.indexing.Keyword;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -39,7 +42,7 @@ import java.util.Set;
modelClass = "org.keycloak.authorization.model.Policy", modelClass = "org.keycloak.authorization.model.Policy",
cacheName = "authz" cacheName = "authz"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodPolicyEntity.VERSION) @ProtoDoc("schema-version: " + HotRodPolicyEntity.VERSION)
public class HotRodPolicyEntity extends AbstractHotRodEntity { public class HotRodPolicyEntity extends AbstractHotRodEntity {
@ -59,61 +62,57 @@ public class HotRodPolicyEntity extends AbstractHotRodEntity {
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true, sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@Keyword(sortable = true, normalizer = "lowercase")
@ProtoField(number = 4) @ProtoField(number = 4)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String name; public String name;
@ProtoField(number = 5) @ProtoField(number = 5)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String nameLowercase;
@ProtoField(number = 6)
public String description; public String description;
@ProtoField(number = 7) @Keyword(sortable = true, normalizer = "lowercase")
@ProtoDoc("@Field(index = Index.YES, store = Store.YES, analyze = Analyze.YES, analyzer = @Analyzer(definition = \"filename\"))") @ProtoField(number = 6)
public String type; public String type;
@ProtoField(number = 8) @ProtoField(number = 7)
public Integer decisionStrategy; public Integer decisionStrategy;
@ProtoField(number = 9) @ProtoField(number = 8)
public Integer logic; public Integer logic;
@ProtoField(number = 10) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 9)
public Set<HotRodStringPair> configs; public Set<HotRodStringPair> configs;
@ProtoField(number = 11) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 10)
public String resourceServerId; public String resourceServerId;
@ProtoField(number = 12) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 11)
public Set<String> associatedPolicyIds; public Set<String> associatedPolicyIds;
@ProtoField(number = 13) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 12)
public Set<String> resourceIds; public Set<String> resourceIds;
@ProtoField(number = 14) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 13)
public Set<String> scopeIds; public Set<String> scopeIds;
@ProtoField(number = 15) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 14)
public String owner; public String owner;
public static abstract class AbstractHotRodPolicyEntity extends UpdatableHotRodEntityDelegateImpl<HotRodPolicyEntity> implements MapPolicyEntity { public static abstract class AbstractHotRodPolicyEntity extends UpdatableHotRodEntityDelegateImpl<HotRodPolicyEntity> implements MapPolicyEntity {
@ -136,7 +135,6 @@ public class HotRodPolicyEntity extends AbstractHotRodEntity {
HotRodPolicyEntity entity = getHotRodEntity(); HotRodPolicyEntity entity = getHotRodEntity();
entity.updated |= ! Objects.equals(entity.name, name); entity.updated |= ! Objects.equals(entity.name, name);
entity.name = name; entity.name = name;
entity.nameLowercase = name == null ? null : name.toLowerCase();
} }
} }

View file

@ -17,6 +17,9 @@
package org.keycloak.models.map.storage.hotRod.authorization; package org.keycloak.models.map.storage.hotRod.authorization;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.api.annotations.indexing.Keyword;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -39,7 +42,7 @@ import java.util.Set;
modelClass = "org.keycloak.authorization.model.Resource", modelClass = "org.keycloak.authorization.model.Resource",
cacheName = "authz" cacheName = "authz"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodResourceEntity.VERSION) @ProtoDoc("schema-version: " + HotRodResourceEntity.VERSION)
public class HotRodResourceEntity extends AbstractHotRodEntity { public class HotRodResourceEntity extends AbstractHotRodEntity {
@ -59,57 +62,53 @@ public class HotRodResourceEntity extends AbstractHotRodEntity {
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true, sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@Keyword(sortable = true, normalizer = "lowercase")
@ProtoField(number = 4) @ProtoField(number = 4)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String name; public String name;
@ProtoField(number = 5) @ProtoField(number = 5)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String nameLowercase;
@ProtoField(number = 6)
public String displayName; public String displayName;
@ProtoField(number = 7) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 6)
public Set<String> uris; public Set<String> uris;
@ProtoField(number = 8) @Keyword(sortable = true, normalizer = "lowercase")
@ProtoDoc("@Field(index = Index.YES, store = Store.YES, analyze = Analyze.YES, analyzer = @Analyzer(definition = \"filename\"))") @ProtoField(number = 7)
public String type; public String type;
@ProtoField(number = 9) @ProtoField(number = 8)
public String iconUri; public String iconUri;
@ProtoField(number = 10) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 9)
public String owner; public String owner;
@ProtoField(number = 11) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 10)
public Boolean ownerManagedAccess; public Boolean ownerManagedAccess;
@ProtoField(number = 12) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 11)
public String resourceServerId; public String resourceServerId;
@ProtoField(number = 13) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 12)
public Set<String> scopeIds; public Set<String> scopeIds;
@ProtoField(number = 14) @ProtoField(number = 13)
public Set<HotRodAttributeEntityNonIndexed> attributes; public Set<HotRodAttributeEntityNonIndexed> attributes;
public static abstract class AbstractHotRodResourceEntity extends UpdatableHotRodEntityDelegateImpl<HotRodResourceEntity> implements MapResourceEntity { public static abstract class AbstractHotRodResourceEntity extends UpdatableHotRodEntityDelegateImpl<HotRodResourceEntity> implements MapResourceEntity {
@ -132,7 +131,6 @@ public class HotRodResourceEntity extends AbstractHotRodEntity {
HotRodResourceEntity entity = getHotRodEntity(); HotRodResourceEntity entity = getHotRodEntity();
entity.updated |= ! Objects.equals(entity.name, name); entity.updated |= ! Objects.equals(entity.name, name);
entity.name = name; entity.name = name;
entity.nameLowercase = name == null ? null : name.toLowerCase();
} }
} }

View file

@ -17,6 +17,8 @@
package org.keycloak.models.map.storage.hotRod.authorization; package org.keycloak.models.map.storage.hotRod.authorization;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -37,7 +39,7 @@ import org.keycloak.models.map.storage.hotRod.common.UpdatableHotRodEntityDelega
cacheName = "authz" cacheName = "authz"
) )
@ProtoDoc("schema-version: " + HotRodResourceServerEntity.VERSION) @ProtoDoc("schema-version: " + HotRodResourceServerEntity.VERSION)
@ProtoDoc("@Indexed") @Indexed
public class HotRodResourceServerEntity extends AbstractHotRodEntity { public class HotRodResourceServerEntity extends AbstractHotRodEntity {
@IgnoreForEntityImplementationGenerator @IgnoreForEntityImplementationGenerator
@ -54,19 +56,19 @@ public class HotRodResourceServerEntity extends AbstractHotRodEntity {
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true, sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 4) @ProtoField(number = 4)
public String clientId; public String clientId;

View file

@ -17,6 +17,9 @@
package org.keycloak.models.map.storage.hotRod.authorization; package org.keycloak.models.map.storage.hotRod.authorization;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.api.annotations.indexing.Keyword;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -37,7 +40,7 @@ import java.util.Objects;
modelClass = "org.keycloak.authorization.model.Scope", modelClass = "org.keycloak.authorization.model.Scope",
cacheName = "authz" cacheName = "authz"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodScopeEntity.VERSION) @ProtoDoc("schema-version: " + HotRodScopeEntity.VERSION)
public class HotRodScopeEntity extends AbstractHotRodEntity { public class HotRodScopeEntity extends AbstractHotRodEntity {
@ -55,34 +58,30 @@ public class HotRodScopeEntity extends AbstractHotRodEntity {
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true, sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@Keyword(sortable = true, normalizer = "lowercase")
@ProtoField(number = 4) @ProtoField(number = 4)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String name; public String name;
@ProtoField(number = 5) @ProtoField(number = 5)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String nameLowercase;
@ProtoField(number = 6)
public String displayName; public String displayName;
@ProtoField(number = 7) @ProtoField(number = 6)
public String iconUri; public String iconUri;
@ProtoField(number = 8) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 7)
public String resourceServerId; public String resourceServerId;
public static abstract class AbstractHotRodScopeEntity extends UpdatableHotRodEntityDelegateImpl<HotRodScopeEntity> implements MapScopeEntity { public static abstract class AbstractHotRodScopeEntity extends UpdatableHotRodEntityDelegateImpl<HotRodScopeEntity> implements MapScopeEntity {
@ -105,7 +104,6 @@ public class HotRodScopeEntity extends AbstractHotRodEntity {
HotRodScopeEntity entity = getHotRodEntity(); HotRodScopeEntity entity = getHotRodEntity();
entity.updated |= ! Objects.equals(entity.name, name); entity.updated |= ! Objects.equals(entity.name, name);
entity.name = name; entity.name = name;
entity.nameLowercase = name == null ? null : name.toLowerCase();
} }
} }

View file

@ -17,6 +17,9 @@
package org.keycloak.models.map.storage.hotRod.client; package org.keycloak.models.map.storage.hotRod.client;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.api.annotations.indexing.Keyword;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -46,7 +49,7 @@ import java.util.stream.Stream;
topLevelEntity = true, topLevelEntity = true,
modelClass = "org.keycloak.models.ClientModel" modelClass = "org.keycloak.models.ClientModel"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodClientEntity.VERSION) @ProtoDoc("schema-version: " + HotRodClientEntity.VERSION)
public class HotRodClientEntity extends AbstractHotRodEntity { public class HotRodClientEntity extends AbstractHotRodEntity {
@ -66,123 +69,115 @@ public class HotRodClientEntity extends AbstractHotRodEntity {
HotRodClientEntitySchema INSTANCE = new HotRodClientEntitySchemaImpl(); HotRodClientEntitySchema INSTANCE = new HotRodClientEntitySchemaImpl();
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true, sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Keyword(sortable = true, normalizer = "lowercase")
@ProtoField(number = 4) @ProtoField(number = 4)
public String clientId; public String clientId;
/**
* Lowercase interpretation of {@link #clientId} field. Infinispan doesn't support case-insensitive LIKE for non-analyzed fields.
* Search on analyzed fields can be case-insensitive (based on used analyzer) but doesn't support ORDER BY analyzed field.
*/
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
@ProtoField(number = 5) @ProtoField(number = 5)
public String clientIdLowercase;
@ProtoField(number = 6)
public String name; public String name;
@ProtoField(number = 7) @ProtoField(number = 6)
public String description; public String description;
@ProtoField(number = 8) @ProtoField(number = 7)
public Set<String> redirectUris; public Set<String> redirectUris;
@ProtoField(number = 9) @ProtoField(number = 8)
public Boolean enabled; public Boolean enabled;
@ProtoField(number = 10) @ProtoField(number = 9)
public Boolean alwaysDisplayInConsole; public Boolean alwaysDisplayInConsole;
@ProtoField(number = 11) @ProtoField(number = 10)
public String clientAuthenticatorType; public String clientAuthenticatorType;
@ProtoField(number = 12) @ProtoField(number = 11)
public String secret; public String secret;
@ProtoField(number = 13) @ProtoField(number = 12)
public String registrationToken; public String registrationToken;
@ProtoField(number = 14) @ProtoField(number = 13)
public String protocol; public String protocol;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 15) @ProtoField(number = 14)
public Set<HotRodAttributeEntity> attributes; public Set<HotRodAttributeEntity> attributes;
@ProtoField(number = 16) @ProtoField(number = 15)
public Set<HotRodPair<String, String>> authenticationFlowBindingOverrides; public Set<HotRodPair<String, String>> authenticationFlowBindingOverrides;
@ProtoField(number = 17) @ProtoField(number = 16)
public Boolean publicClient; public Boolean publicClient;
@ProtoField(number = 18) @ProtoField(number = 17)
public Boolean fullScopeAllowed; public Boolean fullScopeAllowed;
@ProtoField(number = 19) @ProtoField(number = 18)
public Boolean frontchannelLogout; public Boolean frontchannelLogout;
@ProtoField(number = 20) @ProtoField(number = 19)
public Long notBefore; public Long notBefore;
@ProtoField(number = 21) @ProtoField(number = 20)
public Set<String> scope; public Set<String> scope;
@ProtoField(number = 22) @ProtoField(number = 21)
public Set<String> webOrigins; public Set<String> webOrigins;
@ProtoField(number = 23) @ProtoField(number = 22)
public Set<HotRodProtocolMapperEntity> protocolMappers; public Set<HotRodProtocolMapperEntity> protocolMappers;
@ProtoField(number = 24) @ProtoField(number = 23)
public Set<HotRodPair<String, Boolean>> clientScopes; public Set<HotRodPair<String, Boolean>> clientScopes;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 25, collectionImplementation = LinkedList.class) @ProtoField(number = 24, collectionImplementation = LinkedList.class)
public Collection<String> scopeMappings; public Collection<String> scopeMappings;
@ProtoField(number = 26) @ProtoField(number = 25)
public Boolean surrogateAuthRequired; public Boolean surrogateAuthRequired;
@ProtoField(number = 27) @ProtoField(number = 26)
public String managementUrl; public String managementUrl;
@ProtoField(number = 28) @ProtoField(number = 27)
public String baseUrl; public String baseUrl;
@ProtoField(number = 29) @ProtoField(number = 28)
public Boolean bearerOnly; public Boolean bearerOnly;
@ProtoField(number = 30) @ProtoField(number = 29)
public Boolean consentRequired; public Boolean consentRequired;
@ProtoField(number = 31) @ProtoField(number = 30)
public String rootUrl; public String rootUrl;
@ProtoField(number = 32) @ProtoField(number = 31)
public Boolean standardFlowEnabled; public Boolean standardFlowEnabled;
@ProtoField(number = 33) @ProtoField(number = 32)
public Boolean implicitFlowEnabled; public Boolean implicitFlowEnabled;
@ProtoField(number = 34) @ProtoField(number = 33)
public Boolean directAccessGrantsEnabled; public Boolean directAccessGrantsEnabled;
@ProtoField(number = 35) @ProtoField(number = 34)
public Boolean serviceAccountsEnabled; public Boolean serviceAccountsEnabled;
@ProtoField(number = 36) @ProtoField(number = 35)
public Integer nodeReRegistrationTimeout; public Integer nodeReRegistrationTimeout;
public static abstract class AbstractHotRodClientEntityDelegate extends UpdatableHotRodEntityDelegateImpl<HotRodClientEntity> implements MapClientEntity { public static abstract class AbstractHotRodClientEntityDelegate extends UpdatableHotRodEntityDelegateImpl<HotRodClientEntity> implements MapClientEntity {
@ -205,7 +200,6 @@ public class HotRodClientEntity extends AbstractHotRodEntity {
HotRodClientEntity entity = getHotRodEntity(); HotRodClientEntity entity = getHotRodEntity();
entity.updated |= ! Objects.equals(entity.clientId, clientId); entity.updated |= ! Objects.equals(entity.clientId, clientId);
entity.clientId = clientId; entity.clientId = clientId;
entity.clientIdLowercase = clientId == null ? null : clientId.toLowerCase();
} }
@Override @Override

View file

@ -34,10 +34,6 @@ public class HotRodProtocolMapperEntity extends AbstractHotRodEntity {
public String protocol; public String protocol;
@ProtoField(number = 4) @ProtoField(number = 4)
public String protocolMapper; public String protocolMapper;
// @ProtoField(number = 5, defaultValue = "false")
// public boolean consentRequired;
// @ProtoField(number = 5)
// public String consentText;
@ProtoField(number = 5) @ProtoField(number = 5)
public Set<HotRodPair<String, String>> config; public Set<HotRodPair<String, String>> config;

View file

@ -17,6 +17,8 @@
package org.keycloak.models.map.storage.hotRod.clientscope; package org.keycloak.models.map.storage.hotRod.clientscope;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -43,7 +45,7 @@ import java.util.Set;
topLevelEntity = true, topLevelEntity = true,
modelClass = "org.keycloak.models.ClientScopeModel" modelClass = "org.keycloak.models.ClientScopeModel"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodClientScopeEntity.VERSION) @ProtoDoc("schema-version: " + HotRodClientScopeEntity.VERSION)
public class HotRodClientScopeEntity extends AbstractHotRodEntity { public class HotRodClientScopeEntity extends AbstractHotRodEntity {
@ -63,18 +65,18 @@ public class HotRodClientScopeEntity extends AbstractHotRodEntity {
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 4) @ProtoField(number = 4)
public String name; public String name;

View file

@ -17,7 +17,8 @@
package org.keycloak.models.map.storage.hotRod.common; package org.keycloak.models.map.storage.hotRod.common;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.annotations.ProtoField; import org.infinispan.protostream.annotations.ProtoField;
import java.util.List; import java.util.List;
@ -29,13 +30,13 @@ import java.util.Objects;
* If some change is needed please create a new version of this class and solve the migration on top-level entities. * If some change is needed please create a new version of this class and solve the migration on top-level entities.
* *
*/ */
@ProtoDoc("@Indexed") @Indexed
public class HotRodAttributeEntity { public class HotRodAttributeEntity {
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public String name; public String name;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
public List<String> values; public List<String> values;

View file

@ -17,7 +17,6 @@
package org.keycloak.models.map.storage.hotRod.common; package org.keycloak.models.map.storage.hotRod.common;
import org.keycloak.models.map.common.AbstractEntity;
import org.keycloak.models.map.common.UpdatableEntity; import org.keycloak.models.map.common.UpdatableEntity;
public interface HotRodEntityDelegate<E> extends UpdatableEntity { public interface HotRodEntityDelegate<E> extends UpdatableEntity {

View file

@ -17,7 +17,8 @@
package org.keycloak.models.map.storage.hotRod.common; package org.keycloak.models.map.storage.hotRod.common;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.annotations.ProtoField; import org.infinispan.protostream.annotations.ProtoField;
import java.util.Objects; import java.util.Objects;
@ -30,14 +31,14 @@ import java.util.Objects;
* Indexed Hot Rod pair entity where both key and value are {@link String} type. The entity should be used when * Indexed Hot Rod pair entity where both key and value are {@link String} type. The entity should be used when
* there is a need to search by key or/and value. Otherwise {@link HotRodPair<String, String>} should be used. * there is a need to search by key or/and value. Otherwise {@link HotRodPair<String, String>} should be used.
*/ */
@ProtoDoc("@Indexed") @Indexed
public class HotRodStringPair { public class HotRodStringPair {
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public String key; public String key;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
public String value; public String value;

View file

@ -17,6 +17,8 @@
package org.keycloak.models.map.storage.hotRod.events; package org.keycloak.models.map.storage.hotRod.events;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -34,7 +36,7 @@ import org.keycloak.models.map.storage.hotRod.common.UpdatableHotRodEntityDelega
topLevelEntity = true, topLevelEntity = true,
modelClass = "org.keycloak.events.admin.AdminEvent" modelClass = "org.keycloak.events.admin.AdminEvent"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodAdminEventEntity.VERSION) @ProtoDoc("schema-version: " + HotRodAdminEventEntity.VERSION)
public class HotRodAdminEventEntity extends AbstractHotRodEntity { public class HotRodAdminEventEntity extends AbstractHotRodEntity {
@ -50,56 +52,56 @@ public class HotRodAdminEventEntity extends AbstractHotRodEntity {
public interface HotRodAdminEventEntitySchema extends GeneratedSchema { public interface HotRodAdminEventEntitySchema extends GeneratedSchema {
HotRodAdminEventEntitySchema INSTANCE = new HotRodAdminEventEntitySchemaImpl(); HotRodAdminEventEntitySchema INSTANCE = new HotRodAdminEventEntitySchemaImpl();
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public Long expiration; public Long expiration;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 4) @ProtoField(number = 4)
public Long timestamp; public Long timestamp;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 5) @ProtoField(number = 5)
public Integer operationType; public Integer operationType;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 6) @ProtoField(number = 6)
public String authClientId; public String authClientId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 7) @ProtoField(number = 7)
public String authIpAddress; public String authIpAddress;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 8) @ProtoField(number = 8)
public String authRealmId; public String authRealmId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 9) @ProtoField(number = 9)
public String authUserId; public String authUserId;
@ProtoField(number = 10) @ProtoField(number = 10)
public String error; public String error;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 11) @ProtoField(number = 11)
public String realmId; public String realmId;
@ProtoField(number = 12) @ProtoField(number = 12)
public String representation; public String representation;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 13) @ProtoField(number = 13)
public String resourcePath; public String resourcePath;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 14) @ProtoField(number = 14)
public String resourceType; public String resourceType;

View file

@ -17,6 +17,8 @@
package org.keycloak.models.map.storage.hotRod.events; package org.keycloak.models.map.storage.hotRod.events;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -36,7 +38,7 @@ import java.util.Set;
topLevelEntity = true, topLevelEntity = true,
modelClass = "org.keycloak.events.Event" modelClass = "org.keycloak.events.Event"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodAuthEventEntity.VERSION) @ProtoDoc("schema-version: " + HotRodAuthEventEntity.VERSION)
public class HotRodAuthEventEntity extends AbstractHotRodEntity { public class HotRodAuthEventEntity extends AbstractHotRodEntity {
@ -55,44 +57,44 @@ public class HotRodAuthEventEntity extends AbstractHotRodEntity {
HotRodAuthEventEntitySchema INSTANCE = new HotRodAuthEventEntitySchemaImpl(); HotRodAuthEventEntitySchema INSTANCE = new HotRodAuthEventEntitySchemaImpl();
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public Integer type; public Integer type;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 4) @ProtoField(number = 4)
public Long expiration; public Long expiration;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 5) @ProtoField(number = 5)
public Long timestamp; public Long timestamp;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 6) @ProtoField(number = 6)
public String clientId; public String clientId;
@ProtoField(number = 7) @ProtoField(number = 7)
public String error; public String error;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 8) @ProtoField(number = 8)
public String ipAddress; public String ipAddress;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 9) @ProtoField(number = 9)
public String realmId; public String realmId;
@ProtoField(number = 10) @ProtoField(number = 10)
public String sessionId; public String sessionId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 11) @ProtoField(number = 11)
public String userId; public String userId;

View file

@ -17,6 +17,9 @@
package org.keycloak.models.map.storage.hotRod.group; package org.keycloak.models.map.storage.hotRod.group;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.api.annotations.indexing.Keyword;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -38,7 +41,7 @@ import java.util.Set;
topLevelEntity = true, topLevelEntity = true,
modelClass = "org.keycloak.models.GroupModel" modelClass = "org.keycloak.models.GroupModel"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodGroupEntity.VERSION) @ProtoDoc("schema-version: " + HotRodGroupEntity.VERSION)
public class HotRodGroupEntity extends AbstractHotRodEntity { public class HotRodGroupEntity extends AbstractHotRodEntity {
@ -77,44 +80,35 @@ public class HotRodGroupEntity extends AbstractHotRodEntity {
HotRodGroupEntity entity = getHotRodEntity(); HotRodGroupEntity entity = getHotRodEntity();
entity.updated |= ! Objects.equals(entity.name, name); entity.updated |= ! Objects.equals(entity.name, name);
entity.name = name; entity.name = name;
entity.nameLowercase = name == null ? null : name.toLowerCase();
} }
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true, sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Keyword(sortable = true, normalizer = "lowercase")
@ProtoField(number = 4) @ProtoField(number = 4)
public String name; public String name;
/** @Basic(sortable = true)
* Lowercase interpretation of {@link #name} field. Infinispan doesn't support case-insensitive LIKE for non-analyzed fields.
* Search on analyzed fields can be case-insensitive (based on used analyzer) but doesn't support ORDER BY analyzed field.
*/
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
@ProtoField(number = 5) @ProtoField(number = 5)
public String nameLowercase;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
@ProtoField(number = 6)
public String parentId; public String parentId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 7) @ProtoField(number = 6)
public Set<HotRodAttributeEntity> attributes; public Set<HotRodAttributeEntity> attributes;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 8) @ProtoField(number = 7)
public Set<String> grantedRoles; public Set<String> grantedRoles;
@Override @Override

View file

@ -17,6 +17,8 @@
package org.keycloak.models.map.storage.hotRod.loginFailure; package org.keycloak.models.map.storage.hotRod.loginFailure;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -34,7 +36,7 @@ import org.keycloak.models.map.storage.hotRod.common.UpdatableHotRodEntityDelega
topLevelEntity = true, topLevelEntity = true,
modelClass = "org.keycloak.models.UserLoginFailureModel" modelClass = "org.keycloak.models.UserLoginFailureModel"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodUserLoginFailureEntity.VERSION) @ProtoDoc("schema-version: " + HotRodUserLoginFailureEntity.VERSION)
public class HotRodUserLoginFailureEntity extends AbstractHotRodEntity { public class HotRodUserLoginFailureEntity extends AbstractHotRodEntity {
@ -51,18 +53,18 @@ public class HotRodUserLoginFailureEntity extends AbstractHotRodEntity {
HotRodUserLoginFailureEntitySchema INSTANCE = new HotRodUserLoginFailureEntitySchemaImpl(); HotRodUserLoginFailureEntitySchema INSTANCE = new HotRodUserLoginFailureEntitySchemaImpl();
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 4) @ProtoField(number = 4)
public String userId; public String userId;

View file

@ -17,6 +17,8 @@
package org.keycloak.models.map.storage.hotRod.realm; package org.keycloak.models.map.storage.hotRod.realm;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -75,7 +77,7 @@ import static org.keycloak.models.map.common.ExpirationUtils.isExpired;
topLevelEntity = true, topLevelEntity = true,
modelClass = "org.keycloak.models.RealmModel" modelClass = "org.keycloak.models.RealmModel"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodRealmEntity.VERSION) @ProtoDoc("schema-version: " + HotRodRealmEntity.VERSION)
public class HotRodRealmEntity extends AbstractHotRodEntity { public class HotRodRealmEntity extends AbstractHotRodEntity {
@ -106,14 +108,14 @@ public class HotRodRealmEntity extends AbstractHotRodEntity {
HotRodRealmEntitySchema INSTANCE = new HotRodRealmEntitySchemaImpl(); HotRodRealmEntitySchema INSTANCE = new HotRodRealmEntitySchemaImpl();
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String name; public String name;
@ -242,11 +244,11 @@ public class HotRodRealmEntity extends AbstractHotRodEntity {
@ProtoField(number = 65) @ProtoField(number = 65)
public Set<HotRodAuthenticatorConfigEntity> authenticatorConfigs; public Set<HotRodAuthenticatorConfigEntity> authenticatorConfigs;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 66) @ProtoField(number = 66)
public Set<HotRodClientInitialAccessEntity> clientInitialAccesses; public Set<HotRodClientInitialAccessEntity> clientInitialAccesses;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 67) @ProtoField(number = 67)
public Set<HotRodComponentEntity> components; public Set<HotRodComponentEntity> components;

View file

@ -1,6 +1,7 @@
package org.keycloak.models.map.storage.hotRod.realm.entity; package org.keycloak.models.map.storage.hotRod.realm.entity;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.annotations.ProtoField; import org.infinispan.protostream.annotations.ProtoField;
import org.keycloak.models.map.annotations.GenerateHotRodEntityImplementation; import org.keycloak.models.map.annotations.GenerateHotRodEntityImplementation;
import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity; import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity;
@ -11,7 +12,7 @@ import java.util.Set;
@GenerateHotRodEntityImplementation( @GenerateHotRodEntityImplementation(
implementInterface = "org.keycloak.models.map.realm.entity.MapComponentEntity" implementInterface = "org.keycloak.models.map.realm.entity.MapComponentEntity"
) )
@ProtoDoc("@Indexed") @Indexed
public class HotRodComponentEntity extends AbstractHotRodEntity { public class HotRodComponentEntity extends AbstractHotRodEntity {
@ProtoField(number = 1) @ProtoField(number = 1)
public String id; public String id;
@ -22,7 +23,7 @@ public class HotRodComponentEntity extends AbstractHotRodEntity {
@ProtoField(number = 4) @ProtoField(number = 4)
public String providerId; public String providerId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 5) @ProtoField(number = 5)
public String providerType; public String providerType;

View file

@ -16,6 +16,9 @@
*/ */
package org.keycloak.models.map.storage.hotRod.role; package org.keycloak.models.map.storage.hotRod.role;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.api.annotations.indexing.Keyword;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -37,7 +40,7 @@ import java.util.Set;
topLevelEntity = true, topLevelEntity = true,
modelClass = "org.keycloak.models.RoleModel" modelClass = "org.keycloak.models.RoleModel"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodRoleEntity.VERSION) @ProtoDoc("schema-version: " + HotRodRoleEntity.VERSION)
public class HotRodRoleEntity extends AbstractHotRodEntity { public class HotRodRoleEntity extends AbstractHotRodEntity {
@ -77,51 +80,42 @@ public class HotRodRoleEntity extends AbstractHotRodEntity {
HotRodRoleEntity entity = getHotRodEntity(); HotRodRoleEntity entity = getHotRodEntity();
entity.updated |= ! Objects.equals(entity.name, name); entity.updated |= ! Objects.equals(entity.name, name);
entity.name = name; entity.name = name;
entity.nameLowercase = name == null ? null : name.toLowerCase();
} }
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true, sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Keyword(sortable = true, normalizer = "lowercase")
@ProtoField(number = 4) @ProtoField(number = 4)
public String name; public String name;
/** @Keyword(sortable = true, normalizer = "lowercase")
* Lowercase interpretation of {@link #name} field. Infinispan doesn't support case-insensitive LIKE for non-analyzed fields.
* Search on analyzed fields can be case-insensitive (based on used analyzer) but doesn't support ORDER BY analyzed field.
*/
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
@ProtoField(number = 5) @ProtoField(number = 5)
public String nameLowercase;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES, analyze = Analyze.YES, analyzer = @Analyzer(definition = \"filename\"))")
@ProtoField(number = 6)
public String description; public String description;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 7) @ProtoField(number = 6)
public Boolean clientRole; public Boolean clientRole;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 8) @ProtoField(number = 7)
public String clientId; public String clientId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 9) @ProtoField(number = 8)
public Set<String> compositeRoles; public Set<String> compositeRoles;
@ProtoField(number = 10) @ProtoField(number = 9)
public Set<HotRodAttributeEntityNonIndexed> attributes; public Set<HotRodAttributeEntityNonIndexed> attributes;
@Override @Override

View file

@ -17,6 +17,8 @@
package org.keycloak.models.map.storage.hotRod.singleUseObject; package org.keycloak.models.map.storage.hotRod.singleUseObject;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -37,7 +39,7 @@ import java.util.Set;
topLevelEntity = true, topLevelEntity = true,
modelClass = "org.keycloak.models.SingleUseObjectValueModel" modelClass = "org.keycloak.models.SingleUseObjectValueModel"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodSingleUseObjectEntity.VERSION) @ProtoDoc("schema-version: " + HotRodSingleUseObjectEntity.VERSION)
public class HotRodSingleUseObjectEntity extends AbstractHotRodEntity { public class HotRodSingleUseObjectEntity extends AbstractHotRodEntity {
@ -56,7 +58,7 @@ public class HotRodSingleUseObjectEntity extends AbstractHotRodEntity {
HotRodSingleUseObjectEntitySchema INSTANCE = new HotRodSingleUseObjectEntitySchemaImpl(); HotRodSingleUseObjectEntitySchema INSTANCE = new HotRodSingleUseObjectEntitySchemaImpl();
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;

View file

@ -17,23 +17,23 @@
package org.keycloak.models.map.storage.hotRod.user; package org.keycloak.models.map.storage.hotRod.user;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.annotations.ProtoField; import org.infinispan.protostream.annotations.ProtoField;
import org.keycloak.models.map.annotations.GenerateHotRodEntityImplementation; import org.keycloak.models.map.annotations.GenerateHotRodEntityImplementation;
import org.keycloak.models.map.storage.hotRod.client.HotRodProtocolMapperEntityDelegate;
import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity; import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity;
import java.util.Set; import java.util.Set;
@GenerateHotRodEntityImplementation(implementInterface = "org.keycloak.models.map.user.MapUserConsentEntity") @GenerateHotRodEntityImplementation(implementInterface = "org.keycloak.models.map.user.MapUserConsentEntity")
@ProtoDoc("@Indexed") @Indexed
public class HotRodUserConsentEntity extends AbstractHotRodEntity { public class HotRodUserConsentEntity extends AbstractHotRodEntity {
@Basic(sortable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String clientId; public String clientId;
@Basic(sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public Set<String> grantedClientScopesIds; public Set<String> grantedClientScopesIds;
@ProtoField(number = 3) @ProtoField(number = 3)

View file

@ -17,6 +17,9 @@
package org.keycloak.models.map.storage.hotRod.user; package org.keycloak.models.map.storage.hotRod.user;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.api.annotations.indexing.Keyword;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -49,7 +52,7 @@ import java.util.Set;
topLevelEntity = true, topLevelEntity = true,
modelClass = "org.keycloak.models.UserModel" modelClass = "org.keycloak.models.UserModel"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodUserEntity.VERSION) @ProtoDoc("schema-version: " + HotRodUserEntity.VERSION)
public class HotRodUserEntity extends AbstractHotRodEntity { public class HotRodUserEntity extends AbstractHotRodEntity {
@ -73,42 +76,41 @@ public class HotRodUserEntity extends AbstractHotRodEntity {
@IgnoreForEntityImplementationGenerator @IgnoreForEntityImplementationGenerator
private static final Logger LOG = Logger.getLogger(HotRodUserEntity.class); private static final Logger LOG = Logger.getLogger(HotRodUserEntity.class);
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true, sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@Basic(sortable = true)
@ProtoField(number = 4) @ProtoField(number = 4)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String username; public String username;
@ProtoField(number = 22) @Keyword(sortable = true, normalizer = "lowercase")
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 5)
public String usernameLowercase; public String usernameLowercase;
@ProtoField(number = 5) @Keyword(sortable = true, normalizer = "lowercase")
@ProtoDoc("@Field(index = Index.YES, store = Store.YES, analyze = Analyze.YES, analyzer = @Analyzer(definition = \"filename\"))") @ProtoField(number = 6)
public String firstName; public String firstName;
@ProtoField(number = 6) @ProtoField(number = 7)
public Long createdTimestamp; public Long createdTimestamp;
@ProtoField(number = 7) @Keyword(sortable = true, normalizer = "lowercase")
@ProtoDoc("@Field(index = Index.YES, store = Store.YES, analyze = Analyze.YES, analyzer = @Analyzer(definition = \"filename\"))") @ProtoField(number = 8)
public String lastName; public String lastName;
@ProtoField(number = 8) @Keyword(sortable = true, normalizer = "lowercase")
@ProtoDoc("@Field(index = Index.YES, store = Store.YES, analyze = Analyze.YES, analyzer = @Analyzer(definition = \"filename\"))") @ProtoField(number = 9)
public String email; public String email;
@ProtoField(number = 9)
/** /**
* TODO: Workaround for ISPN-8584 * TODO: Workaround for ISPN-8584
* *
@ -121,10 +123,10 @@ public class HotRodUserEntity extends AbstractHotRodEntity {
* *
* In other words it is not possible to combine searching for Analyzed field and non-indexed field in one Ickle query * In other words it is not possible to combine searching for Analyzed field and non-indexed field in one Ickle query
*/ */
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 10)
public Boolean enabled; public Boolean enabled;
@ProtoField(number = 10)
/** /**
* TODO: Workaround for ISPN-8584 * TODO: Workaround for ISPN-8584
* *
@ -135,48 +137,49 @@ public class HotRodUserEntity extends AbstractHotRodEntity {
* *
* In other words it is not possible to combine searching for Analyzed field and non-indexed field in one Ickle query * In other words it is not possible to combine searching for Analyzed field and non-indexed field in one Ickle query
*/ */
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 11)
public Boolean emailVerified; public Boolean emailVerified;
// This is necessary to be able to dynamically switch unique email constraints on and off in the realm settings // This is necessary to be able to dynamically switch unique email constraints on and off in the realm settings
@ProtoField(number = 11) @ProtoField(number = 12)
public String emailConstraint; public String emailConstraint;
@ProtoField(number = 12) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 13)
public Set<HotRodAttributeEntity> attributes; public Set<HotRodAttributeEntity> attributes;
@ProtoField(number = 13) @ProtoField(number = 14)
public Set<String> requiredActions; public Set<String> requiredActions;
@ProtoField(number = 14) @ProtoField(number = 15)
public List<HotRodUserCredentialEntity> credentials; public List<HotRodUserCredentialEntity> credentials;
@ProtoField(number = 15) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 16)
public Set<HotRodUserFederatedIdentityEntity> federatedIdentities; public Set<HotRodUserFederatedIdentityEntity> federatedIdentities;
@ProtoField(number = 16) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 17)
public Set<HotRodUserConsentEntity> userConsents; public Set<HotRodUserConsentEntity> userConsents;
@ProtoField(number = 17) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 18)
public Set<String> groupsMembership = new HashSet<>(); public Set<String> groupsMembership = new HashSet<>();
@ProtoField(number = 18) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 19)
public Set<String> rolesMembership = new HashSet<>(); public Set<String> rolesMembership = new HashSet<>();
@ProtoField(number = 19) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 20)
public String federationLink; public String federationLink;
@ProtoField(number = 20) @Basic(sortable = true)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 21)
public String serviceAccountClientLink; public String serviceAccountClientLink;
@ProtoField(number = 21) @ProtoField(number = 22)
public Long notBefore; public Long notBefore;
public static abstract class AbstractHotRodUserEntityDelegate extends UpdatableHotRodEntityDelegateImpl<HotRodUserEntity> implements MapUserEntity { public static abstract class AbstractHotRodUserEntityDelegate extends UpdatableHotRodEntityDelegateImpl<HotRodUserEntity> implements MapUserEntity {

View file

@ -17,25 +17,25 @@
package org.keycloak.models.map.storage.hotRod.user; package org.keycloak.models.map.storage.hotRod.user;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.annotations.ProtoField; import org.infinispan.protostream.annotations.ProtoField;
import org.keycloak.models.map.annotations.GenerateHotRodEntityImplementation; import org.keycloak.models.map.annotations.GenerateHotRodEntityImplementation;
import org.keycloak.models.map.storage.hotRod.client.HotRodProtocolMapperEntityDelegate;
import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity; import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity;
@GenerateHotRodEntityImplementation(implementInterface = "org.keycloak.models.map.user.MapUserFederatedIdentityEntity") @GenerateHotRodEntityImplementation(implementInterface = "org.keycloak.models.map.user.MapUserFederatedIdentityEntity")
@ProtoDoc("@Indexed") @Indexed
public class HotRodUserFederatedIdentityEntity extends AbstractHotRodEntity { public class HotRodUserFederatedIdentityEntity extends AbstractHotRodEntity {
@Basic(sortable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String identityProvider; public String identityProvider;
@ProtoField(number = 2) @ProtoField(number = 2)
public String token; public String token;
@Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
public String userId; public String userId;
@ProtoField(number = 4) @ProtoField(number = 4)

View file

@ -17,6 +17,8 @@
package org.keycloak.models.map.storage.hotRod.userSession; package org.keycloak.models.map.storage.hotRod.userSession;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -42,7 +44,7 @@ import java.util.Set;
cacheName = "org.keycloak.models.map.storage.ModelEntityUtil.getModelName(org.keycloak.models.UserSessionModel.class)" // Use the same cache name as user-sessions cacheName = "org.keycloak.models.map.storage.ModelEntityUtil.getModelName(org.keycloak.models.UserSessionModel.class)" // Use the same cache name as user-sessions
) )
@ProtoDoc("schema-version: " + HotRodResourceServerEntity.VERSION) @ProtoDoc("schema-version: " + HotRodResourceServerEntity.VERSION)
@ProtoDoc("@Indexed") @Indexed
public class HotRodAuthenticatedClientSessionEntity extends AbstractHotRodEntity { public class HotRodAuthenticatedClientSessionEntity extends AbstractHotRodEntity {
@IgnoreForEntityImplementationGenerator @IgnoreForEntityImplementationGenerator
@ -63,10 +65,11 @@ public class HotRodAuthenticatedClientSessionEntity extends AbstractHotRodEntity
HotRodAuthenticatedClientSessionEntitySchema INSTANCE = new HotRodAuthenticatedClientSessionEntitySchemaImpl(); HotRodAuthenticatedClientSessionEntitySchema INSTANCE = new HotRodAuthenticatedClientSessionEntitySchemaImpl();
} }
@Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true, sortable = true)
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;

View file

@ -17,13 +17,14 @@
package org.keycloak.models.map.storage.hotRod.userSession; package org.keycloak.models.map.storage.hotRod.userSession;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.annotations.ProtoField; import org.infinispan.protostream.annotations.ProtoField;
@ProtoDoc("@Indexed") @Indexed
public class HotRodAuthenticatedClientSessionEntityReference { public class HotRodAuthenticatedClientSessionEntityReference {
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public String clientId; public String clientId;

View file

@ -17,6 +17,8 @@
package org.keycloak.models.map.storage.hotRod.userSession; package org.keycloak.models.map.storage.hotRod.userSession;
import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.infinispan.protostream.annotations.ProtoDoc; import org.infinispan.protostream.annotations.ProtoDoc;
@ -24,20 +26,15 @@ import org.infinispan.protostream.annotations.ProtoField;
import org.keycloak.models.UserSessionModel; import org.keycloak.models.UserSessionModel;
import org.keycloak.models.map.annotations.GenerateHotRodEntityImplementation; import org.keycloak.models.map.annotations.GenerateHotRodEntityImplementation;
import org.keycloak.models.map.annotations.IgnoreForEntityImplementationGenerator; import org.keycloak.models.map.annotations.IgnoreForEntityImplementationGenerator;
import org.keycloak.models.map.common.DeepCloner;
import org.keycloak.models.map.common.delegate.DelegateProvider;
import org.keycloak.models.map.storage.hotRod.authorization.HotRodResourceServerEntity; import org.keycloak.models.map.storage.hotRod.authorization.HotRodResourceServerEntity;
import org.keycloak.models.map.common.UpdatableEntity; import org.keycloak.models.map.common.UpdatableEntity;
import org.keycloak.models.map.storage.hotRod.client.HotRodClientEntityDelegate;
import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity; import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity;
import org.keycloak.models.map.storage.hotRod.common.CommonPrimitivesProtoSchemaInitializer; import org.keycloak.models.map.storage.hotRod.common.CommonPrimitivesProtoSchemaInitializer;
import org.keycloak.models.map.storage.hotRod.common.HotRodEntityDelegate;
import org.keycloak.models.map.storage.hotRod.common.HotRodStringPair; import org.keycloak.models.map.storage.hotRod.common.HotRodStringPair;
import org.keycloak.models.map.storage.hotRod.common.HotRodTypesUtils; import org.keycloak.models.map.storage.hotRod.common.HotRodTypesUtils;
import org.keycloak.models.map.storage.hotRod.common.UpdatableHotRodEntityDelegateImpl; import org.keycloak.models.map.storage.hotRod.common.UpdatableHotRodEntityDelegateImpl;
import org.keycloak.models.map.userSession.MapAuthenticatedClientSessionEntity; import org.keycloak.models.map.userSession.MapAuthenticatedClientSessionEntity;
import org.keycloak.models.map.userSession.MapUserSessionEntity; import org.keycloak.models.map.userSession.MapUserSessionEntity;
import org.keycloak.models.map.userSession.MapUserSessionEntityDelegate;
import java.util.Collections; import java.util.Collections;
import java.util.Objects; import java.util.Objects;
@ -50,7 +47,7 @@ import java.util.Set;
topLevelEntity = true, topLevelEntity = true,
modelClass = "org.keycloak.models.UserSessionModel" modelClass = "org.keycloak.models.UserSessionModel"
) )
@ProtoDoc("@Indexed") @Indexed
@ProtoDoc("schema-version: " + HotRodResourceServerEntity.VERSION) @ProtoDoc("schema-version: " + HotRodResourceServerEntity.VERSION)
public class HotRodUserSessionEntity extends AbstractHotRodEntity { public class HotRodUserSessionEntity extends AbstractHotRodEntity {
@ -70,26 +67,26 @@ public class HotRodUserSessionEntity extends AbstractHotRodEntity {
HotRodUserSessionEntitySchema INSTANCE = new HotRodUserSessionEntitySchemaImpl(); HotRodUserSessionEntitySchema INSTANCE = new HotRodUserSessionEntitySchemaImpl();
} }
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(projectable = true)
@ProtoField(number = 1) @ProtoField(number = 1)
public Integer entityVersion = VERSION; public Integer entityVersion = VERSION;
@ProtoField(number = 2) @ProtoField(number = 2)
public String id; public String id;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 3) @ProtoField(number = 3)
public String realmId; public String realmId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 4) @ProtoField(number = 4)
public String userId; public String userId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 5) @ProtoField(number = 5)
public String brokerSessionId; public String brokerSessionId;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 6) @ProtoField(number = 6)
public String brokerUserId; public String brokerUserId;
@ -108,26 +105,26 @@ public class HotRodUserSessionEntity extends AbstractHotRodEntity {
@ProtoField(number = 11) @ProtoField(number = 11)
public Long timestamp; public Long timestamp;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 12) @ProtoField(number = 12)
public Long lastSessionRefresh; public Long lastSessionRefresh;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 13) @ProtoField(number = 13)
public Long expiration; public Long expiration;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 14) @ProtoField(number = 14)
public Set<HotRodStringPair> notes; public Set<HotRodStringPair> notes;
@ProtoField(number = 15) @ProtoField(number = 15)
public Integer state; public Integer state;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 16) @ProtoField(number = 16)
public Set<HotRodAuthenticatedClientSessionEntityReference> authenticatedClientSessions; public Set<HotRodAuthenticatedClientSessionEntityReference> authenticatedClientSessions;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @Basic(sortable = true)
@ProtoField(number = 17) @ProtoField(number = 17)
public Boolean offline; public Boolean offline;

View file

@ -77,7 +77,7 @@ public class IckleQueryMapModelCriteriaBuilderTest {
DefaultModelCriteria<UserModel> criteria = mcb.compare(UserModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, "realm1"); DefaultModelCriteria<UserModel> criteria = mcb.compare(UserModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, "realm1");
criteria = criteria.compare(UserModel.SearchableFields.SERVICE_ACCOUNT_CLIENT, ModelCriteriaBuilder.Operator.NOT_EXISTS); criteria = criteria.compare(UserModel.SearchableFields.SERVICE_ACCOUNT_CLIENT, ModelCriteriaBuilder.Operator.NOT_EXISTS);
criteria = mcb.and(criteria, mcb.or( criteria = mcb.and(criteria, mcb.or(
mcb.compare(UserModel.SearchableFields.USERNAME, ModelCriteriaBuilder.Operator.ILIKE, "a"), mcb.compare(UserModel.SearchableFields.USERNAME, ModelCriteriaBuilder.Operator.LIKE, "a"),
mcb.compare(UserModel.SearchableFields.EMAIL, ModelCriteriaBuilder.Operator.ILIKE, "a"), mcb.compare(UserModel.SearchableFields.EMAIL, ModelCriteriaBuilder.Operator.ILIKE, "a"),
mcb.compare(UserModel.SearchableFields.FIRST_NAME, ModelCriteriaBuilder.Operator.ILIKE, "a"), mcb.compare(UserModel.SearchableFields.FIRST_NAME, ModelCriteriaBuilder.Operator.ILIKE, "a"),
mcb.compare(UserModel.SearchableFields.LAST_NAME, ModelCriteriaBuilder.Operator.ILIKE, "a") mcb.compare(UserModel.SearchableFields.LAST_NAME, ModelCriteriaBuilder.Operator.ILIKE, "a")
@ -85,7 +85,17 @@ public class IckleQueryMapModelCriteriaBuilderTest {
IckleQueryMapModelCriteriaBuilder<HotRodUserEntity, UserModel> ickle = criteria.flashToModelCriteriaBuilder(new IckleQueryMapModelCriteriaBuilder<>(HotRodUserEntity.class)); IckleQueryMapModelCriteriaBuilder<HotRodUserEntity, UserModel> ickle = criteria.flashToModelCriteriaBuilder(new IckleQueryMapModelCriteriaBuilder<>(HotRodUserEntity.class));
assertThat(ickle.getIckleQuery(), is(equalTo("FROM kc.HotRodUserEntity c WHERE ((c.realmId = :realmId0) AND (c.serviceAccountClientLink IS NULL OR c.serviceAccountClientLink IS EMPTY) AND ((c.usernameLowercase LIKE :usernameLowercase0) OR (c.email : 'a') OR (c.firstName : 'a') OR (c.lastName : 'a')))"))); assertThat(ickle.getIckleQuery(), is(equalTo("FROM kc.HotRodUserEntity c WHERE ((c.realmId = :realmId0) AND (c.serviceAccountClientLink IS NULL OR c.serviceAccountClientLink IS EMPTY) AND ((c.username LIKE :username0) OR (c.email LIKE :email0) OR (c.firstName LIKE :firstName0) OR (c.lastName LIKE :lastName0)))")));
assertThat(ickle.getParameters().entrySet(), hasSize(5));
assertThat(ickle.getParameters(), allOf(hasEntry("realmId0", "realm1"), hasEntry("username0", "a"), hasEntry("email0", "a"), hasEntry("firstName0", "a"), hasEntry("lastName0", "a")));
final DefaultModelCriteria<UserModel> mcb2 = criteria();
criteria = mcb2.compare(UserModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, "realm1")
.compare(UserModel.SearchableFields.USERNAME_CASE_INSENSITIVE, ModelCriteriaBuilder.Operator.ILIKE, "a");
ickle = criteria.flashToModelCriteriaBuilder(new IckleQueryMapModelCriteriaBuilder<>(HotRodUserEntity.class));
assertThat(ickle.getIckleQuery(), is(equalTo("FROM kc.HotRodUserEntity c WHERE ((c.realmId = :realmId0) AND (c.usernameLowercase LIKE :usernameLowercase0))")));
assertThat(ickle.getParameters().entrySet(), hasSize(2)); assertThat(ickle.getParameters().entrySet(), hasSize(2));
assertThat(ickle.getParameters(), allOf(hasEntry("realmId0", "realm1"), hasEntry("usernameLowercase0", "a"))); assertThat(ickle.getParameters(), allOf(hasEntry("realmId0", "realm1"), hasEntry("usernameLowercase0", "a")));
} }

View file

@ -958,6 +958,11 @@
<artifactId>infinispan-server-rest</artifactId> <artifactId>infinispan-server-rest</artifactId>
<version>${infinispan.version}</version> <version>${infinispan.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-api</artifactId>
<version>${infinispan.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.infinispan</groupId> <groupId>org.infinispan</groupId>
<artifactId>infinispan-client-hotrod</artifactId> <artifactId>infinispan-client-hotrod</artifactId>

View file

@ -502,6 +502,17 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-api</artifactId>
<version>${infinispan.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>com.github.ua-parser</groupId> <groupId>com.github.ua-parser</groupId>
<artifactId>uap-java</artifactId> <artifactId>uap-java</artifactId>

View file

@ -149,6 +149,20 @@ public class UserModelTest extends KeycloakModelTest {
return null; return null;
}); });
// try to query storage in a separate transaction to make sure that storage can handle case-sensitive usernames
withRealm(realm1Id, (session, realm) -> {
UserModel user1 = session.users().getUserByUsername(realm, "user");
UserModel user2 = session.users().getUserByUsername(realm, "USER");
assertThat(user1, not(nullValue()));
assertThat(user2, not(nullValue()));
assertThat(user1.getUsername(), equalTo("user"));
assertThat(user2.getUsername(), equalTo("USER"));
return null;
});
realm2Id = inComittedTransaction((Function<KeycloakSession, String>) session -> { realm2Id = inComittedTransaction((Function<KeycloakSession, String>) session -> {
RealmModel realm = session.realms().createRealm("realm2"); RealmModel realm = session.realms().createRealm("realm2");
realm.setDefaultRole(session.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName())); realm.setDefaultRole(session.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName()));