KEYCLOAK-16115 Remove need for MapStorage.keySet() and values()
This commit is contained in:
parent
7b8575fa1a
commit
8060e3b3ac
6 changed files with 72 additions and 34 deletions
|
@ -85,7 +85,7 @@ public class MapClientProvider implements ClientProvider {
|
|||
}
|
||||
|
||||
private MapClientEntity registerEntityForChanges(MapClientEntity origEntity) {
|
||||
final MapClientEntity res = Serialization.from(origEntity);
|
||||
final MapClientEntity res = tx.get(origEntity.getId(), id -> Serialization.from(origEntity));
|
||||
tx.putIfChanged(origEntity.getId(), res, MapClientEntity::isUpdated);
|
||||
return res;
|
||||
}
|
||||
|
@ -96,6 +96,7 @@ public class MapClientProvider implements ClientProvider {
|
|||
return origEntity -> new MapClientAdapter(session, realm, registerEntityForChanges(origEntity)) {
|
||||
@Override
|
||||
public void updateClient() {
|
||||
LOG.tracef("updateClient(%s)%s", realm, origEntity.getId(), getShortStackTrace());
|
||||
session.getKeycloakSessionFactory().publish(clientUpdatedEvent(this));
|
||||
}
|
||||
|
||||
|
@ -143,7 +144,7 @@ public class MapClientProvider implements ClientProvider {
|
|||
Stream<MapClientEntity> updatedAndNotRemovedClientsStream = clientStore.entrySet().stream()
|
||||
.map(tx::getUpdated) // If the client has been removed, tx.get will return null, otherwise it will return me.getValue()
|
||||
.filter(Objects::nonNull);
|
||||
return Stream.concat(tx.createdValuesStream(clientStore.keySet()), updatedAndNotRemovedClientsStream);
|
||||
return Stream.concat(tx.createdValuesStream(), updatedAndNotRemovedClientsStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -97,7 +97,7 @@ public class MapGroupProvider implements GroupProvider {
|
|||
Stream<MapGroupEntity> updatedAndNotRemovedGroupsStream = groupStore.entrySet().stream()
|
||||
.map(tx::getUpdated) // If the group has been removed, tx.get will return null, otherwise it will return me.getValue()
|
||||
.filter(Objects::nonNull);
|
||||
return Stream.concat(tx.createdValuesStream(groupStore.keySet()), updatedAndNotRemovedGroupsStream);
|
||||
return Stream.concat(tx.createdValuesStream(), updatedAndNotRemovedGroupsStream);
|
||||
}
|
||||
|
||||
private Stream<MapGroupEntity> getUnsortedGroupEntitiesStream(RealmModel realm) {
|
||||
|
|
|
@ -133,4 +133,9 @@ public class MapRoleAdapter extends AbstractRoleModel<MapRoleEntity> implements
|
|||
return getAttributes().getOrDefault(name, Collections.EMPTY_LIST).stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MapRoleAdapter{" + getId() + '}';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ public class MapRoleProvider implements RoleProvider {
|
|||
Stream<MapRoleEntity> updatedAndNotRemovedRolesStream = roleStore.entrySet().stream()
|
||||
.map(tx::getUpdated) // If the role has been removed, tx.get will return null, otherwise it will return me.getValue()
|
||||
.filter(Objects::nonNull);
|
||||
return Stream.concat(tx.createdValuesStream(roleStore.keySet()), updatedAndNotRemovedRolesStream)
|
||||
return Stream.concat(tx.createdValuesStream(), updatedAndNotRemovedRolesStream)
|
||||
.filter(entityRealmFilter(realm));
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.keycloak.models.map.storage;
|
|||
|
||||
import org.keycloak.models.KeycloakTransaction;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
@ -32,36 +31,30 @@ public class MapKeycloakTransaction<K, V> implements KeycloakTransaction {
|
|||
private final static Logger log = Logger.getLogger(MapKeycloakTransaction.class);
|
||||
|
||||
private enum MapOperation {
|
||||
PUT {
|
||||
CREATE {
|
||||
@Override
|
||||
protected <K, V> MapTaskWithValue<K, V> taskFor(K key, V value) {
|
||||
return new MapTaskWithValue<K, V>(value) {
|
||||
@Override
|
||||
public void execute(MapStorage<K, V> map) {
|
||||
map.put(key, getValue());
|
||||
}
|
||||
@Override public void execute(MapStorage<K, V> map) { map.putIfAbsent(key, getValue()); }
|
||||
@Override public MapOperation getOperation() { return CREATE; }
|
||||
};
|
||||
}
|
||||
},
|
||||
PUT_IF_ABSENT {
|
||||
UPDATE {
|
||||
@Override
|
||||
protected <K, V> MapTaskWithValue<K, V> taskFor(K key, V value) {
|
||||
return new MapTaskWithValue<K, V>(value) {
|
||||
@Override
|
||||
public void execute(MapStorage<K, V> map) {
|
||||
map.putIfAbsent(key, getValue());
|
||||
}
|
||||
@Override public void execute(MapStorage<K, V> map) { map.put(key, getValue()); }
|
||||
@Override public MapOperation getOperation() { return UPDATE; }
|
||||
};
|
||||
}
|
||||
},
|
||||
REMOVE {
|
||||
DELETE {
|
||||
@Override
|
||||
protected <K, V> MapTaskWithValue<K, V> taskFor(K key, V value) {
|
||||
return new MapTaskWithValue<K, V>(null) {
|
||||
@Override
|
||||
public void execute(MapStorage<K, V> map) {
|
||||
map.remove(key);
|
||||
}
|
||||
@Override public void execute(MapStorage<K, V> map) { map.remove(key); }
|
||||
@Override public MapOperation getOperation() { return DELETE; }
|
||||
};
|
||||
}
|
||||
},
|
||||
|
@ -87,6 +80,8 @@ public class MapKeycloakTransaction<K, V> implements KeycloakTransaction {
|
|||
|
||||
@Override
|
||||
public void commit() {
|
||||
log.trace("Commit");
|
||||
|
||||
if (rollback) {
|
||||
throw new RuntimeException("Rollback only!");
|
||||
}
|
||||
|
@ -146,15 +141,15 @@ public class MapKeycloakTransaction<K, V> implements KeycloakTransaction {
|
|||
}
|
||||
|
||||
public void put(K key, V value) {
|
||||
addTask(MapOperation.PUT, key, value);
|
||||
addTask(MapOperation.UPDATE, key, value);
|
||||
}
|
||||
|
||||
public void putIfAbsent(K key, V value) {
|
||||
addTask(MapOperation.PUT_IF_ABSENT, key, value);
|
||||
addTask(MapOperation.CREATE, key, value);
|
||||
}
|
||||
|
||||
public void putIfChanged(K key, V value, Predicate<V> shouldPut) {
|
||||
log.tracev("Adding operation PUT_IF_CHANGED for {0}", key);
|
||||
log.tracev("Adding operation UPDATE_IF_CHANGED for {0}", key);
|
||||
|
||||
K taskKey = key;
|
||||
MapTaskWithValue<K, V> op = new MapTaskWithValue<K, V>(value) {
|
||||
|
@ -164,12 +159,13 @@ public class MapKeycloakTransaction<K, V> implements KeycloakTransaction {
|
|||
map.put(key, getValue());
|
||||
}
|
||||
}
|
||||
@Override public MapOperation getOperation() { return MapOperation.UPDATE; }
|
||||
};
|
||||
tasks.merge(taskKey, op, MapTaskCompose::new);
|
||||
tasks.merge(taskKey, op, MapKeycloakTransaction::merge);
|
||||
}
|
||||
|
||||
public void remove(K key) {
|
||||
addTask(MapOperation.REMOVE, key, null);
|
||||
addTask(MapOperation.DELETE, key, null);
|
||||
}
|
||||
|
||||
public Stream<V> valuesStream() {
|
||||
|
@ -178,14 +174,22 @@ public class MapKeycloakTransaction<K, V> implements KeycloakTransaction {
|
|||
.filter(Objects::nonNull);
|
||||
}
|
||||
|
||||
public Stream<V> createdValuesStream(Collection<K> existingKeys) {
|
||||
return this.tasks.entrySet().stream()
|
||||
.filter(me -> ! existingKeys.contains(me.getKey()))
|
||||
.map(Map.Entry::getValue)
|
||||
public Stream<V> createdValuesStream() {
|
||||
return this.tasks.values().stream()
|
||||
.filter(v -> v.containsCreate() && ! v.isReplace())
|
||||
.map(MapTaskWithValue<K,V>::getValue)
|
||||
.filter(Objects::nonNull);
|
||||
}
|
||||
|
||||
private static <K, V> MapTaskWithValue<K, V> merge(MapTaskWithValue<K, V> oldValue, MapTaskWithValue<K, V> newValue) {
|
||||
switch (newValue.getOperation()) {
|
||||
case DELETE:
|
||||
return oldValue.containsCreate() ? null : newValue;
|
||||
default:
|
||||
return new MapTaskCompose<>(oldValue, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class MapTaskWithValue<K, V> {
|
||||
protected final V value;
|
||||
|
||||
|
@ -197,6 +201,19 @@ public class MapKeycloakTransaction<K, V> implements KeycloakTransaction {
|
|||
return value;
|
||||
}
|
||||
|
||||
public boolean containsCreate() {
|
||||
return MapOperation.CREATE == getOperation();
|
||||
}
|
||||
|
||||
public boolean containsRemove() {
|
||||
return MapOperation.DELETE == getOperation();
|
||||
}
|
||||
|
||||
public boolean isReplace() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract MapOperation getOperation();
|
||||
public abstract void execute(MapStorage<K,V> map);
|
||||
}
|
||||
|
||||
|
@ -222,5 +239,25 @@ public class MapKeycloakTransaction<K, V> implements KeycloakTransaction {
|
|||
return newValue.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapOperation getOperation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsCreate() {
|
||||
return oldValue.containsCreate() || newValue.containsCreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsRemove() {
|
||||
return oldValue.containsRemove() || newValue.containsRemove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplace() {
|
||||
return (newValue.getOperation() == MapOperation.CREATE && oldValue.containsRemove()) ||
|
||||
(oldValue instanceof MapTaskCompose && ((MapTaskCompose) oldValue).isReplace());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.keycloak.models.map.storage;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -34,10 +33,6 @@ public interface MapStorage<K, V> {
|
|||
|
||||
V remove(K key);
|
||||
|
||||
Set<K> keySet();
|
||||
|
||||
Set<Map.Entry<K,V>> entrySet();
|
||||
|
||||
Collection<V> values();
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue