From 8f3b9f14724e82b9c89ba112e4233b1294386cd1 Mon Sep 17 00:00:00 2001 From: Camiel de Vleeschauwer Date: Sat, 23 Jan 2016 11:53:28 +0200 Subject: [PATCH 1/2] Introduce hazelcast StateRepository --- hazelcast/pom.xml | 41 +++++ .../hazelcast/HazelcastStateRepository.java | 161 ++++++++++++++++++ .../HazelcastStateRepositoryTest.java | 28 +++ hazelcast/template.mf | 11 ++ pom.xml | 1 + 5 files changed, 242 insertions(+) create mode 100644 hazelcast/pom.xml create mode 100644 hazelcast/src/main/java/org/togglz/hazelcast/HazelcastStateRepository.java create mode 100644 hazelcast/src/test/java/org/togglz/hazelcast/HazelcastStateRepositoryTest.java create mode 100644 hazelcast/template.mf diff --git a/hazelcast/pom.xml b/hazelcast/pom.xml new file mode 100644 index 000000000..8e7f00926 --- /dev/null +++ b/hazelcast/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + + org.togglz + togglz-project + 2.3.0-SNAPSHOT + + + togglz-hazelcast + Togglz - Hazelcast integration + Togglz - Hazelcast integration + + + + + org.togglz + togglz-core + + + com.hazelcast + hazelcast + 3.5.2 + + + + junit + junit + test + + + org.apache.commons + commons-lang3 + 3.4 + test + + + + diff --git a/hazelcast/src/main/java/org/togglz/hazelcast/HazelcastStateRepository.java b/hazelcast/src/main/java/org/togglz/hazelcast/HazelcastStateRepository.java new file mode 100644 index 000000000..5aeb8d5fb --- /dev/null +++ b/hazelcast/src/main/java/org/togglz/hazelcast/HazelcastStateRepository.java @@ -0,0 +1,161 @@ +package org.togglz.hazelcast; + +import org.togglz.core.Feature; +import org.togglz.core.repository.FeatureState; +import org.togglz.core.repository.StateRepository; + +import com.hazelcast.config.Config; +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.core.IMap; + +/** + *

+ * A state repository which stores the feature state in a MongoDB database. + *

+ * + *

+ * The class provides a builder which can be used to configure the repository: + *

+ * + *
+ * StateRepository repository = HazelcastStateRepository.newBuilder(mongoClient, "mydb").collection("togglz")
+ * 		.authentication("john", "tiger").writeConcern(WriteConcern.REPLICA_ACKNOWLEDGED).build();
+ * 
+ * + * @author Camiel de Vleeschauwer + */ +public class HazelcastStateRepository implements StateRepository { + + protected final HazelcastInstance hazelcastInstance; + protected final Config hazelcastConfig; + protected final String mapName; + + public HazelcastStateRepository(Config hazelcastConfig, String mapName) + { + this.mapName = mapName; + this.hazelcastConfig = hazelcastConfig; + hazelcastInstance=createHazelcastInstance(); + } + + private HazelcastStateRepository(Builder builder) { + + mapName = builder.mapName; + hazelcastConfig = builder.hazelcastConfig; + hazelcastInstance=createHazelcastInstance(); + } + + private HazelcastInstance createHazelcastInstance() { + if (hazelcastConfig != null) { + return Hazelcast.newHazelcastInstance(hazelcastConfig); + + } else { + return Hazelcast.newHazelcastInstance(); + } + } + + @Override + public FeatureState getFeatureState(Feature feature) { + + IMap map = hazelcastInstance.getMap(mapName); + + FeatureState featureState = map.get(feature); + + return featureState; + + } + + @Override + public void setFeatureState(FeatureState featureState) { + + IMap map = hazelcastInstance.getMap(mapName); + + map.set(featureState.getFeature(), featureState); + } + + /** + * Creates a new builder for creating a {@link HazelcastStateRepository}. + * + */ + public static Builder newBuilder() { + return new Builder(); + } + + /** + * Creates a new builder for creating a {@link HazelcastStateRepository}. + * + * @param mapName + * the Hazelcast map name + */ + public static Builder newBuilder(String mapName) { + return new Builder(mapName); + } + + /** + * Builder for a {@link HazelcastStateRepository}. + */ + public static class Builder { + + private String mapName = "togglz"; + private Config hazelcastConfig = null; + + /** + * Creates a new builder for a {@link HazelcastStateRepository}. + * + */ + public Builder() { + } + + /** + * Creates a new builder for a {@link HazelcastStateRepository}. + * + * @param mapName + * the Hazelcast map name to use for feature state store + */ + public Builder(String mapName) { + this.mapName = mapName; + } + + /** + * Creates a new builder for a {@link HazelcastStateRepository}. + * + * @param hazelcastConfig + * the Hazelcast configuration {@link Config} + */ + public Builder(Config hazelcastConfig) { + this.hazelcastConfig = hazelcastConfig; + } + + /** + * Sets the Hazelcast map name to use. + * + * @param mapName + * the Hazelcast map name to use for feature state store + */ + public Builder mapName(String mapName) { + this.mapName = mapName; + return this; + } + + /** + * Sets the Hazelcast configuration. + * + * @param hazelcastConfig + * the Hazelcast configuration {@link Config} + */ + public Builder config(Config hazelcastConfig) { + this.hazelcastConfig = hazelcastConfig; + return this; + } + + /** + * Creates a new {@link HazelcastStateRepository} using the current + * settings. + */ + public HazelcastStateRepository build() { + return new HazelcastStateRepository(this); + } + + } + +} diff --git a/hazelcast/src/test/java/org/togglz/hazelcast/HazelcastStateRepositoryTest.java b/hazelcast/src/test/java/org/togglz/hazelcast/HazelcastStateRepositoryTest.java new file mode 100644 index 000000000..ea991b9ca --- /dev/null +++ b/hazelcast/src/test/java/org/togglz/hazelcast/HazelcastStateRepositoryTest.java @@ -0,0 +1,28 @@ +package org.togglz.hazelcast; + +import static org.junit.Assert.assertTrue; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.junit.Test; +import org.togglz.core.Feature; +import org.togglz.core.repository.FeatureState; +import org.togglz.core.repository.StateRepository; +import org.togglz.core.util.NamedFeature; + +public class HazelcastStateRepositoryTest { + + private StateRepository stateRepository = HazelcastStateRepository.newBuilder().mapName("togglzMap").build(); + + @Test + public void testSetFeatureState() { + Feature feature = new NamedFeature("SAMPLE_FEATURE"); + FeatureState featureState = new FeatureState(feature, true); + stateRepository.setFeatureState(featureState); + + FeatureState storedFeatureState = stateRepository.getFeatureState(feature); + + assertTrue(EqualsBuilder.reflectionEquals(featureState, storedFeatureState, true)); + + } + +} diff --git a/hazelcast/template.mf b/hazelcast/template.mf new file mode 100644 index 000000000..eb25bc7e0 --- /dev/null +++ b/hazelcast/template.mf @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.togglz.hazelcast +Bundle-Vendor: http://www.togglz.org/ +Bundle-Version: ${osgi.bundles.version} +Bundle-Name: ${project.name} +Version-Patterns: + default;pattern="[=.=.=, =.+1.0)" +Import-Template: + org.togglz.core.*;version="${osgi.bundles.version:default}", + com.hazelcast.*;version="[3.5.2, 4.0)" \ No newline at end of file diff --git a/pom.xml b/pom.xml index 403f43857..1b0b1c442 100644 --- a/pom.xml +++ b/pom.xml @@ -186,6 +186,7 @@ junit distribution cassandra + hazelcast From 9e9e2e85d35af6cd422248199e428c399980c1e9 Mon Sep 17 00:00:00 2001 From: Camiel de Vleeschauwer Date: Sat, 23 Jan 2016 17:12:15 +0200 Subject: [PATCH 2/2] Correct Javadoc --- .../hazelcast/HazelcastStateRepository.java | 8 +++---- .../HazelcastStateRepositoryTest.java | 21 ++++++++++++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/hazelcast/src/main/java/org/togglz/hazelcast/HazelcastStateRepository.java b/hazelcast/src/main/java/org/togglz/hazelcast/HazelcastStateRepository.java index 5aeb8d5fb..ebdb2f6d3 100644 --- a/hazelcast/src/main/java/org/togglz/hazelcast/HazelcastStateRepository.java +++ b/hazelcast/src/main/java/org/togglz/hazelcast/HazelcastStateRepository.java @@ -11,16 +11,16 @@ /** *

- * A state repository which stores the feature state in a MongoDB database. + * A state repository which stores the feature state in a Hazelcast distributed map. *

* *

- * The class provides a builder which can be used to configure the repository: + * The class provides a builder which can be used to configure the Hazelcast instance and map to be used: *

* *
- * StateRepository repository = HazelcastStateRepository.newBuilder(mongoClient, "mydb").collection("togglz")
- * 		.authentication("john", "tiger").writeConcern(WriteConcern.REPLICA_ACKNOWLEDGED).build();
+ * StateRepository repository = HazelcastStateRepository.newBuilder().mapName("my_map")
+ * 		.config(hazelcastConfig).build();
  * 
* * @author Camiel de Vleeschauwer diff --git a/hazelcast/src/test/java/org/togglz/hazelcast/HazelcastStateRepositoryTest.java b/hazelcast/src/test/java/org/togglz/hazelcast/HazelcastStateRepositoryTest.java index ea991b9ca..b515d0983 100644 --- a/hazelcast/src/test/java/org/togglz/hazelcast/HazelcastStateRepositoryTest.java +++ b/hazelcast/src/test/java/org/togglz/hazelcast/HazelcastStateRepositoryTest.java @@ -1,5 +1,6 @@ package org.togglz.hazelcast; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.apache.commons.lang3.builder.EqualsBuilder; @@ -14,7 +15,7 @@ public class HazelcastStateRepositoryTest { private StateRepository stateRepository = HazelcastStateRepository.newBuilder().mapName("togglzMap").build(); @Test - public void testSetFeatureState() { + public void testSetFeatureStateNotExisitingInMap() { Feature feature = new NamedFeature("SAMPLE_FEATURE"); FeatureState featureState = new FeatureState(feature, true); stateRepository.setFeatureState(featureState); @@ -25,4 +26,22 @@ public void testSetFeatureState() { } + @Test + public void testSetFeatureStateExistingInMap() { + Feature feature = new NamedFeature("SAMPLE_FEATURE"); + FeatureState featureState = new FeatureState(feature, true); + stateRepository.setFeatureState(featureState); + + FeatureState storedFeatureState = stateRepository.getFeatureState(feature); + assertTrue(storedFeatureState.isEnabled()); + assertTrue(EqualsBuilder.reflectionEquals(featureState, storedFeatureState, true)); + + featureState.setEnabled(false); + stateRepository.setFeatureState(featureState); + storedFeatureState = stateRepository.getFeatureState(feature); + assertFalse(storedFeatureState.isEnabled()); + + assertTrue(EqualsBuilder.reflectionEquals(featureState, storedFeatureState, true)); + + } }