Package org.globus.workspace.client_core.actions

Source Code of org.globus.workspace.client_core.actions.Create

/*
* 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_core.actions;

import org.apache.axis.message.addressing.EndpointReferenceType;
import org.apache.axis.types.Duration;
import org.apache.axis.types.URI;
import org.ggf.jsdl.RangeValue_Type;
import org.nimbustools.messaging.gt4_0.common.CommonUtil;
import org.nimbustools.messaging.gt4_0.common.InvalidDurationException;
import org.globus.workspace.common.print.Print;
import org.globus.workspace.client_core.ExecutionProblem;
import org.globus.workspace.client_core.ParameterProblem;
import org.globus.workspace.client_core.StubConfigurator;
import org.globus.workspace.client_core.WSAction_Factory;
import org.globus.workspace.client_core.repr.GenericIntRange;
import org.globus.workspace.client_core.repr.Networking;
import org.globus.workspace.client_core.repr.ResourceAllocation;
import org.globus.workspace.client_core.repr.Schedule;
import org.globus.workspace.client_core.repr.ShutdownMech;
import org.globus.workspace.client_core.repr.State;
import org.globus.workspace.client_core.repr.Workspace;
import org.globus.workspace.client_core.utils.RMIUtils;
import org.nimbustools.messaging.gt4_0.generated.WorkspaceFactoryPortType;
import org.nimbustools.messaging.gt4_0.generated.ensemble.WorkspaceEnsembleFault;
import org.nimbustools.messaging.gt4_0.generated.metadata.VirtualWorkspace_Type;
import org.nimbustools.messaging.gt4_0.generated.metadata.logistics.VirtualNetwork_Type;
import org.nimbustools.messaging.gt4_0.generated.negotiable.DeploymentTime_Type;
import org.nimbustools.messaging.gt4_0.generated.negotiable.ResourceAllocation_Type;
import org.nimbustools.messaging.gt4_0.generated.negotiable.ShutdownMechanism_Type;
import org.nimbustools.messaging.gt4_0.generated.negotiable.WorkspaceDeployment_Type;
import org.nimbustools.messaging.gt4_0.generated.types.CreatedWorkspace_Type;
import org.nimbustools.messaging.gt4_0.generated.types.OptionalParameters_Type;
import org.nimbustools.messaging.gt4_0.generated.types.Schedule_Type;
import org.nimbustools.messaging.gt4_0.generated.types.WorkspaceCreateRequest_Type;
import org.nimbustools.messaging.gt4_0.generated.types.WorkspaceCreateResponse_Type;
import org.nimbustools.messaging.gt4_0.generated.types.WorkspaceCreationFault;
import org.nimbustools.messaging.gt4_0.generated.types.WorkspaceMetadataFault;
import org.nimbustools.messaging.gt4_0.generated.types.WorkspaceResourceRequestDeniedFault;
import org.nimbustools.messaging.gt4_0.generated.types.WorkspaceSchedulingFault;
import org.nimbustools.messaging.gt4_0.generated.types.WorkspaceContextualizationFault;

import java.rmi.RemoteException;

/**
* See Action class notes for general usage information.
*
* See Workspace for notes on what will be populated for you after creation
*
* @see org.globus.workspace.client_core.Action
*
* @see WSAction_Factory
*
* @see Workspace
*
*/
public class Create extends WSAction_Factory {

   
    // -------------------------------------------------------------------------
    // INSTANCE VARIABLES
    // -------------------------------------------------------------------------

    protected VirtualWorkspace_Type vw;

    protected WorkspaceDeployment_Type req;

    protected OptionalParameters_Type opts;

    protected EndpointReferenceType joinEnsembleEPR;
    protected EndpointReferenceType joinContextEPR;

    protected boolean createEnsemble;
    protected boolean createContext;

    protected boolean lastInEnsemble;
    protected boolean lastInContext;

    // internal use

    protected boolean expectEnsembleEPR;
    protected boolean expectContextEPR;


    // -------------------------------------------------------------------------
    // CONSTRUCTORS
    // -------------------------------------------------------------------------

    /**
     * @see WSAction_Factory
     */
    public Create(StubConfigurator stubConf,
                  Print debug) {
        super(stubConf, debug);
    }

    /**
     * @see WSAction_Factory
     */
    public Create(EndpointReferenceType epr,
                  StubConfigurator stubConf,
                  Print debug) {
        super(epr, stubConf, debug);
    }

    /**
     * @see WSAction_Factory
     */
    public Create(WorkspaceFactoryPortType factoryPortType,
                  Print debug) {
        super(factoryPortType, debug);
    }

    // -------------------------------------------------------------------------
    // GET/SET OPTIONS
    // -------------------------------------------------------------------------

    /**
     * @return vw to create
     */
    public VirtualWorkspace_Type getVw() {
        return this.vw;
    }

    /**
     * Set vw to create.
     *
     * @param workspace vw to create
     */
    public void setVw(VirtualWorkspace_Type workspace) {
        this.vw = workspace;
    }

    /**
     * @return deployment request in use
     */
    public WorkspaceDeployment_Type getReq() {
        return this.req;
    }

    /**
     * Set deployment request
     *
     * @param deploymentRequest deployment request
     */
    public void setReq(WorkspaceDeployment_Type deploymentRequest) {
        this.req = deploymentRequest;
    }

    /**
     * @return Optional Parameters in use or null
     */
    public OptionalParameters_Type getOpts() {
        return this.opts;
    }

    /**
     * Not required.
     *
     * May be null to override previous setting (default is null).
     *
     * @param optional optional parameters
     */
    public void setOptionalParameters(OptionalParameters_Type optional) {
        this.opts = optional;
    }

    /**
     * @return configured ensemble EPR or null
     */
    public EndpointReferenceType getJoinEnsembleEPR() {
        return this.joinEnsembleEPR;
    }

    /**
     * @return configured context EPR or null
     */
    public EndpointReferenceType getJoinContextEPR() {
        return this.joinContextEPR;
    }

    /**
     * @param epr ensemble EPR to join, may be null to override previous setting
     */
    public void setJoinEnsembleEPR(EndpointReferenceType epr) {
        this.joinEnsembleEPR = epr;
    }

    /**
     * @param epr context EPR to join, may be null to override previous setting
     */
    public void setJoinContextEPR(EndpointReferenceType epr) {
        this.joinContextEPR = epr;
    }

    /**
     * @return true if setCreateEnsemble(true)
     * @see #setCreateEnsemble(boolean)
     */
    public boolean isCreateEnsemble() {
        return this.createEnsemble;
    }

    /**
     * @return true if setCreateContext(true)
     * @see #setCreateContext(boolean)
     */
    public boolean isCreateContext() {
        return this.createContext;
    }

    /**
     * @param create true if the workspace creation request should trigger
     *               an ensemble creation
     */
    public void setCreateEnsemble(boolean create) {
        this.createEnsemble = create;
    }

    /**
     * @param create true if the workspace creation request should trigger
     *               a context creation
     */
    public void setCreateContext(boolean create) {
        this.createContext = create;
    }

    /**
     * @return true if setLastInEnsemble(true)
     * @see #setLastInEnsemble(boolean)
     */
    public boolean isLastInEnsemble() {
        return this.lastInEnsemble;
    }

    /**
     * @return true if setLastInContext(true)
     * @see #setLastInContext(boolean)
     */
    public boolean isLastInContext() {
        return this.lastInContext;
    }

    /**
     * Last-in-ensemble is a creation flag that triggers an "ensemble done"
     * operation after this workspace is created (it's all only one WS operation)
     *
     * Ensemble EPR must also be set if this is true.
     *
     * @param last true if the workspace creation request should trigger
     *             an "ensemble done" operation afterwards
     * @see #setJoinEnsembleEPR(EndpointReferenceType)
     */
    public void setLastInEnsemble(boolean last) {
        this.lastInEnsemble = last;
    }

    /**
     * Last-in-context is a creation flag that triggers a "context lock"
     * operation after this workspace is created (it's all only one WS operation)
     *
     * @param last true if the workspace creation request should trigger
     *             a "context lock" operation afterwards
     * @see #setJoinContextEPR(EndpointReferenceType)
     */
    public void setLastInContext(boolean last) {
        this.lastInContext = last;
    }
   

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

    /**
     * @throws ParameterProblem issue that will stop creation attempt
     */
    public void validateAll() throws ParameterProblem {
        super.validateAll();
        this.validateMetadata();
        this.validateDeploymentRequest();
        this.validateOptionalParameters();
        this.validateEnsembleRelated();
        this.validateContextRelated();
    }

    /**
     * @throws ParameterProblem issue that will stop creation attempt
     */
    public void validateMetadata() throws ParameterProblem {

        if (this.vw == null) {
            throw new ParameterProblem("no metadata is configured");
        }

        if (this.vw.getDefinition() == null) {
            throw new ParameterProblem("no definition in given metadata");
        }

        if (this.vw.getLogistics() == null) {
            throw new ParameterProblem("no logistics in given metadata");
        }

        if (this.vw.getName() == null) {
            // TODO: debug print this
            final URI name;
            try {
                name = new URI("http://no-name");
            } catch (URI.MalformedURIException e) {
                throw new ParameterProblem(
                        "default name problem: " + e.getMessage(), e);
            }
            this.vw.setName(name);
        }

        // do nothing else as of now, could get into pre-validating what
        // factory would semantically reject
    }

    /**
     * NodeNumber may not be uninitialized.
     *
     * Create will only accept requests with NodeNumber == 1
     * CreateGroup will only accept requests with NodeNumber > 1
     *
     * @see Create_Group#validateDeploymentRequestNodeNumber()
     *
     * @throws ParameterProblem issue that will stop creation attempt
     */
    public void validateDeploymentRequest() throws ParameterProblem {
        this.validateDeploymentRequestNodeNumber();
        this.validateDeploymentRequestCommon();
    }
   
    protected void validateDeploymentRequestCommon() throws ParameterProblem {

        if (this.req == null) {
            throw new ParameterProblem("no deployment request is configured");
        }

        this.validateDeploymentRequestNodeNumber();

        final ResourceAllocation_Type ra = this.req.getResourceAllocation();
        if (ra == null) {
            throw new ParameterProblem("ResourceAllocation is not present");
        }

        final RangeValue_Type rvt =
                this.req.getResourceAllocation().getIndividualPhysicalMemory();
        if (rvt == null) {
            throw new ParameterProblem(
                    "memory specification is not present");
        }
        final GenericIntRange exact = new GenericIntRange(rvt);
        if (exact.getMin() != exact.getMax()) {
            throw new ParameterProblem(
                    "memory range requests aren't supported right now");
        }

        if (this.req.getInitialState() != null) {
            final State testing =
                    State.fromInitialState_Type(this.req.getInitialState());
            if (testing == null) {
                throw new ParameterProblem(
                    "initial state in deployment request is unrecognized?");
            }
        }

        final DeploymentTime_Type time = this.req.getDeploymentTime();
        if (time == null) {
            throw new ParameterProblem("no DeploymentTime_Type in request?");
        }

        final Duration minDuration = time.getMinDuration();
        if (minDuration == null) {
            throw new ParameterProblem("no minDuration in request?");
        }

        try {
            if (CommonUtil.durationToSeconds(minDuration) < 1) {
                throw new ParameterProblem(
                        "minDuration in request is less than 1 second?");
            }
        } catch (InvalidDurationException e) {
            throw new ParameterProblem(
                        "minDuration is invalid: " + e.getMessage(), e);
        }
    }

    /**
     * Will only accept requests with NodeNumber == 1
     *
     * @throws ParameterProblem issue that will stop creation attempt
     */
    protected void validateDeploymentRequestNodeNumber()
            throws ParameterProblem {

        final int nodeNum = (int) this.req.getNodeNumber();
        if (nodeNum != 1) {
            throw new ParameterProblem(
                    "this class does not support group requests, " +
                            "deployment request is asking for " + nodeNum);
        }
    }

    /**
     * @throws ParameterProblem issue that will stop creation attempt
     */
    public void validateOptionalParameters() throws ParameterProblem {
        // do nothing as of now, could get into pre-validating what
        // factory would semantically reject
    }

    /**
     * @throws ParameterProblem issue that will stop creation attempt
     */
    public void validateEnsembleRelated() throws ParameterProblem {

        if (this.joinEnsembleEPR != null && this.createEnsemble) {

            throw new ParameterProblem("\"create ensemble\" flag may not be " +
                    "set at the same time as a \"join ensemble\" EPR, that " +
                    "request would not make any sense");

        } else if (this.createEnsemble && this.lastInEnsemble) {

            throw new ParameterProblem("\"create ensemble\" flag may not be " +
                    "set at the same time as the \"last in ensemble\" flag, " +
                    "that request would not make any sense");
        }
    }

    /**
     * @throws ParameterProblem issue that will stop creation attempt
     */
    public void validateContextRelated() throws ParameterProblem {

        if (this.joinContextEPR != null && this.createContext) {

            throw new ParameterProblem("\"create context\" flag may not be " +
                    "set at the same time as a \"join context\" EPR, that " +
                    "request would not make any sense");

        }
    }



    // -------------------------------------------------------------------------
    // EXECUTE
    // -------------------------------------------------------------------------

    protected Object action() throws Exception {
        return this.create();
    }

    /**
     * Create one workspace.
     *
     * @return Workspace
     * @throws ParameterProblem validation problem
     * @throws ExecutionProblem general problem running (connection errors etc)
     * @throws WorkspaceResourceRequestDeniedFault request can not be fulfilled
     *         because of either lack of current resources or the credential
     *         is not authorized to get requested resources (this includes
     *         less familiar limited resources such as public IP addresses)
     * @throws WorkspaceSchedulingFault issue scheduling the request
     * @throws WorkspaceMetadataFault invalid metadata
     * @throws WorkspaceEnsembleFault problem with ensemble service interaction
     * @throws WorkspaceContextualizationFault problem from context broker
     * @throws WorkspaceCreationFault uncategorized factory request issue
     */
    public Workspace create() throws ParameterProblem,
                                     ExecutionProblem,
                                     WorkspaceResourceRequestDeniedFault,
                                     WorkspaceSchedulingFault,
                                     WorkspaceMetadataFault,
                                     WorkspaceEnsembleFault,
                                     WorkspaceContextualizationFault,
                                     WorkspaceCreationFault {
       
        this.validateAll();
        final WorkspaceCreateResponse_Type response = this.createImpl();
        return this.handleInstanceCreation(response);
    }

    protected Workspace handleInstanceCreation(
                            WorkspaceCreateResponse_Type response)

            throws ExecutionProblem {


        final Workspace workspace = new Workspace();

        // these things are not based on any information returned
        try {
            this.populateInitialRepr(workspace);
        } catch (ParameterProblem e) {
            throw new ExecutionProblem(
                        "unexpected problem: " + e.getMessage(), e);
        }

        // length/not-null already checked
        final CreatedWorkspace_Type[] allrefs = response.getCreatedWorkspace();

        final Schedule_Type xmlSchedule = allrefs[0].getSchedule();
        if (xmlSchedule == null) {
            throw new ExecutionProblem(
                    "(?) no schedule in factory response");
        }

        final VirtualNetwork_Type xmlNetwork = allrefs[0].getNetworking();
        if (xmlNetwork != null) {
            workspace.setCurrentNetworking(new Networking(xmlNetwork));
        }

        workspace.setEpr(allrefs[0].getEpr());

        try {
            workspace.setInitialSchedule(new Schedule(xmlSchedule));
            // this is intentionally a separate object:
            workspace.setCurrentSchedule(new Schedule(xmlSchedule));
        } catch (InvalidDurationException e) {
            throw new ExecutionProblem(
                    "(?) invalid data in factory response: " +
                            e.getMessage(), e);
        }

        final EndpointReferenceType ensembleEPR = response.getEnsembleEPR();
        if (ensembleEPR != null) {
            workspace.setEnsembleMemberEPR(ensembleEPR);
        }

        final EndpointReferenceType contextEPR = response.getContextEPR();
        if (contextEPR != null) {
            workspace.setContextMemberEPR(contextEPR);
        }

        return workspace;
    }

    protected WorkspaceCreateResponse_Type createImpl()

                              throws WorkspaceCreationFault,
                                     WorkspaceResourceRequestDeniedFault,
                                     WorkspaceSchedulingFault,
                                     WorkspaceMetadataFault,
                                     WorkspaceEnsembleFault,
                                     WorkspaceContextualizationFault,
                                     ExecutionProblem {

        final WorkspaceCreateRequest_Type createRequest =
                                            new WorkspaceCreateRequest_Type();

        this.populateCreateRequest(createRequest);

        /* CREATE */

        final WorkspaceCreateResponse_Type response;
        try {
            response = ((WorkspaceFactoryPortType)this.portType).
                                                        create(createRequest);
        } catch (WorkspaceCreationFault e) {
            throw e;
        } catch (WorkspaceResourceRequestDeniedFault e) {
            throw e;
        } catch (WorkspaceSchedulingFault e) {
            throw e;
        } catch (WorkspaceMetadataFault e) {
            throw e;
        } catch (WorkspaceEnsembleFault e) {
            throw e;
        } catch (WorkspaceContextualizationFault e) {
            throw e;
        } catch (RemoteException e) {
            throw RMIUtils.generalRemoteException(e);
        }

        /* CHECK GENERAL ASSUMPTIONS */

        // the "(?)" symbol is a shorthand for "very unexpected"...

        if (response == null) {
            throw new ExecutionProblem("(?) null response");
        }

        final CreatedWorkspace_Type[] allrefs = response.getCreatedWorkspace();
        if (allrefs == null) {
            throw new ExecutionProblem(
                    "(?) null references in factory response");
        }

        /* CHECK NODE-NUMBER RELATED ASSUMPTIONS */

        final int expectedNodeNum =
                createRequest.getResourceRequest().getNodeNumber();

        if (expectedNodeNum == 1) {
            if (response.getGroupEPR() != null) {
                throw new ExecutionProblem("(?) group EPR assigned but " +
                        "this was not a group request");
            }
        } else {
            if (response.getGroupEPR() == null) {
                throw new ExecutionProblem("(?) group EPR was not assigned " +
                        "but this was a group request");
            }
        }

        if (allrefs.length != expectedNodeNum) {
            throw new ExecutionProblem("(?) expecting " + expectedNodeNum +
                  "CreatedWorkspace reference(s), received " + allrefs.length);
        }


        /* CHECK ENSEMBLE RELATED ASSUMPTIONS */

        final EndpointReferenceType ensembleEPR = response.getEnsembleEPR();

        if (this.expectEnsembleEPR && ensembleEPR == null) {
            throw new ExecutionProblem("(?) requested ensemble " +
                    "participation but no ensemble EPR was assigned");
        }

        if (!this.expectEnsembleEPR && ensembleEPR != null) {
            throw new ExecutionProblem("(?) ensemble EPR assigned but " +
                    "no request was made for ensemble participation");
        }

        /* CHECK CONTEXT RELATED ASSUMPTIONS */

        final EndpointReferenceType contextEPR = response.getContextEPR();

        if (this.expectContextEPR && contextEPR == null) {
            throw new ExecutionProblem("(?) requested context " +
                    "participation but no context EPR was assigned");
        }

        if (!this.expectContextEPR && contextEPR != null) {
            throw new ExecutionProblem("(?) context EPR assigned but " +
                    "no request was made for context participation");
        }

        return response;
    }

    /**
     * Validated already.  API caller can still cause problems if using
     * multiple thread writers and no locks etc.
     *
     * @param createReq createReq
     */
    protected void populateCreateRequest(WorkspaceCreateRequest_Type createReq) {

        createReq.setMetadata(this.vw);

        createReq.setResourceRequest(this.req);

        if (this.opts != null) {
            createReq.setOptionalParameters(this.opts);
        }

        this.expectEnsembleEPR = false;

        if (this.createEnsemble) {
            createReq.setPartOfEnsemble(Boolean.TRUE);
            createReq.setEnsembleEPR(null);
            this.expectEnsembleEPR = true;
        } else if (this.joinEnsembleEPR != null) {
            createReq.setPartOfEnsemble(Boolean.TRUE);
            createReq.setEnsembleEPR(this.joinEnsembleEPR);
            this.expectEnsembleEPR = true;
        }

        if (this.lastInEnsemble) {
            createReq.setEnsembleDone(Boolean.TRUE);
        }

        this.expectContextEPR = false;

        if (this.createContext) {
            createReq.setContextEPR(null);
            this.expectContextEPR = true;
        } else if (this.joinContextEPR != null) {
            createReq.setContextEPR(this.joinContextEPR);
            this.expectContextEPR = true;
        }

        if (this.lastInContext) {
            createReq.setLockContext(Boolean.TRUE);
        }
       
    }

    /**
     * <p>Populate one workspace representation with as much data as possible
     * without using create's response object (using this class' instance
     * data).</p>
     *
     * <p>This can be called multiple times, all pointers going into the
     * workspace argument are to new, unique objects.  For example, this can
     * be used by CreateGroup to populate many workspace with unique state
     * objects (that can then diverge).</p>
     *
     * <p>Contents going into new Workspace representation are validated
     * already.  Although you can still cause problems if using multiple
     * thread writers and no locks etc., as noted in Action class notes.</p>
     *
     * @param workspace workspace
     * @throws ParameterProblem validation problem, implies race condition
     *         with multiple threads unsafely using this object
     *
     */
    protected void populateInitialRepr(Workspace workspace)
            throws ParameterProblem {

        workspace.setUriName(this.vw.getName().toString());

        final VirtualNetwork_Type net = this.vw.getLogistics().getNetworking();
        if (net != null) {
            workspace.setRequestedNetworking(new Networking(net));
        }

        final ResourceAllocation_Type ra = this.req.getResourceAllocation();
        if (ra == null) {
            throw new ParameterProblem("(?) no ResourceAllocation_Type");
        }

        workspace.setRequestedResourceAllocation(new ResourceAllocation(ra));
        // this is intentionally a separate object:
        workspace.setCurrentResourceAllocation(new ResourceAllocation(ra));

        boolean trash = false;

        if (this.req.getShutdownMechanism() != null
            && this.req.getShutdownMechanism().equals(
                ShutdownMechanism_Type.Trash)) {

            trash = true;
        }
        final ShutdownMech mech = new ShutdownMech(trash);
        workspace.setRequestedShutdownMech(mech);

        if (this.req.getInitialState() == null) {
            workspace.setRequestedInitialState(State.DEFAULT_INITIAL_STATE);
        } else {
            final State initialState =
                    State.fromInitialState_Type(this.req.getInitialState());

            workspace.setRequestedInitialState(initialState);
        }

        // this might be incorrect information already, but it is the initial
        // state of all workspaces
        workspace.setCurrentState(new State(State.STATE_Unstaged));

        try {
            final DeploymentTime_Type time = this.req.getDeploymentTime();
            final int seconds =
                    CommonUtil.durationToSeconds(time.getMinDuration());
            final Schedule schedule = new Schedule();
            schedule.setDurationSeconds(seconds);
            workspace.setRequestedSchedule(schedule);
        } catch (NullPointerException e) {
            throw new ParameterProblem(e.getMessage(), e);
        } catch (InvalidDurationException e) {
            throw new ParameterProblem(e.getMessage(), e);
        }
    }
}
TOP

Related Classes of org.globus.workspace.client_core.actions.Create

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.