diff options
Diffstat (limited to 'sonar-home/src/main')
4 files changed, 0 insertions, 401 deletions
diff --git a/sonar-home/src/main/java/org/sonar/home/cache/DirectoryLock.java b/sonar-home/src/main/java/org/sonar/home/cache/DirectoryLock.java deleted file mode 100644 index db61bac9bcd..00000000000 --- a/sonar-home/src/main/java/org/sonar/home/cache/DirectoryLock.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program 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; either - * version 3 of the License, or (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.home.cache; - -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.channels.FileChannel; -import java.nio.channels.FileLock; -import java.nio.file.Path; - -public class DirectoryLock { - public static final String LOCK_FILE_NAME = ".sonar_lock"; - private final Path lockFilePath; - private final Logger logger; - - private RandomAccessFile lockRandomAccessFile; - private FileChannel lockChannel; - private FileLock lockFile; - - public DirectoryLock(Path directory, Logger logger) { - this.logger = logger; - this.lockFilePath = directory.resolve(LOCK_FILE_NAME).toAbsolutePath(); - } - - public boolean tryLock() { - try { - lockRandomAccessFile = new RandomAccessFile(lockFilePath.toFile(), "rw"); - lockChannel = lockRandomAccessFile.getChannel(); - lockFile = lockChannel.tryLock(0, 1024, false); - - return lockFile != null; - } catch (IOException e) { - throw new IllegalStateException("Failed to create lock in " + lockFilePath.toString(), e); - } - } - - public void unlock() { - if (lockFile != null) { - try { - lockFile.release(); - lockFile = null; - } catch (IOException e) { - logger.error("Error releasing lock", e); - } - } - if (lockChannel != null) { - try { - lockChannel.close(); - lockChannel = null; - } catch (IOException e) { - logger.error("Error closing file channel", e); - } - } - if (lockRandomAccessFile != null) { - try { - lockRandomAccessFile.close(); - lockRandomAccessFile = null; - } catch (IOException e) { - logger.error("Error closing file", e); - } - } - } -} diff --git a/sonar-home/src/main/java/org/sonar/home/cache/FileCache.java b/sonar-home/src/main/java/org/sonar/home/cache/FileCache.java deleted file mode 100644 index bc42ed0335c..00000000000 --- a/sonar-home/src/main/java/org/sonar/home/cache/FileCache.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program 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; either - * version 3 of the License, or (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.home.cache; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.jar.JarOutputStream; -import java.util.jar.Pack200; -import java.util.zip.GZIPInputStream; - -/** - * This class is responsible for managing Sonar batch file cache. You can put file into cache and - * later try to retrieve them. MD5 is used to differentiate files (name is not secure as files may come - * from different Sonar servers and have same name but be actually different, and same for SNAPSHOTs). - */ -public class FileCache { - - /** Maximum loop count when creating temp directories. */ - private static final int TEMP_DIR_ATTEMPTS = 10_000; - - private final File cacheDir; - private final File tmpDir; - private final FileHashes hashes; - private final Logger logger; - - FileCache(File dir, FileHashes fileHashes, Logger logger) { - this.hashes = fileHashes; - this.logger = logger; - this.cacheDir = createDir(dir, "user cache: "); - logger.info(String.format("User cache: %s", dir.getAbsolutePath())); - this.tmpDir = createDir(new File(dir, "_tmp"), "temp dir"); - } - - public static FileCache create(File dir, Logger logger) { - return new FileCache(dir, new FileHashes(), logger); - } - - public File getDir() { - return cacheDir; - } - - public interface Downloader { - void download(String filename, File toFile) throws IOException; - } - - /** - * Look for a file in the cache by its filename and md5 checksum. If the file is not - * present then try to download it. In case of error or if the file is not found - * an exception is thrown. {@code null} is never returned. - */ - public File get(String filename, String hash, Downloader downloader) { - // Does not fail if another process tries to create the directory at the same time. - File hashDir = hashDir(hash); - File targetFile = new File(hashDir, filename); - if (!targetFile.exists()) { - cacheMiss(targetFile, hash, downloader); - } - return targetFile; - } - - private void cacheMiss(File targetFile, String expectedHash, Downloader downloader) { - File tempFile = newTempFile(); - download(downloader, targetFile.getName(), tempFile); - String downloadedHash = hashes.of(tempFile); - if (!expectedHash.equals(downloadedHash)) { - throw new IllegalStateException("INVALID HASH: File " + tempFile.getAbsolutePath() + " was expected to have hash " + expectedHash - + " but was downloaded with hash " + downloadedHash); - } - mkdirQuietly(targetFile.getParentFile()); - renameQuietly(tempFile, targetFile); - } - - public File getCompressed(String filename, String hash, Downloader downloader) { - File hashDir = hashDir(hash); - File compressedFile = new File(hashDir, filename); - File jarFile = new File(compressedFile.getParentFile(), getUnpackedFileName(compressedFile.getName())); - - if (!jarFile.exists()) { - if (!compressedFile.exists()) { - cacheMiss(compressedFile, hash, downloader); - } - File tempFile = newTempFile(); - unpack200(compressedFile.toPath(), tempFile.toPath()); - renameQuietly(tempFile, jarFile); - } - return jarFile; - } - - private static String getUnpackedFileName(String packedName) { - return packedName.substring(0, packedName.length() - 7) + "jar"; - } - - private void unpack200(Path compressedFile, Path jarFile) { - logger.debug("Unpacking plugin " + compressedFile); - Pack200.Unpacker unpacker = Pack200.newUnpacker(); - try { - try (JarOutputStream jarStream = new JarOutputStream(new BufferedOutputStream(Files.newOutputStream(jarFile))); - InputStream in = new GZIPInputStream(new BufferedInputStream(Files.newInputStream(compressedFile)))) { - unpacker.unpack(in, jarStream); - } - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - - private static void download(Downloader downloader, String filename, File tempFile) { - try { - downloader.download(filename, tempFile); - } catch (IOException e) { - throw new IllegalStateException("Fail to download " + filename + " to " + tempFile, e); - } - } - - private void renameQuietly(File sourceFile, File targetFile) { - boolean rename = sourceFile.renameTo(targetFile); - // Check if the file was cached by another process during download - if (!rename && !targetFile.exists()) { - logger.warn(String.format("Unable to rename %s to %s", sourceFile.getAbsolutePath(), targetFile.getAbsolutePath())); - logger.warn("A copy/delete will be tempted but with no guarantee of atomicity"); - try { - Files.move(sourceFile.toPath(), targetFile.toPath()); - } catch (IOException e) { - throw new IllegalStateException("Fail to move " + sourceFile.getAbsolutePath() + " to " + targetFile, e); - } - } - } - - private File hashDir(String hash) { - return new File(cacheDir, hash); - } - - private static void mkdirQuietly(File hashDir) { - try { - Files.createDirectories(hashDir.toPath()); - } catch (IOException e) { - throw new IllegalStateException("Fail to create cache directory: " + hashDir, e); - } - } - - private File newTempFile() { - try { - return File.createTempFile("fileCache", null, tmpDir); - } catch (IOException e) { - throw new IllegalStateException("Fail to create temp file in " + tmpDir, e); - } - } - - public File createTempDir() { - String baseName = System.currentTimeMillis() + "-"; - - for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) { - File tempDir = new File(tmpDir, baseName + counter); - if (tempDir.mkdir()) { - return tempDir; - } - } - throw new IllegalStateException("Failed to create directory in " + tmpDir); - } - - private File createDir(File dir, String debugTitle) { - if (!dir.isDirectory() || !dir.exists()) { - logger.debug("Create : " + dir.getAbsolutePath()); - try { - Files.createDirectories(dir.toPath()); - } catch (IOException e) { - throw new IllegalStateException("Unable to create " + debugTitle + dir.getAbsolutePath(), e); - } - } - return dir; - } -} diff --git a/sonar-home/src/main/java/org/sonar/home/cache/FileCacheBuilder.java b/sonar-home/src/main/java/org/sonar/home/cache/FileCacheBuilder.java deleted file mode 100644 index 0bb78aada30..00000000000 --- a/sonar-home/src/main/java/org/sonar/home/cache/FileCacheBuilder.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program 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; either - * version 3 of the License, or (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.home.cache; - -import java.io.File; - -import javax.annotation.Nullable; - -public class FileCacheBuilder { - private final Logger logger; - private File userHome; - - public FileCacheBuilder(Logger logger) { - this.logger = logger; - } - - public FileCacheBuilder setUserHome(@Nullable File dir) { - this.userHome = dir; - return this; - } - - public FileCache build() { - if (userHome == null) { - userHome = findHome(); - } - File cacheDir = new File(userHome, "cache"); - return FileCache.create(cacheDir, logger); - } - - private static File findHome() { - String path = System.getenv("SONAR_USER_HOME"); - if (path == null) { - // Default - path = System.getProperty("user.home") + File.separator + ".sonar"; - } - return new File(path); - } -} diff --git a/sonar-home/src/main/java/org/sonar/home/cache/FileHashes.java b/sonar-home/src/main/java/org/sonar/home/cache/FileHashes.java deleted file mode 100644 index a76f17c7340..00000000000 --- a/sonar-home/src/main/java/org/sonar/home/cache/FileHashes.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program 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; either - * version 3 of the License, or (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.home.cache; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.security.MessageDigest; - -/** - * Hashes used to store files in the cache directory. - * - * @since 3.5 - */ -public class FileHashes { - - private static final int STREAM_BUFFER_LENGTH = 1024; - - public String of(File file) { - try { - return of(new FileInputStream(file)); - } catch (IOException e) { - throw new IllegalStateException("Fail to compute hash of: " + file.getAbsolutePath(), e); - } - } - - /** - * Computes the hash of given stream. The stream is closed by this method. - */ - public String of(InputStream input) { - try(InputStream is = input) { - MessageDigest digest = MessageDigest.getInstance("MD5"); - byte[] hash = digest(is, digest); - return toHex(hash); - } catch (Exception e) { - throw new IllegalStateException("Fail to compute hash", e); - } - } - - private static byte[] digest(InputStream input, MessageDigest digest) throws IOException { - final byte[] buffer = new byte[STREAM_BUFFER_LENGTH]; - int read = input.read(buffer, 0, STREAM_BUFFER_LENGTH); - while (read > -1) { - digest.update(buffer, 0, read); - read = input.read(buffer, 0, STREAM_BUFFER_LENGTH); - } - return digest.digest(); - } - - static String toHex(byte[] bytes) { - BigInteger bi = new BigInteger(1, bytes); - return String.format("%0" + (bytes.length << 1) + "x", bi); - } -} |