Author: mreutegg
Date: Thu Jul 9 13:00:47 2020
New Revision: 1879706
URL: http://svn.apache.org/viewvc?rev=1879706&view=rev
Log:
OAK-9132: Feature toggles
Commit proposal
Added:
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/Feature.java
(with props)
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/FeatureToggle.java
(with props)
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/package-info.java
(with props)
jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/toggle/
jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/toggle/FeatureToggleTest.java
(with props)
Modified:
jackrabbit/oak/trunk/oak-core-spi/pom.xml
Modified: jackrabbit/oak/trunk/oak-core-spi/pom.xml
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/pom.xml?rev=1879706&r1=1879705&r2=1879706&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core-spi/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-core-spi/pom.xml Thu Jul 9 13:00:47 2020
@@ -58,6 +58,7 @@
org.apache.jackrabbit.oak.spi.namespace,
org.apache.jackrabbit.oak.spi.nodetype,
org.apache.jackrabbit.oak.spi.observation,
+ org.apache.jackrabbit.oak.spi.toggle,
org.apache.jackrabbit.oak.spi.version,
org.apache.jackrabbit.oak.spi.whiteboard,
org.apache.jackrabbit.oak.stats
@@ -174,6 +175,11 @@
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.osgi-mock</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
Added:
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/Feature.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/Feature.java?rev=1879706&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/Feature.java
(added)
+++
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/Feature.java
Thu Jul 9 13:00:47 2020
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.spi.toggle;
+
+import java.io.Closeable;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.jackrabbit.oak.spi.whiteboard.Registration;
+import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
+
+/**
+ * A feature toggle to control new functionality. The default state of a
feature
+ * is {@code false} and can be controlled by third party code discovering
+ * {@link FeatureToggle}s on the {@link Whiteboard}. Every feature is
+ * linked to a feature toggle and allows to control the state of the feature
+ * toggle via {@link FeatureToggle#setEnabled(boolean)}. Creating a new feature
+ * involves registering a feature toggle on the {@link Whiteboard} and
+ * potentially comes with some overhead (e.g. when the whiteboard is based on
+ * OSGi). Therefore, client code should not create a new feature, check the
+ * state and then immediately release/close it again. Instead a feature should
+ * be acquired initially, checked at runtime whenever needed and finally
+ * released when the client component is destroyed.
+ */
+public final class Feature implements Closeable {
+
+ private final AtomicBoolean value;
+
+ private final Registration registration;
+
+ private Feature(AtomicBoolean value, Registration registration) {
+ this.value = value;
+ this.registration = registration;
+ }
+
+ /**
+ * Creates a new {@link Feature} with the given name and registers the
+ * corresponding {@link FeatureToggle} on the {@link Whiteboard}.
+ * Client code must call {@link Feature#close()} when the toggle is
+ * not used anymore.
+ *
+ * @param name the name of the feature toggle.
+ * @param whiteboard the whiteboard where to register the feature toggle.
+ * @return the feature toggle.
+ */
+ public static Feature newFeature(String name, Whiteboard whiteboard) {
+ AtomicBoolean value = new AtomicBoolean();
+ FeatureToggle adapter = new FeatureToggle(name, value);
+ return new Feature(value, whiteboard.register(
+ FeatureToggle.class, adapter, Collections.emptyMap()));
+ }
+
+ /**
+ * @return the current state of this feature.
+ */
+ public boolean isEnabled() {
+ return value.get();
+ }
+
+ /**
+ * Releases resources for this feature toggle.
+ */
+ @Override
+ public void close() {
+ this.registration.unregister();
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/Feature.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/FeatureToggle.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/FeatureToggle.java?rev=1879706&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/FeatureToggle.java
(added)
+++
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/FeatureToggle.java
Thu Jul 9 13:00:47 2020
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.spi.toggle;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
+
+/**
+ * A feature toggle is registered with the {@link Whiteboard} and can be
+ * discovered by third party code to control the state of feature toggles.
+ */
+public final class FeatureToggle {
+
+ private final String name;
+
+ private final AtomicBoolean state;
+
+ /**
+ * Create a new adapter with a given name and value.
+ *
+ * @param name the name of the feature toggle.
+ * @param state the state for the feature toggle.
+ */
+ public FeatureToggle(String name, AtomicBoolean state) {
+ this.name = name;
+ this.state = state;
+ }
+
+ /**
+ * @return the name of the feature toggle.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return the current state of this feature toggle.
+ */
+ public boolean isEnabled() {
+ return state.get();
+ }
+
+ /**
+ * Changes the state of the feature toggle.
+ *
+ * @param state the new state of the feature toggle.
+ * @return the previous state.
+ */
+ public boolean setEnabled(boolean state) {
+ return this.state.getAndSet(state);
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/FeatureToggle.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/package-info.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/package-info.java?rev=1879706&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/package-info.java
(added)
+++
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/package-info.java
Thu Jul 9 13:00:47 2020
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+@Version("1.0.0")
+package org.apache.jackrabbit.oak.spi.toggle;
+
+import org.osgi.annotation.versioning.Version;
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/package-info.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/toggle/FeatureToggleTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/toggle/FeatureToggleTest.java?rev=1879706&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/toggle/FeatureToggleTest.java
(added)
+++
jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/toggle/FeatureToggleTest.java
Thu Jul 9 13:00:47 2020
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.spi.toggle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard;
+import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils;
+import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.jackrabbit.oak.spi.toggle.Feature.newFeature;
+import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public class FeatureToggleTest {
+
+ @Rule
+ public final OsgiContext context = new OsgiContext();
+
+ private final OsgiWhiteboard whiteboard = new
OsgiWhiteboard(context.bundleContext());
+
+ @Test
+ public void disabledByDefault() {
+ try (Feature feature = newFeature("my.toggle", whiteboard)) {
+ assertFalse(feature.isEnabled());
+ }
+ }
+
+ @Test
+ public void register() {
+ try (Feature feature = newFeature("my.toggle", whiteboard)) {
+ assertFalse(feature.isEnabled());
+ List<FeatureToggle> toggles = getFeatureToggles();
+ assertEquals(1, toggles.size());
+ FeatureToggle toggle = toggles.get(0);
+ assertEquals("my.toggle", toggle.getName());
+
+ assertFalse(toggle.setEnabled(true));
+ assertTrue(toggle.isEnabled());
+ assertTrue(feature.isEnabled());
+
+ assertTrue(toggle.setEnabled(true));
+ assertTrue(toggle.setEnabled(false));
+ assertFalse(toggle.isEnabled());
+ assertFalse(feature.isEnabled());
+ }
+ }
+
+ @Test
+ public void registerMultiple() {
+ try (Feature f1 = newFeature("my.t1", whiteboard);
+ Feature f2 = newFeature("my.t2", whiteboard)) {
+ assertFalse(f1.isEnabled());
+ assertFalse(f2.isEnabled());
+ List<FeatureToggle> toggles = getFeatureToggles();
+ assertEquals(2, toggles.size());
+ List<String> toggleNames = new ArrayList<>();
+ for (FeatureToggle adapter : toggles) {
+ toggleNames.add(adapter.getName());
+ }
+ assertThat(toggleNames, hasItems("my.t1", "my.t2"));
+ }
+ }
+
+ @Test
+ public void unregisterOnClose() {
+ List<FeatureToggle> toggles;
+ try (Feature feature = newFeature("my.toggle", whiteboard)) {
+ assertFalse(feature.isEnabled());
+ toggles = getFeatureToggles();
+ assertEquals(1, toggles.size());
+ }
+ toggles = getFeatureToggles();
+ assertThat(toggles, is(empty()));
+ }
+
+ private List<FeatureToggle> getFeatureToggles() {
+ return WhiteboardUtils.getServices(
+ whiteboard, FeatureToggle.class);
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/spi/toggle/FeatureToggleTest.java
------------------------------------------------------------------------------
svn:eol-style = native