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

com.pushtechnology.diffusion.client.features.control.RemoteServers Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2023 DiffusionData Ltd., All Rights Reserved.
 *
 * Use is subject to license terms.
 *
 * NOTICE: All information contained herein is, and remains the
 * property of Push Technology. The intellectual and technical
 * concepts contained herein are proprietary to Push Technology and
 * may be covered by U.S. and Foreign Patents, patents in process, and
 * are protected by trade secret or copyright law.
 *******************************************************************************/

package com.pushtechnology.diffusion.client.features.control;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;

import com.pushtechnology.diffusion.client.Diffusion;
import com.pushtechnology.diffusion.client.features.ClusterRoutingException;
import com.pushtechnology.diffusion.client.features.ErrorReportsException;
import com.pushtechnology.diffusion.client.features.control.RemoteServers.RemoteServer.RemoteServerBuilder;
import com.pushtechnology.diffusion.client.features.control.topics.TopicControl.MissingTopicNotification;
import com.pushtechnology.diffusion.client.session.Feature;
import com.pushtechnology.diffusion.client.session.PermissionsException;
import com.pushtechnology.diffusion.client.session.Session;
import com.pushtechnology.diffusion.client.session.SessionAttributes;
import com.pushtechnology.diffusion.client.session.SessionClosedException;
import com.pushtechnology.diffusion.client.session.SessionException;
import com.pushtechnology.diffusion.client.topics.TopicSelector;
import com.pushtechnology.diffusion.client.types.Credentials;
import com.pushtechnology.diffusion.client.types.ErrorReport;
import com.pushtechnology.diffusion.client.types.GlobalPermission;

/**
 * This feature allows a client session to manage remote servers.
 * 

* This feature provides the ability to configure the various modes of operation * for the use of remote topic views. This is the ability for a topic view * specification to indicate that the source topics for the view are to come * from another server in a different Diffusion cluster. The server where the * topic views are configured is referred to as the 'secondary server' and the * server where the actual topics are is referred to as the 'primary server'. * *

Outbound Connection from the Secondary Server

*

* The typical configuration for a remote server is that there is only * configuration at the secondary server (the configuration is automatically * distributed to all members of the secondary cluster). In this case, each * secondary server connects to a server in the primary cluster (typically via a * load-balancer). *

* Remote topic views can specify the use of such remote servers by name. The * connection and disconnection is handled automatically by the server (or * servers in the same cluster) where the remote servers are defined. *

* A component can specify a remote server by name even if it does not exist * (has not yet been created) and when the remote server is created the * connection will take place automatically. *

* If a remote server is removed and there are topic views that depend upon it, * those topic views will be disabled. *

* This form of connection is provided by a {@link RemoteServer} of type * {@link RemoteServer.Type#SECONDARY_INITIATOR SECONDARY_INITIATOR} and * represented by the sub-type {@link RemoteServers.SecondaryInitiator * SecondaryInitiator}. *

* Such a remote server can be built using an * {@link RemoteServers.SecondaryInitiator.SecondaryInitiatorBuilder * SecondaryInitiatorBuilder} created using * {@link Diffusion#newRemoteServerBuilder(Class)}. It may then be added to the * server (cluster) using {@link #createRemoteServer}. *

* In this mode a connection from secondary to primary server is only maintained * when there is a topic view that depends upon it. There will be no connections * if there are no topic views that specify the remote server. * *

Outbound Connection from the Primary Server

*

* In some cases it may be preferred that the connection is initiated by the * primary server, connecting to the secondary server cluster. In this case a * single primary server will connect to all members of the secondary cluster. *

* This form of connection is provided by a {@link RemoteServer} of type * {@link RemoteServer.Type#PRIMARY_INITIATOR PRIMARY_INITIATOR} and represented * by the sub-type {@link RemoteServers.PrimaryInitiator PrimaryInitiator}. This * can be built using a * {@link RemoteServers.PrimaryInitiator.PrimaryInitiatorBuilder * PrimaryInitiatorBuilder} created using * {@link Diffusion#newRemoteServerBuilder(Class)}. It may then be added to the * primary server (cluster) using {@link #createRemoteServer}. Secondly a * {@link RemoteServer} of type {@link RemoteServer.Type#SECONDARY_ACCEPTOR * SECONDARY_ACCEPTOR} and represented by the sub-type * {@link RemoteServers.SecondaryAcceptor SecondaryAcceptor} should be created * in the secondary server (cluster) with the same name as the primary * initiator. Such a remote server can be built using an * {@link RemoteServers.SecondaryAcceptor.SecondaryAcceptorBuilder * SecondaryAcceptorBuilder} created using * {@link Diffusion#newRemoteServerBuilder(Class)}. It may then be added to the * secondary server (cluster) using {@link #createRemoteServer}. *

* Unlike the secondary initiator mode, this mode of connection will establish * connections even if there are no topic views in the secondary server * (cluster) that name the remote server. If the connection is lost any topic * views that depend upon it will be disabled and the primary initiator will * attempt to re-establish the connection(s). Topic views depending upon the * remote server will only be enabled when the connection is re-established. * *

Remote Server persistence and replication

*

* Remote server configurations created through this feature are replicated * across a cluster and persisted to disk. * *

Access control

*

* The following access control restrictions are applied: * *

    *
  • To {@link #createRemoteServer create}, {@link #removeRemoteServer remove} * or {@link #checkRemoteServer check} a remote server, a session needs the * {@link GlobalPermission#CONTROL_SERVER CONTROL_SERVER} global permission. To * {@link #listRemoteServers list} remote servers , a session needs the * {@link GlobalPermission#VIEW_SERVER VIEW_SERVER} global permission. * *
* *

Accessing the feature

*

* This feature may be obtained from a {@link Session session} as follows: * *

 * RemoteServers remoteServers = session.feature(RemoteServers.class);
 * 
* * @author DiffusionData Limited * @since 6.5 */ public interface RemoteServers extends Feature { /** * Create a new remote server instance at the server. *

* If a remote server with the same name already exists an error will be * returned. * * @param remoteServer a remote server definition created using the * appropriate sub-type of {@link RemoteServerBuilder}. * * @return a CompletableFuture that completes when a response is received * from the server, returning a full definition of the remote server * created by the operation. The returned object may need to be cast * to the appropriate sub-type in order to obtain its full details. * *

* If the task fails, the CompletableFuture will complete * exceptionally with a {@link CompletionException}. Common reasons * for failure, listed by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link RemoteServerExistsException} – if a remote * server with the given name already exists; *
  • {@link RemoteServerOptionsException} – if one or more * connection options are invalid; *
  • {@link ClusterRoutingException} – if the operation * failed due to a transient cluster error; *
  • {@link PermissionsException} – if the calling session * does not have CONTROL_SERVER permission; *
  • {@link SessionClosedException} – if the session is * closed. *
*/ CompletableFuture createRemoteServer( RemoteServer remoteServer); /** * Create a new remote server instance with default connection options. *

* If a remote server with the same name already exists an error will be * returned. * * @param name the name of the remote server * * @param url the URL to use to connect to the primary server * * @param principal the name of a principal used by the remote server to * connect to the primary server. A zero length string may be * supplied to indicate an anonymous connection * * @param credentials to use for connecting to the primary server * * @return a CompletableFuture that completes when a response is received * from the server, returning a full definition of the remote server * created by the operation. * *

* If the task fails, the CompletableFuture will complete * exceptionally with a {@link CompletionException}. Common reasons * for failure, listed by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link RemoteServerExistsException} – if a remote * server with the given name already exists; *
  • {@link ClusterRoutingException} – if the operation * failed due to a transient cluster error; *
  • {@link PermissionsException} – if the calling session * does not have CONTROL_SERVER permission; *
  • {@link SessionClosedException} – if the session is * closed. *
* * @deprecated since 6.7 *

* Use {@link #createRemoteServer(RemoteServer)} in preference. * This method will be removed in a future release. */ @Deprecated default CompletableFuture createRemoteServer( String name, String url, String principal, Credentials credentials) { return createRemoteServer( name, url, principal, credentials, Collections.emptyMap()); } /** * Create a new remote server instance. *

* If a remote server with the same name already exists an error will be * returned. * * @param name the name of the remote server * * @param url the URL to use to connect to the primary server * * @param principal the name of a principal used by the remote server to * connect to the primary server. A zero length string may be * supplied to indicate an anonymous connection * * @param credentials to use for connecting to the primary server * * @param connectionOptions a map of connection option settings. Any options * not supplied will take their default values * * @return a CompletableFuture that completes when a response is received * from the server, returning a full definition of the remote server * created by the operation. * *

* If the task fails, the CompletableFuture will complete * exceptionally with a {@link CompletionException}. Common reasons * for failure, listed by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link RemoteServerExistsException} – if a remote * server with the given name already exists; *
  • {@link RemoteServerOptionsException} – if one or more * connection options are invalid; *
  • {@link ClusterRoutingException} – if the operation * failed due to a transient cluster error; *
  • {@link PermissionsException} – if the calling session * does not have CONTROL_SERVER permission; *
  • {@link SessionClosedException} – if the session is * closed. *
* * @deprecated since 6.7 *

* Use {@link #createRemoteServer(RemoteServer)} in preference. * This method will be removed in a future release. */ @Deprecated CompletableFuture createRemoteServer( String name, String url, String principal, Credentials credentials, Map connectionOptions); /** * List all the remote servers that have been created. * * @return a CompletableFuture that completes when a response is received * from the server, returning a list of remote servers. The remote * server objects may need to be cast to the appropriate sub-type in * order to obtain all details. * *

* If the task fails, the CompletableFuture will complete * exceptionally with a {@link CompletionException}. Common reasons * for failure, listed by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link PermissionsException} – if the calling session * does not have VIEW_SERVER permission; *
  • {@link SessionClosedException} – if the session is * closed. *
*/ CompletableFuture> listRemoteServers(); /** * Check the current state of a named remote server. *

* This will report back the current state of the remote server, but also * can be used to forcibly retry a failed secondary initiator connection. *

* Currently this only reports the state of the remote server at the server * the session is connected to. In a cluster the state of the remote server * on other cluster members is not reported. * * @param name the name of the remote server * * @return a CompletableFuture that completes when a response is received * from the server, returning details of the remote server state. * *

* If the task fails, the CompletableFuture will complete * exceptionally with a {@link CompletionException}. Common reasons * for failure, listed by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link PermissionsException} – if the calling session * does not have CONTROL_SERVER permission; *
  • {@link SessionClosedException} – if the session is * closed. *
*/ CompletableFuture checkRemoteServer(String name); /** * Remove a named remote server if it exists. *

* If the named remote server does not exist the CompletableFuture will * complete successfully. *

* When a named remote server is removed, any topic views that specify it * would be disabled. * * @param name the name of the remote server * * @return a CompletableFuture that completes when a response is received * from the server. * *

* If the task fails, the CompletableFuture will complete * exceptionally with a {@link CompletionException}. Common reasons * for failure, listed by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link ClusterRoutingException} – if the operation * failed due to a transient cluster error; *
  • {@link PermissionsException} – if the calling session * does not have CONTROL_SERVER permission; *
  • {@link SessionClosedException} – if the session is * closed. *
*/ CompletableFuture removeRemoteServer(String name); /** * Base interface for a remote server definition. */ interface RemoteServer { /** * The remote server type. */ enum Type { /** * Secondary initiator remote server. *

* Defined on secondary servers. *

* This type will initiate connection from a secondary server * (cluster) to a primary server (cluster member). */ SECONDARY_INITIATOR, /** * Primary initiator. *

* Defined on primary servers. *

* This type will connect to an inbound remote server of the same * name configured at the secondary server (cluster). */ PRIMARY_INITIATOR, /** * Secondary acceptor remote server. *

* Defined on secondary servers. *

* This type will accept a primary remote server connection and * support remote topic views. */ SECONDARY_ACCEPTOR } /** * Returns the remote server type. *

* A {@link RemoteServer} can be cast to the corresponding sub-type to * access all methods, as follows: * *

* * * * * * * * * * * * * * * * *
TypeType class
{@link Type#SECONDARY_INITIATOR * SECONDARY_INITIATOR}{@link SecondaryInitiator}
{@link Type#PRIMARY_INITIATOR * PRIMARY_INITIATOR}{@link PrimaryInitiator}
{@link Type#SECONDARY_ACCEPTOR * SECONDARY_ACCEPTOR}{@link SecondaryAcceptor}
* * @return the remote server type. */ Type getType(); /** * Return the remote server name. * * @return remote server name */ String getName(); /** * Returns the url for connection to primary server. * * @deprecated since 6.9 *

* For backwards compatibility this method is retained for * secondary initiator compatibility but will be removed at * a future release. */ @Deprecated String getUrl(); /** * Return the principal used for the remote server connection. * * @deprecated since 6.9 *

* For backwards compatibility this method is retained for * secondary initiator compatibility but will be removed at * a future release. */ @Deprecated String getPrincipal(); /** * Return the remote server connection options. * * @deprecated since 6.9 *

* For backwards compatibility this method is retained for * secondary initiator compatibility but will be removed at * a future release. */ @Deprecated Map getConnectionOptions(); /** * Return the missing topic notification filter expression or null if * one has not been specified. * * @deprecated since 6.9 *

* For backwards compatibility this method is retained for * secondary initiator compatibility but will be removed at * a future release. */ @Deprecated String getMissingTopicNotificationFilter(); /** * The base interface for all remote server builders. *

* A builder of this type cannot be instantiated. * * @param the remote server type. */ interface RemoteServerBuilder { /** * Reset the builder to its default values. * * @return this Builder */ B reset(); } /** * A remote server builder. *

* A builder of this type may be created using * {@link Diffusion#newRemoteServerBuilder newRemoteServerBuilder} and * used to create instances of {@link RemoteServer} that can be supplied * to {@link RemoteServers#createRemoteServer(RemoteServer) * createRemoteServer(RemoteServer)}. * * @since 6.7 * * @deprecated since 6.9 *

* This builder is retained for backwards compatibility * only. It can only be used to create a secondary * initiator. * {@link SecondaryInitiator.SecondaryInitiatorBuilder} * should be used in preference. This builder will be * removed in a future release. */ @Deprecated interface Builder { /** * Specifies the name of a principal used by the remote server to * connect to the primary server. *

* The default, if not specified is the anonymous principal. * * @param principal principal name or a zero length string to * indicate an anonymous connection * * @return this builder */ Builder principal(String principal); /** * Specifies the credentials to use when connecting to the primary * server. *

* The default, if not specified, is {@link Credentials.Type#NONE * NONE}. * * @param credentials the credentials to use * * @return this builder */ Builder credentials(Credentials credentials); /** * Specifies a map of {@link ConnectionOption} settings. *

* This will replace any options currently set for the builder. *

* Any options not supplied will take their default values. *

* If no connection options are specified, either using this method * or {@link #connectionOption} then all options will take their * default value. * * @param connectionOptions map of options * * @return this builder */ Builder connectionOptions( Map connectionOptions); /** * Specifies a single connection option. *

* This will add to the options currently specified to the builder, * or replace a value if it has already been specified. * * @param connectionOption the connection option * * @param value the connection option value or null to remove the * option * * @return this builder */ Builder connectionOption( ConnectionOption connectionOption, String value); /** * Specifies a topic selector expression which will filter missing * topic notifications propagated from secondary to primary server. *

* {@link MissingTopicNotification}s are notified when a client * subscribes using a topic selector that matches no existing * topics. By specifying a missing topic notification filter all * notifications that match the filter on the secondary server will * be propagated to the primary server. *

* A match occurs if the path prefix of the subscription selector * matches the path prefix of the specified selector. If the * selector is a {@link TopicSelector#SELECTOR_SET_PREFIX selector * set} then the notification will be propagated if it matches any * selector in the set. *

* If no filter is specified then no missing topic notifications * will be propagated. *

* The special selector expression "*.*" may be used to indicate * that all missing topic notifications should be propagated. *

* Only the path prefix of the specified selector(s) is considered * when matching therefore any use of regular expressions would be * ignored. * * @param filter a topic selector expression specifying the filter * to apply or null to remove any existing filter * * @return this builder */ Builder missingTopicNotificationFilter(String filter); /** * Reset the builder. * * @return this Builder */ Builder reset(); /** * Creates a remote server object using the current values known to * this builder. * * @param name the name of the remote server * * @param url the URL to use to connect to the primary server * * @return a new remote server instance */ RemoteServer create(String name, String url); } /** * Connection options for use with {@link SecondaryServer}s. */ enum ConnectionOption { /** * Specifies the reconnection timeout session attribute. *

* This is the total time in milliseconds that will be allowed to * reconnect a failed connection. *

* For reconnection to work the remote server connector must have * been configured to support reconnection. *

* If a value is not specified * {@link SessionAttributes#DEFAULT_RECONNECTION_TIMEOUT * DEFAULT_RECONNECTION_TIMEOUT} is used. *

* This value cannot be supplied for a * {@link Type#SECONDARY_ACCEPTOR SECONDARY_ACCEPTOR} server. */ RECONNECTION_TIMEOUT, /** * Specifies the delay after losing a connection before attempting a * reconnection. *

* The value is specified in milliseconds. Default 1000 (1 second). *

* This value cannot be supplied for a * {@link Type#SECONDARY_ACCEPTOR SECONDARY_ACCEPTOR} server. */ RETRY_DELAY, /** * Specifies the recovery buffer size session attribute. *

* If the remote server is configured to support reconnection, a * session established with a non-zero reconnect-timeout retains a * buffer of sent messages. If the session disconnects and * reconnects, this buffer is used to re-send messages that the * server has not received. *

* The default value is 10,000 messages. If reconnect-timeout is 0 * then this value is ignored. *

* This value cannot be supplied for a * {@link Type#SECONDARY_ACCEPTOR SECONDARY_ACCEPTOR} server. */ RECOVERY_BUFFER_SIZE, /** * Specifies the input buffer size session attribute. *

* This is the size of the input buffer to use for the connection * with the remote server. It is used to receive messages from the * remote server. This should be set to the same size as the output * buffer used at the remote server. *

* If not specified, a default of 1024k is used. */ INPUT_BUFFER_SIZE, /** * Specifies the output buffer size session attribute. *

* This is the size of the output buffer to use for the connection * with the remote server. It is used to send messages to the remote * server. This should be set to the same size as the input buffer * used by the remote server. *

* If not specified, a default of 1024k is used. */ OUTPUT_BUFFER_SIZE, /** * Specifies the maximum queue size session attribute. *

* This is the maximum number of messages that can be queued to send * to the remote server. If this number is exceeded, the connection * will be closed. This must be sufficient to cater for messages * that may be queued whilst disconnected (awaiting reconnect). *

* The default value is 10,000 messages. */ MAXIMUM_QUEUE_SIZE, /** * Specifies the connection timeout session attribute value (in * milliseconds). *

* If a value is not specified * {@link SessionAttributes#DEFAULT_CONNECTION_TIMEOUT * DEFAULT_CONNECTION_TIMEOUT} is used. */ CONNECTION_TIMEOUT, /** * Specifies the write timeout session attribute value (in * milliseconds). *

* If a value is not specified * {@link SessionAttributes#DEFAULT_WRITE_TIMEOUT * DEFAULT_WRITE_TIMEOUT} is used. */ WRITE_TIMEOUT; } } /** * A primary initiator. *

* This type makes a connection from a primary server (cluster) to a * secondary server (or all secondary cluster members) with an * {@link SecondaryAcceptor} of the same name. *

* Use a {@link PrimaryInitiatorBuilder} to create an instance of this type. */ interface PrimaryInitiator extends RemoteServer { /** * Returns the urls for connection to secondary servers. * * @return the list of urls for connection to secondary servers */ List getUrls(); /** * Returns the connector that the primary initiator will use to * establish a connection between the secondary server and the primary * server. * * @return the connector name */ String getConnector(); /** * Returns the interval in milliseconds between connection retries. *

* If a primary initiator cannot connect to a secondary server, or loses * the connection, this is the amount of time before it will try to * connect again. * * @return the retry delay time in milliseconds */ int getRetryDelay(); /** * Builder for a {@link PrimaryInitiator}. *

* A builder of this type may be created using * {@link Diffusion#newRemoteServerBuilder(Class)} specifying * {@code PrimaryInitiatorBuilder.class} as the parameter. */ interface PrimaryInitiatorBuilder extends RemoteServerBuilder { /** * Specifies the delay after losing a connection before attempting a * reconnection. *

* The value is specified in milliseconds. Default 1000 (1 second). */ PrimaryInitiatorBuilder retryDelay(int delay); /** * Builds a primary initiator using the current values known to this * builder. * * @param name the name of the primary initiator which must * correspond too the name of an {@link SecondaryAcceptor} * defined on the secondary server * * @param urls the list of URLs to use to initiate connections to * the secondary servers * * @param connector the name of the connector used to establish the * connection with the secondary server * * @return a new primary initiator instance */ PrimaryInitiator build( String name, List urls, String connector); } } /** * Base interface for a secondary remote server. */ interface SecondaryServer extends RemoteServer { /** * Return the principal used for the connection. *

* This is used to authenticate the connection at the primary server. * * @return the principal */ @Override String getPrincipal(); /** * Return the remote server connection options. * * @return the connection options */ @Override Map getConnectionOptions(); /** * Return the missing topic notification filter expression. * * @return missing topic notification filter, or null if one has not * been specified */ @Override String getMissingTopicNotificationFilter(); /** * Base builder interface for {@link SecondaryServer}. *

* A builder of this type cannot be instantiated. * * @param the builder type */ interface SecondaryBuilder extends RemoteServerBuilder { /** * Specifies the name of a principal to use to use for the * connection. *

* This specifies the principal for the connection to the primary * server and is authenticated at the primary. *

* The default, if not specified is the anonymous principal. * * @param principal principal name or a zero length string to * indicate an anonymous connection * * @return this builder */ B principal(String principal); /** * Specifies the credentials to use to authenticate the connection. *

* The default, if not specified, is {@link Credentials.Type#NONE * NONE}. *

* This is used along with the specified principal. * * @param credentials the credentials to use * * @return this builder * * @see #principal */ B credentials(Credentials credentials); /** * Specifies a map of {@link ConnectionOption} settings. *

* This will replace any options currently set for the builder. *

* Any options not supplied will take their default values. *

* If no connection options are specified, either using this method * or {@link #connectionOption} then all options will take their * default value. *

* Not all remote server types support all options. See * {@link ConnectionOption} for details. * * @param connectionOptions map of options * * @return this builder * * @see #connectionOption */ B connectionOptions( Map connectionOptions); /** * Specifies a single connection option. *

* This will add to the options currently specified to the builder, * or replace a value if it has already been specified. *

* Not all remote server types support all options. See * {@link ConnectionOption} for details. * * @param connectionOption the connection option * * @param value the connection option value or null to remove the * option * * @return this builder */ B connectionOption( ConnectionOption connectionOption, String value); /** * Specifies a topic selector expression which will filter missing * topic notifications propagated from secondary to primary server. *

* {@link MissingTopicNotification}s are notified when a client * subscribes using a topic selector that matches no existing * topics. By specifying a missing topic notification filter all * notifications that match the filter on the secondary server will * be propagated to the primary server. *

* A match occurs if the path prefix of the subscription selector * matches the path prefix of the specified selector. If the * selector is a {@link TopicSelector#SELECTOR_SET_PREFIX selector * set} then the notification will be propagated if it matches any * selector in the set. *

* If no filter is specified then no missing topic notifications * will be propagated. *

* The special selector expression "*.*" may be used to indicate * that all missing topic notifications should be propagated. *

* Only the path prefix of the specified selector(s) is considered * when matching therefore any use of regular expressions would be * ignored. * * @param filter a topic selector expression specifying the filter * to apply or null to remove any existing filter * * @return this builder */ B missingTopicNotificationFilter(String filter); } } /** * Secondary remote server that initiates a connection to a primary server. *

* This type makes a connection from a secondary server (or each secondary * cluster member) to a primary server. No remote server definition is * required at the primary server. *

* Use an {@link SecondaryInitiatorBuilder} to create an instance of this * type. */ interface SecondaryInitiator extends SecondaryServer { /** * Builder for an {@link SecondaryInitiator}. *

* A builder of this type may be created using * {@link Diffusion#newRemoteServerBuilder(Class)} specifying * {@code SecondaryInitiatorBuilder.class} as the parameter. */ interface SecondaryInitiatorBuilder extends SecondaryBuilder { /** * Builds a secondary initiator instance using the current values * known to this builder. * * @param name the remote server name. This is the name that will be * specified in topic views * * @param url the URL to use to connect to the primary server * * @return a new secondary initiator instance */ SecondaryInitiator build(String name, String url); } /** * Returns the url for connection to primary server. * * @return the primary server (cluster) url */ @Override String getUrl(); } /** * Secondary remote server that accepts a connection from a primary server. *

* This type accepts a connection from a {@link PrimaryInitiator} with the * same name configured at the primary server (cluster). *

* Use an {@link SecondaryAcceptorBuilder} to create an instance of this * type. */ interface SecondaryAcceptor extends SecondaryServer { /** * Builder for a {@link SecondaryAcceptor}. *

* A builder of this type may be created using * {@link Diffusion#newRemoteServerBuilder(Class)} specifying * {@code SecondaryAcceptorBuilder.class} as the parameter. */ interface SecondaryAcceptorBuilder extends SecondaryBuilder { /** * Builds a secondary acceptor using the current values known to * this builder. * * @param name the remote server name. A primary initiator of the * same name will be able to connect to this acceptor. This * is the name that will be specified in topic views * * @param primaryHostName the primary server host name that will be * used in SSL validation of the primary server * * @return a new secondary acceptor instance */ SecondaryAcceptor build(String name, String primaryHostName); } /** * Returns the primary server host name used in SSL validation. * * @return the primary server host name */ String getPrimaryHostName(); } /** * Result returned from a {@link #checkRemoteServer} invocation. */ interface CheckRemoteServerResult { /** * Represents the current connection state of the remote server. */ enum ConnectionState { /** * The connection is inactive. *

* This is the initial state for all types. *

* For a {@link SecondaryInitiator} this could also mean that the * remote server can successfully connect but a physical connection * is not being maintained as there are no components that require * the remote server. *

* If in an inactive or failed state, a test connection will have * been tried to check that the connection can be made and the * connection will then have been closed. */ INACTIVE, /** * The remote server is connected. *

* For a {@link SecondaryInitiator} this means that there are * components actually using it. *

* A {@link SecondaryAcceptor} can be in this state even if there * are no components using it as a reverse connection is always * maintained. *

* A {@link PrimaryInitiator} will only be in this state if it has * a successful connection to all secondary acceptors configured for * it. If any secondary acceptor connection has failed then it will * be in a FAILED state even if there are some active connections. */ CONNECTED, /** * The connection has failed but is retrying. *

* In this case {@link CheckRemoteServerResult#getFailureMessage} * will provide details of the failure that resulted in a retry. */ RETRYING, /** * The connection has failed. *

* If the connection was in an inactive or failed state state, a * test connection was tried and failed. *

* In this case {@link CheckRemoteServerResult#getFailureMessage} * will provide more detail. */ FAILED, /** * The named remote server did not exist. */ MISSING } /** * Returns the connection state of the remote server. * * @return the connection state */ ConnectionState getConnectionState(); /** * Returns a failure message when the state returned is * {@link ConnectionState#FAILED} or {@link ConnectionState#RETRYING}. *

* For other states this will return an empty string. * * @return the failure message, if there is one, otherwise an empty * string */ String getFailureMessage(); } /** * Exception thrown when an attempt has been made to create a remote server * when one with the same name is already defined. */ final class RemoteServerExistsException extends SessionException { private static final long serialVersionUID = 4675880972876068202L; /** * Constructor. */ public RemoteServerExistsException(String message) { super(message); } } /** * Exception thrown when one or more of the options specified when creating * a remote server have been found to be invalid. */ final class RemoteServerOptionsException extends ErrorReportsException { private static final long serialVersionUID = 6069777787663040691L; /** * Constructor. */ public RemoteServerOptionsException( String message, List reports) { super(message, reports); } } }