Skip to content

Commit

Permalink
ISPN-14861 Migrate stores to ConfigurationElement
Browse files Browse the repository at this point in the history
* Exposes mutable attributes
* Deprecate numerous attributes which are no longer in use
  • Loading branch information
tristantarrant authored and ryanemerson committed Jun 15, 2023
1 parent 2b49713 commit 2a47a53
Show file tree
Hide file tree
Showing 46 changed files with 195 additions and 788 deletions.
Expand Up @@ -1177,6 +1177,13 @@ public static byte[] concat(byte[] a, byte[] b) {
return ret;
}

public static <T> T[] concat(T[] a, T b) {
int aLen = a.length;
T[] ret = Arrays.copyOf(a, aLen + 1);
ret[aLen] = b;
return ret;
}

public static RuntimeException unchecked(Throwable t) {
if (t instanceof RuntimeException) {
return (RuntimeException) t;
Expand Down
Expand Up @@ -11,8 +11,8 @@
* @since 9.4
*/
public abstract class AbstractSegmentedStoreConfiguration<T extends AbstractStoreConfiguration> extends AbstractStoreConfiguration {
public AbstractSegmentedStoreConfiguration(AttributeSet attributes, AsyncStoreConfiguration async) {
super(attributes, async);
public AbstractSegmentedStoreConfiguration(Enum<?> element, AttributeSet attributes, AsyncStoreConfiguration async) {
super(element, attributes, async);
}

/**
Expand Down
Expand Up @@ -5,10 +5,12 @@
import org.infinispan.commons.configuration.attributes.Attribute;
import org.infinispan.commons.configuration.attributes.AttributeDefinition;
import org.infinispan.commons.configuration.attributes.AttributeSet;
import org.infinispan.commons.configuration.attributes.ConfigurationElement;
import org.infinispan.commons.util.TypedProperties;
import org.infinispan.commons.util.Util;
import org.infinispan.configuration.parsing.Element;

public class AbstractStoreConfiguration implements StoreConfiguration {
public class AbstractStoreConfiguration<T extends StoreConfiguration> extends ConfigurationElement<AbstractStoreConfiguration<T>> implements StoreConfiguration {
public static final AttributeDefinition<Boolean> PURGE_ON_STARTUP = AttributeDefinition.builder(org.infinispan.configuration.parsing.Attribute.PURGE, false).immutable().build();
public static final AttributeDefinition<Boolean> READ_ONLY = AttributeDefinition.builder(org.infinispan.configuration.parsing.Attribute.READ_ONLY, false).immutable().build();
public static final AttributeDefinition<Boolean> WRITE_ONLY = AttributeDefinition.builder(org.infinispan.configuration.parsing.Attribute.WRITE_ONLY, false).immutable().build();
Expand All @@ -19,42 +21,24 @@ public class AbstractStoreConfiguration implements StoreConfiguration {
public static final AttributeDefinition<Boolean> SEGMENTED = AttributeDefinition.builder(org.infinispan.configuration.parsing.Attribute.SEGMENTED, true).immutable().build();
public static final AttributeDefinition<TypedProperties> PROPERTIES = AttributeDefinition.builder(Element.PROPERTIES, null, TypedProperties.class)
.initializer(() -> new TypedProperties()).autoPersist(false).immutable().build();
private final Attribute<Integer> maxBatchSize;

public static AttributeSet attributeDefinitionSet() {
return new AttributeSet(AbstractStoreConfiguration.class, PURGE_ON_STARTUP,
READ_ONLY, WRITE_ONLY, PRELOAD, SHARED, TRANSACTIONAL, MAX_BATCH_SIZE, SEGMENTED, PROPERTIES);
}

private final Attribute<Boolean> purgeOnStartup;
private final Attribute<Boolean> ignoreModifications;
private final Attribute<Boolean> writeOnly;
private final Attribute<Boolean> preload;
private final Attribute<Boolean> shared;
private final Attribute<Boolean> transactional;
private final Attribute<Integer> maxBatchSize;
private final Attribute<Boolean> segmented;
private final Attribute<TypedProperties> properties;

protected final AttributeSet attributes;
private final AsyncStoreConfiguration async;

public AbstractStoreConfiguration(AttributeSet attributes, AsyncStoreConfiguration async) {
this.attributes = attributes.checkProtection();
protected AbstractStoreConfiguration(Enum<?> element, AttributeSet attributes, AsyncStoreConfiguration async, ConfigurationElement<?>... children) {
super(element, attributes, Util.concat(children, async));
this.async = async;
this.purgeOnStartup = attributes.attribute(PURGE_ON_STARTUP);
this.ignoreModifications = attributes.attribute(READ_ONLY);
this.writeOnly = attributes.attribute(WRITE_ONLY);
this.preload = attributes.attribute(PRELOAD);
this.shared = attributes.attribute(SHARED);
this.transactional = attributes.attribute(TRANSACTIONAL);
this.maxBatchSize = attributes.attribute(MAX_BATCH_SIZE);
this.segmented = attributes.attribute(SEGMENTED);
this.properties = attributes.attribute(PROPERTIES);
maxBatchSize = attributes.attribute(MAX_BATCH_SIZE);
}

/**
* Configuration for the async cache loader. If enabled, this provides you with asynchronous
* writes to the cache store, giving you 'write-behind' caching.
* Configuration for the async cache loader. If enabled, this provides you with asynchronous writes to the cache
* store, giving you 'write-behind' caching.
*/
@Override
public AsyncStoreConfiguration async() {
Expand All @@ -66,17 +50,17 @@ public AsyncStoreConfiguration async() {
*/
@Override
public boolean purgeOnStartup() {
return purgeOnStartup.get();
return attributes.attribute(PURGE_ON_STARTUP).get();
}

@Override
public boolean shared() {
return shared.get();
return attributes.attribute(SHARED).get();
}

@Override
public boolean transactional() {
return transactional.get();
return attributes.attribute(TRANSACTIONAL).get();
}

@Override
Expand All @@ -86,15 +70,14 @@ public int maxBatchSize() {

@Override
public boolean segmented() {
return segmented.get();
return attributes.attribute(SEGMENTED).get();
}

/**
* If true, fetch persistent state when joining a cluster. If multiple cache stores are chained,
* only one of them can have this property enabled. Persistent state transfer with a shared cache
* store does not make sense, as the same persistent store that provides the data will just end
* up receiving it. Therefore, if a shared cache store is used, the cache will not allow a
* persistent state transfer even if a cache store has this property set to true.
* If true, fetch persistent state when joining a cluster. If multiple cache stores are chained, only one of them can
* have this property enabled. Persistent state transfer with a shared cache store does not make sense, as the same
* persistent store that provides the data will just end up receiving it. Therefore, if a shared cache store is used,
* the cache will not allow a persistent state transfer even if a cache store has this property set to true.
*
* @deprecated since 14.0. Always returns false. The first non shared store is used instead.
*/
Expand All @@ -105,13 +88,12 @@ public boolean fetchPersistentState() {
}

/**
* If true, any operation that modifies the cache (put, remove, clear, store...etc) won't be
* applied to the cache store. This means that the cache store could become out of sync with the
* cache.
* If true, any operation that modifies the cache (put, remove, clear, store...etc) won't be applied to the cache
* store. This means that the cache store could become out of sync with the cache.
*/
@Override
public boolean ignoreModifications() {
return ignoreModifications.get();
return attributes.attribute(READ_ONLY).get();
}

/**
Expand All @@ -120,54 +102,16 @@ public boolean ignoreModifications() {
*/
@Override
public boolean writeOnly() {
return writeOnly.get();
return attributes.attribute(WRITE_ONLY).get();
}

@Override
public boolean preload() {
return preload.get();
return attributes.attribute(PRELOAD).get();
}

@Override
public Properties properties() {
return properties.get();
}

public AttributeSet attributes() {
return attributes;
}

@Override
public String toString() {
return "AbstractStoreConfiguration [attributes=" + attributes + ", async=" + async + "]";
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((async == null) ? 0 : async.hashCode());
result = prime * result + ((attributes == null) ? 0 : attributes.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
AbstractStoreConfiguration other = (AbstractStoreConfiguration) obj;
if (async == null) {
if (other.async != null)
return false;
} else if (!async.equals(other.async))
return false;
if (attributes == null) {
return other.attributes == null;
} else if (!attributes.equals(other.attributes)) {
return false;
}
return true;
return attributes.attribute(PROPERTIES).get();
}
}
Expand Up @@ -11,15 +11,12 @@
import static org.infinispan.configuration.cache.AbstractStoreConfiguration.WRITE_ONLY;
import static org.infinispan.util.logging.Log.CONFIG;

import java.lang.reflect.Method;
import java.util.Properties;

import org.infinispan.commons.CacheConfigurationException;
import org.infinispan.commons.configuration.Builder;
import org.infinispan.commons.configuration.ConfigurationFor;
import org.infinispan.commons.configuration.attributes.AttributeSet;
import org.infinispan.commons.persistence.Store;
import org.infinispan.commons.util.ReflectionUtil;
import org.infinispan.commons.util.TypedProperties;
import org.infinispan.configuration.global.GlobalConfiguration;
import org.infinispan.persistence.spi.NonBlockingStore;
Expand Down Expand Up @@ -229,15 +226,8 @@ public void validate(GlobalConfiguration globalConfig) {

@Override
public Builder<?> read(T template) {

Method attributesMethod = ReflectionUtil.findMethod(template.getClass(), "attributes");
try {
attributes.read((AttributeSet) attributesMethod.invoke(template, null));
} catch (Exception e) {
throw new CacheConfigurationException(e);
}
attributes.read(template.attributes());
async.read(template.async());

return this;
}

Expand Down
Expand Up @@ -3,6 +3,8 @@
import org.infinispan.commons.configuration.attributes.Attribute;
import org.infinispan.commons.configuration.attributes.AttributeDefinition;
import org.infinispan.commons.configuration.attributes.AttributeSet;
import org.infinispan.commons.configuration.attributes.ConfigurationElement;
import org.infinispan.configuration.parsing.Element;

/**
* Configuration for the async cache store. If enabled, this provides you with asynchronous writes
Expand All @@ -11,7 +13,7 @@
* @author pmuir
*
*/
public class AsyncStoreConfiguration {
public class AsyncStoreConfiguration extends ConfigurationElement<AsyncStoreConfiguration> {
public static final AttributeDefinition<Boolean> ENABLED = AttributeDefinition.builder(org.infinispan.configuration.parsing.Attribute.ENABLED, false).immutable().build();
public static final AttributeDefinition<Integer> MODIFICATION_QUEUE_SIZE = AttributeDefinition.builder(org.infinispan.configuration.parsing.Attribute.MODIFICATION_QUEUE_SIZE, 1024).immutable().build();
@Deprecated
Expand All @@ -22,26 +24,18 @@ public static AttributeSet attributeDefinitionSet() {
return new AttributeSet(AsyncStoreConfiguration.class, ENABLED, MODIFICATION_QUEUE_SIZE, THREAD_POOL_SIZE, FAIL_SILENTLY);
}

private final Attribute<Boolean> enabled;
private final Attribute<Integer> modificationQueueSize;
private final Attribute<Integer> threadPoolSize;
private final Attribute<Boolean> failSilently;

private final AttributeSet attributes;

public AsyncStoreConfiguration(AttributeSet attributes) {
this.attributes = attributes.checkProtection();
this.enabled = attributes.attribute(ENABLED);
this.modificationQueueSize = attributes.attribute(MODIFICATION_QUEUE_SIZE);
this.threadPoolSize = attributes.attribute(THREAD_POOL_SIZE);
super(Element.WRITE_BEHIND, attributes);
this.failSilently = attributes.attribute(FAIL_SILENTLY);
}

/**
* If true, all modifications to this cache store happen asynchronously, on a separate thread.
*/
public boolean enabled() {
return enabled.get();
return attributes.attribute(ENABLED).get();
}

/**
Expand All @@ -51,7 +45,7 @@ public boolean enabled() {
* elements.
*/
public int modificationQueueSize() {
return modificationQueueSize.get();
return attributes.attribute(MODIFICATION_QUEUE_SIZE).get();
}

/**
Expand All @@ -60,45 +54,10 @@ public int modificationQueueSize() {
*/
@Deprecated
public int threadPoolSize() {
return threadPoolSize.get();
return attributes.attribute(THREAD_POOL_SIZE).get();
}

public boolean failSilently() {
return failSilently.get();
}

public AttributeSet attributes() {
return attributes;
}

@Override
public String toString() {
return "AsyncStoreConfiguration [attributes=" + attributes + "]";
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AsyncStoreConfiguration other = (AsyncStoreConfiguration) obj;
if (attributes == null) {
if (other.attributes != null)
return false;
} else if (!attributes.equals(other.attributes))
return false;
return true;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((attributes == null) ? 0 : attributes.hashCode());
return result;
}

}
Expand Up @@ -7,6 +7,7 @@
import org.infinispan.commons.configuration.attributes.Attribute;
import org.infinispan.commons.configuration.attributes.AttributeDefinition;
import org.infinispan.commons.configuration.attributes.AttributeSet;
import org.infinispan.configuration.parsing.Element;
import org.infinispan.persistence.cluster.ClusterLoader;

/**
Expand All @@ -19,7 +20,7 @@
@BuiltBy(ClusterLoaderConfigurationBuilder.class)
@ConfigurationFor(ClusterLoader.class)
@Deprecated
public class ClusterLoaderConfiguration extends AbstractStoreConfiguration {
public class ClusterLoaderConfiguration extends AbstractStoreConfiguration<ClusterLoaderConfiguration> {

static final AttributeDefinition<Long> REMOTE_CALL_TIMEOUT = AttributeDefinition.builder(org.infinispan.configuration.parsing.Attribute.REMOTE_TIMEOUT, TimeUnit.SECONDS.toMillis(15)).immutable().build();

Expand All @@ -30,21 +31,11 @@ public static AttributeSet attributeDefinitionSet() {
private final Attribute<Long> remoteCallTimeout;

ClusterLoaderConfiguration(AttributeSet attributes, AsyncStoreConfiguration async) {
super(attributes, async);
super(Element.CLUSTER_LOADER, attributes, async);
remoteCallTimeout = attributes.attribute(REMOTE_CALL_TIMEOUT);
}

@Override
public AttributeSet attributes() {
return attributes;
}

public long remoteCallTimeout() {
return remoteCallTimeout.get();
}

@Override
public String toString() {
return "ClusterLoaderConfiguration [attributes=" + attributes + "]";
}
}
Expand Up @@ -65,6 +65,7 @@ public static AttributeSet attributeDefinitionSet() {
queryConfiguration,
indexingConfiguration,
statisticsConfiguration,
persistenceConfiguration,
lockingConfiguration,
securityConfiguration,
transactionConfiguration,
Expand Down

0 comments on commit 2a47a53

Please sign in to comment.