Closes #8969 - Add Groups HotRod storage

This commit is contained in:
Michal Hajas 2021-11-30 18:06:19 +01:00 committed by Hynek Mlnařík
parent 8e03942e87
commit 5aa9a09b20
11 changed files with 153 additions and 40 deletions

View file

@ -111,7 +111,7 @@ public class HotRodMapStorage<K, E extends AbstractHotRodEntity, V extends HotRo
@Override @Override
public Stream<V> read(QueryParameters<M> queryParameters) { public Stream<V> read(QueryParameters<M> queryParameters) {
IckleQueryMapModelCriteriaBuilder<K, V, M> iqmcb = queryParameters.getModelCriteriaBuilder() IckleQueryMapModelCriteriaBuilder<E, M> iqmcb = queryParameters.getModelCriteriaBuilder()
.flashToModelCriteriaBuilder(createCriteriaBuilder()); .flashToModelCriteriaBuilder(createCriteriaBuilder());
String queryString = iqmcb.getIckleQuery(); String queryString = iqmcb.getIckleQuery();
@ -137,7 +137,7 @@ public class HotRodMapStorage<K, E extends AbstractHotRodEntity, V extends HotRo
@Override @Override
public long getCount(QueryParameters<M> queryParameters) { public long getCount(QueryParameters<M> queryParameters) {
IckleQueryMapModelCriteriaBuilder<K, V, M> iqmcb = queryParameters.getModelCriteriaBuilder() IckleQueryMapModelCriteriaBuilder<E, M> iqmcb = queryParameters.getModelCriteriaBuilder()
.flashToModelCriteriaBuilder(createCriteriaBuilder()); .flashToModelCriteriaBuilder(createCriteriaBuilder());
String queryString = iqmcb.getIckleQuery(); String queryString = iqmcb.getIckleQuery();
@ -153,7 +153,7 @@ public class HotRodMapStorage<K, E extends AbstractHotRodEntity, V extends HotRo
@Override @Override
public long delete(QueryParameters<M> queryParameters) { public long delete(QueryParameters<M> queryParameters) {
IckleQueryMapModelCriteriaBuilder<K, V, M> iqmcb = queryParameters.getModelCriteriaBuilder() IckleQueryMapModelCriteriaBuilder<E, M> iqmcb = queryParameters.getModelCriteriaBuilder()
.flashToModelCriteriaBuilder(createCriteriaBuilder()); .flashToModelCriteriaBuilder(createCriteriaBuilder());
String queryString = "SELECT id " + iqmcb.getIckleQuery(); String queryString = "SELECT id " + iqmcb.getIckleQuery();
@ -183,8 +183,8 @@ public class HotRodMapStorage<K, E extends AbstractHotRodEntity, V extends HotRo
return result.get(); return result.get();
} }
public IckleQueryMapModelCriteriaBuilder<K, V, M> createCriteriaBuilder() { public IckleQueryMapModelCriteriaBuilder<E, M> createCriteriaBuilder() {
return new IckleQueryMapModelCriteriaBuilder<>(); return new IckleQueryMapModelCriteriaBuilder<>(storedEntityDescriptor.getEntityTypeClass());
} }
@Override @Override

View file

@ -22,8 +22,10 @@ import org.keycloak.Config;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
import org.keycloak.component.AmphibianProviderFactory; import org.keycloak.component.AmphibianProviderFactory;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.map.group.MapGroupEntity;
import org.keycloak.models.map.storage.hotRod.client.HotRodClientEntity; import org.keycloak.models.map.storage.hotRod.client.HotRodClientEntity;
import org.keycloak.models.map.storage.hotRod.client.HotRodClientEntityDelegate; import org.keycloak.models.map.storage.hotRod.client.HotRodClientEntityDelegate;
import org.keycloak.models.map.storage.hotRod.client.HotRodProtocolMapperEntityDelegate; import org.keycloak.models.map.storage.hotRod.client.HotRodProtocolMapperEntityDelegate;
@ -34,6 +36,8 @@ import org.keycloak.models.map.storage.hotRod.common.HotRodEntityDescriptor;
import org.keycloak.models.map.storage.hotRod.connections.HotRodConnectionProvider; import org.keycloak.models.map.storage.hotRod.connections.HotRodConnectionProvider;
import org.keycloak.models.map.storage.MapStorageProvider; import org.keycloak.models.map.storage.MapStorageProvider;
import org.keycloak.models.map.storage.MapStorageProviderFactory; import org.keycloak.models.map.storage.MapStorageProviderFactory;
import org.keycloak.models.map.storage.hotRod.group.HotRodGroupEntity;
import org.keycloak.models.map.storage.hotRod.group.HotRodGroupEntityDelegate;
import org.keycloak.provider.EnvironmentDependentProviderFactory; import org.keycloak.provider.EnvironmentDependentProviderFactory;
import java.util.HashMap; import java.util.HashMap;
@ -45,8 +49,9 @@ public class HotRodMapStorageProviderFactory implements AmphibianProviderFactory
private static final Logger LOG = Logger.getLogger(HotRodMapStorageProviderFactory.class); private static final Logger LOG = Logger.getLogger(HotRodMapStorageProviderFactory.class);
private final static DeepCloner CLONER = new DeepCloner.Builder() private final static DeepCloner CLONER = new DeepCloner.Builder()
.constructorDC(MapClientEntity.class, HotRodClientEntityDelegate::new) .constructorDC(MapClientEntity.class, HotRodClientEntityDelegate::new)
.constructor(MapProtocolMapperEntity.class, HotRodProtocolMapperEntityDelegate::new) .constructor(MapProtocolMapperEntity.class, HotRodProtocolMapperEntityDelegate::new)
.constructor(MapGroupEntity.class, HotRodGroupEntityDelegate::new)
.build(); .build();
public static final Map<Class<?>, HotRodEntityDescriptor<?, ?>> ENTITY_DESCRIPTOR_MAP = new HashMap<>(); public static final Map<Class<?>, HotRodEntityDescriptor<?, ?>> ENTITY_DESCRIPTOR_MAP = new HashMap<>();
@ -56,6 +61,12 @@ public class HotRodMapStorageProviderFactory implements AmphibianProviderFactory
new HotRodEntityDescriptor<>(ClientModel.class, new HotRodEntityDescriptor<>(ClientModel.class,
HotRodClientEntity.class, HotRodClientEntity.class,
HotRodClientEntityDelegate::new)); HotRodClientEntityDelegate::new));
// Groups descriptor
ENTITY_DESCRIPTOR_MAP.put(GroupModel.class,
new HotRodEntityDescriptor<>(GroupModel.class,
HotRodGroupEntity.class,
HotRodGroupEntityDelegate::new));
} }
@Override @Override
@ -95,6 +106,6 @@ public class HotRodMapStorageProviderFactory implements AmphibianProviderFactory
@Override @Override
public String getHelpText() { public String getHelpText() {
return "HotRod client storage"; return "HotRod map storage";
} }
} }

View file

@ -18,8 +18,9 @@
package org.keycloak.models.map.storage.hotRod; package org.keycloak.models.map.storage.hotRod;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.map.common.AbstractEntity; import org.keycloak.models.GroupModel;
import org.keycloak.models.map.storage.ModelCriteriaBuilder; import org.keycloak.models.map.storage.ModelCriteriaBuilder;
import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity;
import org.keycloak.storage.SearchableModelField; import org.keycloak.storage.SearchableModelField;
import java.util.Arrays; import java.util.Arrays;
@ -32,10 +33,12 @@ import java.util.stream.Collectors;
import static org.keycloak.models.map.storage.hotRod.IckleQueryOperators.C; import static org.keycloak.models.map.storage.hotRod.IckleQueryOperators.C;
import static org.keycloak.models.map.storage.hotRod.IckleQueryOperators.findAvailableNamedParam; import static org.keycloak.models.map.storage.hotRod.IckleQueryOperators.findAvailableNamedParam;
import static org.keycloak.models.map.storage.hotRod.common.ProtoSchemaInitializer.HOT_ROD_ENTITY_PACKAGE;
public class IckleQueryMapModelCriteriaBuilder<K, V extends AbstractEntity, M> implements ModelCriteriaBuilder<M, IckleQueryMapModelCriteriaBuilder<K, V, M>> { public class IckleQueryMapModelCriteriaBuilder<E extends AbstractHotRodEntity, M> implements ModelCriteriaBuilder<M, IckleQueryMapModelCriteriaBuilder<E, M>> {
private static final int INITIAL_BUILDER_CAPACITY = 250; private static final int INITIAL_BUILDER_CAPACITY = 250;
private final Class<E> hotRodEntityClass;
private final StringBuilder whereClauseBuilder = new StringBuilder(INITIAL_BUILDER_CAPACITY); private final StringBuilder whereClauseBuilder = new StringBuilder(INITIAL_BUILDER_CAPACITY);
private final Map<String, Object> parameters; private final Map<String, Object> parameters;
public static final Map<SearchableModelField<?>, String> INFINISPAN_NAME_OVERRIDES = new HashMap<>(); public static final Map<SearchableModelField<?>, String> INFINISPAN_NAME_OVERRIDES = new HashMap<>();
@ -43,14 +46,19 @@ public class IckleQueryMapModelCriteriaBuilder<K, V extends AbstractEntity, M> i
static { static {
INFINISPAN_NAME_OVERRIDES.put(ClientModel.SearchableFields.SCOPE_MAPPING_ROLE, "scopeMappings"); INFINISPAN_NAME_OVERRIDES.put(ClientModel.SearchableFields.SCOPE_MAPPING_ROLE, "scopeMappings");
INFINISPAN_NAME_OVERRIDES.put(ClientModel.SearchableFields.ATTRIBUTE, "attributes"); INFINISPAN_NAME_OVERRIDES.put(ClientModel.SearchableFields.ATTRIBUTE, "attributes");
INFINISPAN_NAME_OVERRIDES.put(GroupModel.SearchableFields.PARENT_ID, "parentId");
INFINISPAN_NAME_OVERRIDES.put(GroupModel.SearchableFields.ASSIGNED_ROLE, "grantedRoles");
} }
public IckleQueryMapModelCriteriaBuilder(StringBuilder whereClauseBuilder, Map<String, Object> parameters) { public IckleQueryMapModelCriteriaBuilder(Class<E> hotRodEntityClass, StringBuilder whereClauseBuilder, Map<String, Object> parameters) {
this.hotRodEntityClass = hotRodEntityClass;
this.whereClauseBuilder.append(whereClauseBuilder); this.whereClauseBuilder.append(whereClauseBuilder);
this.parameters = parameters; this.parameters = parameters;
} }
public IckleQueryMapModelCriteriaBuilder() { public IckleQueryMapModelCriteriaBuilder(Class<E> hotRodEntityClass) {
this.hotRodEntityClass = hotRodEntityClass;
this.parameters = new HashMap<>(); this.parameters = new HashMap<>();
} }
@ -63,7 +71,7 @@ public class IckleQueryMapModelCriteriaBuilder<K, V extends AbstractEntity, M> i
} }
@Override @Override
public IckleQueryMapModelCriteriaBuilder<K, V, M> compare(SearchableModelField<? super M> modelField, Operator op, Object... value) { public IckleQueryMapModelCriteriaBuilder<E, M> compare(SearchableModelField<? super M> modelField, Operator op, Object... value) {
StringBuilder newBuilder = new StringBuilder(INITIAL_BUILDER_CAPACITY); StringBuilder newBuilder = new StringBuilder(INITIAL_BUILDER_CAPACITY);
newBuilder.append("("); newBuilder.append("(");
@ -78,17 +86,17 @@ public class IckleQueryMapModelCriteriaBuilder<K, V extends AbstractEntity, M> i
newBuilder.append(")"); newBuilder.append(")");
} }
return new IckleQueryMapModelCriteriaBuilder<>(newBuilder.append(")"), newParameters); return new IckleQueryMapModelCriteriaBuilder<>(hotRodEntityClass, newBuilder.append(")"), newParameters);
} }
private StringBuilder joinBuilders(IckleQueryMapModelCriteriaBuilder<K, V, M>[] builders, String delimiter) { private StringBuilder joinBuilders(IckleQueryMapModelCriteriaBuilder<E, M>[] builders, String delimiter) {
return new StringBuilder(INITIAL_BUILDER_CAPACITY).append("(").append(Arrays.stream(builders) return new StringBuilder(INITIAL_BUILDER_CAPACITY).append("(").append(Arrays.stream(builders)
.map(IckleQueryMapModelCriteriaBuilder::getWhereClauseBuilder) .map(IckleQueryMapModelCriteriaBuilder::getWhereClauseBuilder)
.filter(IckleQueryMapModelCriteriaBuilder::notEmpty) .filter(IckleQueryMapModelCriteriaBuilder::notEmpty)
.collect(Collectors.joining(delimiter))).append(")"); .collect(Collectors.joining(delimiter))).append(")");
} }
private Map<String, Object> joinParameters(IckleQueryMapModelCriteriaBuilder<K, V, M>[] builders) { private Map<String, Object> joinParameters(IckleQueryMapModelCriteriaBuilder<E, M>[] builders) {
return Arrays.stream(builders) return Arrays.stream(builders)
.map(IckleQueryMapModelCriteriaBuilder::getParameters) .map(IckleQueryMapModelCriteriaBuilder::getParameters)
.map(Map::entrySet) .map(Map::entrySet)
@ -97,7 +105,7 @@ public class IckleQueryMapModelCriteriaBuilder<K, V extends AbstractEntity, M> i
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private IckleQueryMapModelCriteriaBuilder<K, V, M>[] resolveNamedQueryConflicts(IckleQueryMapModelCriteriaBuilder<K, V, M>[] builders) { private IckleQueryMapModelCriteriaBuilder<E, M>[] resolveNamedQueryConflicts(IckleQueryMapModelCriteriaBuilder<E, M>[] builders) {
final Set<String> existingKeys = new HashSet<>(); final Set<String> existingKeys = new HashSet<>();
return Arrays.stream(builders).map(builder -> { return Arrays.stream(builders).map(builder -> {
@ -123,36 +131,36 @@ public class IckleQueryMapModelCriteriaBuilder<K, V extends AbstractEntity, M> i
} }
} }
return new IckleQueryMapModelCriteriaBuilder<>(new StringBuilder(newWhereClause), newParameters); return new IckleQueryMapModelCriteriaBuilder<>(hotRodEntityClass, new StringBuilder(newWhereClause), newParameters);
}).toArray(IckleQueryMapModelCriteriaBuilder[]::new); }).toArray(IckleQueryMapModelCriteriaBuilder[]::new);
} }
@Override @Override
public IckleQueryMapModelCriteriaBuilder<K, V, M> and(IckleQueryMapModelCriteriaBuilder<K, V, M>... builders) { public IckleQueryMapModelCriteriaBuilder<E, M> and(IckleQueryMapModelCriteriaBuilder<E, M>... builders) {
if (builders.length == 0) { if (builders.length == 0) {
return new IckleQueryMapModelCriteriaBuilder<>(); return new IckleQueryMapModelCriteriaBuilder<>(hotRodEntityClass);
} }
builders = resolveNamedQueryConflicts(builders); builders = resolveNamedQueryConflicts(builders);
return new IckleQueryMapModelCriteriaBuilder<>(joinBuilders(builders, " AND "), return new IckleQueryMapModelCriteriaBuilder<>(hotRodEntityClass, joinBuilders(builders, " AND "),
joinParameters(builders)); joinParameters(builders));
} }
@Override @Override
public IckleQueryMapModelCriteriaBuilder<K, V, M> or(IckleQueryMapModelCriteriaBuilder<K, V, M>... builders) { public IckleQueryMapModelCriteriaBuilder<E, M> or(IckleQueryMapModelCriteriaBuilder<E, M>... builders) {
if (builders.length == 0) { if (builders.length == 0) {
return new IckleQueryMapModelCriteriaBuilder<>(); return new IckleQueryMapModelCriteriaBuilder<>(hotRodEntityClass);
} }
builders = resolveNamedQueryConflicts(builders); builders = resolveNamedQueryConflicts(builders);
return new IckleQueryMapModelCriteriaBuilder<>(joinBuilders(builders, " OR "), return new IckleQueryMapModelCriteriaBuilder<>(hotRodEntityClass, joinBuilders(builders, " OR "),
joinParameters(builders)); joinParameters(builders));
} }
@Override @Override
public IckleQueryMapModelCriteriaBuilder<K, V, M> not(IckleQueryMapModelCriteriaBuilder<K, V, M> builder) { public IckleQueryMapModelCriteriaBuilder<E, M> not(IckleQueryMapModelCriteriaBuilder<E, M> builder) {
StringBuilder newBuilder = new StringBuilder(INITIAL_BUILDER_CAPACITY); StringBuilder newBuilder = new StringBuilder(INITIAL_BUILDER_CAPACITY);
StringBuilder originalBuilder = builder.getWhereClauseBuilder(); StringBuilder originalBuilder = builder.getWhereClauseBuilder();
@ -160,7 +168,7 @@ public class IckleQueryMapModelCriteriaBuilder<K, V extends AbstractEntity, M> i
newBuilder.append("not").append(originalBuilder); newBuilder.append("not").append(originalBuilder);
} }
return new IckleQueryMapModelCriteriaBuilder<>(newBuilder, builder.getParameters()); return new IckleQueryMapModelCriteriaBuilder<>(hotRodEntityClass, newBuilder, builder.getParameters());
} }
private StringBuilder getWhereClauseBuilder() { private StringBuilder getWhereClauseBuilder() {
@ -172,7 +180,7 @@ public class IckleQueryMapModelCriteriaBuilder<K, V extends AbstractEntity, M> i
* @return Ickle query that represents this QueryBuilder * @return Ickle query that represents this QueryBuilder
*/ */
public String getIckleQuery() { public String getIckleQuery() {
return "FROM org.keycloak.models.map.storage.hotrod.HotRodClientEntity " + C + ((whereClauseBuilder.length() != 0) ? " WHERE " + whereClauseBuilder : ""); return "FROM " + HOT_ROD_ENTITY_PACKAGE + "." + hotRodEntityClass.getSimpleName() + " " + C + ((whereClauseBuilder.length() != 0) ? " WHERE " + whereClauseBuilder : "");
} }
/** /**

View file

@ -112,7 +112,7 @@ public class IckleQueryOperators {
operands = new HashSet<>(Arrays.asList(values)); operands = new HashSet<>(Arrays.asList(values));
} }
return C + "." + modelField + " IN (" + operands.stream() return operands.isEmpty() ? "false" : C + "." + modelField + " IN (" + operands.stream()
.map(operand -> { .map(operand -> {
String namedParam = findAvailableNamedParam(parameters.keySet(), modelField); String namedParam = findAvailableNamedParam(parameters.keySet(), modelField);
parameters.put(namedParam, operand); parameters.put(namedParam, operand);
@ -149,9 +149,13 @@ public class IckleQueryOperators {
return (modelFieldName, values, parameters) -> { return (modelFieldName, values, parameters) -> {
if (values.length != 1) throw new RuntimeException("Invalid arguments, expected (" + modelFieldName + "), got: " + Arrays.toString(values)); if (values.length != 1) throw new RuntimeException("Invalid arguments, expected (" + modelFieldName + "), got: " + Arrays.toString(values));
String namedParameter = findAvailableNamedParam(parameters.keySet(), modelFieldName); if (values[0] == null && op.equals(ModelCriteriaBuilder.Operator.EQ)) {
return C + "." + modelFieldName + " IS NULL";
}
String namedParameter = findAvailableNamedParam(parameters.keySet(), modelFieldName);
parameters.put(namedParameter, values[0]); parameters.put(namedParameter, values[0]);
return C + "." + modelFieldName + " " + IckleQueryOperators.operatorToString(op) + " :" + namedParameter; return C + "." + modelFieldName + " " + IckleQueryOperators.operatorToString(op) + " :" + namedParameter;
}; };
} }

View file

@ -22,20 +22,29 @@ import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
import org.keycloak.models.map.storage.hotRod.client.HotRodAttributeEntity; import org.keycloak.models.map.storage.hotRod.client.HotRodAttributeEntity;
import org.keycloak.models.map.storage.hotRod.client.HotRodClientEntity; import org.keycloak.models.map.storage.hotRod.client.HotRodClientEntity;
import org.keycloak.models.map.storage.hotRod.client.HotRodProtocolMapperEntity; import org.keycloak.models.map.storage.hotRod.client.HotRodProtocolMapperEntity;
import org.keycloak.models.map.storage.hotRod.group.HotRodGroupEntity;
/** /**
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a> * @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
*/ */
@AutoProtoSchemaBuilder( @AutoProtoSchemaBuilder(
includeClasses = { includeClasses = {
HotRodAttributeEntity.class, // Clients
HotRodClientEntity.class, HotRodClientEntity.class,
HotRodAttributeEntity.class,
HotRodProtocolMapperEntity.class, HotRodProtocolMapperEntity.class,
// Groups
HotRodGroupEntity.class,
// Common
HotRodPair.class HotRodPair.class
}, },
schemaFileName = "KeycloakHotRodMapStorage.proto", schemaFileName = "KeycloakHotRodMapStorage.proto",
schemaFilePath = "proto/", schemaFilePath = "proto/",
schemaPackageName = "org.keycloak.models.map.storage.hotrod") schemaPackageName = ProtoSchemaInitializer.HOT_ROD_ENTITY_PACKAGE)
public interface ProtoSchemaInitializer extends GeneratedSchema { public interface ProtoSchemaInitializer extends GeneratedSchema {
String HOT_ROD_ENTITY_PACKAGE = "kc";
ProtoSchemaInitializer INSTANCE = new ProtoSchemaInitializerImpl(); ProtoSchemaInitializer INSTANCE = new ProtoSchemaInitializerImpl();
} }

View file

@ -0,0 +1,72 @@
/*
* Copyright 2021 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.models.map.storage.hotRod.group;
import org.infinispan.protostream.annotations.ProtoField;
import org.keycloak.models.map.annotations.GenerateHotRodEntityImplementation;
import org.keycloak.models.map.common.UpdatableEntity;
import org.keycloak.models.map.group.MapGroupEntity;
import org.keycloak.models.map.storage.hotRod.client.HotRodAttributeEntity;
import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity;
import org.keycloak.models.map.storage.hotRod.common.HotRodEntityDelegate;
import java.util.Set;
@GenerateHotRodEntityImplementation(
implementInterface = "org.keycloak.models.map.group.MapGroupEntity",
inherits = "org.keycloak.models.map.storage.hotRod.group.HotRodGroupEntity.AbstractHotRodGroupEntityDelegate"
)
public class HotRodGroupEntity implements AbstractHotRodEntity {
public static abstract class AbstractHotRodGroupEntityDelegate extends UpdatableEntity.Impl implements HotRodEntityDelegate<HotRodGroupEntity>, MapGroupEntity {
@Override
public String getId() {
return getHotRodEntity().id;
}
@Override
public void setId(String id) {
HotRodGroupEntity entity = getHotRodEntity();
if (entity.id != null) throw new IllegalStateException("Id cannot be changed");
entity.id = id;
this.updated |= id != null;
}
}
@ProtoField(number = 1, required = true)
public int entityVersion = 1;
@ProtoField(number = 2, required = true)
public String id;
@ProtoField(number = 3)
public String realmId;
@ProtoField(number = 4)
public String name;
@ProtoField(number = 5)
public String parentId;
@ProtoField(number = 6)
public Set<HotRodAttributeEntity> attributes;
@ProtoField(number = 7)
public Set<String> grantedRoles;
}

View file

@ -6,5 +6,8 @@
<distributed-cache name="clients" mode="SYNC"> <distributed-cache name="clients" mode="SYNC">
<encoding media-type="application/x-protostream"/> <encoding media-type="application/x-protostream"/>
</distributed-cache> </distributed-cache>
<distributed-cache name="groups" mode="SYNC">
<encoding media-type="application/x-protostream"/>
</distributed-cache>
</cache-container> </cache-container>
</infinispan> </infinispan>

View file

@ -8,5 +8,8 @@
<distributed-cache name="clients" mode="SYNC"> <distributed-cache name="clients" mode="SYNC">
<encoding media-type="application/x-protostream"/> <encoding media-type="application/x-protostream"/>
</distributed-cache> </distributed-cache>
<distributed-cache name="groups" mode="SYNC">
<encoding media-type="application/x-protostream"/>
</distributed-cache>
</cache-container> </cache-container>
</infinispan> </infinispan>

View file

@ -37,9 +37,9 @@ import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.crit
public class IckleQueryMapModelCriteriaBuilderTest { public class IckleQueryMapModelCriteriaBuilderTest {
@Test @Test
public void testSimpleIckleQuery() { public void testSimpleIckleQuery() {
IckleQueryMapModelCriteriaBuilder<String, HotRodClientEntityDelegate, ClientModel> v = new IckleQueryMapModelCriteriaBuilder<>(); IckleQueryMapModelCriteriaBuilder<HotRodClientEntity, ClientModel> v = new IckleQueryMapModelCriteriaBuilder<>(HotRodClientEntity.class);
IckleQueryMapModelCriteriaBuilder<String, HotRodClientEntityDelegate, ClientModel> mcb = v.compare(CLIENT_ID, ModelCriteriaBuilder.Operator.EQ, 3); IckleQueryMapModelCriteriaBuilder<HotRodClientEntity, ClientModel> mcb = v.compare(CLIENT_ID, ModelCriteriaBuilder.Operator.EQ, 3);
assertThat(mcb.getIckleQuery(), is(equalTo("FROM org.keycloak.models.map.storage.hotrod.HotRodClientEntity c WHERE (c.clientId = :clientId0)"))); assertThat(mcb.getIckleQuery(), is(equalTo("FROM kc.HotRodClientEntity c WHERE (c.clientId = :clientId0)")));
assertThat(mcb.getParameters().entrySet(), hasSize(1)); assertThat(mcb.getParameters().entrySet(), hasSize(1));
assertThat(mcb.getParameters(), hasEntry("clientId0", 3)); assertThat(mcb.getParameters(), hasEntry("clientId0", 3));
@ -47,7 +47,7 @@ public class IckleQueryMapModelCriteriaBuilderTest {
mcb = v.compare(CLIENT_ID, ModelCriteriaBuilder.Operator.EQ, 4) mcb = v.compare(CLIENT_ID, ModelCriteriaBuilder.Operator.EQ, 4)
.compare(ID, ModelCriteriaBuilder.Operator.EQ, 5); .compare(ID, ModelCriteriaBuilder.Operator.EQ, 5);
assertThat(mcb.getIckleQuery(), is(equalTo("FROM org.keycloak.models.map.storage.hotrod.HotRodClientEntity c WHERE ((c.clientId = :clientId0) AND (c.id = :id0))"))); assertThat(mcb.getIckleQuery(), is(equalTo("FROM kc.HotRodClientEntity c WHERE ((c.clientId = :clientId0) AND (c.id = :id0))")));
assertThat(mcb.getParameters().entrySet(), hasSize(2)); assertThat(mcb.getParameters().entrySet(), hasSize(2));
assertThat(mcb.getParameters(), allOf(hasEntry("clientId0", 4), hasEntry("id0", 5))); assertThat(mcb.getParameters(), allOf(hasEntry("clientId0", 4), hasEntry("id0", 5)));
} }
@ -56,16 +56,16 @@ public class IckleQueryMapModelCriteriaBuilderTest {
@Test @Test
public void testSimpleIckleQueryFlashedFromDefault() { public void testSimpleIckleQueryFlashedFromDefault() {
DefaultModelCriteria<ClientModel> v = criteria(); DefaultModelCriteria<ClientModel> v = criteria();
IckleQueryMapModelCriteriaBuilder<String, HotRodClientEntityDelegate, ClientModel> mcb = v.compare(CLIENT_ID, ModelCriteriaBuilder.Operator.EQ, 3).flashToModelCriteriaBuilder(new IckleQueryMapModelCriteriaBuilder<>()); IckleQueryMapModelCriteriaBuilder<HotRodClientEntity, ClientModel> mcb = v.compare(CLIENT_ID, ModelCriteriaBuilder.Operator.EQ, 3).flashToModelCriteriaBuilder(new IckleQueryMapModelCriteriaBuilder<>(HotRodClientEntity.class));
assertThat(mcb.getIckleQuery(), is(equalTo("FROM org.keycloak.models.map.storage.hotrod.HotRodClientEntity c WHERE (c.clientId = :clientId0)"))); assertThat(mcb.getIckleQuery(), is(equalTo("FROM kc.HotRodClientEntity c WHERE (c.clientId = :clientId0)")));
assertThat(mcb.getParameters().entrySet(), hasSize(1)); assertThat(mcb.getParameters().entrySet(), hasSize(1));
assertThat(mcb.getParameters(), hasEntry("clientId0", 3)); assertThat(mcb.getParameters(), hasEntry("clientId0", 3));
mcb = v.compare(CLIENT_ID, ModelCriteriaBuilder.Operator.EQ, 4) mcb = v.compare(CLIENT_ID, ModelCriteriaBuilder.Operator.EQ, 4)
.compare(ID, ModelCriteriaBuilder.Operator.EQ, 5).flashToModelCriteriaBuilder(new IckleQueryMapModelCriteriaBuilder<>()); .compare(ID, ModelCriteriaBuilder.Operator.EQ, 5).flashToModelCriteriaBuilder(new IckleQueryMapModelCriteriaBuilder<>(HotRodClientEntity.class));
assertThat(mcb.getIckleQuery(), is(equalTo("FROM org.keycloak.models.map.storage.hotrod.HotRodClientEntity c WHERE ((c.clientId = :clientId0) AND (c.id = :id0))"))); assertThat(mcb.getIckleQuery(), is(equalTo("FROM kc.HotRodClientEntity c WHERE ((c.clientId = :clientId0) AND (c.id = :id0))")));
assertThat(mcb.getParameters().entrySet(), hasSize(2)); assertThat(mcb.getParameters().entrySet(), hasSize(2));
assertThat(mcb.getParameters(), allOf(hasEntry("clientId0", 4), hasEntry("id0", 5))); assertThat(mcb.getParameters(), allOf(hasEntry("clientId0", 4), hasEntry("id0", 5)));
} }

View file

@ -1497,6 +1497,7 @@
<configuration> <configuration>
<systemPropertyVariables> <systemPropertyVariables>
<keycloak.client.map.storage.provider>hotrod</keycloak.client.map.storage.provider> <keycloak.client.map.storage.provider>hotrod</keycloak.client.map.storage.provider>
<keycloak.group.map.storage.provider>hotrod</keycloak.group.map.storage.provider>
</systemPropertyVariables> </systemPropertyVariables>
</configuration> </configuration>
</plugin> </plugin>

View file

@ -1,9 +1,11 @@
<infinispan> <infinispan>
<cache-container> <cache-container>
<transport stack="udp"/> <transport stack="udp"/>
<distributed-cache name="clients" mode="SYNC"> <distributed-cache name="clients" mode="SYNC">
<encoding media-type="application/x-protostream"/> <encoding media-type="application/x-protostream"/>
</distributed-cache> </distributed-cache>
<distributed-cache name="groups" mode="SYNC">
<encoding media-type="application/x-protostream"/>
</distributed-cache>
</cache-container> </cache-container>
</infinispan> </infinispan>