Package org.globus.workspace.client.modes

Source Code of org.globus.workspace.client.modes.Subscribe

/*
* Copyright 1999-2008 University of Chicago
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package org.globus.workspace.client.modes;

import org.globus.workspace.common.print.Print;
import org.globus.workspace.client_core.print.PrCodes;
import org.globus.workspace.client_core.ParameterProblem;
import org.globus.workspace.client_core.ExecutionProblem;
import org.globus.workspace.client_core.ExitNow;
import org.globus.workspace.client_core.StubConfigurator;
import org.globus.workspace.client_core.utils.EPRUtils;
import org.globus.workspace.client_core.subscribe_tools.ListeningSubscriptionMaster;
import org.globus.workspace.client_core.subscribe_tools.PollingSubscriptionMaster;
import org.globus.workspace.client_core.subscribe_tools.SubscriptionMaster;
import org.globus.workspace.client_core.subscribe_tools.NotificationImplementationException;
import org.globus.workspace.client_core.subscribe_tools.SubscriptionMasterFactory;
import org.globus.workspace.client_core.repr.State;
import org.globus.workspace.client_core.repr.Workspace;
import org.globus.workspace.client.AllArguments;
import org.globus.workspace.client.modes.aux.SubscribeLaunch;
import org.globus.workspace.client.modes.aux.CommonLogs;
import org.nimbustools.messaging.gt4_0.common.CommonUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.axis.message.addressing.EndpointReferenceType;
import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;

import java.net.URL;
import java.net.MalformedURLException;

public class Subscribe extends Mode {


    // -------------------------------------------------------------------------
    // STATIC VARIABLES
    // -------------------------------------------------------------------------

    private static final Log logger =
            LogFactory.getLog(Subscribe.class.getName());


    // -------------------------------------------------------------------------
    // INSTANCE VARIABLES
    // -------------------------------------------------------------------------
   
    EndpointReferenceType epr;
    boolean dryrun;
    boolean autodestroy;
    boolean isGroupRequest;
    String nameToPrint;
    String shortName;
    Workspace[] workspaces;

    // note that "subscribe" has same meaning here whether polling or not
    boolean pollDontListen; // true: poll, false: async listen
    State exitState;
    State veryTerseNotifyState;
    SubscribeLaunch subscribeLaunch;
    ListeningSubscriptionMaster listeningSubscriptionMaster;
    PollingSubscriptionMaster pollingSubscriptionMaster;
    SubscriptionMaster eitherSubscriptionMaster;
    String notificationListenerOverride_IPorHost;
    Integer notificationListenerOverride_Port;
    long pollMS = -1;
    int pollMaxThreads = -1;


    // -------------------------------------------------------------------------
    // CONSTRUCTOR
    // -------------------------------------------------------------------------

    public Subscribe(Print print,
                     AllArguments arguments,
                     StubConfigurator stubConfigurator) {
        super(print, arguments, stubConfigurator);
    }


    // -------------------------------------------------------------------------
    // GENERAL
    // -------------------------------------------------------------------------

    public String name() {
        return "Subscribe";
    }

    // -------------------------------------------------------------------------
    // VALIDATE
    // -------------------------------------------------------------------------

    public void validateOptionsImpl() throws ParameterProblem {
        this.validateEndpoint();
        this.validateName();
        this._handleExitState();
        this._handleVeryTerseNotifyState();
        this._handlePollDelay();
        this._handlePollMaxThreads();
        this._handleListenerOverride();

        this.dryrun = this.args.dryrun;
        CommonLogs.logBoolean(this.dryrun, "dryrun mode",
                              this.pr, logger);

        this.autodestroy = this.args.autodestroy;
        CommonLogs.logBoolean(this.autodestroy, "autodestroy mode",
                              this.pr, logger);

        this._logSubscribeStatus();
       
        if (this.pollDontListen) {
            this._handleSubscribeWithPoll();
        } else {
            this._handleSubscribeWithListen();
        }

        this._handleWorkspaces();
    }

    protected void validateEndpoint() throws ParameterProblem {

        this.epr = this.stubConf.getEPR();

        if (this.epr == null) {
            throw new ParameterProblem(name() + " requires EPR");
        }

        final String eprStr;
        try {
            eprStr = EPRUtils.eprToString(this.epr);
        } catch (Exception e) {
            final String err = CommonUtil.genericExceptionMessageWrapper(e);
            throw new ParameterProblem(err, e);
        }

        if (this.pr.enabled()) {
            // xml print
            final String dbg =
                    "\nGiven EPR:\n----------\n" + eprStr + "----------\n";

            if (this.pr.useThis()) {
                this.pr.dbg(dbg);
            } else if (this.pr.useLogging()) {
                logger.debug(dbg);
            }
        }

        final String kind;
        if (EPRUtils.isInstanceEPR(this.epr)) {
            this.isGroupRequest = false;
            kind = "an instance";
        } else if (EPRUtils.isGroupEPR(this.epr)) {
            this.isGroupRequest = true;
            kind = "a group";
        } else {
            throw new ParameterProblem(name() + " requires a valid EPR.");
        }

        if (this.pr.enabled()) {
            final String dbg = "Given EPR is " + kind + " EPR";
            if (this.pr.useThis()) {
                this.pr.dbg(dbg);
            } else if (this.pr.useLogging()) {
                logger.debug(dbg);
            }
        }

        if (this.isGroupRequest) {
            throw new ParameterProblem(name() + " can not handle group " +
                    "subscribe yet (only after deploying).  Stay tuned.");
        }
    }

    protected void validateName() throws ParameterProblem {

        String eprName;
        if (this.isGroupRequest) {
            eprName = EPRUtils.getGroupIdFromEPR(this.epr);
            eprName = "group-" + eprName;
        } else {
            eprName = Integer.toString(EPRUtils.getIdFromEPR(this.epr));
            eprName = "workspace-" + eprName;
        }

        this.shortName = this.args.shortName;
        if (this.pr.enabled()) {
            final String dbg;
            if (this.shortName == null) {
                dbg = "Given display name is null";
            } else {
                dbg = "Given display name: " + this.shortName + "'";
            }
            if (this.pr.useThis()) {
                this.pr.dbg(dbg);
            } else if (this.pr.useLogging()) {
                logger.debug(dbg);
            }
        }

        if (this.shortName != null) {
            this.nameToPrint = this.shortName;
        } else {
            this.nameToPrint = eprName;
        }
    }

    protected void _handleExitState() throws ParameterProblem {

        if (this.args.exitStateString == null) {
            return// *** EARLY RETURN ***
        }

        if (!State.testValidState(this.args.exitStateString)) {
            throw new ParameterProblem("Provided exit string is not a " +
                    "valid state: '" + this.args.exitStateString + "'");
        }

        this.exitState = new State(this.args.exitStateString);
        if (this.pr.enabled()) {
            final String dbg = "Exit state: " + this.exitState.toString();
            if (this.pr.useThis()) {
                this.pr.dbg(dbg);
            } else if (this.pr.useLogging()) {
                logger.debug(dbg);
            }
        }
    }

    protected void _handleVeryTerseNotifyState() throws ParameterProblem {

        if (this.args.veryTerseNotifyStateString == null) {
            return// *** EARLY RETURN ***
        }

        if (!State.testValidState(this.args.veryTerseNotifyStateString)) {
            throw new ParameterProblem(
                    "Provided very-terse-notify state string is not a " +
                    "valid state: '" +
                            this.args.veryTerseNotifyStateString + "'");
        }

        this.veryTerseNotifyState =
                new State(this.args.veryTerseNotifyStateString);
        if (this.pr.enabled()) {
            final String dbg = "very-terse-notify state: " +
                    this.veryTerseNotifyState.toString();
            if (this.pr.useThis()) {
                this.pr.dbg(dbg);
            } else if (this.pr.useLogging()) {
                logger.debug(dbg);
            }
        }
    }

    protected void _handlePollDelay() throws ParameterProblem {

        if (this.args.pollDelayString == null) {
            return// *** EARLY RETURN ***
        }

        // default subscription mode is notification listener
        // setting the poll delay sets the subscription mode to poll
        this.pollDontListen = true;

        try {
            this.pollMS = Long.parseLong(this.args.pollDelayString);
        } catch (NumberFormatException e) {
            throw new ParameterProblem("Given poll delay is not valid: '" +
                    this.args.pollDelayString + "': " + e.getMessage(), e);
        }

        if (this.pollMS < 1) {
            throw new ParameterProblem("Given poll delay is less than 1ms: " +
                    this.pollMS + "ms");
        }
    }

    protected void _handlePollMaxThreads() throws ParameterProblem {

        if (this.args.pollMaxThreadsString == null) {
            return// *** EARLY RETURN ***
        }

        try {
            this.pollMaxThreads =
                    Integer.parseInt(this.args.pollMaxThreadsString);
        } catch (NumberFormatException e) {
            throw new ParameterProblem(
                    "Given poll max-threads number is not valid: '" +
                    this.args.pollMaxThreadsString + "': " + e.getMessage(), e);
        }

        if (this.pollMaxThreads < 1) {
            throw new ParameterProblem("Given poll max-threads is invalid, " +
                    "it is less than 1: " + this.pollMaxThreads);
        }
    }

    protected void _handleListenerOverride() throws ParameterProblem {

        final String given = this.args.listenerOverride;
        if (given == null) {
            return// *** EARLY RETURN ***
        }

        if (given.indexOf('/') >= 0) {
            throw new ParameterProblem("Listener override address has a '/' " +
                    "in it, use just a host or IP, not an URL");
        }

        final int splt = given.indexOf(':'); // first occurence only
        final String host;
        final String port;
        if (splt >= 0) {
            host = given.substring(0, splt).trim();
            port = given.substring(splt).trim();
        } else {
            host = given.trim();
            port = null;
        }

        if (host.length() == 0) {
            throw new ParameterProblem("Listener override address " +
                    "has zero-length hostname, given: \"" + given + "\"");
        }

        if (port != null && port.length() == 0) {
            throw new ParameterProblem("Listener override address " +
                    "has zero-length port, given: \"" + given + "\"");
        }

        final String urlString;
        if (port == null) {
            urlString = "http://" + host;
        } else {
            urlString = "http://" + host + ":" + port;
        }

        final String usingHost;
        int usingPort = -1;
        try {
            final URL url = new URL(urlString);
            usingHost = url.getHost();
            if (port != null) {
                usingPort = url.getPort();
            }
        } catch (MalformedURLException e) {
            throw new ParameterProblem("Falied to test validity of listener " +
                    "override address using given input '" + given + "', " +
                    "testing with URL constructed from '" + urlString +
                    "': " + e.getMessage(), e);
        }

        this.notificationListenerOverride_IPorHost = usingHost;
        if (usingPort > 0) {
            this.notificationListenerOverride_Port = new Integer(usingPort);
        }
    }

    protected void _logSubscribeStatus() {

        if (!this.pr.enabled()) {
            return; // *** EARLY RETURN ***
        }

        String listenTail = "";
        if (this.notificationListenerOverride_IPorHost != null
                && this.notificationListenerOverride_Port != null) {

            final String addr =
                    this.notificationListenerOverride_IPorHost + ":" +
                            this.notificationListenerOverride_Port.intValue();

            listenTail = " (listener override host+port: '" + addr + "')";

        } else if (this.notificationListenerOverride_IPorHost != null) {

            listenTail = " (listener override host: '" +
                    this.notificationListenerOverride_IPorHost + "')";

        }

        final String dbg;
        if (this.pollDontListen) {
            dbg = "subscription mode: POLL (" + this.pollMS + "ms delay)";
        } else {
            dbg = "subscription mode: LISTENER" + listenTail;
        }
        if (this.pr.useThis()) {
            this.pr.dbg(dbg);
        } else if (this.pr.useLogging()) {
            logger.debug(dbg);
        }
    }

    protected void _handleSubscribeWithListen() throws ParameterProblem {

        if (this.eitherSubscriptionMaster != null) {
            throw new IllegalStateException("you may only make one " +
                    "subscription master non-null (and copy its reference " +
                    "to 'either' variable)");
        }

        this.listeningSubscriptionMaster =
                SubscriptionMasterFactory.newListeningMaster(null, this.pr);

        this.eitherSubscriptionMaster = this.listeningSubscriptionMaster;


        if (this.dryrun) {
            final String dbg =
                    "Dryrun, not starting to listen for notifications.";
            if (this.pr.useThis()) {
                this.pr.info(PrCodes.CREATE__DRYRUN, dbg);
            } else if (this.pr.useLogging()) {
                logger.info(dbg);
            }

            return; // *** EARLY RETURN ***
        }

        final String errPrefix =
                "Problem starting to listen for notifications: ";
        try {
            this.listeningSubscriptionMaster.listen(
                this.notificationListenerOverride_IPorHost,
                    this.notificationListenerOverride_Port);
        } catch (IllegalStateException e) {
            throw new ParameterProblem(errPrefix + e.getMessage(), e);
        } catch (IllegalArgumentException e) {
            throw new ParameterProblem(errPrefix + e.getMessage(), e);
        } catch (Exception e) {
            throw new ParameterProblem(errPrefix + e.getMessage(), e);
        }

        this.subscribeLaunch =
                new SubscribeLaunch(this.listeningSubscriptionMaster,
                                    this.nameToPrint,
                                    this.pr,
                                    this.stubConf,
                                    null);
    }

    protected void _handleSubscribeWithPoll() throws ParameterProblem {

        if (this.eitherSubscriptionMaster != null) {
            throw new IllegalStateException("you may only make one " +
                    "subscription master non-null (and copy its reference " +
                    "to 'either' variable)");
        }

        final long ms = this.pollMS;
        final int thrNum = this.pollMaxThreads;
        final ExecutorService execService = null;
        final StubConfigurator conf = this.stubConf;

        final PollingSubscriptionMaster master;

        if (thrNum < 1) {
            // default maxThreads
            master = SubscriptionMasterFactory.newPollingMaster(ms,
                                                                conf,
                                                                execService,
                                                                this.pr);
        } else {
            // cap the maxThreads
            master = SubscriptionMasterFactory.newPollingMaster(ms,
                                                                thrNum,
                                                                conf,
                                                                execService,
                                                                this.pr);
        }

        this.pollingSubscriptionMaster = master;
        this.eitherSubscriptionMaster = master;

        this.subscribeLaunch = new SubscribeLaunch(master,
                                                   this.nameToPrint,
                                                   this.pr,
                                                   this.stubConf,
                                                   null);
    }


    protected void _handleWorkspaces() {

        if (this.isGroupRequest) {
            throw new IllegalStateException(
                    "group requests should have been rejected already");
        }

        final Workspace workspace = new Workspace();

        workspace.setEpr(this.epr);
        workspace.setCurrentState(new State());

        this.workspaces = new Workspace[1];
        this.workspaces[0] = workspace;
    }
   
    // -------------------------------------------------------------------------
    // EXECUTE
    // -------------------------------------------------------------------------

    public void runImpl() throws ParameterProblem, ExecutionProblem, ExitNow {
        try {
            _runImpl();
        } finally {
            this.doneCleanupSubscriptions();
        }
    }

    private void _runImpl() throws ParameterProblem, ExecutionProblem, ExitNow {
        this.subscribeLaunch.subscribe(this.workspaces,
                                       this.exitState,
                                       this.veryTerseNotifyState,
                                       this.autodestroy,
                                       false,
                                       false);
    }

    protected void doneCleanupSubscriptions() {

        if (this.listeningSubscriptionMaster != null) {
            try {
                this.listeningSubscriptionMaster.stopListening();
            } catch (NotificationImplementationException e) {

                if (this.pr.enabled()) {

                    final String err =
                            "Problem stopping notification listener: " +
                                    e.getMessage();

                    if (this.pr.useThis()) {
                        this.pr.errln(PrCodes.ANY_ERROR_CATCH_ALL,
                                      err);
                    } else if (this.pr.useLogging()) {
                        if (logger.isDebugEnabled()) {
                            logger.error(err, e);
                        } else {
                            logger.error(err);
                        }
                    }
                }
            }
        }

        if (this.pollingSubscriptionMaster != null) {
            this.pollingSubscriptionMaster.stopPolling();
        }
    }


}
TOP

Related Classes of org.globus.workspace.client.modes.Subscribe

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.