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

jakarta.ws.rs.SeBootstrap Maven / Gradle / Ivy

Go to download

A bundle project producing JAX-RS RI bundles. The primary artifact is an "all-in-one" OSGi-fied JAX-RS RI bundle (jaxrs-ri.jar). Attached to that are two compressed JAX-RS RI archives. The first archive (jaxrs-ri.zip) consists of binary RI bits and contains the API jar (under "api" directory), RI libraries (under "lib" directory) as well as all external RI dependencies (under "ext" directory). The secondary archive (jaxrs-ri-src.zip) contains buildable JAX-RS RI source bundle and contains the API jar (under "api" directory), RI sources (under "src" directory) as well as all external RI dependencies (under "ext" directory). The second archive also contains "build.xml" ANT script that builds the RI sources. To build the JAX-RS RI simply unzip the archive, cd to the created jaxrs-ri directory and invoke "ant" from the command line.

There is a newer version: 3.1.9
Show newest version
/*
 * Copyright (c) 2018 Markus KARG. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package jakarta.ws.rs;

import java.net.URI;
import java.util.Optional;
import java.util.concurrent.CompletionStage;
import java.util.function.BiFunction;
import java.util.function.Consumer;

import javax.net.ssl.SSLContext;

import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.UriBuilder;
import jakarta.ws.rs.ext.RuntimeDelegate;

/**
 * Bootstrap class used to startup a JAX-RS application in Java SE environments.
 * 

* The {@code SeBootstrap} class is available in a Jakarta EE container environment as well; however, support for the Java SE * bootstrapping APIs is not required in container environments. *

*

* In a Java SE environment an application is getting started by the following command using default configuration * values (i. e. mounting application at {@code http://localhost:80/} or a different port (there is no * particular default port mandated by this specification). As the JAX-RS implementation is free to choose any port * by default, the caller will not know the actual port unless explicitly checking the actual configuration of the * instance started: *

* *
 * Application app = new MyApplication();
 * SeBootstrap.Configuration config = SeBootstrap.Configuration.builder().build();
 * SeBootstrap.start(app, config).thenAccept(instance -> instance.configuration().port());
 * 
* *

* Running instances can be instructed to stop serving the application: *

* *
 * SeBootstrap.start(app, config).thenAccept(instance -> { ... instance.stop(); } );
 * 
* *

* A shutdown callback can be registered which will get invoked once the implementation stops serving the application: *

* *
 * instance.stop().thenAccept(stopResult -> ...));
 * 
* * {@code stopResult} is not further defined but solely acts as a wrapper around a native result provided by the * particular JAX-RS implementation. Portable applications should not assume any particular data type or value. * *

* Protocol, host address, port and root path can be overridden explicitly. As the JAX-RS implementation is bound to * that values, no querying of the actual configuration is needed in that case: *

* *
 * SeBootstrap.Configuration.builder().protocol("HTTPS").host("0.0.0.0").port(8443).rootPath("api").build();
 * 
* *

* TLS can be configured by explicitly passing a customized {@link SSLContext}: *

* *
 * SSLContext tls = SSLContext.getInstance("TLSv1.2");
 * // ...further initialize context here (see JSSE API)...
 * SeBootstrap.Configuration.builder().protocol("HTTPS").sslContext(tls).build();
 * 
* *

* In case of HTTPS, client authentication can be enforced to ensure that only trustworthy clients can connect: *

* *
 * SeBootstrap.Configuration.builder().protocol("HTTPS").sslClientAuthentication(SSLClientAuthentication.MANDATORY).build();
 * 
* *

* Implementations are free to support more use cases by native properties, which effectively render the application * non-portable: *

* *
 * SeBootstrap.Configuration.builder().property("productname.foo", "bar").build()
 * 
* *

* Bulk-loading allows to attach configuration storages easily without the need to write down all properties to be * transferred. Hence, even properties unknown to the application author will get channeled into the implementation. * This can be done both, explicitly (hence portable) and implicitly (hence not necessarily portable as no * particular configuration mechanics are required to be supported by compliant implementations): *

* *
 * // Explicit use of particular configuration mechanics is portable
 * SeBootstrap.Configuration.builder().from((name, type) -> externalConfigurationSystem.getValue(name, type)).build();
 *
 * // Implicitly relying on the support of particular configuration mechanics by
 * // the actual JAX-RS implementation is not necessarily portable
 * SeBootstrap.Configuration.builder().from(externalConfigurationSystem).build();
 * 
* * @author Markus KARG ([email protected]) * @since 3.1 */ public interface SeBootstrap { /** * Starts the provided application using the specified configuration. * *

* This method is intended to be used in Java SE environments only. The outcome of invocations in Jakarta EE container * environments is undefined. *

* * @param application The application to start up. * @param configuration Provides information needed for bootstrapping the application. * @return {@code CompletionStage} (possibly asynchronously) producing handle of the running application * {@link SeBootstrap.Instance instance}. * @see Configuration * @since 3.1 */ static CompletionStage start(final Application application, final Configuration configuration) { return RuntimeDelegate.getInstance().bootstrap(application, configuration); } /** * Starts the provided application using a default configuration. * *

* This method is intended to be used in Java SE environments only. The outcome of invocations in Jakarta EE container * environments is undefined. *

* * @param application The application to start up. * @return {@code CompletionStage} (possibly asynchronously) producing handle of the running application * {@link SeBootstrap.Instance instance}. * @see Configuration * @since 3.1 */ static CompletionStage start(final Application application) { Configuration configuration = Configuration.builder().build(); return start(application, configuration); } /** * Starts the provided application using the specified configuration. Creates application instance * from class using default constructor. Injection is not supported. * *

* This method is intended to be used in Java SE environments only. The outcome of invocations in Jakarta EE container * environments is undefined. *

* * @param clazz The application class. * @param configuration Provides information needed for bootstrapping the application. * @return {@code CompletionStage} (possibly asynchronously) producing handle of the running application * {@link SeBootstrap.Instance instance}. * @see Configuration * @since 3.1 */ static CompletionStage start(final Class clazz, final Configuration configuration) { return RuntimeDelegate.getInstance().bootstrap(clazz, configuration); } /** * Starts the provided application using a default configuration. Creates application instance * from class using default constructor. Injection is not supported. * *

* This method is intended to be used in Java SE environments only. The outcome of invocations in Jakarta EE container * environments is undefined. *

* * @param clazz The application class. * @return {@code CompletionStage} (possibly asynchronously) producing handle of the running application * {@link SeBootstrap.Instance instance}. * @see Configuration * @since 3.1 */ static CompletionStage start(final Class clazz) { Configuration configuration = Configuration.builder().build(); return start(clazz, configuration); } /** * Provides information needed by the JAX-RS implementation for bootstrapping an application. *

* The configuration essentially consists of a set of parameters. While the set of actually effective keys is product * specific, the key constants defined by the {@link SeBootstrap.Configuration} interface MUST be effective on all compliant * products. Any unknown key MUST be silently ignored. *

* * @author Markus KARG ([email protected]) * @since 3.1 */ interface Configuration { /** * Configuration key for the protocol an application is bound to. *

* A compliant implementation at least MUST accept the strings {@code "HTTP"} and {@code "HTTPS"} if these protocols are * supported. *

*

* The default value is {@code "HTTP"}. *

* * @since 3.1 */ String PROTOCOL = "jakarta.ws.rs.SeBootstrap.Protocol"; /** * Configuration key for the hostname or IP address an application is bound to. *

* A compliant implementation at least MUST accept string values bearing hostnames, IP4 address text representations, * and IP6 address text representations. If a hostname string, the special IP4 address string {@code "0.0.0.0"} or * {@code "::"} for IP6 is provided, the application MUST be bound to all IP addresses assigned to that * hostname. If the hostname string is {@code "localhost"} the application MUST be bound to the local host's loopback * adapter only. *

*

* The default value is {@code "localhost"}. *

* * @since 3.1 */ String HOST = "jakarta.ws.rs.SeBootstrap.Host"; /** * Configuration key for the TCP port an application is bound to. * *

* A compliant implementation MUST accept {@code java.lang.Integer} values. *

*

* There is no default port mandated by this specification, but the default value of this property is * {@link #DEFAULT_PORT} (i. e. -1). A compliant implementation MUST use its own default port when * the value -1 is provided, and MAY apply (but is not obligated to) auto-selection and * range-scanning algorithms. *

* * @since 3.1 */ String PORT = "jakarta.ws.rs.SeBootstrap.Port"; /** * Configuration key for the root path an application is bound to. *

* The default value is {@code "/"}. *

* * @since 3.1 */ String ROOT_PATH = "jakarta.ws.rs.SeBootstrap.RootPath"; /** * Configuration key for the secure socket configuration to be used. *

* The default value is {@link SSLContext#getDefault()}. *

* * @since 3.1 */ String SSL_CONTEXT = "jakarta.ws.rs.SeBootstrap.SSLContext"; /** * Configuration key for the secure socket client authentication policy. * *

* A compliant implementation MUST accept {@link SSLClientAuthentication} enums. *

*

* The default value is {@code SSLClientAuthentication#NONE}. *

* * @since 3.1 */ String SSL_CLIENT_AUTHENTICATION = "jakarta.ws.rs.SeBootstrap.SSLClientAuthentication"; /** * Secure socket client authentication policy * *

* This policy is used in secure socket handshake to control whether the server requests client authentication, * and whether successful client authentication is mandatory (i. e. connection attempt will fail for * invalid clients). *

* * @author Markus KARG ([email protected]) * @since 3.1 */ enum SSLClientAuthentication { /** * Server will not request client authentication. * * @since 3.1 */ NONE, /** * Client authentication is performed, but invalid clients are accepted. * * @since 3.1 */ OPTIONAL, /** * Client authentication is performed, and invalid clients are rejected. * * @since 3.1 */ MANDATORY } /** * Special value for {@link #PORT} property indicating that the implementation MUST scan for a free port. * * @since 3.1 */ int FREE_PORT = 0; /** * Special value for {@link #PORT} property indicating that the implementation MUST use its default port. * * @since 3.1 */ int DEFAULT_PORT = -1; /** * Returns the value of the property with the given name, or {@code null} if there is no property of that name. * * @param name a {@code String} specifying the name of the property. * @return an {@code Object} containing the value of the property, or {@code null} if no property exists matching the * given name. * @since 3.1 */ Object property(String name); /** * Returns whether the property with the given name is configured, either explicitly or by default. * * @param name a {@code String} specifying the name of the property. * @return {@code false} if no property exists matching the given name, {@code true} otherwise. * @since 3.1 */ default boolean hasProperty(String name) { return property(name) != null; } /** * Convenience method to get the {@code protocol} to be used. *

* Same as if calling {@link #property(String) (String) property(PROTOCOL)}. *

* * @return protocol to be used (e. g. {@code "HTTP")}. * @throws ClassCastException if protocol is not a {@link String}. * @see SeBootstrap.Configuration#PROTOCOL * @since 3.1 */ default String protocol() { return (String) property(PROTOCOL); } /** * Convenience method to get the {@code host} to be used. *

* Same as if calling {@link #property(String) (String) property(HOST)}. *

* * @return host name or IP address to be used (e. g. {@code "localhost"} or {@code "0.0.0.0"}). * @throws ClassCastException if host is not a {@link String}. * @see SeBootstrap.Configuration#HOST * @since 3.1 */ default String host() { return (String) property(HOST); } /** * Convenience method to get the actually used {@code port}. *

* Same as if calling {@link #property(String) (int) property(PORT)}. *

*

* If the port was not explicitly given, this will return the port chosen implicitly by the JAX-RS * implementation. *

* * @return port number actually used (e. g. {@code 8080}). * @throws ClassCastException if port is not an {@code Integer}. * @see SeBootstrap.Configuration#PORT * @since 3.1 */ default int port() { return (int) property(PORT); } /** * Convenience method to get the {@code rootPath} to be used. *

* Same as if calling {@link #property(String) (String) property(ROOT_PATH)}. *

* * @return root path to be used, e.g. {@code "/"}. * @throws ClassCastException if root path is not a {@link String}. * @see SeBootstrap.Configuration#ROOT_PATH * @since 3.1 */ default String rootPath() { return (String) property(ROOT_PATH); } /** * Convenience method to get the {@code sslContext} to be used. *

* Same as if calling {@link #property(String) (SSLContext) property(SSL_CONTEXT)}. *

* * @return root path to be used, e. g. {@code "/"}. * @throws ClassCastException if sslContext is not a {@link SSLContext}. * @see SeBootstrap.Configuration#SSL_CONTEXT * @since 3.1 */ default SSLContext sslContext() { return (SSLContext) property(SSL_CONTEXT); } /** * Convenience method to get the secure socket client authentication policy. *

* Same as if calling {@link #property(String) (SSLClientAuthentication) property(SSL_CLIENT_AUTHENTICATION)}. *

* * @return client authentication mode, e. g. {@code NONE}. * @throws ClassCastException if sslClientAuthentication is not a {@link SSLClientAuthentication}. * @see SeBootstrap.Configuration#SSL_CLIENT_AUTHENTICATION * @since 3.1 */ default SSLClientAuthentication sslClientAuthentication() { return (SSLClientAuthentication) property(SSL_CLIENT_AUTHENTICATION); } /** * Returns a {@link UriBuilder} that includes the application root path. * * @return a {@link UriBuilder} for the application. * @since 3.1 */ default UriBuilder baseUriBuilder() { return UriBuilder.newInstance().scheme(protocol().toLowerCase()) .host(host()).port(port()).path(rootPath()); } /** * Convenience method that returns a built the {@link URI} for the application. * * @return a built {@link URI} for the application. * @see Configuration#baseUriBuilder() * @since 3.1 */ default URI baseUri() { return baseUriBuilder().build(); } /** * Creates a new bootstrap configuration builder instance. * * @return {@link Builder} for bootstrap configuration. * @since 3.1 */ static Builder builder() { return RuntimeDelegate.getInstance().createConfigurationBuilder(); } /** * Builder for bootstrap {@link Configuration}. * * @author Markus KARG ([email protected]) * @since 3.1 */ interface Builder { /** * Builds a bootstrap configuration instance from the provided property values. * * @return {@link Configuration} built from provided property values. * @since 3.1 */ Configuration build(); /** * Sets the property {@code name} to the provided {@code value}. *

* This method does not check the validity, type or syntax of the provided value. *

* * @param name name of the parameter to set. * @param value value to set, or {@code null} to use the default value. * @return the updated builder. * @since 3.1 */ Builder property(String name, Object value); /** * Convenience method to set the {@code protocol} to be used. *

* Same as if calling {@link #property(String, Object) property(PROTOCOL, value)}. *

* * @param protocol protocol parameter of this configuration, or {@code null} to use the default value. * @return the updated builder. * @see SeBootstrap.Configuration#PROTOCOL * @since 3.1 */ default Builder protocol(String protocol) { return property(PROTOCOL, protocol); } /** * Convenience method to set the {@code host} to be used. *

* Same as if calling {@link #property(String, Object) property(HOST, value)}. *

* * @param host host parameter (IP address or hostname) of this configuration, or {@code null} to use the default value. * @return the updated builder. * @see SeBootstrap.Configuration#HOST * @since 3.1 */ default Builder host(String host) { return property(HOST, host); } /** * Convenience method to set the {@code port} to be used. *

* Same as if calling {@link #property(String, Object) property(PORT, value)}. *

* * @param port port parameter of this configuration, or {@code null} to use the default value. * @return the updated builder. * @see SeBootstrap.Configuration#PORT * @since 3.1 */ default Builder port(Integer port) { return property(PORT, port); } /** * Convenience method to set the {@code rootPath} to be used. *

* Same as if calling {@link #property(String, Object) property(ROOT_PATH, value)}. *

* * @param rootPath rootPath parameter of this configuration, or {@code null} to use the default value. * @return the updated builder. * @see SeBootstrap.Configuration#ROOT_PATH * @since 3.1 */ default Builder rootPath(String rootPath) { return property(ROOT_PATH, rootPath); } /** * Convenience method to set the {@code sslContext} to be used. *

* Same as if calling {@link #property(String, Object) property(SSL_CONTEXT, value)}. *

* * @param sslContext sslContext parameter of this configuration, or {@code null} to use the default value. * @return the updated builder. * @see SeBootstrap.Configuration#SSL_CONTEXT * @since 3.1 */ default Builder sslContext(SSLContext sslContext) { return property(SSL_CONTEXT, sslContext); } /** * Convenience method to set SSL client authentication policy. *

* Same as if calling {@link #property(String, Object) property(SSL_CLIENT_AUTHENTICATION, value)}. *

* * @param sslClientAuthentication SSL client authentication mode of this configuration * @return the updated builder. * @see SeBootstrap.Configuration#SSL_CLIENT_AUTHENTICATION * @since 3.1 */ default Builder sslClientAuthentication(SSLClientAuthentication sslClientAuthentication) { return property(SSL_CLIENT_AUTHENTICATION, sslClientAuthentication); } /** * Convenience method for bulk-loading configuration from a property supplier. *

* Implementations ask the passed provider function for the actual values of all their supported properties, before * returning from this configuration method. For each single request the implementation provides the name of the * property and the expected data type of the value. If no such property exists (i. e. either the name is unknown or * misspelled, or the type does not exactly match), the {@link Optional} is {@link Optional#empty() empty}. *

* * @param Type of the requested property value. * @param propertiesProvider Retrieval function of externally managed properties. MUST NOT return {@code null}. * @return the updated builder. * @since 3.1 */ Builder from(BiFunction, Optional> propertiesProvider); /** * Optional convenience method to bulk-load external configuration. *

* Implementations are free to support any external configuration mechanics, or none at all. It is completely up to the * implementation what set of properties is effectively loaded from the provided external configuration, possibly none * at all. *

*

* If the passed external configuration mechanics is unsupported, this method MUST simply do nothing. *

*

* Portable applications should not call this method, as the outcome is completely implementation-specific. *

* * @param externalConfig source of externally managed properties * @return the updated builder. * @since 3.1 */ default Builder from(Object externalConfig) { return this; } } } /** * Handle of the running application instance. * * @author Markus KARG ([email protected]) * @since 3.1 */ interface Instance { /** * Provides access to the configuration actually used by the implementation used to create this instance. *

* This may, or may not, be the same instance passed to {@link SeBootstrap#start(Application, Configuration)}, not even an * equal instance, as implementations MAY create a new intance and MUST update at least the {@code PORT} property with * the actually used value. Portable applications should not make any assumptions but always explicitly read the actual * values from the configuration returned from this method. *

* * @return The configuration actually used to create this instance. * @since 3.1 */ Configuration configuration(); /** * Initiate immediate shutdown of running application instance. * * @return {@code CompletionStage} asynchronously shutting down this application instance. * @since 3.1 */ CompletionStage stop(); /** * Result of stopping the application instance. * * @author Markus KARG ([email protected]) * @since 3.1 */ interface StopResult { /** * Provides access to the wrapped native shutdown result. *

* Implementations may, or may not, have native shutdown results. Portable applications should not invoke this method, * as the outcome is undefined. *

* * @param Requested type of the native result to return. * @param nativeClass Requested type of the native result to return. * @return Native result of shutting down the running application instance or {@code null} if the implementation has no * native result. * @throws ClassCastException if the result is not {@code null} or is not assignable to the type {@code T}. * @since 3.1 */ T unwrap(Class nativeClass); } /** * Provides access to the wrapped native handle of the application instance. *

* Implementations may, or may not, have native handles. Portable applications should not invoke this method, as the * outcome is undefined. *

* * @param Requested type of the native handle to return. * @param nativeClass Requested type of the native handle to return. * @return Native handle of the running application instance or {@code null} if the implementation has no native handle. * @throws ClassCastException if the handle is not {@code null} and is not assignable to the type {@code T}. * @since 3.1 */ T unwrap(Class nativeClass); /** * Registers a consumer for a {@link StopResult} which will be executed in a new thread * during the JVM shutdown phase. * * @param consumer The consumer. * @since 3.1 */ default void stopOnShutdown(Consumer consumer) { Runtime.getRuntime().addShutdownHook(new Thread(() -> stop().thenAccept(consumer))); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy