diff --git a/subsystem/src/main/java/org/wildfly/subsystem/service/capture/FunctionExecutor.java b/service/src/main/java/org/wildfly/service/capture/FunctionExecutor.java similarity index 74% rename from subsystem/src/main/java/org/wildfly/subsystem/service/capture/FunctionExecutor.java rename to service/src/main/java/org/wildfly/service/capture/FunctionExecutor.java index 49b54cd465e..f514fbb0b33 100644 --- a/subsystem/src/main/java/org/wildfly/subsystem/service/capture/FunctionExecutor.java +++ b/service/src/main/java/org/wildfly/service/capture/FunctionExecutor.java @@ -2,19 +2,25 @@ * Copyright The WildFly Authors * SPDX-License-Identifier: Apache-2.0 */ -package org.wildfly.subsystem.service.capture; +package org.wildfly.service.capture; import java.util.function.Supplier; import org.wildfly.common.function.ExceptionFunction; /** - * Encapsulates execution of a function. + * Encapsulates execution of a single argument function. * @author Paul Ferraro * @param the type of the function argument */ public interface FunctionExecutor { + /** + * Creates a function executor from the specified argument supplier. + * @param the value type of the function argument + * @param reference a supplier of the function argument + * @return a new function executor instance + */ static FunctionExecutor of(Supplier reference) { return new FunctionExecutor<>() { @Override diff --git a/service/src/main/java/org/wildfly/service/capture/FunctionExecutorRegistry.java b/service/src/main/java/org/wildfly/service/capture/FunctionExecutorRegistry.java new file mode 100644 index 00000000000..a46b054eff6 --- /dev/null +++ b/service/src/main/java/org/wildfly/service/capture/FunctionExecutorRegistry.java @@ -0,0 +1,20 @@ +/* + * Copyright The WildFly Authors + * SPDX-License-Identifier: Apache-2.0 + */ +package org.wildfly.service.capture; + +/** + * Registry of {@link FunctionExecutor} objects. + * @author Paul Ferraro + * @param the registry key type + * @param the registry value type + */ +public interface FunctionExecutorRegistry { + /** + * Returns the executor for the specified key. + * @param key a registry key + * @return an executor, or null, if no such executor exists in the registry + */ + FunctionExecutor getExecutor(K key); +} diff --git a/service/src/main/java/org/wildfly/service/capture/ServiceValueExecutorRegistry.java b/service/src/main/java/org/wildfly/service/capture/ServiceValueExecutorRegistry.java new file mode 100644 index 00000000000..9cb5481fbcf --- /dev/null +++ b/service/src/main/java/org/wildfly/service/capture/ServiceValueExecutorRegistry.java @@ -0,0 +1,42 @@ +/* + * Copyright The WildFly Authors + * SPDX-License-Identifier: Apache-2.0 + */ +package org.wildfly.service.capture; + +import java.util.function.Consumer; + +import org.jboss.msc.service.ServiceName; + +/** + * A registry of captured values. + * @author Paul Ferraro + * @param the captured value type + */ +public interface ServiceValueExecutorRegistry extends ServiceValueRegistry, FunctionExecutorRegistry { + + /** + * Creates a new {@link ServiceValueExecutorRegistry}. + * @param the captured value type + * @return a new value executor registry + */ + static ServiceValueExecutorRegistry newInstance() { + ValueExecutorRegistry registry = ValueExecutorRegistry.newInstance(); + return new ServiceValueExecutorRegistry<>() { + @Override + public Consumer add(ServiceName key) { + return registry.add(key); + } + + @Override + public void remove(ServiceName key) { + registry.remove(key); + } + + @Override + public FunctionExecutor getExecutor(ServiceName key) { + return registry.getExecutor(key); + } + }; + } +} diff --git a/service/src/main/java/org/wildfly/service/capture/ServiceValueRegistry.java b/service/src/main/java/org/wildfly/service/capture/ServiceValueRegistry.java new file mode 100644 index 00000000000..a9006dbcac6 --- /dev/null +++ b/service/src/main/java/org/wildfly/service/capture/ServiceValueRegistry.java @@ -0,0 +1,41 @@ +/* + * Copyright The WildFly Authors + * SPDX-License-Identifier: Apache-2.0 + */ +package org.wildfly.service.capture; + +import java.util.function.Consumer; + +import org.jboss.msc.service.ServiceName; +import org.wildfly.service.ServiceDependency; +import org.wildfly.service.ServiceInstaller; + +/** + * A registry of service values, keyed by {@link ServiceName}. + * @author Paul Ferraro + * @param the registry value type + */ +public interface ServiceValueRegistry extends ValueRegistry { + + /** + * Creates a service installer to capture and release the value provided by the specified service dependency. + * @param dependency a service dependency + * @return a service installer + */ + default ServiceInstaller capture(ServiceName name) { + Consumer startTask = new Consumer<>() { + @Override + public void accept(V value) { + ServiceValueRegistry.this.add(name).accept(value); + } + }; + Consumer stopTask = new Consumer<>() { + @Override + public void accept(V value) { + ServiceValueRegistry.this.remove(name); + } + }; + ServiceDependency dependency = ServiceDependency.on(name); + return ServiceInstaller.builder(dependency).onStart(startTask).onStop(stopTask).build(); + } +} diff --git a/service/src/main/java/org/wildfly/service/capture/ValueExecutorRegistry.java b/service/src/main/java/org/wildfly/service/capture/ValueExecutorRegistry.java new file mode 100644 index 00000000000..ab6fedc61de --- /dev/null +++ b/service/src/main/java/org/wildfly/service/capture/ValueExecutorRegistry.java @@ -0,0 +1,56 @@ +/* + * Copyright The WildFly Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.wildfly.service.capture; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +/** + * A registry of captured values. + * @author Paul Ferraro + * @param the registry key type + * @param the registry value type + */ +public interface ValueExecutorRegistry extends ValueRegistry, FunctionExecutorRegistry { + + /** + * Creates a new registry of values. + * @param the registry key type + * @param the registry value type + * @return a new registry instance + */ + static ValueExecutorRegistry newInstance() { + return new ValueExecutorRegistry<>() { + private final Map> references = new ConcurrentHashMap<>(); + + private AtomicReference create(K dependency) { + return new AtomicReference<>(); + } + + @Override + public Consumer add(K key) { + AtomicReference reference = this.references.computeIfAbsent(key, this::create); + return reference::set; + } + + @Override + public void remove(K key) { + AtomicReference reference = this.references.remove(key); + if (reference != null) { + reference.set(null); + } + } + + @Override + public FunctionExecutor getExecutor(K key) { + AtomicReference reference = this.references.get(key); + return (reference != null) ? FunctionExecutor.of(reference::get) : null; + } + }; + } +} diff --git a/service/src/main/java/org/wildfly/service/capture/ValueRegistry.java b/service/src/main/java/org/wildfly/service/capture/ValueRegistry.java new file mode 100644 index 00000000000..4ef2e2e5316 --- /dev/null +++ b/service/src/main/java/org/wildfly/service/capture/ValueRegistry.java @@ -0,0 +1,29 @@ +/* + * Copyright The WildFly Authors + * SPDX-License-Identifier: Apache-2.0 + */ +package org.wildfly.service.capture; + +import java.util.function.Consumer; + +/** + * A registry of values. + * @author Paul Ferraro + * @param the registry key type + * @param the registry value type + */ +public interface ValueRegistry { + + /** + * Adds a value registration for the specified key + * @param key a registry key + * @return a consumer to capture the value + */ + Consumer add(K key); + + /** + * Removes the registration for the specified key + * @param key a registry key + */ + void remove(K key); +} diff --git a/service/src/test/java/org/wildfly/service/capture/ServiceValueExecutorRegistryTestCase.java b/service/src/test/java/org/wildfly/service/capture/ServiceValueExecutorRegistryTestCase.java new file mode 100644 index 00000000000..dec6672b317 --- /dev/null +++ b/service/src/test/java/org/wildfly/service/capture/ServiceValueExecutorRegistryTestCase.java @@ -0,0 +1,70 @@ +/* + * Copyright The WildFly Authors + * SPDX-License-Identifier: Apache-2.0 + */ +package org.wildfly.service.capture; + +import java.util.UUID; +import java.util.function.Consumer; + +import org.jboss.msc.service.ServiceName; +import org.junit.Assert; +import org.junit.Test; +import org.wildfly.common.function.ExceptionFunction; + +/** + * @author Paul Ferraro + */ +public class ServiceValueExecutorRegistryTestCase { + + private final ServiceValueExecutorRegistry registry = ServiceValueExecutorRegistry.newInstance(); + + @Test + public void test() { + this.test(ServiceName.JBOSS.append("foo"), ServiceName.JBOSS.append("bar")); + } + + private void test(ServiceName service1, ServiceName service2) { + Object value1 = UUID.randomUUID(); + Object value2 = UUID.randomUUID(); + + Assert.assertNull(this.registry.getExecutor(service1)); + Assert.assertNull(this.registry.getExecutor(service2)); + + ExceptionFunction function = value -> value; + + Consumer captor1 = this.registry.add(service1); + Consumer captor2 = this.registry.add(service2); + + FunctionExecutor executor1 = this.registry.getExecutor(service1); + FunctionExecutor executor2 = this.registry.getExecutor(service2); + + Assert.assertNull(executor1.execute(function)); + Assert.assertNull(executor2.execute(function)); + + captor1.accept(value1); + captor2.accept(value2); + + Assert.assertSame(value1, executor1.execute(function)); + Assert.assertSame(value2, executor2.execute(function)); + + captor1.accept(null); + captor2.accept(null); + + Assert.assertNull(executor1.execute(function)); + Assert.assertNull(executor2.execute(function)); + + captor1.accept(value1); + captor2.accept(value2); + + // Once removed, executor should return null + this.registry.remove(service1); + this.registry.remove(service2); + + Assert.assertNull(this.registry.getExecutor(service1)); + Assert.assertNull(this.registry.getExecutor(service2)); + + Assert.assertNull(executor1.execute(function)); + Assert.assertNull(executor2.execute(function)); + } +} diff --git a/subsystem/src/main/java/org/wildfly/subsystem/service/capture/FunctionExecutorRegistry.java b/subsystem/src/main/java/org/wildfly/subsystem/service/capture/FunctionExecutorRegistry.java index ecbadc109e1..ea375ea1f83 100644 --- a/subsystem/src/main/java/org/wildfly/subsystem/service/capture/FunctionExecutorRegistry.java +++ b/subsystem/src/main/java/org/wildfly/subsystem/service/capture/FunctionExecutorRegistry.java @@ -9,13 +9,8 @@ /** * Registry of {@link FunctionExecutor} objects. * @author Paul Ferraro - * @param the argument type of the function executor + * @param the registry key type + * @param the registry value type */ -public interface FunctionExecutorRegistry { - /** - * Returns the function executor for the value provided by the specified dependency - * @param dependency a service dependency - * @return a function executor - */ - FunctionExecutor getExecutor(ServiceDependency dependency); +public interface FunctionExecutorRegistry extends org.wildfly.service.capture.FunctionExecutorRegistry, V> { } diff --git a/subsystem/src/main/java/org/wildfly/subsystem/service/capture/ServiceValueExecutorRegistry.java b/subsystem/src/main/java/org/wildfly/subsystem/service/capture/ServiceValueExecutorRegistry.java index 6a304ac6486..fe45ea254a0 100644 --- a/subsystem/src/main/java/org/wildfly/subsystem/service/capture/ServiceValueExecutorRegistry.java +++ b/subsystem/src/main/java/org/wildfly/subsystem/service/capture/ServiceValueExecutorRegistry.java @@ -4,11 +4,10 @@ */ package org.wildfly.subsystem.service.capture; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; +import org.wildfly.service.capture.FunctionExecutor; +import org.wildfly.service.capture.ValueExecutorRegistry; import org.wildfly.subsystem.service.ServiceDependency; /** @@ -23,34 +22,23 @@ public interface ServiceValueExecutorRegistry extends ServiceValueRegistry * @param the captured value type * @return a new value executor registry */ - static ServiceValueExecutorRegistry create() { + static ServiceValueExecutorRegistry newInstance() { + ValueExecutorRegistry, V> registry = ValueExecutorRegistry.newInstance(); return new ServiceValueExecutorRegistry<>() { - private final Map, AtomicReference> references = new ConcurrentHashMap<>(); - - private AtomicReference create(ServiceDependency dependency) { - return new AtomicReference<>(); - } - @Override public Consumer add(ServiceDependency dependency) { - AtomicReference reference = this.references.computeIfAbsent(dependency, this::create); - return reference::set; + return registry.add(dependency); } @Override public void remove(ServiceDependency dependency) { - AtomicReference reference = this.references.remove(dependency); - if (reference != null) { - reference.set(null); - } + registry.remove(dependency); } @Override public FunctionExecutor getExecutor(ServiceDependency dependency) { - AtomicReference reference = this.references.get(dependency); - return (reference != null) ? FunctionExecutor.of(reference::get) : null; + return registry.getExecutor(dependency); } }; } - } diff --git a/subsystem/src/main/java/org/wildfly/subsystem/service/capture/ServiceValueRegistry.java b/subsystem/src/main/java/org/wildfly/subsystem/service/capture/ServiceValueRegistry.java index eecd63403a6..e2913f7d987 100644 --- a/subsystem/src/main/java/org/wildfly/subsystem/service/capture/ServiceValueRegistry.java +++ b/subsystem/src/main/java/org/wildfly/subsystem/service/capture/ServiceValueRegistry.java @@ -6,6 +6,7 @@ import java.util.function.Consumer; +import org.wildfly.service.capture.ValueRegistry; import org.wildfly.subsystem.service.ServiceDependency; import org.wildfly.subsystem.service.ServiceInstaller; @@ -14,20 +15,7 @@ * @author Paul Ferraro * @param the captured service value type */ -public interface ServiceValueRegistry { - - /** - * Adds a registration for the specified service dependency - * @param dependency a service dependency - * @return a consumer to capture the service value - */ - Consumer add(ServiceDependency dependency); - - /** - * Removes the registration for the specified service dependency - * @param dependency a service dependency - */ - void remove(ServiceDependency dependency); +public interface ServiceValueRegistry extends ValueRegistry, V> { /** * Creates a service installer to capture and release the value provided by the specified service dependency. @@ -47,6 +35,6 @@ public void accept(V value) { ServiceValueRegistry.this.remove(dependency); } }; - return ServiceInstaller.builder(dependency).onStart(startTask).onStop(stopTask).asPassive().build(); + return ServiceInstaller.builder(dependency).onStart(startTask).onStop(stopTask).build(); } } diff --git a/subsystem/src/test/java/org/wildfly/subsystem/service/capture/ServiceValueExecutorRegistryTestCase.java b/subsystem/src/test/java/org/wildfly/subsystem/service/capture/ServiceValueExecutorRegistryTestCase.java index 880d47d9d9b..c64c95fd9c8 100644 --- a/subsystem/src/test/java/org/wildfly/subsystem/service/capture/ServiceValueExecutorRegistryTestCase.java +++ b/subsystem/src/test/java/org/wildfly/subsystem/service/capture/ServiceValueExecutorRegistryTestCase.java @@ -11,6 +11,7 @@ import org.junit.Assert; import org.junit.Test; import org.wildfly.common.function.ExceptionFunction; +import org.wildfly.service.capture.FunctionExecutor; import org.wildfly.service.descriptor.BinaryServiceDescriptor; import org.wildfly.service.descriptor.NullaryServiceDescriptor; import org.wildfly.service.descriptor.TernaryServiceDescriptor; @@ -22,7 +23,7 @@ */ public class ServiceValueExecutorRegistryTestCase { - private final ServiceValueExecutorRegistry registry = ServiceValueExecutorRegistry.create(); + private final ServiceValueExecutorRegistry registry = ServiceValueExecutorRegistry.newInstance(); @Test public void test() {