Package org.globus.workspace.service.binding.defaults

Source Code of org.globus.workspace.service.binding.defaults.DefaultBindCustomizations

/*
* 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.service.binding.defaults;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.globus.workspace.service.binding.vm.FileCopyNeed;
import org.nimbustools.api.repr.CustomizationRequest;
import org.nimbustools.api.services.rm.CreationException;
import org.nimbustools.api.services.rm.ResourceRequestDeniedException;
import org.globus.workspace.PathConfigs;
import org.globus.workspace.WorkspaceException;
import org.globus.workspace.service.binding.BindCustomizations;
import org.globus.workspace.service.binding.vm.VirtualMachine;
import org.safehaus.uuid.UUIDGenerator;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class DefaultBindCustomizations implements BindCustomizations {
   
    // -------------------------------------------------------------------------
    // STATIC VARIABLES
    // -------------------------------------------------------------------------
   
    private static final Log logger =
            LogFactory.getLog(DefaultBindCustomizations.class.getName());


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

    protected final PathConfigs paths;
    protected final UUIDGenerator uuidGen = UUIDGenerator.getInstance();

    // Paths are validated once as working.  If the values are changed after
    // that, the failures will be seen as FileNotFoundException etc. instead of
    // nice messages.  Changing values during deployment is not supported.
    protected boolean workingPathConfigs;
    protected String localDirPath;

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

    public DefaultBindCustomizations(PathConfigs paths) {
        if (paths == null) {
            throw new IllegalArgumentException("paths may not be null");
        }
        this.paths = paths;
    }
   

    // -------------------------------------------------------------------------
    // IoC INIT METHOD
    // -------------------------------------------------------------------------

    public synchronized void validate() throws Exception {
        if (!this.workingPathConfigs) {
            this.validatePaths();
            // see note at variable declaration, races not expected:
            this.workingPathConfigs = true;
        }

        if (this.localDirPath == null) {
            final String srcDir = this.paths.getLocalTempDirPath();
            final File srcDirFile = new File(srcDir);
            // using getPath() not getAbsolutePath() because the basePath does
            // not need to be absolute, just the right base path for the env.
            this.localDirPath = srcDirFile.getPath();
        }
    }
   
   

    // -------------------------------------------------------------------------
    // implements BindCustomizations
    // -------------------------------------------------------------------------

    public void consume(VirtualMachine vm,
                        CustomizationRequest[] reqs)
            throws CreationException, ResourceRequestDeniedException {

        if (reqs == null || reqs.length == 0) {
            return; // *** EARLY RETURN ***
        }

        try {
            this.validate();
            this.bindFileWrites(vm, reqs);
        } catch (Exception e) {
            throw new CreationException(e.getMessage(), e);
        }
    }

    public FileCopyNeed newFileCopyNeedImpl(String srcContent,
                                                      String dstPath)
            throws WorkspaceException {

        try {
            this.validate();
            return this.newNeed(srcContent, dstPath);
        } catch (Exception e) {
            throw new WorkspaceException(e.getMessage(), e);
        }
    }

   
    // -------------------------------------------------------------------------
    // VALIDATE-IMPL
    // -------------------------------------------------------------------------

    protected void validatePaths() throws Exception {

        final String srcDir = this.paths.getLocalTempDirPath();
        final String destDir = this.paths.getBackendTempDirPath();

        _validatePathsNull(srcDir, "localTempDirPath");
        _validatePathsNull(destDir, "backendTempDirPath");

        final File srcDirFile = new File(srcDir);
        _validatePathsExists(srcDirFile, "localTempDirPath", srcDir);
        _validatePathsDir(srcDirFile, "localTempDirPath", srcDir);

        // can't validate anything about backendTempDir, it's on another node
    }

    private static void _validatePathsNull(String path, String name)

            throws Exception {

        if (path == null) {
            throw new Exception("Customization needed but " + name +
                    " configuration is missing");
        }
    }

    private static void _validatePathsExists(File dir, String name, String value)

            throws Exception {

        if (!dir.exists()) {
            throw new Exception("Customization needed but " + name +
                    " configuration does not exist: '" + value + "'");
        }
    }

    private static void _validatePathsDir(File dir, String name, String value)

            throws Exception {

        if (!dir.isDirectory()) {
            throw new Exception("Customization needed but " + name +
                    " configuration is not for a directory: '" + value + "'");
        }
    }

   
    // -------------------------------------------------------------------------
    // CONSUME-IMPL
    // -------------------------------------------------------------------------

    protected void bindFileWrites(VirtualMachine vm,
                                  CustomizationRequest[] filewrites)
            throws Exception {

        for (int i = 0; i < filewrites.length; i++) {

            final String src = filewrites[i].getContent();
            final String dstPath = filewrites[i].getPathOnVM();
            vm.addFileCopyNeed(this.newNeed(src, dstPath));
        }

    }

    protected FileCopyNeed newNeed(String src,
                                        String dstPath) throws Exception {

        // already checked, this is for object extenders
        if (this.localDirPath == null) {
            throw new CreationException("cannot perform customization " +
                    "without local tmp directory");
        }

        final int maxContentLength = 40960; // embedded policy for now
       
        if (src == null) {
                throw new Exception("customize content may not be missing");
        }
        if (dstPath == null) {
            throw new Exception("customize path-on-VM may not be missing");
        }

        if (src.length() > maxContentLength) {
            logger.error(
                    "customize source string too long: " + src.length());
            final String err = "customization task source string is too long";
            throw new Exception(err);
        }

        final String srcPath = this.newSrcPath();

        final FileCopyNeed need;
        try {
            need = new FileCopyNeed(srcPath, dstPath);
        } catch (Exception e) {
            if (logger.isDebugEnabled()) {
                logger.error(e.getMessage(), e);
            } else {
                logger.error(e.getMessage());
            }
            final String err = "customization task request is invalid " +
                    "(the one with given destination path: '" + dstPath + "')";
            throw new Exception(err);
        }

        final File f = new File(this.localDirPath, srcPath);

        FileWriter fw = null;
        try {
            fw = new FileWriter(f);
            fw.write(src);
            fw.flush();
        } catch (IOException e) {
            if (logger.isDebugEnabled()) {
                logger.error(e.getMessage(), e);
            } else {
                logger.error(e.getMessage());
            }
            final String err =
                    "customization task failed unexpectedly: " + e.getMessage();
            throw new Exception(err);
        } finally {
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Successfully added customization task. " +
                    "srcPath = '" + srcPath +
                    "', dstPath = '" + dstPath + "'");
        }

        return need;
    }

    protected String newSrcPath() throws Exception {

        // already checked, this is for object extenders
        if (this.localDirPath == null) {
            throw new Exception("cannot perform customization " +
                    "without local tmp directory");
        }

        final String uuid = this.uuidGen.generateRandomBasedUUID().toString();

        if (uuid.length() != 36) {
            final String err = "customization task failed unexpectedly: UUID " +
                    "is not 36 characters?";
            throw new Exception(err);
        }

        final String srcPath = uuid.substring(0,23);

        final File f = new File(this.localDirPath, srcPath);

        // highly unlikely:
        if (f.exists()) {
            final String uuid2 =
                    this.uuidGen.generateRandomBasedUUID().toString();

            if (uuid2.length() != 36) {
                final String err = "customization task failed unexpectedly: UUID " +
                    "is not 36 characters?";
                throw new Exception(err);
            }
            final String srcPath2 = uuid2.substring(0,23);

            final File f2 = new File(this.localDirPath, srcPath2);

            // highly unlikely:
            if (f2.exists()) {
                final String err = "customization task failed unexpectedly: " +
                        "cannot obtain unique task name";
                throw new Exception(err);
            } else {
                return srcPath2;
            }
        } else {
            return srcPath;
        }
    }
}
TOP

Related Classes of org.globus.workspace.service.binding.defaults.DefaultBindCustomizations

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.