All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wildfly.service.ServiceInstaller Maven / Gradle / Ivy

There is a newer version: 27.0.0.Final
Show newest version
/*
 * Copyright The WildFly Authors
 * SPDX-License-Identifier: Apache-2.0
 */
package org.wildfly.service;

import java.util.concurrent.Executor;
import java.util.function.Function;
import java.util.function.Supplier;

import org.jboss.msc.Service;
import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceTarget;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StopContext;
import org.wildfly.common.function.Functions;

/**
 * Encapsulates service installation into a {@link ServiceTarget}.
 * @author Paul Ferraro
 */
public interface ServiceInstaller extends Installer {

    /**
     * Returns a {@link ServiceInstaller} builder whose installed service provides the specified value.
     * @param  the service value type
     * @param value the service value
     * @return a service installer builder
     */
    static  UnaryBuilder builder(V value) {
        return builder(Functions.constantSupplier(value)).asActive();
    }

    /**
     * Returns a {@link ServiceInstaller} builder whose installed service provides the value supplied by the specified dependency.
     * @param  the service value type
     * @param dependency a service dependency
     * @return a service installer builder
     */
    static  UnaryBuilder builder(ServiceDependency dependency) {
        Supplier supplier = dependency;
        return builder(supplier).requires(dependency).asPassive();
    }

    /**
     * Returns a {@link ServiceInstaller} builder whose installed service provides the value supplied by the specified factory.
     * @param  the service value type
     * @param factory provides the service value
     * @return a service installer builder
     */
    static  UnaryBuilder builder(Supplier factory) {
        return builder(Function.identity(), factory);
    }

    /**
     * Returns a {@link ServiceInstaller} builder whose installed service provides the value supplied by the specified factory and mapping function.
     * @param  the source value type
     * @param  the service value type
     * @param mapper a function that returns the service value given the value supplied by the factory
     * @param factory provides the input to the specified mapper
     * @return a service installer builder
     */
    static  UnaryBuilder builder(Function mapper, Supplier factory) {
        return new DefaultUnaryBuilder<>(mapper, factory);
    }

    /**
     * Returns a {@link ServiceInstaller} builder that installs the specified installer into a child target.
     * @param installer a service installer
     * @return a service installer builder
     */
    static Builder builder(ServiceInstaller installer) {
        return new DefaultNullaryBuilder(new Service() {
            @Override
            public void start(StartContext context) {
                installer.install(context.getChildTarget());
            }

            @Override
            public void stop(StopContext context) {
                // Services installed into child target are auto-removed after this service stops.
            }
        }).asActive();
    }

    /**
     * Returns a {@link ServiceInstaller} builder that executes the specified tasks on {@link Service#start(StartContext)} and {@link Service#stop(StopContext)}, respectively.
     * @param startTask a start task
     * @param stopTask a stop task
     * @return a service installer builder
     */
    static Builder builder(Runnable startTask, Runnable stopTask) {
        return new DefaultNullaryBuilder(new Service() {
            @Override
            public void start(StartContext context) {
                startTask.run();
            }

            @Override
            public void stop(StopContext context) {
                stopTask.run();
            }
        });
    }

    /**
     * Implemented by builds with asynchronous service support.
     * @param  the builder type
     */
    interface AsyncBuilder {
        /**
         * Indicates that the installed service should start and, if a stop task was specified, stop asynchronously.
         * @param executor supplies the executor used for asynchronous execution
         * @return a reference to this builder
         */
        B async(Supplier executor);
    }

    /**
     * Builds a {@link ServiceInstaller}.
     * @param  the source value type
     * @param  the service value type
     */
    interface Builder extends AsyncBuilder, Installer.Builder> {
    }

    /**
     * Builds a {@link ServiceInstaller} whose service provides a single value.
     * @param  the source value type
     * @param  the service value type
     */
    interface UnaryBuilder extends AsyncBuilder>, Installer.UnaryBuilder, ServiceInstaller, ServiceTarget, ServiceBuilder, T, V> {
    }

    class DefaultServiceInstaller extends DefaultInstaller, ServiceBuilder> implements ServiceInstaller {

        DefaultServiceInstaller(Configuration, ServiceBuilder> config, Function> serviceBuilderFactory) {
            super(config, serviceBuilderFactory);
        }
    }

    class DefaultNullaryBuilder extends AbstractNullaryBuilder, ServiceBuilder> implements Builder {
        private volatile Supplier executor = null;

        DefaultNullaryBuilder(Service service) {
            super(service);
        }

        @Override
        public Builder async(Supplier executor) {
            this.executor = executor;
            return this;
        }

        @Override
        public ServiceInstaller build() {
            Supplier executor = this.executor;
            return new DefaultServiceInstaller(this, new Function<>() {
                @Override
                public ServiceBuilder apply(ServiceTarget target) {
                    ServiceBuilder builder = target.addService();
                    return (executor != null) ? new AsyncServiceBuilder<>(builder, executor, AsyncServiceBuilder.Async.START_AND_STOP) : builder;
                }
            });
        }

        @Override
        protected Builder builder() {
            return this;
        }
    }

    class DefaultUnaryBuilder extends AbstractUnaryBuilder, ServiceInstaller, ServiceTarget, ServiceBuilder, ServiceBuilder, T, V> implements ServiceInstaller.UnaryBuilder {
        private volatile Supplier executor = null;

        DefaultUnaryBuilder(Function mapper, Supplier factory) {
            super(mapper, factory);
        }

        @Override
        public ServiceInstaller.UnaryBuilder async(Supplier executor) {
            this.executor = executor;
            return this;
        }

        @Override
        public ServiceInstaller build() {
            Supplier executor = this.executor;
            // If no stop task is specified, we can stop synchronously
            AsyncServiceBuilder.Async async = this.hasStopTask() ? AsyncServiceBuilder.Async.START_AND_STOP : AsyncServiceBuilder.Async.START_ONLY;
            return new DefaultServiceInstaller(this, new Function<>() {
                @Override
                public ServiceBuilder apply(ServiceTarget target) {
                    ServiceBuilder builder = target.addService();
                    return (executor != null) ? new AsyncServiceBuilder<>(builder, executor, async) : builder;
                }
            });
        }

        @Override
        protected UnaryBuilder builder() {
            return this;
        }
    }
}