org.cloudifysource.dsl.context.utils.VolumeUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.cloudifysource.dsl.context.utils.VolumeUtils.java

Source

/*******************************************************************************
 * Copyright (c) 2012 GigaSpaces Technologies Ltd. All rights reserved
 *
 * 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.cloudifysource.dsl.context.utils;

import com.gigaspaces.internal.sigar.SigarHolder;
import org.apache.commons.exec.*;
import org.apache.commons.lang.StringUtils;
import org.cloudifysource.dsl.context.blockstorage.LocalStorageOperationException;
import org.cloudifysource.dsl.context.blockstorage.StorageFacade;
import org.hyperic.sigar.FileSystem;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;

/**
 * 
 * @author elip
 *
 */
public final class VolumeUtils {

    // prevent instantiation.
    private VolumeUtils() {

    }

    private static final Logger logger = Logger.getLogger(VolumeUtils.class.getName());

    private static final String USER_NAME = System.getProperty("user.name");

    private static final long MOUNT_TIMEOUT = 30 * 1000;
    private static final long FORMAT_TIMEOUT = 5 * 60 * 1000;
    private static final long UNMOUNT_TIMEOUT = 15 * 1000;

    private static final long TEN_SECONDS = 10 * 1000;

    /**
     * @see {@link StorageFacade#unmount(String, long)}.
     * @param device .
     * @param timeoutInMillis .
     * @throws LocalStorageOperationException .
     * @throws TimeoutException .
     */
    public static void unmount(final String device, final long timeoutInMillis)
            throws LocalStorageOperationException, TimeoutException {
        executeCommandLine("sudo umount -d -v -l -f " + device, timeoutInMillis);
    }

    /**
     * @see {@link StorageFacade#unmount(String)}
     * @param device . 
     * @throws LocalStorageOperationException .
     * @throws TimeoutException .
     */
    public static void unmount(final String device) throws LocalStorageOperationException, TimeoutException {
        unmount(device, UNMOUNT_TIMEOUT);
    }

    /**
     * @see {@link StorageFacade#mount(String, String, long)}
     * @param device .
     * @param path .
     * @param timeoutInMillis .
     * @throws LocalStorageOperationException .
     * @throws TimeoutException .
     */
    public static void mount(final String device, final String path, final long timeoutInMillis)
            throws LocalStorageOperationException, TimeoutException {
        File devicePath = new File(path);
        executeCommandLine("sudo mkdir " + path, TEN_SECONDS);
        executeCommandLine("sudo mount " + device + " " + path, timeoutInMillis);
        executeCommandLine("sudo chown " + USER_NAME + " " + devicePath.getAbsolutePath(), TEN_SECONDS);
    }

    /**
     * @see {@link StorageFacade#mount(String, String)}
     * @param device .
     * @param path .
     * @throws LocalStorageOperationException .
     * @throws TimeoutException .
     */
    public static void mount(final String device, final String path)
            throws LocalStorageOperationException, TimeoutException {
        mount(device, path, MOUNT_TIMEOUT);
    }

    /**
     * @see {@link StorageFacade#format(String, String, long)}
     * @param device . 
     * @param fileSystem .
     * @param timeoutInMillis .
     * @throws LocalStorageOperationException .
     * @throws TimeoutException .
     */
    public static void format(final String device, final String fileSystem, final long timeoutInMillis)
            throws LocalStorageOperationException, TimeoutException {
        checkFileSystemSupported(fileSystem);
        executeCommandLine("sudo mkfs -F -t " + fileSystem + " " + device, timeoutInMillis);
    }

    /**
     * @see {@link StorageFacade#format(String, String)}.
     * @param device .
     * @param fileSystem .
     * @throws LocalStorageOperationException .
     * @throws TimeoutException .
     */
    public static void format(final String device, final String fileSystem)
            throws LocalStorageOperationException, TimeoutException {
        format(device, fileSystem, FORMAT_TIMEOUT);
    }

    private static void checkFileSystemSupported(final String fileSystem) throws LocalStorageOperationException {

        FileSystem[] fileSystemList;
        try {
            Sigar sigar = SigarHolder.getSigar();
            fileSystemList = sigar.getFileSystemList();
        } catch (final SigarException e) {
            throw new LocalStorageOperationException(e);
        }

        List<String> supportedFileSystems = new ArrayList<String>();
        for (FileSystem fs : fileSystemList) {
            if (fileSystem.equalsIgnoreCase(fs.getSysTypeName())) {
                return;
            } else {
                supportedFileSystems.add(fs.getSysTypeName());
            }
        }
        throw new LocalStorageOperationException("File system type " + fileSystem
                + " is not supported for the current operating system. Supported File Systems are : "
                + StringUtils.join(supportedFileSystems, ","));
    }

    private static void executeCommandLine(final String commandLine, final long timeout)
            throws LocalStorageOperationException, TimeoutException {

        Executor executor = new DefaultExecutor();
        executor.setExitValue(0);
        ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout);
        executor.setWatchdog(watchdog);
        ProcessOutputStream outAndErr = new ProcessOutputStream();
        try {
            PumpStreamHandler streamHandler = new PumpStreamHandler(outAndErr);
            executor.setStreamHandler(streamHandler);
            logger.info("Executing commandLine : '" + commandLine + "'");
            executor.execute(CommandLine.parse(commandLine));
            logger.info("Execution completed successfully. Process output was : " + outAndErr.getOutput());
        } catch (final Exception e) {
            if (watchdog.killedProcess()) {
                throw new TimeoutException("Timed out while executing commandLine : '" + commandLine + "'");
            }
            throw new LocalStorageOperationException("Failed executing commandLine : '" + commandLine
                    + ". Process output was : " + outAndErr.getOutput(), e);
        }
    }

    /**
     * Logs process output to the logger.
     * @author elip
     *
     */
    private static class ProcessOutputStream extends LogOutputStream {

        private List<String> output = new java.util.LinkedList<String>();

        private String getOutput() {
            return StringUtils.join(output, "\n");
        }

        @Override
        protected void processLine(final String line, final int level) {
            output.add(line);
            logger.info(line);
        }
    }
}