Skip to content

Commit

Permalink
ISPN-4104 Generic store cache child creation fails
Browse files Browse the repository at this point in the history
* Added ConfiguredBy annotation
** This allows a Cachestore to tell what Configuration to use
* Updated existing cache stores and loaders to define this
* Added parsing support for embedded and server configuration
* Added tests to verify generic loader definitions
* Refactored base configuration builder to reduce code copy for read
  • Loading branch information
wburns authored and tristantarrant committed Mar 19, 2014
1 parent ab43486 commit bbee749
Show file tree
Hide file tree
Showing 37 changed files with 256 additions and 157 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.infinispan.commons.configuration;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* BuiltBy. An annotation for configuration beans to specify what builder builds them.
Expand All @@ -12,6 +14,7 @@
* @since 5.2
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface BuiltBy {
@SuppressWarnings("rawtypes")
Class<? extends Builder> value();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.infinispan.commons.configuration;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Defines the configuration used to configure the given class instances
*
* @author wburns
* @since 7.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ConfiguredBy {
Class<?> value();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.infinispan.configuration.cache;

import org.infinispan.commons.configuration.Builder;
import org.infinispan.configuration.parsing.XmlConfigHelper;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
Expand Down Expand Up @@ -125,4 +126,17 @@ public void validate() {
log.localIndexingWithSharedCacheLoaderRequiresPreload();
}

@Override
public Builder<?> read(T template) {
async.read(template.async());
singletonStore.read(template.singletonStore());
fetchPersistentState = template.fetchPersistentState();
ignoreModifications = template.ignoreModifications();
purgeOnStartup = template.purgeOnStartup();
shared = template.shared();
preload = template.preload();
properties = template.properties();

return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.infinispan.configuration.cache;

import org.infinispan.commons.configuration.Builder;

/**
* StoreConfigurationBuilder used for stores/loaders that don't have a configuration builder
*
* @author wburns
* @since 7.0
*/
public class BaseStoreConfigurationBuilder extends AbstractStoreConfigurationBuilder<AbstractStoreConfiguration, BaseStoreConfigurationBuilder> {
public BaseStoreConfigurationBuilder(PersistenceConfigurationBuilder builder) {
super(builder);
}

@Override
public AbstractStoreConfiguration create() {
return new AbstractStoreConfiguration(purgeOnStartup, fetchPersistentState, ignoreModifications, async.create(),
singletonStore.create(), preload, shared, properties);
}

@Override
public BaseStoreConfigurationBuilder self() {
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public ClusterLoaderConfiguration create() {

@Override
public ClusterLoaderConfigurationBuilder read(ClusterLoaderConfiguration template) {
super.read(template);
this.remoteCallTimeout = template.remoteCallTimeout();
this.properties = template.properties();
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,12 @@ public SingleFileStoreConfiguration create() {

@Override
public Builder<?> read(SingleFileStoreConfiguration template) {
super.read(template);

// SingleFileStore-specific configuration
location = template.location();
maxEntries = template.maxEntries();

// AbstractStore-specific configuration
fetchPersistentState = template.fetchPersistentState();
ignoreModifications = template.ignoreModifications();
properties = template.properties();
purgeOnStartup = template.purgeOnStartup();
async.read(template.async());
singletonStore.read(template.singletonStore());
preload = template.preload();
shared = template.shared();

return this;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package org.infinispan.configuration.parsing;

import org.infinispan.commons.CacheConfigurationException;
import org.infinispan.commons.configuration.Builder;
import org.infinispan.commons.configuration.BuiltBy;
import org.infinispan.commons.configuration.ConfiguredBy;
import org.infinispan.commons.equivalence.Equivalence;
import org.infinispan.commons.executors.ExecutorFactory;
import org.infinispan.commons.hash.Hash;
Expand All @@ -24,6 +27,7 @@
import org.infinispan.persistence.cluster.ClusterLoader;
import org.infinispan.persistence.file.SingleFileStore;
import org.infinispan.persistence.spi.CacheLoader;
import org.infinispan.persistence.spi.CacheWriter;
import org.infinispan.remoting.ReplicationQueue;
import org.infinispan.remoting.transport.Transport;
import org.infinispan.transaction.LockingMode;
Expand Down Expand Up @@ -718,6 +722,39 @@ private void parseStore(final XMLExtendedStreamReader reader, final Configuratio
} else if (store instanceof ClusterLoader) {
ClusterLoaderConfigurationBuilder cscb = builder.persistence().addClusterLoader();
parseLoaderChildren(reader, cscb);
} else {
ConfiguredBy annotation = store.getClass().getAnnotation(ConfiguredBy.class);
Class<? extends StoreConfigurationBuilder> builderClass = null;
if (annotation != null) {
Class<?> configuredBy = annotation.value();
if (configuredBy != null) {
BuiltBy builtBy = configuredBy.getAnnotation(BuiltBy.class);
builderClass = builtBy.value().asSubclass(StoreConfigurationBuilder.class);
}
}

// If they don't specify a builder just use the base configuration builder
if (builderClass == null) {
builderClass = BaseStoreConfigurationBuilder.class;
}

StoreConfigurationBuilder configBuilder = builder.persistence().addStore(
builderClass);
if (fetchPersistentState != null)
configBuilder.fetchPersistentState(fetchPersistentState);
if (ignoreModifications != null)
configBuilder.ignoreModifications(ignoreModifications);
if (purgeOnStartup != null)
configBuilder.purgeOnStartup(purgeOnStartup);
if (preload != null)
configBuilder.preload(preload);
if (shared != null)
configBuilder.shared(shared);
if (store instanceof CacheWriter) {
parseStoreChildren(reader, configBuilder);
} else if (store instanceof CacheLoader) {
parseLoaderChildren(reader, configBuilder);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.infinispan.AdvancedCache;
import org.infinispan.commands.remote.ClusteredGetCommand;
import org.infinispan.commons.configuration.ConfiguredBy;
import org.infinispan.commons.util.InfinispanCollections;
import org.infinispan.configuration.cache.ClusterLoaderConfiguration;
import org.infinispan.container.entries.InternalCacheValue;
Expand Down Expand Up @@ -34,6 +35,7 @@
*
* @author [email protected]
*/
@ConfiguredBy(ClusterLoaderConfiguration.class)
public class ClusterLoader implements CacheLoader, LocalOnlyCacheLoader {
private static final Log log = LogFactory.getLog(ClusterLoader.class);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.infinispan.persistence.file;

import org.infinispan.commons.configuration.ConfiguredBy;
import org.infinispan.commons.equivalence.AnyEquivalence;
import org.infinispan.commons.equivalence.Equivalence;
import org.infinispan.commons.equivalence.EquivalentLinkedHashMap;
Expand Down Expand Up @@ -65,6 +66,7 @@
* @author Mircea Markus
* @since 6.0
*/
@ConfiguredBy(SingleFileStoreConfiguration.class)
public class SingleFileStore implements AdvancedLoadWriteStore {
private static final Log log = LogFactory.getLog(SingleFileStore.class);
private static final boolean trace = log.isTraceEnabled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@
import org.infinispan.commons.CacheConfigurationException;
import org.infinispan.commons.equivalence.AnyEquivalence;
import org.infinispan.commons.equivalence.ByteArrayEquivalence;
import org.infinispan.configuration.cache.AbstractStoreConfiguration;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ClusterLoaderConfiguration;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.InterceptorConfiguration;
import org.infinispan.configuration.cache.PersistenceConfiguration;
import org.infinispan.configuration.cache.SingleFileStoreConfiguration;
import org.infinispan.configuration.cache.StoreConfiguration;
import org.infinispan.configuration.global.GlobalConfiguration;
import org.infinispan.configuration.global.ShutdownHookBehavior;
import org.infinispan.eviction.EvictionStrategy;
Expand All @@ -36,8 +39,14 @@
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.commons.marshall.AdvancedExternalizer;
import org.infinispan.marshall.AdvancedExternalizerTest;
import org.infinispan.marshall.core.MarshalledEntry;
import org.infinispan.marshall.core.VersionAwareMarshaller;
import org.infinispan.commons.marshall.jboss.GenericJBossMarshaller;
import org.infinispan.persistence.dummy.DummyInMemoryStoreConfiguration;
import org.infinispan.persistence.dummy.DummyInMemoryStoreConfigurationBuilder;
import org.infinispan.persistence.spi.CacheLoader;
import org.infinispan.persistence.spi.CacheWriter;
import org.infinispan.persistence.spi.InitializationContext;
import org.infinispan.remoting.transport.jgroups.JGroupsTransport;
import org.infinispan.test.AbstractInfinispanTest;
import org.infinispan.test.CacheManagerCallable;
Expand Down Expand Up @@ -345,6 +354,77 @@ public void call() {
});
}

public void testDummyInMemoryStore() throws IOException {
String config = INFINISPAN_START_TAG_NO_SCHEMA +
"<default>\n" +
"<persistence >\n" +
"<store class=\"org.infinispan.persistence.dummy.DummyInMemoryStore\" >\n" +
"<properties >" +
"<property name=\"storeName\" value=\"myStore\"/>" +
"</properties >" +
"</store >\n" +
"</persistence >\n" +
"</default>\n" +
INFINISPAN_END_TAG;

InputStream is = new ByteArrayInputStream(config.getBytes());
withCacheManager(new CacheManagerCallable(TestCacheManagerFactory.fromStream(is)) {
@Override
public void call() {
PersistenceConfiguration cfg = cm.getDefaultCacheConfiguration().persistence();
StoreConfiguration config = cfg.stores().get(0);
assertTrue(config instanceof DummyInMemoryStoreConfiguration);
DummyInMemoryStoreConfiguration dummyInMemoryStoreConfiguration = (DummyInMemoryStoreConfiguration)config;
assertEquals("myStore", dummyInMemoryStoreConfiguration.storeName());
}
});
}

public static class GenericLoader implements CacheLoader {

@Override
public void init(InitializationContext ctx) { }

@Override
public MarshalledEntry load(Object key) { return null; }

@Override
public boolean contains(Object key) { return false; }

@Override
public void start() { }

@Override
public void stop() { }
}

public void testStoreWithNoConfigureBy() throws IOException {
String config = INFINISPAN_START_TAG_NO_SCHEMA +
"<default>\n" +
"<persistence >\n" +
"<store class=\"org.infinispan.configuration.XmlFileParsingTest$GenericLoader\" preload=\"true\" >\n" +
"<properties >" +
"<property name=\"fetchPersistentState\" value=\"true\"/>" +
"</properties >" +
"</store >\n" +
"</persistence >\n" +
"</default>\n" +
INFINISPAN_END_TAG;

InputStream is = new ByteArrayInputStream(config.getBytes());
withCacheManager(new CacheManagerCallable(TestCacheManagerFactory.fromStream(is)) {
@Override
public void call() {
PersistenceConfiguration cfg = cm.getDefaultCacheConfiguration().persistence();
StoreConfiguration config = cfg.stores().get(0);
assertTrue(config instanceof AbstractStoreConfiguration);
AbstractStoreConfiguration abstractStoreConfiguration = (AbstractStoreConfiguration)config;
assertTrue(abstractStoreConfiguration.fetchPersistentState());
assertTrue(abstractStoreConfiguration.preload());
}
});
}

private void assertNamedCacheFile(EmbeddedCacheManager cm, boolean deprecated) {
final GlobalConfiguration gc = cm.getCacheManagerConfiguration();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,18 +261,6 @@ public CountingStoreConfiguration create() {
return new CountingStoreConfiguration(purgeOnStartup, fetchPersistentState, ignoreModifications, async.create(), singletonStore.create(), preload, shared, properties);
}

@Override
public Builder<?> read(CountingStoreConfiguration template) {
// AbstractStore-specific configuration
fetchPersistentState = template.fetchPersistentState();
ignoreModifications = template.ignoreModifications();
properties = template.properties();
purgeOnStartup = template.purgeOnStartup();
async.read(template.async());
singletonStore.read(template.singletonStore());
return this;
}

@Override
public CountingStoreConfigurationBuilder self() {
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.infinispan.Cache;
import org.infinispan.commons.CacheException;
import org.infinispan.commons.configuration.ConfiguredBy;
import org.infinispan.commons.equivalence.Equivalence;
import org.infinispan.commons.marshall.StreamingMarshaller;
import org.infinispan.commons.util.InfinispanCollections;
Expand Down Expand Up @@ -32,6 +33,7 @@
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;

@ConfiguredBy(DummyInMemoryStoreConfiguration.class)
public class DummyInMemoryStore implements AdvancedLoadWriteStore {
private static final Log log = LogFactory.getLog(DummyInMemoryStore.class);
private static final boolean trace = log.isTraceEnabled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,14 @@ public DummyInMemoryStoreConfiguration create() {

@Override
public DummyInMemoryStoreConfigurationBuilder read(DummyInMemoryStoreConfiguration template) {
super.read(template);

debug = template.debug();
slow = template.slow();
storeName = template.storeName();
failKey = template.failKey();
shared =template.shared();

// AbstractStore-specific configuration
fetchPersistentState = template.fetchPersistentState();
ignoreModifications = template.ignoreModifications();
properties = template.properties();
purgeOnStartup = template.purgeOnStartup();
async.read(template.async());
singletonStore.read(template.singletonStore());

this.preload = template.preload();

return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,6 @@ public RemoteEventStoreConfiguration create() {
async.create(), singletonStore.create(),preload, shared, properties);
}

@Override
public Builder<?> read(RemoteEventStoreConfiguration template) {
// AbstractStore-specific configuration
fetchPersistentState = template.fetchPersistentState();
ignoreModifications = template.ignoreModifications();
properties = template.properties();
purgeOnStartup = template.purgeOnStartup();
async.read(template.async());
singletonStore.read(template.singletonStore());
shared = template.shared();
preload = template.preload();
return this;
}

@Override
public RemoteEventStoreConfigurationBuilder self() {
return this;
Expand Down
Loading

0 comments on commit bbee749

Please sign in to comment.