/** * Abiquo community edition * cloud management application for hybrid clouds * Copyright (C) 2008-2010 - Abiquo Holdings S.L. * * This application is free software; you can redistribute it and/or * modify it under the terms of the GNU LESSER GENERAL PUBLIC * LICENSE as published by the Free Software Foundation under * version 3 of the License * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * LESSER GENERAL PUBLIC LICENSE v.3 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package com.abiquo.am.services.filesystem; import static com.abiquo.appliancemanager.config.AMConfiguration.ENTERPRISE_REPOSITORY_REFRESH_TIMEOUT; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.abiquo.am.exceptions.AMError; import com.abiquo.appliancemanager.config.AMConfiguration; import com.abiquo.appliancemanager.exceptions.AMException; import com.abiquo.appliancemanager.transport.TemplateStateDto; public class EnterpriseRepositoryFileSystem { private final static Logger LOG = LoggerFactory.getLogger(EnterpriseRepositoryFileSystem.class); private final static String BASE_REPO_PATH = AMConfiguration.getRepositoryPath(); /** * Check if it exist or create it. */ public static void validateEnterpirseRepositoryPathFile(final String enterpriseRepositoryPath) { File enterpriseRepositoryFile = new File(enterpriseRepositoryPath); if (!enterpriseRepositoryFile.exists()) { if (!enterpriseRepositoryFile.mkdirs()) { throw new AMException(AMError.REPO_NOT_ACCESSIBLE, enterpriseRepositoryPath); } } if (!(enterpriseRepositoryFile.exists() && enterpriseRepositoryFile.canWrite() && enterpriseRepositoryFile .isDirectory())) { throw new AMException(AMError.REPO_NOT_ACCESSIBLE, enterpriseRepositoryPath); } } public static List<TemplateStateDto> getAllOVF(final String enterpriseRepositoryPath, final boolean includeBundeles) { List<TemplateStateDto> availableOvs = null; // TODO consider global thread limit final ExecutorService executor = Executors.newSingleThreadExecutor(); final Future<List<TemplateStateDto>> futureAvailable = executor.submit(new EnterpriseRepositoryRefreshWithTimeout(// new File(enterpriseRepositoryPath).getAbsolutePath(), new String(), includeBundeles, false)); // do not clean downloading packages try { availableOvs = futureAvailable.get(ENTERPRISE_REPOSITORY_REFRESH_TIMEOUT, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { futureAvailable.cancel(true); LOG.warn("Timeout while refresh the repository folder " + enterpriseRepositoryPath, e); } catch (Exception e) { LOG.error("Can't access the folder " + enterpriseRepositoryPath, e); } finally { executor.shutdownNow(); } if (availableOvs == null) { throw new AMException(AMError.REPO_TIMEOUT_REFRESH, enterpriseRepositoryPath); } return availableOvs; } /***/ /** ############### REPOSITORY USAGE ############### */ public static boolean isEnoughtSpaceOn(final String enterpriseRepositoryPath, final Long expected) { return new File(enterpriseRepositoryPath).getFreeSpace() > expected; } public static Long getUsedMb(final String enterpriseRepositoryPath) { return sizeOfDirectory(new File(enterpriseRepositoryPath)) / (1024 * 1024); } public static Long getCapacityMb() { return new File(BASE_REPO_PATH).getTotalSpace() / (1024 * 1024); } public static Long getFreeMb() { return new File(BASE_REPO_PATH).getFreeSpace() / (1024 * 1024); } private static Long sizeOfDirectory(final File f) { if (f.isFile()) { return f.length(); } else if (f.isDirectory() && f.listFiles().length != 0) { Long acum = 0l; for (File element : f.listFiles()) { acum += sizeOfDirectory(element); } return acum; } else { return 0l; } } /** ############### DOWNLOADING FILE ############### */ /** * A prefix to add at ''destinationPath'' to indicate the file is being download (see * ''takeFile'' and ''releaseFile''). */ private final static String FILE_MARK = ".download"; /** * Check the target file is not being download by another package. * * @return null if the destination file is being download by another package. * @throws FileNotFoundException */ public static BufferedOutputStream takeFile(final String destinationPath) { File destination = new File(destinationPath); File destinationMark = new File(destinationPath + FILE_MARK); if (destination.exists()) { if (destinationMark.exists()) { throw new AMException(AMError.TEMPLATE_INSTALL_ALREADY, destinationPath); } } try { File parent = destinationMark.getParentFile(); if (!parent.exists()) { if (!parent.mkdirs()) { LOG.error("Can't create file folder at " + parent.getAbsolutePath()); } } destinationMark.createNewFile(); } catch (IOException e) { LOG.error(String.format("Can't create the destination mark for [%s]", destinationPath)); e.printStackTrace(); } try { return new BufferedOutputStream(new FileOutputStream(destination)); } catch (FileNotFoundException e) { throw new AMException(AMError.TEMPLATE_INSTALL, e); } } /** * Ends a file download transaction. */ public static void releaseFile(final String destinationPath) { File destinationMark = new File(destinationPath + FILE_MARK); if (destinationMark.exists()) { destinationMark.delete(); } else { final String msg = String.format("The destination file [%s] was not bbeing download", destinationPath); LOG.error(msg); } } }