aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-home
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2017-12-07 11:38:28 +0100
committerDuarte Meneses <duarte.meneses@sonarsource.com>2017-12-07 15:40:03 +0100
commit0001182a007e70261d447023f1fa5ad5e1a0b69f (patch)
treeeaae3a5bb2cf5f54a68ca42ac744494d0ead5908 /sonar-home
parent204f88df32a21b401b4bff3190ee0e3cfb7628a3 (diff)
downloadsonarqube-0001182a007e70261d447023f1fa5ad5e1a0b69f.tar.gz
sonarqube-0001182a007e70261d447023f1fa5ad5e1a0b69f.zip
SONAR-10142 Download compressed plugins
Diffstat (limited to 'sonar-home')
-rw-r--r--sonar-home/src/main/java/org/sonar/home/cache/FileCache.java73
-rw-r--r--sonar-home/src/test/java/org/sonar/home/cache/FileCacheTest.java66
-rw-r--r--sonar-home/src/test/resources/test.pack.gzbin0 -> 2689 bytes
3 files changed, 104 insertions, 35 deletions
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
index 4a03ec24794..e3cbafd22de 100644
--- a/sonar-home/src/main/java/org/sonar/home/cache/FileCache.java
+++ b/sonar-home/src/main/java/org/sonar/home/cache/FileCache.java
@@ -24,10 +24,8 @@ import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
import java.util.zip.GZIPInputStream;
@@ -43,7 +41,7 @@ public class FileCache {
/** Maximum loop count when creating temp directories. */
private static final int TEMP_DIR_ATTEMPTS = 10_000;
- private final File dir;
+ private final File cacheDir;
private final File tmpDir;
private final FileHashes hashes;
private final Logger logger;
@@ -51,7 +49,7 @@ public class FileCache {
FileCache(File dir, FileHashes fileHashes, Logger logger) {
this.hashes = fileHashes;
this.logger = logger;
- this.dir = createDir(dir, "user cache: ");
+ this.cacheDir = createDir(dir, "user cache: ");
logger.info(String.format("User cache: %s", dir.getAbsolutePath()));
this.tmpDir = createDir(new File(dir, "_tmp"), "temp dir");
}
@@ -61,7 +59,7 @@ public class FileCache {
}
public File getDir() {
- return dir;
+ return cacheDir;
}
/**
@@ -70,7 +68,7 @@ public class FileCache {
*/
@CheckForNull
public File get(String filename, String hash) {
- File cachedFile = new File(new File(dir, hash), filename);
+ File cachedFile = new File(new File(cacheDir, hash), filename);
if (cachedFile.exists()) {
return cachedFile;
}
@@ -82,41 +80,54 @@ public class FileCache {
void download(String filename, File toFile) throws IOException;
}
- public File get(String jarFilename, String hash, Downloader downloader) {
+ 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, jarFilename);
+ File targetFile = new File(hashDir, filename);
if (!targetFile.exists()) {
- File tempPackedFile = newTempFile();
- File tempJarFile = newTempFile();
- String packedFileName = getPackedFileName(jarFilename);
- download(downloader, packedFileName, tempPackedFile);
-
- logger.debug("Unpacking plugin " + jarFilename);
-
- unpack200(tempPackedFile.toPath(), tempJarFile.toPath());
- logger.debug("Done");
- String downloadedHash = hashes.of(tempJarFile);
- // if (!hash.equals(downloadedHash)) {
- // throw new IllegalStateException("INVALID HASH: File " + tempJarFile.getAbsolutePath() + " was expected to have hash " + hash
- // + " but was downloaded with hash " + downloadedHash);
- // }
- mkdirQuietly(hashDir);
- renameQuietly(tempJarFile, targetFile);
-
+ cacheMiss(targetFile, hash, downloader);
}
return targetFile;
}
- private static String getPackedFileName(String jarName) {
- return jarName.substring(0, jarName.length() - 3) + "pack.gz";
+ 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 static void unpack200(Path tempFile, Path targetFile) {
+ 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(targetFile)));
- InputStream in = new GZIPInputStream(new BufferedInputStream(Files.newInputStream(tempFile)))) {
+ 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) {
@@ -147,7 +158,7 @@ public class FileCache {
}
private File hashDir(String hash) {
- return new File(dir, hash);
+ return new File(cacheDir, hash);
}
private static void mkdirQuietly(File hashDir) {
diff --git a/sonar-home/src/test/java/org/sonar/home/cache/FileCacheTest.java b/sonar-home/src/test/java/org/sonar/home/cache/FileCacheTest.java
index 2a7381c866a..67635b5ab70 100644
--- a/sonar-home/src/test/java/org/sonar/home/cache/FileCacheTest.java
+++ b/sonar-home/src/test/java/org/sonar/home/cache/FileCacheTest.java
@@ -22,7 +22,6 @@ package org.sonar.home.cache;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
-import org.assertj.core.util.Files;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -32,6 +31,7 @@ import org.junit.rules.TemporaryFolder;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
public class FileCacheTest {
@@ -77,7 +77,7 @@ public class FileCacheTest {
thrown.expectMessage("Fail to download");
cache.get("sonar-foo-plugin-1.5.jar", "ABCDE", downloader);
}
-
+
@Test
public void fail_create_hash_dir() throws IOException {
File file = tempFolder.newFile();
@@ -85,11 +85,11 @@ public class FileCacheTest {
thrown.expectMessage("Unable to create user cache");
cache = new FileCache(file, fileHashes, mock(Logger.class));
}
-
+
@Test
public void fail_to_create_hash_dir() throws IOException {
when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
-
+
File hashDir = new File(cache.getDir(), "ABCDE");
hashDir.createNewFile();
thrown.expect(IllegalStateException.class);
@@ -114,6 +114,60 @@ public class FileCacheTest {
}
@Test
+ public void download_and_add_to_cache_compressed_file() throws IOException {
+ when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
+
+ FileCache.Downloader downloader = new FileCache.Downloader() {
+ public void download(String filename, File toFile) throws IOException {
+ FileUtils.copyFile(compressedFile(), toFile);
+ }
+ };
+ File cachedFile = cache.getCompressed("sonar-foo-plugin-1.5.pack.gz", "ABCDE", downloader);
+ assertThat(cachedFile).isNotNull().exists().isFile();
+
+ assertThat(cachedFile.getName()).isEqualTo("sonar-foo-plugin-1.5.jar");
+ assertThat(cachedFile.getParentFile().list()).containsOnly("sonar-foo-plugin-1.5.jar", "sonar-foo-plugin-1.5.pack.gz");
+ assertThat(cachedFile.getParentFile().getParentFile()).isEqualTo(cache.getDir());
+ }
+
+ @Test
+ public void dont_download_compressed_file_if_jar_exists() throws IOException {
+ when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
+ FileCache.Downloader downloader = mock(FileCache.Downloader.class);
+
+ File hashDir = new File(cache.getDir(), "ABCDE");
+ hashDir.mkdirs();
+ File jar = new File(new File(cache.getDir(), "ABCDE"), "sonar-foo-plugin-1.5.jar");
+ jar.createNewFile();
+ File cachedFile = cache.getCompressed("sonar-foo-plugin-1.5.pack.gz", "ABCDE", downloader);
+ assertThat(cachedFile).isNotNull().exists().isFile();
+
+ assertThat(cachedFile.getName()).isEqualTo("sonar-foo-plugin-1.5.jar");
+ assertThat(cachedFile.getParentFile().list()).containsOnly("sonar-foo-plugin-1.5.jar");
+ assertThat(cachedFile.getParentFile().getParentFile()).isEqualTo(cache.getDir());
+
+ verifyZeroInteractions(downloader);
+ }
+
+ @Test
+ public void dont_download_compressed_file_if_it_exists() throws IOException {
+ when(fileHashes.of(any(File.class))).thenReturn("ABCDE");
+ FileCache.Downloader downloader = mock(FileCache.Downloader.class);
+
+ File hashDir = new File(cache.getDir(), "ABCDE");
+ hashDir.mkdirs();
+ FileUtils.copyFile(compressedFile(), new File(hashDir, "sonar-foo-plugin-1.5.pack.gz"));
+ File cachedFile = cache.getCompressed("sonar-foo-plugin-1.5.pack.gz", "ABCDE", downloader);
+ assertThat(cachedFile).isNotNull().exists().isFile();
+
+ assertThat(cachedFile.getName()).isEqualTo("sonar-foo-plugin-1.5.jar");
+ assertThat(cachedFile.getParentFile().list()).containsOnly("sonar-foo-plugin-1.5.jar", "sonar-foo-plugin-1.5.pack.gz");
+ assertThat(cachedFile.getParentFile().getParentFile()).isEqualTo(cache.getDir());
+
+ verifyZeroInteractions(downloader);
+ }
+
+ @Test
public void download_corrupted_file() throws IOException {
thrown.expect(IllegalStateException.class);
thrown.expectMessage("INVALID HASH");
@@ -149,4 +203,8 @@ public class FileCacheTest {
assertThat(cachedFile.getParentFile().getParentFile()).isEqualTo(cache.getDir());
assertThat(FileUtils.readFileToString(cachedFile)).contains("downloaded by");
}
+
+ private File compressedFile() {
+ return new File("src/test/resources/test.pack.gz");
+ }
}
diff --git a/sonar-home/src/test/resources/test.pack.gz b/sonar-home/src/test/resources/test.pack.gz
new file mode 100644
index 00000000000..8e3a43c8e3d
--- /dev/null
+++ b/sonar-home/src/test/resources/test.pack.gz
Binary files differ