diff --git a/common/source/java/ch/systemsx/cisd/common/highwatermark/AlwaysAboveFreeSpaceProvider.java b/common/source/java/ch/systemsx/cisd/common/highwatermark/AlwaysAboveFreeSpaceProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..6e455aa6902c28738ddfcea96dd90ff32e5c4d73 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/highwatermark/AlwaysAboveFreeSpaceProvider.java @@ -0,0 +1,53 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * 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 ch.systemsx.cisd.common.highwatermark; + +import java.io.File; +import java.io.IOException; + +import ch.systemsx.cisd.common.highwatermark.HighwaterMarkWatcher.IFreeSpaceProvider; + +/** + * An <code>IFreeSpaceProvider</code> implementation which returns {@link Long#MAX_VALUE} as free + * space value. + * <p> + * Therefore the free space available will never be below the <i>high water mark</i>. + * </p> + * + * @author Christian Ribeaud + */ +public final class AlwaysAboveFreeSpaceProvider implements IFreeSpaceProvider +{ + + /** The only instance of this class. */ + public final static IFreeSpaceProvider INSTANCE = new AlwaysAboveFreeSpaceProvider(); + + private AlwaysAboveFreeSpaceProvider() + { + // Can not be instantiated. + } + + // + // IFreeSpaceProvider + // + + public final long freeSpaceKb(final File path) throws IOException + { + return Long.MAX_VALUE; + } + +} diff --git a/common/source/java/ch/systemsx/cisd/common/highwatermark/RemoteFreeSpaceProvider.java b/common/source/java/ch/systemsx/cisd/common/highwatermark/RemoteFreeSpaceProvider.java index 151537cb6d5c99ae3fdce9572dcbb9e540c5ec20..c9aa4bdcf4b182aef1472790b0071b90feed4573 100644 --- a/common/source/java/ch/systemsx/cisd/common/highwatermark/RemoteFreeSpaceProvider.java +++ b/common/source/java/ch/systemsx/cisd/common/highwatermark/RemoteFreeSpaceProvider.java @@ -21,9 +21,13 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.time.DateUtils; import org.apache.log4j.Logger; import ch.systemsx.cisd.common.highwatermark.HighwaterMarkWatcher.IFreeSpaceProvider; +import ch.systemsx.cisd.common.logging.LogCategory; +import ch.systemsx.cisd.common.logging.LogFactory; import ch.systemsx.cisd.common.process.ProcessExecutionHelper; import ch.systemsx.cisd.common.process.ProcessResult; @@ -35,29 +39,77 @@ import ch.systemsx.cisd.common.process.ProcessResult; */ public final class RemoteFreeSpaceProvider implements IFreeSpaceProvider { + private static final String DF_COMMAND_TEMPLATE = "df -k %s"; + + private static final Logger machineLog = + LogFactory.getLogger(LogCategory.MACHINE, RemoteFreeSpaceProvider.class); + + private static final Logger operationLog = + LogFactory.getLogger(LogCategory.OPERATION, RemoteFreeSpaceProvider.class); + + private static final long MILLIS_TO_WAIT_FOR_COMPLETION = 2 * DateUtils.MILLIS_PER_SECOND; + private final File sshExecutable; private final String host; + private final long millisToWaitForCompletion = MILLIS_TO_WAIT_FOR_COMPLETION; + public RemoteFreeSpaceProvider(final String host, final File sshExecutable) { + assert host != null : "Unspecified host"; + assert sshExecutable != null : "Unspecified ssh executable"; this.host = host; this.sshExecutable = sshExecutable; } + private final static long parseKbytes(final String freeSpaceInKb, final String dfCommand) + throws IOException + { + try + { + final long kBytes = Long.parseLong(freeSpaceInKb); + if (kBytes < 0) + { + throw new IOException(String.format( + "Command line '%s' did not find free space in response.", dfCommand)); + } + return kBytes; + } catch (final NumberFormatException ex) + { + throw new IOException(String.format( + "Command line '%s' did not return numeric data as expected.", dfCommand)); + } + } + // // IFreeSpaceProvider // - public final long freeSpaceKb(final File path) throws IOException + public final long freeSpaceKb(final File file) throws IOException { - final List<String> command = - Arrays.asList(sshExecutable.getPath(), host, "df -k " + path.getPath() + ""); - Logger rootLogger = Logger.getRootLogger(); - System.out.println(command); + assert file != null : "Unspecified remote file."; + final String path = file.getPath(); + assert StringUtils.isNotEmpty(path) : "Empty path."; + final String dfCommand = String.format(DF_COMMAND_TEMPLATE, path); + final List<String> command = Arrays.asList(sshExecutable.getPath(), host, dfCommand); final ProcessResult processResult = - ProcessExecutionHelper.run(command, 2000L, rootLogger, rootLogger); - System.out.println(processResult.getProcessOutput()); - return 0L; + ProcessExecutionHelper.run(command, millisToWaitForCompletion, operationLog, + machineLog); + processResult.log(); + final List<String> processOutput = processResult.getProcessOutput(); + if (processOutput.size() >= 2) + { + final String output = processOutput.get(1); + final String[] split = StringUtils.split(output, ' '); + if (split.length >= 4) + { + // The column 'avail' (3th column) interests us. + return parseKbytes(split[3], dfCommand); + } + } + throw new IOException(String.format( + "Command line '%s' did not return info as expected. Response was '%s'", dfCommand, + processOutput)); } } \ No newline at end of file diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/highwatermark/RemoteFreeSpaceProviderTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/highwatermark/RemoteFreeSpaceProviderTest.java index 91081ae427c7542ca161634cbf9f929fdf0da293..2511ec873d78fba3920319cc37299b9e9b37b0ee 100644 --- a/common/sourceTest/java/ch/systemsx/cisd/common/highwatermark/RemoteFreeSpaceProviderTest.java +++ b/common/sourceTest/java/ch/systemsx/cisd/common/highwatermark/RemoteFreeSpaceProviderTest.java @@ -23,7 +23,6 @@ import java.io.IOException; import org.testng.annotations.Test; -import ch.systemsx.cisd.common.highwatermark.RemoteFreeSpaceProvider; import ch.systemsx.cisd.common.utilities.OSUtilities; /**