Code format hawkbit-artifact-repository-filesystem (#1933)
Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -1,11 +1,12 @@
|
|||||||
# Eclipse.IoT hawkBit - Artifact Repository File System
|
# Eclipse.IoT hawkBit - Artifact Repository File System
|
||||||
|
|
||||||
This module contains the implementation of the `ArtifactRepository` based on the file-system.
|
This module contains the implementation of the `ArtifactRepository` based on the file-system.
|
||||||
It's a very convenient and easy implementation of storing the artifact binaries into the file-system based on the SHA-1 hash naming.
|
It's a very convenient and easy implementation of storing the artifact binaries into the file-system based on the SHA-1
|
||||||
|
hash naming.
|
||||||
|
|
||||||
Due the limit of many file-systems of files within one directory, the files
|
Due the limit of many file-systems of files within one directory, the files
|
||||||
are stored in different sub-directories based on the last four digits of the
|
are stored in different sub-directories based on the last four digits of the
|
||||||
SHA1-hash `/basepath/[two digit sha1]/[two digit sha1/sha1-hash-filename]`.
|
SHA1-hash `/basepath/[two digit sha1]/[two digit sha1/sha1-hash-filename]`.
|
||||||
|
|
||||||
# Compile
|
# Compile
|
||||||
|
|
||||||
|
|||||||
@@ -9,44 +9,45 @@
|
|||||||
SPDX-License-Identifier: EPL-2.0
|
SPDX-License-Identifier: EPL-2.0
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
<modelVersion>4.0.0</modelVersion>
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.eclipse.hawkbit</groupId>
|
<parent>
|
||||||
<artifactId>hawkbit-parent</artifactId>
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
<version>${revision}</version>
|
<artifactId>hawkbit-parent</artifactId>
|
||||||
</parent>
|
<version>${revision}</version>
|
||||||
<artifactId>hawkbit-artifact-repository-filesystem</artifactId>
|
</parent>
|
||||||
<name>hawkBit :: Artifact Repository :: Filesystem</name>
|
<artifactId>hawkbit-artifact-repository-filesystem</artifactId>
|
||||||
|
<name>hawkBit :: Artifact Repository :: Filesystem</name>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.hawkbit</groupId>
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
<artifactId>hawkbit-core</artifactId>
|
<artifactId>hawkbit-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-core</artifactId>
|
<artifactId>spring-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.qameta.allure</groupId>
|
<groupId>io.qameta.allure</groupId>
|
||||||
<artifactId>allure-junit5</artifactId>
|
<artifactId>allure-junit5</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ public class ArtifactFileNotFoundException extends RuntimeException {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the Exception from it's cause
|
* Creates the Exception from it's cause
|
||||||
|
*
|
||||||
* @param cause the original exception
|
* @param cause the original exception
|
||||||
*/
|
*/
|
||||||
public ArtifactFileNotFoundException(final Exception cause) {
|
public ArtifactFileNotFoundException(final Exception cause) {
|
||||||
|
|||||||
@@ -22,8 +22,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
public class ArtifactFilesystemConfiguration {
|
public class ArtifactFilesystemConfiguration {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param artifactFilesystemProperties
|
* @param artifactFilesystemProperties the artifact file system properties
|
||||||
* the artifact file system properties
|
|
||||||
* @return Default {@link ArtifactRepository} implementation.
|
* @return Default {@link ArtifactRepository} implementation.
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
* Implementation of the {@link ArtifactRepository} to store artifacts on the
|
* Implementation of the {@link ArtifactRepository} to store artifacts on the
|
||||||
* file-system. The files are stored by their SHA1 hash of the artifact binary.
|
* file-system. The files are stored by their SHA1 hash of the artifact binary.
|
||||||
* Duplicate files with the same SHA1 hash will only stored once.
|
* Duplicate files with the same SHA1 hash will only stored once.
|
||||||
*
|
*
|
||||||
* All files are stored flat in one base directory configured in the
|
* All files are stored flat in one base directory configured in the
|
||||||
* {@link ArtifactFilesystemProperties#getPath()}.
|
* {@link ArtifactFilesystemProperties#getPath()}.
|
||||||
*
|
*
|
||||||
* Due the limit of many file-systems of files within one directory, the files
|
* Due the limit of many file-systems of files within one directory, the files
|
||||||
* are stored in different sub-directories based on the last four digits of the
|
* are stored in different sub-directories based on the last four digits of the
|
||||||
* SHA1-hash {@code (/basepath/[two digit sha1]/[two digit sha1])}.
|
* SHA1-hash {@code (/basepath/[two digit sha1]/[two digit sha1])}.
|
||||||
@@ -39,10 +39,9 @@ public class ArtifactFilesystemRepository extends AbstractArtifactRepository {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param artifactResourceProperties
|
* @param artifactResourceProperties the properties which holds the necessary configuration for the
|
||||||
* the properties which holds the necessary configuration for the
|
* file-system repository
|
||||||
* file-system repository
|
|
||||||
*/
|
*/
|
||||||
public ArtifactFilesystemRepository(final ArtifactFilesystemProperties artifactResourceProperties) {
|
public ArtifactFilesystemRepository(final ArtifactFilesystemProperties artifactResourceProperties) {
|
||||||
this.artifactResourceProperties = artifactResourceProperties;
|
this.artifactResourceProperties = artifactResourceProperties;
|
||||||
@@ -64,10 +63,22 @@ public class ArtifactFilesystemRepository extends AbstractArtifactRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractDbArtifact store(final String tenant, final DbArtifactHash base16Hashes, final String contentType, final String tempFile) throws IOException {
|
public void deleteByTenant(final String tenant) {
|
||||||
|
FileUtils.deleteQuietly(Paths.get(artifactResourceProperties.getPath(), sanitizeTenant(tenant)).toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean existsByTenantAndSha1(final String tenant, final String sha1) {
|
||||||
|
return getFile(tenant, sha1).exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AbstractDbArtifact store(final String tenant, final DbArtifactHash base16Hashes, final String contentType, final String tempFile)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
final File file = new File(tempFile);
|
final File file = new File(tempFile);
|
||||||
return renameFileToSHA1Naming(tenant, file, new ArtifactFilesystem(file, base16Hashes.getSha1(), base16Hashes, file.length(), contentType));
|
return renameFileToSHA1Naming(tenant, file,
|
||||||
|
new ArtifactFilesystem(file, base16Hashes.getSha1(), base16Hashes, file.length(), contentType));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArtifactFilesystem renameFileToSHA1Naming(final String tenant, final File file,
|
private ArtifactFilesystem renameFileToSHA1Naming(final String tenant, final File file,
|
||||||
@@ -95,14 +106,4 @@ public class ArtifactFilesystemRepository extends AbstractArtifactRepository {
|
|||||||
final String folder2 = sha1.substring(length - 2, length);
|
final String folder2 = sha1.substring(length - 2, length);
|
||||||
return Paths.get(artifactResourceProperties.getPath(), sanitizeTenant(tenant), folder1, folder2);
|
return Paths.get(artifactResourceProperties.getPath(), sanitizeTenant(tenant), folder1, folder2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteByTenant(final String tenant) {
|
|
||||||
FileUtils.deleteQuietly(Paths.get(artifactResourceProperties.getPath(), sanitizeTenant(tenant)).toFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean existsByTenantAndSha1(final String tenant, final String sha1) {
|
|
||||||
return getFile(tenant, sha1).exists();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import io.qameta.allure.Description;
|
||||||
|
import io.qameta.allure.Feature;
|
||||||
|
import io.qameta.allure.Story;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
@@ -26,10 +29,6 @@ import org.junit.jupiter.api.AfterAll;
|
|||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
|
||||||
import io.qameta.allure.Feature;
|
|
||||||
import io.qameta.allure.Story;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Feature("Unit Tests - Artifact File System Repository")
|
@Feature("Unit Tests - Artifact File System Repository")
|
||||||
@Story("Test storing artifact binaries in the file-system")
|
@Story("Test storing artifact binaries in the file-system")
|
||||||
@@ -121,12 +120,6 @@ public class ArtifactFilesystemRepositoryTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AbstractDbArtifact storeRandomArtifact(final byte[] fileContent) {
|
|
||||||
final String fileName = "filename.tmp";
|
|
||||||
final ByteArrayInputStream inputStream = new ByteArrayInputStream(fileContent);
|
|
||||||
return artifactFilesystemRepository.store(TENANT, inputStream, fileName, "application/txt", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] randomBytes() {
|
private static byte[] randomBytes() {
|
||||||
final byte[] randomBytes = new byte[20];
|
final byte[] randomBytes = new byte[20];
|
||||||
final Random ran = new Random();
|
final Random ran = new Random();
|
||||||
@@ -134,4 +127,10 @@ public class ArtifactFilesystemRepositoryTest {
|
|||||||
return randomBytes;
|
return randomBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AbstractDbArtifact storeRandomArtifact(final byte[] fileContent) {
|
||||||
|
final String fileName = "filename.tmp";
|
||||||
|
final ByteArrayInputStream inputStream = new ByteArrayInputStream(fileContent);
|
||||||
|
return artifactFilesystemRepository.store(TENANT, inputStream, fileName, "application/txt", null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,15 +16,14 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
|
||||||
|
import io.qameta.allure.Description;
|
||||||
|
import io.qameta.allure.Feature;
|
||||||
|
import io.qameta.allure.Story;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.assertj.core.api.Assertions;
|
import org.assertj.core.api.Assertions;
|
||||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
|
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
|
||||||
import io.qameta.allure.Feature;
|
|
||||||
import io.qameta.allure.Story;
|
|
||||||
|
|
||||||
@Feature("Unit Tests - Artifact File System Repository")
|
@Feature("Unit Tests - Artifact File System Repository")
|
||||||
@Story("Test storing artifact binaries in the file-system")
|
@Story("Test storing artifact binaries in the file-system")
|
||||||
public class ArtifactFilesystemTest {
|
public class ArtifactFilesystemTest {
|
||||||
|
|||||||
Reference in New Issue
Block a user