diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/impl/ReplicatingCache.java b/java/com.sap.sse.security/src/com/sap/sse/security/impl/ReplicatingCache.java index 461b5633ec5..720ce6057c8 100755 --- a/java/com.sap.sse.security/src/com/sap/sse/security/impl/ReplicatingCache.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/impl/ReplicatingCache.java @@ -14,6 +14,9 @@ import org.apache.shiro.cache.CacheException; import org.apache.shiro.session.Session; import com.sap.sse.common.Named; +import com.sap.sse.security.operations.ClearReplicatingCacheOperation; +import com.sap.sse.security.operations.PutToReplicatingCacheOperation; +import com.sap.sse.security.operations.RemoveFromReplicatingCacheOperation; /** * A {@link Cache}s whose modifying operations are replicated. This works by intercepting the writing operations @@ -68,10 +71,8 @@ public class ReplicatingCache implements Cache, Named { } } V result = cache.put(key, value); - final String myName = name; if (store && value instanceof Session) { - securityService.replicate(s-> - s.getCacheManager().getCache(myName).put(key, value)); + securityService.replicate(new PutToReplicatingCacheOperation(getName(), key, value)); securityService.storeSession(getName(), (Session) value); } return result; @@ -93,9 +94,7 @@ public class ReplicatingCache implements Cache, Named { @Override public V remove(K key) throws CacheException { V result = cache.remove(key); - final String myName = name; - securityService.replicate(s-> - s.getCacheManager().getCache(myName).remove(key)); + securityService.replicate(new RemoveFromReplicatingCacheOperation(getName(), key)); if (result instanceof Session) { securityService.removeSession(getName(), (Session) result); } @@ -105,10 +104,7 @@ public class ReplicatingCache implements Cache, Named { @Override public void clear() throws CacheException { cache.clear(); - final String myName = name; - securityService.replicate(s->{ - s.getCacheManager().getCache(myName).clear(); return null; - }); + securityService.replicate(new ClearReplicatingCacheOperation(getName())); securityService.removeAllSessions(getName()); } diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/operations/ClearReplicatingCacheOperation.java b/java/com.sap.sse.security/src/com/sap/sse/security/operations/ClearReplicatingCacheOperation.java new file mode 100755 index 00000000000..7439428c1cc --- /dev/null +++ b/java/com.sap.sse.security/src/com/sap/sse/security/operations/ClearReplicatingCacheOperation.java @@ -0,0 +1,20 @@ +package com.sap.sse.security.operations; + +import com.sap.sse.security.impl.ReplicableSecurityService; + +public class ClearReplicatingCacheOperation + implements SecurityOperationNotRequiringExplicitTransitiveReplication { + private static final long serialVersionUID = -5773023000924245582L; + private final String cacheName; + + public ClearReplicatingCacheOperation(String cacheName) { + super(); + this.cacheName = cacheName; + } + + @Override + public Void internalApplyTo(ReplicableSecurityService toState) throws Exception { + toState.getCacheManager().getCache(cacheName).clear(); + return null; + } +} diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/operations/PutToReplicatingCacheOperation.java b/java/com.sap.sse.security/src/com/sap/sse/security/operations/PutToReplicatingCacheOperation.java new file mode 100755 index 00000000000..9c233a1d6f6 --- /dev/null +++ b/java/com.sap.sse.security/src/com/sap/sse/security/operations/PutToReplicatingCacheOperation.java @@ -0,0 +1,24 @@ +package com.sap.sse.security.operations; + +import com.sap.sse.security.impl.ReplicableSecurityService; + +public class PutToReplicatingCacheOperation + implements SecurityOperationNotRequiringExplicitTransitiveReplication { + private static final long serialVersionUID = -9018465352648434564L; + private final String cacheName; + private final K key; + private final V value; + + public PutToReplicatingCacheOperation(String cacheName, K key, V value) { + super(); + this.cacheName = cacheName; + this.key = key; + this.value = value; + } + + @Override + public Object internalApplyTo(ReplicableSecurityService toState) throws Exception { + return toState.getCacheManager().getCache(cacheName).put(key, value); + } + +} diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/operations/RemoveFromReplicatingCacheOperation.java b/java/com.sap.sse.security/src/com/sap/sse/security/operations/RemoveFromReplicatingCacheOperation.java new file mode 100755 index 00000000000..89c0e37a6f1 --- /dev/null +++ b/java/com.sap.sse.security/src/com/sap/sse/security/operations/RemoveFromReplicatingCacheOperation.java @@ -0,0 +1,22 @@ +package com.sap.sse.security.operations; + +import com.sap.sse.security.impl.ReplicableSecurityService; + +public class RemoveFromReplicatingCacheOperation + implements SecurityOperationNotRequiringExplicitTransitiveReplication { + private static final long serialVersionUID = -1754187358645381535L; + private final String cacheName; + private final K key; + + public RemoveFromReplicatingCacheOperation(String cacheName, K key) { + super(); + this.cacheName = cacheName; + this.key = key; + } + + @Override + public Object internalApplyTo(ReplicableSecurityService toState) throws Exception { + return toState.getCacheManager().getCache(cacheName).remove(key); + } + +} diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/operations/SecurityOperation.java b/java/com.sap.sse.security/src/com/sap/sse/security/operations/SecurityOperation.java index f3566be10f2..443b5480dab 100755 --- a/java/com.sap.sse.security/src/com/sap/sse/security/operations/SecurityOperation.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/operations/SecurityOperation.java @@ -4,11 +4,4 @@ import com.sap.sse.replication.OperationWithResult; import com.sap.sse.security.impl.ReplicableSecurityService; public interface SecurityOperation extends OperationWithResult { - /** - * By default, the security-related operations will perform an update on the receiving replica that in turn - * will trigger replication of this change transitively. - */ - default boolean isRequiresExplicitTransitiveReplication() { - return false; - } } diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/operations/SecurityOperationNotRequiringExplicitTransitiveReplication.java b/java/com.sap.sse.security/src/com/sap/sse/security/operations/SecurityOperationNotRequiringExplicitTransitiveReplication.java new file mode 100755 index 00000000000..d9a3be43364 --- /dev/null +++ b/java/com.sap.sse.security/src/com/sap/sse/security/operations/SecurityOperationNotRequiringExplicitTransitiveReplication.java @@ -0,0 +1,20 @@ +package com.sap.sse.security.operations; + +/** + * To be implemented by those {@link SecurityOperation}s that do not require explicit transitive replication. + * This interface has a default implementation for the {@link #isRequiresExplicitTransitiveReplication()} method + * that always returns {@code false}. + * + * @author Axel Uhl (D043530) + * + * @param + */ +public interface SecurityOperationNotRequiringExplicitTransitiveReplication extends SecurityOperation { + /** + * By default, the security-related operations will perform an update on the receiving replica that in turn + * will trigger replication of this change transitively. + */ + default boolean isRequiresExplicitTransitiveReplication() { + return false; + } +}