Closes #8969 - Add Groups HotRod storage
This commit is contained in:
parent
8e03942e87
commit
5aa9a09b20
11 changed files with 153 additions and 40 deletions
|
@ -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
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue