Cleanup file streaming utilities (#559)
* Cleanup file streaming. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Added missing comments. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix typo. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Split utility class. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Dependency cleanup. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Add missing dependency, Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Remove repository api dependency from rest core. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix build and sonar issues. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Remove custom ConstraintViolationException Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * RequestMapping should be public. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix errors. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Removed dead code. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Not null Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix nullpointer. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Code cleanup. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
@@ -10,13 +10,14 @@ package org.eclipse.hawkbit.artifact.repository;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
||||
import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact;
|
||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
|
||||
|
||||
import com.mongodb.gridfs.GridFSDBFile;
|
||||
import com.mongodb.gridfs.GridFSFile;
|
||||
|
||||
/**
|
||||
* A wrapper object for the {@link DbArtifact} object which returns the
|
||||
* A wrapper object for the {@link AbstractDbArtifact} object which returns the
|
||||
* {@link InputStream} directly from {@link GridFSDBFile#getInputStream()} which
|
||||
* retrieves when calling {@link #getFileInputStream()} always a new
|
||||
* {@link InputStream} and not the same.
|
||||
@@ -24,7 +25,7 @@ import com.mongodb.gridfs.GridFSFile;
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class GridFsArtifact extends DbArtifact {
|
||||
public class GridFsArtifact extends AbstractDbArtifact {
|
||||
|
||||
private final GridFSFile dbFile;
|
||||
|
||||
@@ -32,6 +33,8 @@ public class GridFsArtifact extends DbArtifact {
|
||||
* @param dbFile
|
||||
*/
|
||||
public GridFsArtifact(final GridFSFile dbFile) {
|
||||
super(dbFile.getId().toString(), new DbArtifactHash(dbFile.getFilename(), dbFile.getMD5()), dbFile.getLength(),
|
||||
dbFile.getContentType());
|
||||
this.dbFile = dbFile;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
||||
import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact;
|
||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.slf4j.Logger;
|
||||
@@ -89,7 +89,7 @@ public class MongoDBArtifactStore implements ArtifactRepository {
|
||||
* @return The DbArtifact object or {@code null} if no file exists.
|
||||
*/
|
||||
@Override
|
||||
public DbArtifact getArtifactBySha1(final String tenant, final String sha1Hash) {
|
||||
public AbstractDbArtifact getArtifactBySha1(final String tenant, final String sha1Hash) {
|
||||
|
||||
GridFSDBFile found = gridFs.findOne(new Query()
|
||||
.addCriteria(Criteria.where(FILENAME).is(sha1Hash).and(TENANT_QUERY).is(sanitizeTenant(tenant))));
|
||||
@@ -104,13 +104,13 @@ public class MongoDBArtifactStore implements ArtifactRepository {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DbArtifact store(final String tenant, final InputStream content, final String filename,
|
||||
public AbstractDbArtifact store(final String tenant, final InputStream content, final String filename,
|
||||
final String contentType) {
|
||||
return store(tenant, content, filename, contentType, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DbArtifact store(final String tenant, final InputStream content, final String filename,
|
||||
public AbstractDbArtifact store(final String tenant, final InputStream content, final String filename,
|
||||
final String contentType, final DbArtifactHash hash) {
|
||||
File tempFile = null;
|
||||
try {
|
||||
@@ -155,8 +155,8 @@ public class MongoDBArtifactStore implements ArtifactRepository {
|
||||
|
||||
}
|
||||
|
||||
private DbArtifact store(final String t, final InputStream content, final String contentType, final OutputStream os,
|
||||
final File tempFile, final DbArtifactHash hash) {
|
||||
private AbstractDbArtifact store(final String t, final InputStream content, final String contentType,
|
||||
final OutputStream os, final File tempFile, final DbArtifactHash hash) {
|
||||
final GridFsArtifact storedArtifact;
|
||||
final String tenant = sanitizeTenant(t);
|
||||
try {
|
||||
@@ -216,15 +216,16 @@ public class MongoDBArtifactStore implements ArtifactRepository {
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a list of {@link GridFSDBFile} to paged list of {@link DbArtifact}s.
|
||||
* Maps a list of {@link GridFSDBFile} to a list of
|
||||
* {@link AbstractDbArtifact}s.
|
||||
*
|
||||
* @param tenant
|
||||
* the tenant
|
||||
* @param dbFiles
|
||||
* the list of mongoDB gridFs files.
|
||||
* @return a paged list of artifacts mapped from the given dbFiles
|
||||
* @return list of artifacts mapped from the given dbFiles
|
||||
*/
|
||||
private static List<DbArtifact> map(final List<GridFSDBFile> dbFiles) {
|
||||
private static List<AbstractDbArtifact> map(final List<GridFSDBFile> dbFiles) {
|
||||
return dbFiles.stream().map(MongoDBArtifactStore::map).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@@ -233,14 +234,14 @@ public class MongoDBArtifactStore implements ArtifactRepository {
|
||||
*
|
||||
* @param ids
|
||||
* the ids of the files to lookup.
|
||||
* @return list of artfiacts
|
||||
* @return list of artifacts
|
||||
*/
|
||||
public List<DbArtifact> getArtifactsByIds(final List<String> ids) {
|
||||
public List<AbstractDbArtifact> getArtifactsByIds(final List<String> ids) {
|
||||
return map(gridFs.find(new Query().addCriteria(Criteria.where(ID).in(ids))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a single {@link GridFSFile} to {@link DbArtifact}.
|
||||
* Maps a single {@link GridFSFile} to {@link AbstractDbArtifact}.
|
||||
*
|
||||
* @param tenant
|
||||
* the tenant
|
||||
@@ -252,12 +253,8 @@ public class MongoDBArtifactStore implements ArtifactRepository {
|
||||
if (fsFile == null) {
|
||||
return null;
|
||||
}
|
||||
final GridFsArtifact artifact = new GridFsArtifact(fsFile);
|
||||
artifact.setArtifactId(fsFile.getId().toString());
|
||||
artifact.setSize(fsFile.getLength());
|
||||
artifact.setContentType(fsFile.getContentType());
|
||||
artifact.setHashes(new DbArtifactHash(fsFile.getFilename(), fsFile.getMD5()));
|
||||
return artifact;
|
||||
|
||||
return new GridFsArtifact(fsFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,21 +10,28 @@ package org.eclipse.hawkbit.artifact.repository;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
||||
import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact;
|
||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.amazonaws.services.s3.AmazonS3;
|
||||
|
||||
/**
|
||||
* An {@link DbArtifact} implementation which retrieves the {@link InputStream}
|
||||
* from the {@link AmazonS3} client.
|
||||
* An {@link AbstractDbArtifact} implementation which retrieves the
|
||||
* {@link InputStream} from the {@link AmazonS3} client.
|
||||
*/
|
||||
public class S3Artifact extends DbArtifact {
|
||||
public class S3Artifact extends AbstractDbArtifact {
|
||||
|
||||
private final AmazonS3 amazonS3;
|
||||
private final S3RepositoryProperties s3Properties;
|
||||
private final String key;
|
||||
|
||||
S3Artifact(final AmazonS3 amazonS3, final S3RepositoryProperties s3Properties, final String key) {
|
||||
S3Artifact(final AmazonS3 amazonS3, final S3RepositoryProperties s3Properties, final String key,
|
||||
final String artifactId, final DbArtifactHash hashes, final Long size, final String contentType) {
|
||||
super(artifactId, hashes, size, contentType);
|
||||
Assert.notNull(amazonS3, "S3 cannot be null");
|
||||
Assert.notNull(s3Properties, "Properties cannot be null");
|
||||
Assert.notNull(key, "Key cannot be null");
|
||||
this.amazonS3 = amazonS3;
|
||||
this.s3Properties = s3Properties;
|
||||
this.key = key;
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.security.DigestOutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
||||
import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact;
|
||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -77,7 +77,7 @@ public class S3Repository implements ArtifactRepository {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DbArtifact store(final String tenant, final InputStream content, final String filename,
|
||||
public AbstractDbArtifact store(final String tenant, final InputStream content, final String filename,
|
||||
final String contentType) {
|
||||
return store(tenant, content, filename, contentType, null);
|
||||
}
|
||||
@@ -86,7 +86,7 @@ public class S3Repository implements ArtifactRepository {
|
||||
// suppress warning, of not strong enough hashing algorithm, SHA-1 and MD5
|
||||
// is not used security related
|
||||
@SuppressWarnings("squid:S2070")
|
||||
public DbArtifact store(final String tenant, final InputStream content, final String filename,
|
||||
public AbstractDbArtifact store(final String tenant, final InputStream content, final String filename,
|
||||
final String contentType, final DbArtifactHash hash) {
|
||||
final MessageDigest mdSHA1;
|
||||
final MessageDigest mdMD5;
|
||||
@@ -117,7 +117,7 @@ public class S3Repository implements ArtifactRepository {
|
||||
}
|
||||
}
|
||||
|
||||
private DbArtifact store(final String tenant, final String sha1Hash16, final String mdMD5Hash16,
|
||||
private AbstractDbArtifact store(final String tenant, final String sha1Hash16, final String mdMD5Hash16,
|
||||
final String contentType, final File file, final DbArtifactHash hash) {
|
||||
final S3Artifact s3Artifact = createS3Artifact(tenant, sha1Hash16, mdMD5Hash16, contentType, file);
|
||||
checkHashes(s3Artifact, hash);
|
||||
@@ -145,14 +145,8 @@ public class S3Repository implements ArtifactRepository {
|
||||
|
||||
private S3Artifact createS3Artifact(final String tenant, final String sha1Hash, final String mdMD5Hash16,
|
||||
final String contentType, final File file) {
|
||||
final String key = objectKey(tenant, sha1Hash);
|
||||
final S3Artifact s3Artifact = new S3Artifact(amazonS3, s3Properties, key);
|
||||
s3Artifact.setContentType(contentType);
|
||||
s3Artifact.setArtifactId(sha1Hash);
|
||||
s3Artifact.setSize(file.length());
|
||||
s3Artifact.setContentType(contentType);
|
||||
s3Artifact.setHashes(new DbArtifactHash(sha1Hash, mdMD5Hash16));
|
||||
return s3Artifact;
|
||||
return new S3Artifact(amazonS3, s3Properties, objectKey(tenant, sha1Hash), sha1Hash,
|
||||
new DbArtifactHash(sha1Hash, mdMD5Hash16), file.length(), contentType);
|
||||
}
|
||||
|
||||
private ObjectMetadata createObjectMetadata(final String mdMD5Hash16, final String contentType, final File file) {
|
||||
@@ -181,7 +175,7 @@ public class S3Repository implements ArtifactRepository {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DbArtifact getArtifactBySha1(final String tenant, final String sha1Hash) {
|
||||
public AbstractDbArtifact getArtifactBySha1(final String tenant, final String sha1Hash) {
|
||||
final String key = objectKey(tenant, sha1Hash);
|
||||
|
||||
LOG.info("Retrieving S3 object from bucket {} and key {}", s3Properties.getBucketName(), key);
|
||||
@@ -192,17 +186,15 @@ public class S3Repository implements ArtifactRepository {
|
||||
|
||||
final ObjectMetadata s3ObjectMetadata = s3Object.getObjectMetadata();
|
||||
|
||||
final S3Artifact s3Artifact = new S3Artifact(amazonS3, s3Properties, key);
|
||||
s3Artifact.setArtifactId(sha1Hash);
|
||||
s3Artifact.setSize(s3ObjectMetadata.getContentLength());
|
||||
// the MD5Content is stored in the ETag
|
||||
s3Artifact.setHashes(new DbArtifactHash(sha1Hash,
|
||||
BaseEncoding.base16().lowerCase().encode(BaseEncoding.base64().decode(s3ObjectMetadata.getETag()))));
|
||||
s3Artifact.setContentType(s3ObjectMetadata.getContentType());
|
||||
return s3Artifact;
|
||||
return new S3Artifact(amazonS3, s3Properties, key, sha1Hash,
|
||||
new DbArtifactHash(sha1Hash,
|
||||
BaseEncoding.base16().lowerCase()
|
||||
.encode(BaseEncoding.base64().decode(s3ObjectMetadata.getETag()))),
|
||||
s3ObjectMetadata.getContentLength(), s3ObjectMetadata.getContentType());
|
||||
}
|
||||
|
||||
private static void checkHashes(final DbArtifact artifact, final DbArtifactHash hash) {
|
||||
private static void checkHashes(final AbstractDbArtifact artifact, final DbArtifactHash hash) {
|
||||
if (hash == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Random;
|
||||
|
||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
||||
import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact;
|
||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -117,7 +117,7 @@ public class S3RepositoryTest {
|
||||
when(s3ObjectMetadataMock.getContentType()).thenReturn(knownContentType);
|
||||
|
||||
// test
|
||||
final DbArtifact artifactBySha1 = s3RepositoryUnderTest.getArtifactBySha1(TENANT, knownSHA1Hash);
|
||||
final AbstractDbArtifact artifactBySha1 = s3RepositoryUnderTest.getArtifactBySha1(TENANT, knownSHA1Hash);
|
||||
|
||||
// verify
|
||||
assertThat(artifactBySha1.getArtifactId()).isEqualTo(knownSHA1Hash);
|
||||
@@ -152,7 +152,7 @@ public class S3RepositoryTest {
|
||||
when(amazonS3Mock.getObject(s3Properties.getBucketName(), knownSHA1Hash)).thenReturn(null);
|
||||
|
||||
// test
|
||||
final DbArtifact artifactBySha1NotExists = s3RepositoryUnderTest.getArtifactBySha1(TENANT, knownSHA1Hash);
|
||||
final AbstractDbArtifact artifactBySha1NotExists = s3RepositoryUnderTest.getArtifactBySha1(TENANT, knownSHA1Hash);
|
||||
|
||||
// verify
|
||||
assertThat(artifactBySha1NotExists).isNull();
|
||||
|
||||
Reference in New Issue
Block a user