/*
* JBoss, Home of Professional Open Source
* Copyright 2010, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.remoting3;
import static java.security.AccessController.doPrivileged;
import static org.jboss.remoting3.EndpointImpl.AUTH_CONFIGURATION_CLIENT;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.security.GeneralSecurityException;
import java.security.PrivilegedAction;
import org.jboss.remoting3._private.Messages;
import org.jboss.remoting3.security.RemotingPermission;
import org.jboss.remoting3.spi.ConnectionProviderFactory;
import org.wildfly.common.Assert;
import org.wildfly.common.context.ContextManager;
import org.wildfly.common.context.Contextual;
import org.wildfly.security.auth.client.AuthenticationConfiguration;
import org.wildfly.security.auth.client.AuthenticationContext;
import org.wildfly.security.auth.client.AuthenticationContextConfigurationClient;
import org.xnio.FailedIoFuture;
import org.xnio.IoFuture;
import org.xnio.OptionMap;
import org.xnio.XnioWorker;
import javax.net.ssl.SSLContext;
/**
* A potential participant in a JBoss Remoting communications relationship.
* <p/>
* This interface is part of the Remoting public API. It is intended to be consumed by Remoting applications; it is
* not intended to be implemented by them. Methods may be added to this interface in future minor releases without
* advance notice.
*
* @apiviz.landmark
*/
public interface Endpoint extends HandleableCloseable<Endpoint>, Attachable, Contextual<Endpoint> {
/**
* The context manager for Remoting endpoints.
*/
ContextManager<Endpoint> ENDPOINT_CONTEXT_MANAGER = doPrivileged((PrivilegedAction<ContextManager<Endpoint>>) () -> {
final ContextManager<Endpoint> contextManager = new ContextManager<>(Endpoint.class, "jboss-remoting.endpoint");
contextManager.setGlobalDefaultSupplierIfNotSet(ConfigurationEndpointSupplier::new);
return contextManager;
});
/**
* Get the context manager for Remoting endpoints ({@link #ENDPOINT_CONTEXT_MANAGER}).
*
* @return the context manager for Remoting endpoints (not {@code null})
*/
default ContextManager<Endpoint> getInstanceContextManager() {
return EndpointImpl.ENDPOINT_CONTEXT_MANAGER;
}
/**
* Get the currently active Remoting endpoint. If none is selected, {@code null} is returned.
*
* @return the currently active Remoting endpoint, or {@code null} if none
*/
static Endpoint getCurrent() {
return EndpointGetterHolder.SUPPLIER.get();
}
/**
* Get the name of this endpoint.
*
* @return the endpoint name, or {@code null} if there is no name
*/
String getName();
/**
* Register a new service.
*
* @param serviceType the service type
* @param openListener the channel open listener
* @param optionMap the option map
* @return the service registration which may be closed to remove the service
* @throws ServiceRegistrationException if the service could not be registered
*/
Registration registerService(String serviceType, OpenListener openListener, OptionMap optionMap) throws ServiceRegistrationException;
/**
* Get a possibly shared, possibly existing connection to the destination. The authentication and SSL configuration is selected from
* the given context with the given abstract type (if specified).
*
* @param destination the destination URI (must not be {@code null})
* @param abstractType the abstract type of the connection (may be {@code null})
* @param abstractTypeAuthority the authority name of the abstract type of the connection (may be {@code null})
* @param context the authentication context to use (must not be {@code null})
* @return the future connection identity (not {@code null})
*/
default IoFuture<ConnectionPeerIdentity> getConnectedIdentity(URI destination, String abstractType, String abstractTypeAuthority, AuthenticationContext context) {
Assert.checkNotNullParam("destination", destination);
Assert.checkNotNullParam("context", context);
final AuthenticationContextConfigurationClient client = AUTH_CONFIGURATION_CLIENT;
final SSLContext sslContext;
try {
sslContext = client.getSSLContext(destination, context);
} catch (GeneralSecurityException e) {
return new FailedIoFuture<>(Messages.conn.failedToConfigureSslContext(e));
}
final AuthenticationConfiguration authenticationConfiguration = client.getAuthenticationConfiguration(destination, context, -1, abstractType, abstractTypeAuthority);
return getConnectedIdentity(destination, sslContext, authenticationConfiguration);
}
/**
* Get a possibly shared, possibly existing connection to the destination. The authentication and SSL configuration is selected from
* the currently active authentication context with the given abstract type (if specified).
*
* @param destination the destination URI (must not be {@code null})
* @param abstractType the abstract type of the connection (may be {@code null})
* @param abstractTypeAuthority the authority name of the abstract type of the connection (may be {@code null})
* @return the future connection identity (not {@code null})
*/
default IoFuture<ConnectionPeerIdentity> getConnectedIdentity(URI destination, String abstractType, String abstractTypeAuthority) {
return getConnectedIdentity(destination, abstractType, abstractTypeAuthority, AuthenticationContext.captureCurrent());
}
/**
* Get a possibly shared, possibly existing connection to the destination. The authentication and SSL configuration is specified
* directly.
*
* @param destination the destination URI (must not be {@code null})
* @param sslContext the SSL context to use for secure connections (may be {@code null})
* @param authenticationConfiguration the authentication configuration to use (must not be {@code null})
* @return the future connection identity (not {@code null})
*/
IoFuture<ConnectionPeerIdentity> getConnectedIdentity(URI destination, SSLContext sslContext, AuthenticationConfiguration authenticationConfiguration);
/**
* Get a possibly shared, possibly existing connection to the destination, if the connection was already established.
* The authentication and SSL configuration is specified directly.
* <p>
* If no existing connection was found, {@code null} is returned. If a non-{@code null} {@code IoFuture} is
* returned, it may represent a complete connection, a failed attempt, or an in-progress attempt.
*
* @param destination the destination URI (must not be {@code null})
* @param abstractType the abstract type of the connection (may be {@code null})
* @param abstractTypeAuthority the authority name of the abstract type of the connection (may be {@code null})
* @param context the authentication context to use (must not be {@code null})
* @return the existing connection, or {@code null} if no connection currently exists
*/
default IoFuture<ConnectionPeerIdentity> getConnectedIdentityIfExists(URI destination, String abstractType, String abstractTypeAuthority, AuthenticationContext context) {
Assert.checkNotNullParam("destination", destination);
Assert.checkNotNullParam("context", context);
final AuthenticationContextConfigurationClient client = AUTH_CONFIGURATION_CLIENT;
final SSLContext sslContext;
try {
sslContext = client.getSSLContext(destination, context);
} catch (GeneralSecurityException e) {
return new FailedIoFuture<>(Messages.conn.failedToConfigureSslContext(e));
}
final AuthenticationConfiguration authenticationConfiguration = client.getAuthenticationConfiguration(destination, context, -1, abstractType, abstractTypeAuthority);
return getConnectedIdentityIfExists(destination, sslContext, authenticationConfiguration);
}
/**
* Get a possibly shared, possibly existing connection to the destination, if the connection was already established.
* The authentication and SSL configuration is specified directly.
* <p>
* If no existing connection was found, {@code null} is returned. If a non-{@code null} {@code IoFuture} is
* returned, it may represent a complete connection, a failed attempt, or an in-progress attempt.
*
* @param destination the destination URI (must not be {@code null})
* @param sslContext the SSL context to use for secure connections (may be {@code null})
* @param authenticationConfiguration the authentication configuration to use (must not be {@code null})
* @return the existing connection, or {@code null} if no connection currently exists
*/
IoFuture<ConnectionPeerIdentity> getConnectedIdentityIfExists(URI destination, SSLContext sslContext, AuthenticationConfiguration authenticationConfiguration);
/**
* Get a possibly pre-existing connection to the destination.
*
* @param destination the destination URI
* @return the future (or existing) connection
*/
@Deprecated
default IoFuture<Connection> getConnection(URI destination) {
return getConnection(destination, (String) null, null);
}
/**
* Get a possibly pre-existing connection to the destination. The given abstract type and authority are used
* to locate the authentication configuration.
*
* @param destination the destination URI (must not be {@code null})
* @param abstractType the abstract type of the connection (may be {@code null})
* @param abstractTypeAuthority the authority name of the abstract type of the connection (may be {@code null})
* @return the future (or existing) connection
*/
@Deprecated
default IoFuture<Connection> getConnection(URI destination, String abstractType, String abstractTypeAuthority) {
return new ToConnectionFuture(getConnectedIdentity(destination, abstractType, abstractTypeAuthority));
}
/**
* Get a possibly pre-existing connection to the destination. The given authentication configuration is used to
* authenticate the connection.
* <p>
* The given SSL context factory is used only for TLS-based protocols. It may be {@code null}, but in such cases,
* no TLS-based protocols will be available.
*
* @param destination the destination URI (must not be {@code null})
* @param sslContext the SSL context to use for secure connections (may be {@code null})
* @param authenticationConfiguration the authentication configuration to use (must not be {@code null})
* @return the future (or existing) connection
*/
@Deprecated
default IoFuture<Connection> getConnection(URI destination, SSLContext sslContext, AuthenticationConfiguration authenticationConfiguration) {
return new ToConnectionFuture(getConnectedIdentity(destination, sslContext, authenticationConfiguration));
}
/**
* Get a possibly pre-existing connection to the destination. The connection authentication configuration is used
* to authenticate
* the peer if the connection supports multiple identity switching. The run authentication configuration is used to
* authenticate
* the peer if the connection does not support multiple identity switching.
*
* @param destination the destination URI (must not be {@code null})
* @param sslContext the SSL context to use for secure connections (may be {@code null})
* @param connectionConfiguration the connection authentication configuration (must not be {@code null})
* @param operateConfiguration the run authentication configuration (must not be {@code null})
* @return the future (or existing) connection
*/
@Deprecated
default IoFuture<Connection> getConnection(URI destination, SSLContext sslContext, AuthenticationConfiguration connectionConfiguration, AuthenticationConfiguration operateConfiguration) {
return getConnection(destination, sslContext, operateConfiguration);
}
/**
* Get a pre-existing connection to the destination. The connection authentication configuration is used to
* authenticate
* the peer if the connection supports multiple identity switching. The run authentication configuration is used to
* authenticate
* the peer if the connection does not support multiple identity switching.
* <p>
* If no existing connection was found, {@code null} is returned. If a non-{@code null} {@code IoFuture} is
* returned, it may represent a complete connection, a failed attempt, or an in-progress attempt.
*
* @param destination the destination URI (must not be {@code null})
* @param sslContext the SSL context to use for secure connections (may be {@code null})
* @param connectionConfiguration the connection authentication configuration (must not be {@code null})
* @param operateConfiguration the run authentication configuration (must not be {@code null})
* @return the existing connection, or {@code null} if no connection currently exists
*/
@Deprecated
default IoFuture<Connection> getConnectionIfExists(URI destination, SSLContext sslContext, AuthenticationConfiguration connectionConfiguration, AuthenticationConfiguration operateConfiguration) {
return new ToConnectionFuture(getConnectedIdentityIfExists(destination, sslContext, operateConfiguration));
}
/**
* Get a pre-existing connection to the destination.
* <p>
* If no existing connection was found, {@code null} is returned. If a non-{@code null} {@code IoFuture} is
* returned, it may represent a complete connection, a failed attempt, or an in-progress attempt.
*
* @param destination the destination URI (must not be {@code null})
* @param abstractType the abstract type of the connection (may be {@code null})
* @param abstractTypeAuthority the authority name of the abstract type of the connection (may be {@code null})
* @return the existing connection, or {@code null} if no connection currently exists
*/
@Deprecated
default IoFuture<Connection> getConnectionIfExists(URI destination, String abstractType, String abstractTypeAuthority) {
final AuthenticationContext context = AuthenticationContext.captureCurrent();
final AuthenticationContextConfigurationClient client = AUTH_CONFIGURATION_CLIENT;
final SSLContext sslContext;
try {
sslContext = client.getSSLContext(destination, context);
} catch (GeneralSecurityException e) {
return new FailedIoFuture<>(Messages.conn.failedToConfigureSslContext(e));
}
final AuthenticationConfiguration authenticationConfiguration = client.getAuthenticationConfiguration(destination, context, -1, abstractType, abstractTypeAuthority);
return getConnectionIfExists(destination, sslContext, authenticationConfiguration, authenticationConfiguration);
}
/**
* Get a pre-existing shared connection to the destination.
* <p>
* If no existing connection was found, {@code null} is returned. If a non-{@code null} {@code IoFuture} is
* returned, it may represent a complete connection, a failed attempt, or an in-progress attempt.
*
* @param destination the destination URI (must not be {@code null})
* @return the existing connection, or {@code null} if no connection currently exists
*/
@Deprecated
default IoFuture<Connection> getConnectionIfExists(URI destination) {
return getConnectionIfExists(destination, null, null);
}
/**
* Open an unshared connection with a peer. Returns a future connection which may be used to cancel the connection attempt.
* This method does not block; use the return value to wait for a result if you wish to block.
* <p/>
* You must have the {@link RemotingPermission connect EndpointPermission} to invoke this method.
*
* @param destination the destination
*
* @return the future connection
*/
default IoFuture<Connection> connect(URI destination) {
return connect(destination, OptionMap.EMPTY);
}
/**
* Open an unshared connection with a peer. Returns a future connection which may be used to cancel the connection attempt.
* This method does not block; use the return value to wait for a result if you wish to block.
* <p/>
* You must have the {@link RemotingPermission connect EndpointPermission} to invoke this method.
*
* @param destination the destination
* @param connectOptions options to configure this connection
*
* @return the future connection
*/
IoFuture<Connection> connect(URI destination, OptionMap connectOptions);
/**
* Open an unshared connection with a peer. Returns a future connection which may be used to cancel the connection attempt.
* This method does not block; use the return value to wait for a result if you wish to block.
* <p/>
* You must have the {@link RemotingPermission connect EndpointPermission} to invoke this method.
*
* @param destination the destination
* @param connectOptions options to configure this connection
* @param authenticationContext the client authentication context to use
*
* @return the future connection
*/
IoFuture<Connection> connect(URI destination, OptionMap connectOptions, AuthenticationContext authenticationContext);
/**
* Open an unshared connection with a peer. Returns a future connection which may be used to cancel the connection attempt.
* This method does not block; use the return value to wait for a result if you wish to block.
* <p/>
* You must have the {@link RemotingPermission connect EndpointPermission} to invoke this method.
*
* @param destination the destination
* @param bindAddress the local bind address
* @param connectOptions options to configure this connection
* @param authenticationContext the client authentication context to use
*
* @return the future connection
*/
IoFuture<Connection> connect(URI destination, InetSocketAddress bindAddress, OptionMap connectOptions, AuthenticationContext authenticationContext);
/**
* Open an unshared connection with a peer. Returns a future connection which may be used to cancel the connection attempt.
* This method does not block; use the return value to wait for a result if you wish to block.
* <p/>
* You must have the {@link RemotingPermission connect EndpointPermission} to invoke this method.
*
* @param destination the destination
* @param bindAddress the local bind address
* @param connectOptions options to configure this connection
* @param sslContext the SSL context to use for secure connections (may be {@code null})
* @param connectionConfiguration the connection authentication configuration (must not be {@code null})
* @return the future connection (not {@code null})
*/
IoFuture<Connection> connect(URI destination, InetSocketAddress bindAddress, OptionMap connectOptions, SSLContext sslContext, AuthenticationConfiguration connectionConfiguration);
/**
* Register a connection provider for a URI scheme. The provider factory is called with the context which can
* be used to accept new connections or terminate the registration.
* <p/>
* You must have the {@link RemotingPermission addConnectionProvider EndpointPermission} to invoke this method.
*
* @param uriScheme the URI scheme
* @param providerFactory the provider factory
* @param optionMap the configuration options for the connection provider
* @return a handle which may be used to remove the registration
* @throws IOException if the provider failed to initialize
* @throws DuplicateRegistrationException if there is already a provider registered to that URI scheme
*/
Registration addConnectionProvider(String uriScheme, ConnectionProviderFactory providerFactory, OptionMap optionMap) throws DuplicateRegistrationException, IOException;
/**
* Get the interface for a connection provider.
* <p/>
* You must have the {@link RemotingPermission getConnectionProviderInterface EndpointPermission} to invoke this method.
*
* @param uriScheme the URI scheme of the registered connection provider
* @param expectedType the expected type of the interface
* @param <T> the expected type of the interface
* @return the provider interface
* @throws UnknownURISchemeException if the given URI scheme is not registered
* @throws ClassCastException if the interface type does not match the expected type
*/
<T> T getConnectionProviderInterface(String uriScheme, Class<T> expectedType) throws UnknownURISchemeException, ClassCastException;
/**
* Determine whether the given URI scheme is valid for this endpoint.
*
* @param uriScheme the URI scheme
* @return {@code true} if the URI scheme is valid at the time this method is called
*/
boolean isValidUriScheme(String uriScheme);
/**
* Get the XNIO worker configured for this endpoint.
*
* @return the XNIO worker
*/
XnioWorker getXnioWorker();
/**
* Create a new endpoint builder.
*
* @return the new endpoint builder
*/
static EndpointBuilder builder() {
return new EndpointBuilder();
}
}