Refactor Management interfaces: find/get pattern (#2609)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-08-15 16:18:32 +03:00
committed by GitHub
parent fa4dea75a3
commit b4edde8cc3
100 changed files with 713 additions and 986 deletions

View File

@@ -67,8 +67,9 @@ public abstract class AbstractArtifactRepository implements ArtifactRepository {
checkHashes(providedHashes, sha1Hash16, md5Hash16, sha256Hash16);
// Check if file with same sha1 hash exists and if so return it
if (existsByTenantAndSha1(tenant, sha1Hash16)) {
return addMissingHashes(getArtifactBySha1(tenant, sha1Hash16), sha1Hash16, md5Hash16, sha256Hash16);
if (existsBySha1(tenant, sha1Hash16)) {
// TODO - shall check if the file is really the same as bytes or just sha1 hash is the same
return addMissingHashes(getBySha1(tenant, sha1Hash16), sha1Hash16, md5Hash16, sha256Hash16);
}
return store(sanitizeTenant(tenant), new DbArtifactHash(sha1Hash16, md5Hash16, sha256Hash16), contentType, tempFile);

View File

@@ -41,6 +41,26 @@ public interface ArtifactRepository {
@NotEmpty String tenant, @NotNull InputStream content, @NotEmpty String filename,
String contentType, DbArtifactHash hash);
/**
* Retrieves a {@link AbstractDbArtifact} from the store by its SHA1 hash. Throws {@link org.eclipse.hawkbit.repository.artifact.exception.ArtifactBinaryNotFoundException} if not found.
*
* @param tenant the tenant to store the artifact
* @param sha1Hash the sha1-hash of the file to lookup.
* @return The artifact file object or {@code null} if no file exists.
* @throws UnsupportedOperationException if implementation does not support the operation
*/
AbstractDbArtifact getBySha1(@NotEmpty String tenant, @NotEmpty String sha1Hash);
/**
* Checks if an artifact exists for a given tenant by its sha1 hash
*
* @param tenant the tenant
* @param sha1Hash the sha1-hash of the file to lookup.
* @return the boolean whether the artifact exists or not
*/
boolean existsBySha1(@NotEmpty String tenant, @NotEmpty String sha1Hash);
/**
* Deletes an artifact by its SHA1 hash.
*
@@ -50,29 +70,10 @@ public interface ArtifactRepository {
*/
void deleteBySha1(@NotEmpty String tenant, @NotEmpty String sha1Hash);
/**
* Retrieves a {@link AbstractDbArtifact} from the store by its SHA1 hash.
*
* @param tenant the tenant to store the artifact
* @param sha1Hash the sha1-hash of the file to lookup.
* @return The artifact file object or {@code null} if no file exists.
* @throws UnsupportedOperationException if implementation does not support the operation
*/
AbstractDbArtifact getArtifactBySha1(@NotEmpty String tenant, @NotEmpty String sha1Hash);
/**
* Deletes all artifacts of given tenant.
*
* @param tenant to erase
*/
void deleteByTenant(@NotEmpty String tenant);
/**
* Checks if an artifact exists for a given tenant by its sha1 hash
*
* @param tenant the tenant
* @param sha1Hash the sha1-hash of the file to lookup.
* @return the boolean whether the artifact exists or not
*/
boolean existsByTenantAndSha1(@NotEmpty String tenant, @NotEmpty String sha1Hash);
}

View File

@@ -0,0 +1,56 @@
/**
* Copyright (c) 2021 Bosch.IO GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.artifact.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Exception indicating that an artifact's binary does not exist anymore. This might be caused due to the soft deletion of a software module.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ArtifactBinaryNoLongerExistsException extends AbstractServerRtException {
@Serial
private static final long serialVersionUID = 1L;
private static final SpServerError THIS_ERROR = SpServerError.SP_ARTIFACT_BINARY_DELETED;
/**
* Creates a new ArtifactBinaryGoneException error.
*/
public ArtifactBinaryNoLongerExistsException() {
super(THIS_ERROR);
}
/**
* Creates a new ArtifactBinaryGoneException error with cause.
*
* @param cause for the exception
*/
public ArtifactBinaryNoLongerExistsException(final Throwable cause) {
super(THIS_ERROR, cause);
}
/**
* Creates a new ArtifactBinaryGoneException error with message.
*
* @param message of the error
*/
public ArtifactBinaryNoLongerExistsException(final String message) {
super(message, THIS_ERROR);
}
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.artifact.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public final class ArtifactBinaryNotFoundException extends AbstractServerRtException {
@Serial
private static final long serialVersionUID = 1L;
/**
* Creates a new FileUploadFailedException with
* {@link SpServerError#SP_ARTIFACT_LOAD_FAILED} error.
*/
public ArtifactBinaryNotFoundException() {
super(SpServerError.SP_ARTIFACT_LOAD_FAILED);
}
/**
* @param cause for the exception
*/
public ArtifactBinaryNotFoundException(final Throwable cause) {
super(SpServerError.SP_ARTIFACT_LOAD_FAILED, cause);
}
/**
* @param message of the error
*/
public ArtifactBinaryNotFoundException(final String message) {
super(message, SpServerError.SP_ARTIFACT_LOAD_FAILED);
}
}

View File

@@ -0,0 +1,50 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.artifact.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if artifact deletion failed.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public final class ArtifactDeleteFailedException extends AbstractServerRtException {
@Serial
private static final long serialVersionUID = 1L;
/**
* Creates a new FileUploadFailedException with
* {@link SpServerError#SP_ARTIFACT_DELETE_FAILED} error.
*/
public ArtifactDeleteFailedException() {
super(SpServerError.SP_ARTIFACT_DELETE_FAILED);
}
/**
* @param cause for the exception
*/
public ArtifactDeleteFailedException(final Throwable cause) {
super(SpServerError.SP_ARTIFACT_DELETE_FAILED, cause);
}
/**
* @param message of the error
*/
public ArtifactDeleteFailedException(final String message) {
super(message, SpServerError.SP_ARTIFACT_DELETE_FAILED);
}
}

View File

@@ -0,0 +1,56 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.artifact.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public final class ArtifactUploadFailedException extends AbstractServerRtException {
@Serial
private static final long serialVersionUID = 1L;
/**
* Creates a new FileUploadFailedException with
* {@link SpServerError#SP_ARTIFACT_UPLOAD_FAILED} error.
*/
public ArtifactUploadFailedException() {
super(SpServerError.SP_ARTIFACT_UPLOAD_FAILED);
}
/**
* @param cause for the exception
*/
public ArtifactUploadFailedException(final Throwable cause) {
super(SpServerError.SP_ARTIFACT_UPLOAD_FAILED, cause);
}
/**
* @param message of the error
*/
public ArtifactUploadFailedException(final String message) {
super(message, SpServerError.SP_ARTIFACT_UPLOAD_FAILED);
}
/**
* @param message for the error
* @param cause of the error
*/
public ArtifactUploadFailedException(final String message, final Throwable cause) {
super(message, SpServerError.SP_ARTIFACT_UPLOAD_FAILED, cause);
}
}

View File

@@ -14,8 +14,10 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
import org.apache.commons.io.FileUtils;
import org.eclipse.hawkbit.repository.artifact.exception.ArtifactBinaryNotFoundException;
import org.eclipse.hawkbit.repository.artifact.model.AbstractDbArtifact;
import org.eclipse.hawkbit.repository.artifact.model.DbArtifactHash;
import org.springframework.validation.annotation.Validated;
@@ -52,10 +54,10 @@ public class ArtifactFilesystemRepository extends AbstractArtifactRepository {
}
@Override
public ArtifactFilesystem getArtifactBySha1(final String tenant, final String sha1) {
public AbstractDbArtifact getBySha1(final String tenant, final String sha1) {
final File file = getFile(tenant, sha1);
if (!file.exists()) {
return null;
throw new ArtifactBinaryNotFoundException(sha1);
}
return new ArtifactFilesystem(file, sha1, new DbArtifactHash(sha1, null, null), file.length(), null);
@@ -67,7 +69,7 @@ public class ArtifactFilesystemRepository extends AbstractArtifactRepository {
}
@Override
public boolean existsByTenantAndSha1(final String tenant, final String sha1) {
public boolean existsBySha1(final String tenant, final String sha1) {
return getFile(tenant, sha1).exists();
}

View File

@@ -10,6 +10,7 @@
package org.eclipse.hawkbit.repository.artifact;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -20,16 +21,17 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.assertj.core.api.Assertions;
import org.eclipse.hawkbit.repository.artifact.exception.ArtifactBinaryNotFoundException;
import org.eclipse.hawkbit.repository.artifact.model.AbstractDbArtifact;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@Slf4j
/**
* Feature: Unit Tests - Artifact File System Repository<br/>
* Story: Test storing artifact binaries in the file-system
*/
@Slf4j
class ArtifactFilesystemRepositoryTest {
private static final String TENANT = "test_tenant";
@@ -77,7 +79,7 @@ class ArtifactFilesystemRepositoryTest {
final byte[] fileContent = randomBytes();
final AbstractDbArtifact artifact = storeRandomArtifact(fileContent);
assertThat(artifactFilesystemRepository.getArtifactBySha1(TENANT, artifact.getHashes().getSha1())).isNotNull();
assertThat(artifactFilesystemRepository.getBySha1(TENANT, artifact.getHashes().getSha1())).isNotNull();
}
/**
@@ -88,7 +90,9 @@ class ArtifactFilesystemRepositoryTest {
final AbstractDbArtifact artifact = storeRandomArtifact(randomBytes());
artifactFilesystemRepository.deleteBySha1(TENANT, artifact.getHashes().getSha1());
assertThat(artifactFilesystemRepository.getArtifactBySha1(TENANT, artifact.getHashes().getSha1())).isNull();
final String sha1Hash = artifact.getHashes().getSha1();
assertThatExceptionOfType(ArtifactBinaryNotFoundException.class)
.isThrownBy(() -> artifactFilesystemRepository.getBySha1(TENANT, sha1Hash));
}
/**
@@ -99,7 +103,9 @@ class ArtifactFilesystemRepositoryTest {
final AbstractDbArtifact artifact = storeRandomArtifact(randomBytes());
artifactFilesystemRepository.deleteByTenant(TENANT);
assertThat(artifactFilesystemRepository.getArtifactBySha1(TENANT, artifact.getHashes().getSha1())).isNull();
final String sha1Hash = artifact.getHashes().getSha1();
assertThatExceptionOfType(ArtifactBinaryNotFoundException.class)
.isThrownBy(() -> artifactFilesystemRepository.getBySha1(TENANT, sha1Hash));
}
/**