/*
 * Copyright (c) 1998, 2019 Oracle and/or its affiliates. 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,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.sessions.coordination;


/**
 * <p>
 * <b>Purpose</b>: Provide an interface that clients can use to invoke remote
 * commands on other EclipseLink instances, or on other applications that may want
 * to receive and process EclipseLink commands.
 * <p>
 * <b>Description</b>: This is the main interface that is used to send and receive
 * remote commands in a EclipseLink cluster. The sequence of remote command execution
 * is as follows:
 *
 * <ol>
 * <li> CommandProcessor creates a command and gives it to its local CommandManager
 * to send to remote services.
 * <li> CommandManager uses its CommandConverter to convert the command into a
 * TopLink Command object
 * <li> CommandManager then uses its TransportManager to send the Command to all
 * other known cluster members that are subscribing to the same channel
 * <li> Each remote TransportManager receives the Command and passes it off to the
 * CommandManager
 * <li> Each CommandManager uses its local CommandConverter to convert the command
 * into a format appropriate to its application (CommandProcessor)
 * <li> Each CommandManager invokes its local CommandProcessor and passes it the
 * command (formatted the way that the application-specified converter left it in)
 * to be executed. If the CommandProcessor is a EclipseLink session then the
 * executeWithSession method will be invoked on the command.
 * </ol>
 * <p>
 * <b>Responsibilities</b>:
 * <ul>
 * <li> Invoke the DiscoveryManager to establish the EclipseLink cluster
 * <li> Propagate remote command to EclipseLink cluster
 * <li> Delegate processing command to its CommandProssesor
 * <li> Convert command to appropriate format for sending to EclipseLink cluster
 * or its command processor
 * </ul>
 * @see Command
 * @see CommandProcessor
 * @author Steven Vo
 * @since OracleAS TopLink 10<i>g</i> (9.0.4)
 */
public interface CommandManager {

    /**
     * PUBLIC:
     * Initialize the remote command manager. This will also trigger the
     * DiscoveryManager to start establishing the EclipseLink cluster.
     */
    void initialize();

    /**
     * PUBLIC:
     * Shut down the remote command manager. This will also trigger the
     * DiscoveryManager to stop.
     * NOTE: Although this call initiates the shutdown process,
     * no guarantees are made as to when it will actually complete.
     */
    void shutdown();

    /**
     * PUBLIC:
     * Return the URL for this command manager.
     *
     * @return The URL String for this CommandManager
     */
    String getUrl();

    /**
     * ADVANCED:
     * Set the URL for this command manager.
     *
     * @param url The URL String for this CommandManager
     */
    void setUrl(String url);

    /**
     * PUBLIC:
     * Return the service channel for this command manager. All command managers
     * with the same service channel will send and receive commands from each other.
     * Commands sent on other service channels will not be exchanged with this
     * command manager.
     *
     * @return The service channel String subscribed to by this CommandManager
     */
    String getChannel();

    /**
     * ADVANCED:
     * Set the service channel for this command manager. All command managers
     * with the same service channel will send and receive commands from each other.
     * Commands sent on other service channels will not be exchanged with this
     * command manager.
     *
     * @param channel The service channel subscribed to by this CommandManager
     */
    void setChannel(String channel);

    /**
     * ADVANCED:
     * Propagate a remote command to all remote RCM services participating
     * in the EclipseLink cluster.
     *
     * @param command An object representing a TopLink command
     */
    void propagateCommand(Object command);

    /**
     * PUBLIC:
     * Return the command processor that processes commands received from the cluster.
     *
     * @return An implementation instance of CommandProcessor
     */
    CommandProcessor getCommandProcessor();

    /**
     * ADVANCED:
     * Set the command processor that will be invoked to process commands. EclipseLink
     * applications can implement this interface in order to receive remote commands
     * from a EclipseLink cluster.
     *
     * @param commandProcessor The intended processor of remote commands
     */
    void setCommandProcessor(CommandProcessor commandProcessor);

    /**
     * ADVANCED:
     * Set a specific transport manager to manage sending and receiving of remote commands.
     *
     * @param newTransportManager An instance of the desired transport manager type
     */
    void setTransportManager(TransportManager newTransportManager);

    /**
    * PUBLIC:
     * Return the transport manager that manages sending and receiving of remote commands.
     *
     * @return The TransportManager instance being used by this CommandManager
     */
    TransportManager getTransportManager();

    /**
     * PUBLIC:
     * Return the discovery manager that manages membership in the EclipseLink cluster.
     *
     * @return The DiscoveryManager instance being used by this CommandManager
     */
    DiscoveryManager getDiscoveryManager();

    /**
     * PUBLIC:
     * Return the converter instance used to convert between TopLink Command
     * objects and an application command format.
     *
     * @return The converter being used by this CommandManager
     */
    CommandConverter getCommandConverter();

    /**
     * ADVANCED:
     * Set the converter instance that will be invoked by this CommandProcessor
     * to convert commands from their application command format into EclipseLink
     * Command objects before being propagated to remote command manager services.
     * The converter will also be invoked to convert EclipseLink Command objects into
     * application format before being sent to the CommandProcessor for execution.
     *
     * @param commandConverter The converter to be used by this CommandManager
     */
    void setCommandConverter(CommandConverter commandConverter);

    /**
     * PUBLIC:
     * Return whether this command manager should propagate commands
     * synchronously or asynchronously. If set to synchronous propagation then
     * propagateCommand() will not return to the caller until the command has
     * been executed on all of the services in the cluster. In asynchronous mode
     * the command manager will create a separate thread for each of the remote
     * service executions, and then promptly return to the caller.
     */
    boolean shouldPropagateAsynchronously();

    /**
     * ADVANCED:
     * Set whether this command manager should propagate commands
     * synchronously or asynchronously. If set to synchronous propagation then
     * propagateCommand() will not return to the caller until the command has
     * been executed on all of the services in the cluster. In asynchronous mode
     * the command manager will create a separate thread for each of the remote
     * service executions, and then promptly return to the caller.
     */
    void setShouldPropagateAsynchronously(boolean asyncMode);

    /**
    * ADVANCE:
    * Return whether this commandProcessor is a EclipseLink session or not.
    */
    boolean isCommandProcessorASession();

}
