diff --git a/examples/hawkbit-example-app/.gitignore b/examples/hawkbit-example-app/.gitignore
index b83d22266..0b628eb5a 100644
--- a/examples/hawkbit-example-app/.gitignore
+++ b/examples/hawkbit-example-app/.gitignore
@@ -1 +1,2 @@
/target/
+/artifactrepo/*
diff --git a/extensions/hawkbit-extension-artifact-repository-mongo/README.md b/extensions/hawkbit-extension-artifact-repository-mongo/README.md
new file mode 100644
index 000000000..bd0d2951d
--- /dev/null
+++ b/extensions/hawkbit-extension-artifact-repository-mongo/README.md
@@ -0,0 +1,23 @@
+# Eclipse.IoT hawkBit - Artifact Repository MongoDB
+HawkBit Artifact Repository is a library for storing binary artifacts and metadata into MongoDB.
+
+
+## Using Artifact Repository MongoDB Extension
+The module contains a spring-boot autoconfiguration for easily integration into spring-boot projects.
+For using this extension in the hawkbit-example-application you just need to add the maven dependency.
+```
+
+ org.eclipse.hawkbit
+ hawkbit-extension-artifact-repository-mongo
+ ${project.version}
+
+```
+
+If you do not have a mongoDB running you can use the the flapdoodle project to download and start an mongoDB on demand
+```
+
+ de.flapdoodle.embed
+ de.flapdoodle.embed.mongo
+ ${flapdoodle.version}
+
+```
diff --git a/hawkbit-artifact-repository-mongo/pom.xml b/extensions/hawkbit-extension-artifact-repository-mongo/pom.xml
similarity index 97%
rename from hawkbit-artifact-repository-mongo/pom.xml
rename to extensions/hawkbit-extension-artifact-repository-mongo/pom.xml
index fb1d7df41..1270d0681 100644
--- a/hawkbit-artifact-repository-mongo/pom.xml
+++ b/extensions/hawkbit-extension-artifact-repository-mongo/pom.xml
@@ -16,7 +16,7 @@
0.2.0-SNAPSHOT
hawkbit-parent
- hawkbit-artifact-repository-mongo
+ hawkbit-extension-artifact-repository-mongo
hawkBit :: Artifact Repository Mongo
@@ -70,7 +70,6 @@
de.flapdoodle.embed.mongo
test
-
org.mockito
diff --git a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/GridFsArtifact.java b/extensions/hawkbit-extension-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/GridFsArtifact.java
similarity index 100%
rename from hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/GridFsArtifact.java
rename to extensions/hawkbit-extension-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/GridFsArtifact.java
diff --git a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java b/extensions/hawkbit-extension-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/MongoDBArtifactStore.java
similarity index 96%
rename from hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java
rename to extensions/hawkbit-extension-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/MongoDBArtifactStore.java
index 1edfe4afb..a6b4b4084 100644
--- a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java
+++ b/extensions/hawkbit-extension-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/MongoDBArtifactStore.java
@@ -44,13 +44,14 @@ import com.mongodb.gridfs.GridFSFile;
* The file management which looks up all the file in the file tore.
*
*/
-public class ArtifactStore implements ArtifactRepository {
+public class MongoDBArtifactStore implements ArtifactRepository {
- private static final Logger LOGGER = LoggerFactory.getLogger(ArtifactStore.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(MongoDBArtifactStore.class);
/**
- * The mongoDB field which holds the filename of the file to download. SP
- * Server uses the SHA hash as a filename and lookup in the mongoDB.
+ * The mongoDB field which holds the filename of the file to download.
+ * hawkBit update-server uses the SHA hash as a filename and lookup in the
+ * mongoDB.
*/
private static final String FILENAME = "filename";
@@ -206,7 +207,7 @@ public class ArtifactStore implements ArtifactRepository {
* @return a paged list of artifacts mapped from the given dbFiles
*/
private List map(final List dbFiles) {
- return dbFiles.stream().map(ArtifactStore::map).collect(Collectors.toList());
+ return dbFiles.stream().map(MongoDBArtifactStore::map).collect(Collectors.toList());
}
/**
diff --git a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStoreAutoConfiguration.java b/extensions/hawkbit-extension-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/MongoDBArtifactStoreAutoConfiguration.java
similarity index 79%
rename from hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStoreAutoConfiguration.java
rename to extensions/hawkbit-extension-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/MongoDBArtifactStoreAutoConfiguration.java
index 38df78dcb..9014ca1c8 100644
--- a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStoreAutoConfiguration.java
+++ b/extensions/hawkbit-extension-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/MongoDBArtifactStoreAutoConfiguration.java
@@ -13,17 +13,16 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
- * Auto configuration for the {@link ArtifactStore}.
+ * Auto configuration for the {@link MongoDBArtifactStore}.
*/
@Configuration
-@ConditionalOnMissingBean(value = ArtifactRepository.class)
-public class ArtifactStoreAutoConfiguration {
+public class MongoDBArtifactStoreAutoConfiguration {
/**
* @return Default {@link ArtifactRepository} implementation.
*/
@Bean
public ArtifactRepository artifactRepository() {
- return new ArtifactStore();
+ return new MongoDBArtifactStore();
}
}
diff --git a/hawkbit-artifact-repository-mongo/src/main/resources/META-INF/spring.factories b/extensions/hawkbit-extension-artifact-repository-mongo/src/main/resources/META-INF/spring.factories
similarity index 51%
rename from hawkbit-artifact-repository-mongo/src/main/resources/META-INF/spring.factories
rename to extensions/hawkbit-extension-artifact-repository-mongo/src/main/resources/META-INF/spring.factories
index 35e5415c9..09c60408f 100644
--- a/hawkbit-artifact-repository-mongo/src/main/resources/META-INF/spring.factories
+++ b/extensions/hawkbit-extension-artifact-repository-mongo/src/main/resources/META-INF/spring.factories
@@ -1,3 +1,3 @@
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-org.eclipse.hawkbit.artifact.repository.ArtifactStoreAutoConfiguration
\ No newline at end of file
+org.eclipse.hawkbit.artifact.repository.MongoDBArtifactStoreAutoConfiguration
\ No newline at end of file
diff --git a/hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/TestConfiguration.java b/extensions/hawkbit-extension-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/TestConfiguration.java
similarity index 100%
rename from hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/TestConfiguration.java
rename to extensions/hawkbit-extension-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/TestConfiguration.java
diff --git a/hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/repository/ArtifactStoreTest.java b/extensions/hawkbit-extension-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/repository/MongoDBArtifactStoreTest.java
similarity index 94%
rename from hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/repository/ArtifactStoreTest.java
rename to extensions/hawkbit-extension-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/repository/MongoDBArtifactStoreTest.java
index 9ac19cde4..338ad62db 100644
--- a/hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/repository/ArtifactStoreTest.java
+++ b/extensions/hawkbit-extension-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/repository/MongoDBArtifactStoreTest.java
@@ -34,12 +34,12 @@ import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("Artifact Store MongoDB")
@RunWith(SpringJUnit4ClassRunner.class)
-@SpringApplicationConfiguration(classes = { ArtifactStoreAutoConfiguration.class, TestConfiguration.class })
+@SpringApplicationConfiguration(classes = { MongoDBArtifactStoreAutoConfiguration.class, TestConfiguration.class })
@TestPropertySource(properties = { "spring.data.mongodb.port=0", "spring.mongodb.embedded.version=3.2.7" })
-public class ArtifactStoreTest {
+public class MongoDBArtifactStoreTest {
@Autowired
- private ArtifactStore artifactStoreUnderTest;
+ private MongoDBArtifactStore artifactStoreUnderTest;
@Autowired
private GridFsOperations gridFs;
diff --git a/extensions/pom.xml b/extensions/pom.xml
index d98ad0c48..160f7287c 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -22,6 +22,7 @@
hawkbit-extension-uaa
+ hawkbit-extension-artifact-repository-mongo
diff --git a/hawkbit-artifact-repository-filesystem/.gitignore b/hawkbit-artifact-repository-filesystem/.gitignore
new file mode 100644
index 000000000..2316d547d
--- /dev/null
+++ b/hawkbit-artifact-repository-filesystem/.gitignore
@@ -0,0 +1 @@
+/artifactrepo/*
diff --git a/hawkbit-artifact-repository-filesystem/README.md b/hawkbit-artifact-repository-filesystem/README.md
new file mode 100644
index 000000000..2c1e51bbb
--- /dev/null
+++ b/hawkbit-artifact-repository-filesystem/README.md
@@ -0,0 +1,17 @@
+# Eclipse.IoT hawkBit - Artifact Repository 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.
+
+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
+SHA1-hash `/basepath/[two digit sha1]/[two digit sha1/sha1-hash-filename]`.
+
+# Compile
+
+#### Build hawkbit-artifact-repository-filesystem
+
+```
+$ cd hawkbit/hawkbit-artifact-repository-filesystem
+$ mvn clean install
+```
diff --git a/hawkbit-artifact-repository-filesystem/pom.xml b/hawkbit-artifact-repository-filesystem/pom.xml
new file mode 100644
index 000000000..0d9500c07
--- /dev/null
+++ b/hawkbit-artifact-repository-filesystem/pom.xml
@@ -0,0 +1,69 @@
+
+
+ 4.0.0
+
+ org.eclipse.hawkbit
+ hawkbit-parent
+ 0.2.0-SNAPSHOT
+
+ hawkbit-artifact-repository-filesystem
+
+
+
+ org.eclipse.hawkbit
+ hawkbit-core
+ ${project.version}
+
+
+ com.google.guava
+ guava
+
+
+ org.springframework
+ spring-core
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+
+
+ commons-io
+ commons-io
+
+
+ org.easytesting
+ fest-assert-core
+ test
+
+
+ org.easytesting
+ fest-assert
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+ ru.yandex.qatools.allure
+ allure-junit-adaptor
+ test
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
+
diff --git a/hawkbit-artifact-repository-filesystem/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystem.java b/hawkbit-artifact-repository-filesystem/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystem.java
new file mode 100644
index 000000000..fed6acc86
--- /dev/null
+++ b/hawkbit-artifact-repository-filesystem/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystem.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.artifact.repository;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
+
+import com.google.common.base.Throwables;
+
+/**
+ * A {@link DbArtifact} implementation which dynamically creates a
+ * {@link FileInputStream} on calling {@link #getFileInputStream()}.
+ */
+public class ArtifactFilesystem extends DbArtifact {
+
+ private final File file;
+
+ ArtifactFilesystem(final File file) {
+ this.file = file;
+ }
+
+ @Override
+ // suppress warning, this InputStream needs to be closed by the caller, this
+ // cannot be closed in this method
+ @SuppressWarnings("squid:S2095")
+ public InputStream getFileInputStream() {
+ try {
+ return new BufferedInputStream(new FileInputStream(file));
+ } catch (final FileNotFoundException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+}
diff --git a/hawkbit-artifact-repository-filesystem/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystemProperties.java b/hawkbit-artifact-repository-filesystem/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystemProperties.java
new file mode 100644
index 000000000..1d19cd36f
--- /dev/null
+++ b/hawkbit-artifact-repository-filesystem/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystemProperties.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.artifact.repository;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration properties for the file-system repository, e.g. the base-path
+ * to store the files.
+ */
+@ConfigurationProperties("org.eclipse.hawkbit.repository.file")
+public class ArtifactFilesystemProperties {
+
+ /**
+ * The base-path of the directory to store the artifacts.
+ */
+ private String path = "./artifactrepo";
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(final String path) {
+ this.path = path;
+ }
+}
diff --git a/hawkbit-artifact-repository-filesystem/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystemRepository.java b/hawkbit-artifact-repository-filesystem/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystemRepository.java
new file mode 100644
index 000000000..f8f4801e8
--- /dev/null
+++ b/hawkbit-artifact-repository-filesystem/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystemRepository.java
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.artifact.repository;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.DigestOutputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
+import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
+
+import com.google.common.base.Splitter;
+import com.google.common.io.BaseEncoding;
+import com.google.common.io.ByteStreams;
+
+/**
+ * Implementation of the {@link ArtifactRepository} to store artifacts on the
+ * 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.
+ *
+ * All files are stored flat in one base directory configured in the
+ * {@link ArtifactFilesystemProperties#getPath()}.
+ *
+ * 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
+ * SHA1-hash {@code (/basepath/[two digit sha1]/[two digit sha1])}.
+ */
+public class ArtifactFilesystemRepository implements ArtifactRepository {
+
+ private static final String TEMP_FILE_PREFIX = "tmp";
+ private static final String TEMP_FILE_SUFFIX = "artifactrepo";
+ private final ArtifactFilesystemProperties artifactResourceProperties;
+
+ /**
+ * Constructor.
+ *
+ * @param artifactResourceProperties
+ * the properties which holds the necessary configuration for the
+ * file-system repository
+ */
+ public ArtifactFilesystemRepository(final ArtifactFilesystemProperties artifactResourceProperties) {
+ this.artifactResourceProperties = artifactResourceProperties;
+ }
+
+ @Override
+ public ArtifactFilesystem store(final InputStream content, final String filename, final String contentType) {
+ return store(content, filename, contentType, null);
+ }
+
+ @Override
+ // suppress warning, of not strong enough hashing algorithm, SHA-1 and MD5
+ // is not used security related
+ @SuppressWarnings("squid:S2070")
+ public ArtifactFilesystem store(final InputStream content, final String filename, final String contentType,
+ final DbArtifactHash hash) {
+
+ final MessageDigest mdSHA1;
+ final MessageDigest mdMD5;
+ try {
+ mdSHA1 = MessageDigest.getInstance("SHA1");
+ mdMD5 = MessageDigest.getInstance("MD5");
+ } catch (final NoSuchAlgorithmException e) {
+ throw new ArtifactStoreException(e.getMessage(), e);
+ }
+
+ final File file = createTempFile();
+ final DbArtifact artifact = store(content, contentType, hash, mdSHA1, mdMD5, file);
+ return renameFileToSHA1Naming(file, artifact);
+ }
+
+ @Override
+ public void deleteBySha1(final String sha1Hash) {
+ FileUtils.deleteQuietly(getFile(sha1Hash));
+ }
+
+ @Override
+ public ArtifactFilesystem getArtifactBySha1(final String sha1) {
+ final File file = getFile(sha1);
+ if (!file.exists()) {
+ return null;
+ }
+ final ArtifactFilesystem artifact = new ArtifactFilesystem(file);
+ artifact.setArtifactId(sha1);
+ artifact.setHashes(new DbArtifactHash(sha1, null));
+ artifact.setSize(file.length());
+ return artifact;
+ }
+
+ private DbArtifact store(final InputStream content, final String contentType, final DbArtifactHash hash,
+ final MessageDigest mdSHA1, final MessageDigest mdMD5, final File file) {
+ final DbArtifact artifact = new DbArtifact();
+ try (final DigestOutputStream outputstream = openFileOutputStream(file, mdSHA1, mdMD5)) {
+ final long artifactSize = ByteStreams.copy(content, outputstream);
+ outputstream.flush();
+ final String sha1Hash = BaseEncoding.base16().lowerCase().encode(mdSHA1.digest());
+ final String md5Hash = BaseEncoding.base16().lowerCase().encode(mdMD5.digest());
+ artifact.setArtifactId(sha1Hash);
+ artifact.setSize(artifactSize);
+ artifact.setContentType(contentType);
+ artifact.setHashes(new DbArtifactHash(sha1Hash, md5Hash));
+ checkHashes(artifact, hash);
+ } catch (final IOException e) {
+ throw new ArtifactStoreException(e.getMessage(), e);
+ } catch (final HashNotMatchException e) {
+ file.delete();
+ throw e;
+ }
+ return artifact;
+ }
+
+ private ArtifactFilesystem renameFileToSHA1Naming(final File file, final DbArtifact artifact) {
+ final File fileSHA1Naming = getFile(artifact.getHashes().getSha1());
+ final ArtifactFilesystem fileSystemArtifact = new ArtifactFilesystem(fileSHA1Naming);
+ if (fileSHA1Naming.exists()) {
+ FileUtils.deleteQuietly(file);
+ } else if (!file.renameTo(fileSHA1Naming)) {
+ throw new ArtifactStoreException("Could not store the file " + fileSHA1Naming);
+ }
+
+ file.delete();
+ fileSystemArtifact.setArtifactId(artifact.getArtifactId());
+ fileSystemArtifact.setContentType(artifact.getContentType());
+ fileSystemArtifact.setHashes(artifact.getHashes());
+ fileSystemArtifact.setSize(artifact.getSize());
+ return fileSystemArtifact;
+ }
+
+ private DbArtifact checkHashes(final DbArtifact artifact, final DbArtifactHash hash) {
+ if (hash == null) {
+ return artifact;
+ }
+ if (hash.getSha1() != null && !artifact.getHashes().getSha1().equals(hash.getSha1())) {
+ throw new HashNotMatchException("The given sh1 hash " + hash.getSha1()
+ + " does not match with the calcualted sha1 hash " + artifact.getHashes().getSha1(),
+ HashNotMatchException.SHA1);
+ }
+ if (hash.getMd5() != null && !artifact.getHashes().getMd5().equals(hash.getMd5())) {
+ throw new HashNotMatchException("The given md5 hash " + hash.getMd5()
+ + " does not match with the calcualted md5 hash " + artifact.getHashes().getMd5(),
+ HashNotMatchException.MD5);
+ }
+ return artifact;
+ }
+
+ private File createTempFile() {
+ try {
+ return File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX);
+ } catch (final IOException e) {
+ throw new ArtifactStoreException("Cannot create tempfile", e);
+ }
+ }
+
+ private File getFile(final String sha1) {
+ final File aritfactDirectory = getSha1DirectoryPath(sha1).toFile();
+ aritfactDirectory.mkdirs();
+ return new File(aritfactDirectory, sha1);
+ }
+
+ private Path getSha1DirectoryPath(final String sha1) {
+ final int length = sha1.length();
+ final List folders = Splitter.fixedLength(2).splitToList(sha1.substring(length - 4, length));
+ final String folder1 = folders.get(0);
+ final String folder2 = folders.get(1);
+ return Paths.get(artifactResourceProperties.getPath(), folder1, folder2);
+ }
+
+ private DigestOutputStream openFileOutputStream(final File file, final MessageDigest mdSHA1,
+ final MessageDigest mdMD5) throws FileNotFoundException {
+ return new DigestOutputStream(
+ new DigestOutputStream(new BufferedOutputStream(new FileOutputStream(file)), mdMD5), mdSHA1);
+ }
+}
diff --git a/hawkbit-artifact-repository-filesystem/src/test/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystemRepositoryTest.java b/hawkbit-artifact-repository-filesystem/src/test/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystemRepositoryTest.java
new file mode 100644
index 000000000..40006d086
--- /dev/null
+++ b/hawkbit-artifact-repository-filesystem/src/test/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystemRepositoryTest.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.artifact.repository;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Random;
+
+import org.apache.commons.io.IOUtils;
+import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
+import org.fest.assertions.api.Assertions;
+import org.junit.Test;
+
+import ru.yandex.qatools.allure.annotations.Description;
+import ru.yandex.qatools.allure.annotations.Features;
+import ru.yandex.qatools.allure.annotations.Stories;
+
+@Features("Unit Tests - Artifact File System Repository")
+@Stories("Test storing artifact binaries in the file-system")
+public class ArtifactFilesystemRepositoryTest {
+
+ private final ArtifactFilesystemProperties artifactResourceProperties = new ArtifactFilesystemProperties();
+
+ private final ArtifactFilesystemRepository artifactFilesystemRepository = new ArtifactFilesystemRepository(
+ artifactResourceProperties);
+
+ @Test
+ @Description("Verfies that an artifact can be successfully stored in the file-system repository")
+ public void storeSuccessfully() throws IOException {
+ final byte[] fileContent = randomBytes();
+ final ArtifactFilesystem artifact = storeRandomArtifact(fileContent);
+
+ final byte[] readContent = new byte[fileContent.length];
+ IOUtils.read(artifact.getFileInputStream(), readContent);
+
+ assertThat(readContent).isEqualTo(fileContent);
+ }
+
+ @Test
+ @Description("Verfies that an artifact can be successfully stored in the file-system repository")
+ public void getStoredArtifactBasedOnSHA1Hash() {
+
+ final byte[] fileContent = randomBytes();
+ final ArtifactFilesystem artifact = storeRandomArtifact(fileContent);
+
+ final DbArtifact artifactBySha1 = artifactFilesystemRepository
+ .getArtifactBySha1(artifact.getHashes().getSha1());
+ assertThat(artifactBySha1).isNotNull();
+ }
+
+ @Test
+ @Description("Verfies that an artifact can be deleted in the file-system repository")
+ public void deleteStoredArtifactBySHA1Hash() {
+ final ArtifactFilesystem artifact = storeRandomArtifact(randomBytes());
+
+ artifactFilesystemRepository.deleteBySha1(artifact.getHashes().getSha1());
+
+ assertThat(artifactFilesystemRepository.getArtifactBySha1(artifact.getHashes().getSha1())).isNull();
+ }
+
+ @Test
+ @Description("Verfies that an artifact which does not exists is deleted quietly in the file-system repository")
+ public void deleteArtifactWhichDoesNotExistsBySHA1HashWithoutException() {
+ try {
+ artifactFilesystemRepository.deleteBySha1("sha1HashWhichDoesNotExists");
+ } catch (final Exception e) {
+ Assertions.fail("did not expect an exception while deleting a file which does not exists");
+ }
+ }
+
+ private ArtifactFilesystem storeRandomArtifact(final byte[] fileContent) {
+ final String fileName = "filename.tmp";
+ final ByteArrayInputStream inputStream = new ByteArrayInputStream(fileContent);
+ final ArtifactFilesystem store = artifactFilesystemRepository.store(inputStream, fileName, "application/txt");
+ return store;
+ }
+
+ private static byte[] randomBytes() {
+ final byte[] randomBytes = new byte[20];
+ final Random ran = new Random();
+ ran.nextBytes(randomBytes);
+ return randomBytes;
+ }
+
+}
diff --git a/hawkbit-artifact-repository-filesystem/src/test/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystemTest.java b/hawkbit-artifact-repository-filesystem/src/test/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystemTest.java
new file mode 100644
index 000000000..cb523577f
--- /dev/null
+++ b/hawkbit-artifact-repository-filesystem/src/test/java/org/eclipse/hawkbit/artifact/repository/ArtifactFilesystemTest.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.artifact.repository;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import org.apache.commons.io.IOUtils;
+import org.fest.assertions.api.Assertions;
+import org.junit.Test;
+
+import ru.yandex.qatools.allure.annotations.Description;
+import ru.yandex.qatools.allure.annotations.Features;
+import ru.yandex.qatools.allure.annotations.Stories;
+
+@Features("Unit Tests - Artifact File System Repository")
+@Stories("Test storing artifact binaries in the file-system")
+public class ArtifactFilesystemTest {
+
+ @Test
+ @Description("Verifies that an exception is thrown on opening an InputStream when file does not exists")
+ public void getInputStreamOfNonExistingFileThrowsException() {
+ final File file = new File("fileWhichTotalDoesNotExists");
+ final ArtifactFilesystem underTest = new ArtifactFilesystem(file);
+ try {
+ underTest.getFileInputStream();
+ Assertions.fail("Expected a FileNotFoundException because file does not exists");
+ } catch (final RuntimeException e) {
+ assertThat(e.getCause()).isInstanceOf(FileNotFoundException.class);
+ }
+ }
+
+ @Test
+ @Description("Verifies that an InputStream can be opened if file exists")
+ public void getInputStreamOfExistingFile() throws IOException {
+ final File createTempFile = File.createTempFile(ArtifactFilesystemTest.class.getSimpleName(), "");
+ createTempFile.deleteOnExit();
+
+ final ArtifactFilesystem underTest = new ArtifactFilesystem(createTempFile);
+ final byte[] buffer = new byte[1024];
+ IOUtils.read(underTest.getFileInputStream(), buffer);
+ }
+}
diff --git a/hawkbit-artifact-repository-mongo/README.md b/hawkbit-artifact-repository-mongo/README.md
deleted file mode 100644
index 3f05d04e6..000000000
--- a/hawkbit-artifact-repository-mongo/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# HawkBit Artifact Repositoy
-HawkBit Artifact Repository is library for storing binary artifacts and metadata into MongoDB.
-It has an spring-boot autoconfiguration for easily integration into spring-boot projects.
\ No newline at end of file
diff --git a/hawkbit-autoconfigure/pom.xml b/hawkbit-autoconfigure/pom.xml
index 7eb1b6d3a..e9b102a88 100644
--- a/hawkbit-autoconfigure/pom.xml
+++ b/hawkbit-autoconfigure/pom.xml
@@ -8,8 +8,7 @@
http://www.eclipse.org/legal/epl-v10.html
-->
-
+
4.0.0
org.eclipse.hawkbit
@@ -68,7 +67,13 @@
${project.version}
true
-
+
+ org.eclipse.hawkbit
+ hawkbit-artifact-repository-filesystem
+ ${project.version}
+ true
+
+
org.springframework
spring-context-support
diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/repository/ArtifactStoreAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/repository/ArtifactStoreAutoConfiguration.java
new file mode 100644
index 000000000..f75343538
--- /dev/null
+++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/repository/ArtifactStoreAutoConfiguration.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.autoconfigure.repository;
+
+import org.eclipse.hawkbit.artifact.repository.ArtifactFilesystemProperties;
+import org.eclipse.hawkbit.artifact.repository.ArtifactFilesystemRepository;
+import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Auto configuration for the {@link ArtifactFilesystemRepository}.
+ */
+@Configuration
+@ConditionalOnMissingBean(ArtifactRepository.class)
+@EnableConfigurationProperties(ArtifactFilesystemProperties.class)
+public class ArtifactStoreAutoConfiguration {
+
+ /**
+ * @param artifactFilesystemProperties
+ * the artifact file system properties
+ * @return Default {@link ArtifactRepository} implementation.
+ */
+ @Bean
+ public ArtifactRepository artifactRepository(final ArtifactFilesystemProperties artifactFilesystemProperties) {
+ return new ArtifactFilesystemRepository(artifactFilesystemProperties);
+ }
+}
diff --git a/hawkbit-autoconfigure/src/main/resources/META-INF/spring.factories b/hawkbit-autoconfigure/src/main/resources/META-INF/spring.factories
index 176c84bb0..86bde0447 100644
--- a/hawkbit-autoconfigure/src/main/resources/META-INF/spring.factories
+++ b/hawkbit-autoconfigure/src/main/resources/META-INF/spring.factories
@@ -11,4 +11,5 @@ org.eclipse.hawkbit.autoconfigure.event.EventPublisherAutoConfiguration,\
org.eclipse.hawkbit.autoconfigure.scheduling.AsyncConfigurerAutoConfiguration,\
org.eclipse.hawkbit.autoconfigure.scheduling.ExecutorAutoConfiguration,\
org.eclipse.hawkbit.autoconfigure.amqp.AmqpAutoConfiguration,\
-org.eclipse.hawkbit.autoconfigure.security.InMemoryUserManagementConfiguration
+org.eclipse.hawkbit.autoconfigure.security.InMemoryUserManagementConfiguration,\
+org.eclipse.hawkbit.autoconfigure.repository.ArtifactStoreAutoConfiguration
diff --git a/hawkbit-ddi-resource/pom.xml b/hawkbit-ddi-resource/pom.xml
index 9664789eb..c798534aa 100644
--- a/hawkbit-ddi-resource/pom.xml
+++ b/hawkbit-ddi-resource/pom.xml
@@ -133,11 +133,6 @@
fest-assert
test
-
- de.flapdoodle.embed
- de.flapdoodle.embed.mongo
- test
-
ru.yandex.qatools.allure
allure-junit-adaptor
diff --git a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java
index d293afcd6..de42360fe 100644
--- a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java
+++ b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java
@@ -38,7 +38,7 @@ import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.test.util.WithUser;
-import org.eclipse.hawkbit.rest.AbstractRestIntegrationTestWithMongoDB;
+import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.test.SpringApplicationConfiguration;
@@ -62,7 +62,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Direct Device Integration API")
@Stories("Artifact Download Resource")
@SpringApplicationConfiguration(classes = DownloadTestConfiguration.class)
-public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMongoDB {
+public class DdiArtifactDownloadTest extends AbstractRestIntegrationTest {
private static final int ARTIFACT_SIZE = 5 * 1024 * 1024;
diff --git a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java
index 7e13b8755..762e6f35c 100644
--- a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java
+++ b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java
@@ -37,7 +37,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.model.RepositoryModelConstants;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
-import org.eclipse.hawkbit.rest.AbstractRestIntegrationTestWithMongoDB;
+import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest;
import org.eclipse.hawkbit.rest.util.JsonBuilder;
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
import org.fest.assertions.core.Condition;
@@ -59,7 +59,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
*/
@Features("Component Tests - Direct Device Integration API")
@Stories("Deployment Action Resource")
-public class DdiDeploymentBaseTest extends AbstractRestIntegrationTestWithMongoDB {
+public class DdiDeploymentBaseTest extends AbstractRestIntegrationTest {
private static final String HTTP_LOCALHOST = "http://localhost:8080/";
diff --git a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java
index 843b26479..7e7fb6c23 100644
--- a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java
+++ b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java
@@ -38,7 +38,7 @@ import org.eclipse.hawkbit.repository.test.matcher.Expect;
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
import org.eclipse.hawkbit.repository.test.util.WithUser;
-import org.eclipse.hawkbit.rest.AbstractRestIntegrationTestWithMongoDB;
+import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest;
import org.eclipse.hawkbit.rest.util.JsonBuilder;
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
@@ -57,7 +57,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
*/
@Features("Component Tests - Direct Device Integration API")
@Stories("Root Poll Resource")
-public class DdiRootControllerTest extends AbstractRestIntegrationTestWithMongoDB {
+public class DdiRootControllerTest extends AbstractRestIntegrationTest {
@Autowired
private HawkbitSecurityProperties securityProperties;
diff --git a/hawkbit-dmf-amqp/pom.xml b/hawkbit-dmf-amqp/pom.xml
index b9541f85e..540b4d53d 100644
--- a/hawkbit-dmf-amqp/pom.xml
+++ b/hawkbit-dmf-amqp/pom.xml
@@ -137,11 +137,6 @@
fest-assert
test
-
- de.flapdoodle.embed
- de.flapdoodle.embed.mongo
- test
-
org.springframework.security
spring-security-config
diff --git a/hawkbit-mgmt-resource/pom.xml b/hawkbit-mgmt-resource/pom.xml
index a425a4db7..173507809 100644
--- a/hawkbit-mgmt-resource/pom.xml
+++ b/hawkbit-mgmt-resource/pom.xml
@@ -131,11 +131,6 @@
fest-assert
test
-
- de.flapdoodle.embed
- de.flapdoodle.embed.mongo
- test
-
ru.yandex.qatools.allure
allure-junit-adaptor
diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadResource.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadResource.java
index 14b09cbb0..32976f4a6 100644
--- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadResource.java
+++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadResource.java
@@ -9,6 +9,7 @@
package org.eclipse.hawkbit.mgmt.rest.resource;
import java.io.IOException;
+import java.io.InputStream;
import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
@@ -82,8 +83,8 @@ public class MgmtDownloadResource implements MgmtDownloadRestApi {
artifactCache.getId(), artifactCache.getDownloadType());
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
- try {
- ByteStreams.copy(artifact.getFileInputStream(),
+ try (InputStream inputstream = artifact.getFileInputStream()) {
+ ByteStreams.copy(inputstream,
requestResponseContextHolder.getHttpServletResponse().getOutputStream());
} catch (final IOException e) {
LOGGER.error("Cannot copy streams", e);
diff --git a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadResourceTest.java b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadResourceTest.java
index 92552954c..7ae128996 100644
--- a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadResourceTest.java
+++ b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadResourceTest.java
@@ -18,7 +18,7 @@ import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
-import org.eclipse.hawkbit.rest.AbstractRestIntegrationTestWithMongoDB;
+import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest;
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
import org.junit.Before;
import org.junit.Test;
@@ -30,7 +30,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Management API")
@Stories("Download Resource")
-public class MgmtDownloadResourceTest extends AbstractRestIntegrationTestWithMongoDB {
+public class MgmtDownloadResourceTest extends AbstractRestIntegrationTest {
@Autowired
private DownloadIdCache downloadIdCache;
diff --git a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResourceTest.java b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResourceTest.java
index 2bda57ddf..7c3099ecb 100644
--- a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResourceTest.java
+++ b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResourceTest.java
@@ -27,6 +27,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -43,7 +44,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.test.util.HashGeneratorUtils;
import org.eclipse.hawkbit.repository.test.util.WithUser;
-import org.eclipse.hawkbit.rest.AbstractRestIntegrationTestWithMongoDB;
+import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest;
import org.eclipse.hawkbit.rest.json.model.ExceptionInfo;
import org.eclipse.hawkbit.rest.util.JsonBuilder;
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
@@ -70,7 +71,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
*/
@Features("Component Tests - Management API")
@Stories("Software Module Resource")
-public class MgmtSoftwareModuleResourceTest extends AbstractRestIntegrationTestWithMongoDB {
+public class MgmtSoftwareModuleResourceTest extends AbstractRestIntegrationTest {
@Before
public void assertPreparationOfRepo() {
@@ -165,12 +166,12 @@ public class MgmtSoftwareModuleResourceTest extends AbstractRestIntegrationTestW
assertThat(artifactManagement.countArtifactsAll()).as("Wrong artifact size").isEqualTo(1);
// binary
- assertTrue("Wrong artifact content",
- IOUtils.contentEquals(new ByteArrayInputStream(random),
- artifactManagement
- .loadArtifactBinary(
- softwareManagement.findSoftwareModuleById(sm.getId()).getArtifacts().get(0))
- .getFileInputStream()));
+ try (InputStream fileInputStream = artifactManagement
+ .loadArtifactBinary(softwareManagement.findSoftwareModuleById(sm.getId()).getArtifacts().get(0))
+ .getFileInputStream()) {
+ assertTrue("Wrong artifact content",
+ IOUtils.contentEquals(new ByteArrayInputStream(random), fileInputStream));
+ }
// hashes
assertThat(artifactManagement.findArtifactByFilename("origFilename").get(0).getSha1Hash()).as("Wrong sha1 hash")
diff --git a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/SMRessourceMisingMongoDbConnectionTest.java b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/SMRessourceMisingMongoDbConnectionTest.java
deleted file mode 100644
index 0c815831d..000000000
--- a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/SMRessourceMisingMongoDbConnectionTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package org.eclipse.hawkbit.mgmt.rest.resource;
-
-import static org.fest.assertions.api.Assertions.assertThat;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.fileUpload;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-import org.apache.commons.lang3.RandomStringUtils;
-import org.eclipse.hawkbit.exception.SpServerError;
-import org.eclipse.hawkbit.repository.model.SoftwareModule;
-import org.eclipse.hawkbit.rest.AbstractRestIntegrationTestWithMongoDB;
-import org.eclipse.hawkbit.rest.json.model.ExceptionInfo;
-import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
-import org.junit.After;
-import org.junit.Test;
-import org.springframework.mock.web.MockMultipartFile;
-import org.springframework.test.web.servlet.MvcResult;
-
-import ru.yandex.qatools.allure.annotations.Description;
-import ru.yandex.qatools.allure.annotations.Features;
-import ru.yandex.qatools.allure.annotations.Stories;
-
-/**
- * Tests {@link MgmtSoftwareModuleResource} in case of missing MongoDB
- * connection.
- *
- */
-@Features("Component Tests - Management API")
-@Stories("Download Resource")
-public class SMRessourceMisingMongoDbConnectionTest extends AbstractRestIntegrationTestWithMongoDB {
-
- @Test
- @Description("Ensures that the correct error code is returned in case MongoDB unavailable.")
- public void missingMongoDbConnectionResultsInErrorAtUpload() throws Exception {
- mongodExecutable.stop();
-
- assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
- assertThat(artifactManagement.countArtifactsAll()).isEqualTo(0);
- SoftwareModule sm = entityFactory.generateSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"),
- "name 1", "version 1", null, null);
- sm = softwareManagement.createSoftwareModule(sm);
- assertThat(artifactManagement.countArtifactsAll()).isEqualTo(0);
-
- // create test file
- final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
- final MockMultipartFile file = new MockMultipartFile("file", "origFilename", null, random);
-
- // upload
- final MvcResult mvcResult = mvc
- .perform(fileUpload("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file))
- .andDo(MockMvcResultPrinter.print()).andExpect(status().isInternalServerError()).andReturn();
-
- // check error result
- final ExceptionInfo exceptionInfo = ResourceUtility
- .convertException(mvcResult.getResponse().getContentAsString());
- assertThat(exceptionInfo.getErrorCode()).isEqualTo(SpServerError.SP_ARTIFACT_UPLOAD_FAILED.getKey());
- assertThat(exceptionInfo.getMessage()).isEqualTo(SpServerError.SP_ARTIFACT_UPLOAD_FAILED.getMessage());
-
- // ensure that the JPA transaction was rolled back
- assertThat(artifactManagement.countArtifactsAll()).isEqualTo(0);
-
- }
-
- @Override
- @After
- public void cleanCurrentCollection() {
- // not needed, mongodb is stopped already
- }
-
-}
diff --git a/hawkbit-repository/hawkbit-repository-jpa/pom.xml b/hawkbit-repository/hawkbit-repository-jpa/pom.xml
index 42fc9a62f..d1f275f81 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/pom.xml
+++ b/hawkbit-repository/hawkbit-repository-jpa/pom.xml
@@ -49,7 +49,7 @@
org.eclipse.hawkbit
- hawkbit-artifact-repository-mongo
+ hawkbit-artifact-repository-filesystem
${project.version}
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaArtifact.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaArtifact.java
index 13be80d71..847250491 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaArtifact.java
+++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaArtifact.java
@@ -20,12 +20,10 @@ import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
+import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
-import com.mongodb.gridfs.GridFS;
-import com.mongodb.gridfs.GridFSFile;
-
/**
* JPA implementation of {@link LocalArtifact}.
*
@@ -73,9 +71,9 @@ public class JpaArtifact extends AbstractJpaTenantAwareBaseEntity implements Art
* Constructs artifact.
*
* @param gridFsFileName
- * that is the link to the {@link GridFS} entity.
+ * that is the link to the {@link DbArtifact} entity.
* @param filename
- * that is used by {@link GridFSFile} store.
+ * that is used by {@link DbArtifact} store.
* @param softwareModule
* of this artifact
*/
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/AbstractJpaIntegrationTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/AbstractJpaIntegrationTest.java
index a4b929eb0..3b22f9f74 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/AbstractJpaIntegrationTest.java
+++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/AbstractJpaIntegrationTest.java
@@ -15,7 +15,6 @@ import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
import org.eclipse.hawkbit.repository.test.util.AbstractIntegrationTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
-import org.springframework.data.mongodb.gridfs.GridFsOperations;
@SpringApplicationConfiguration(classes = { org.eclipse.hawkbit.RepositoryApplicationConfiguration.class })
public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest {
@@ -62,9 +61,6 @@ public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest
@Autowired
protected TargetInfoRepository targetInfoRepository;
- @Autowired
- protected GridFsOperations operations;
-
@Autowired
protected RolloutGroupRepository rolloutGroupRepository;
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/AbstractJpaIntegrationTestWithMongoDB.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/AbstractJpaIntegrationTestWithMongoDB.java
deleted file mode 100644
index d71accc46..000000000
--- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/AbstractJpaIntegrationTestWithMongoDB.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package org.eclipse.hawkbit.repository.jpa;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-
-import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
-import org.eclipse.hawkbit.repository.test.util.AbstractIntegrationTest;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.SpringApplicationConfiguration;
-
-@SpringApplicationConfiguration(classes = { org.eclipse.hawkbit.RepositoryApplicationConfiguration.class })
-public abstract class AbstractJpaIntegrationTestWithMongoDB extends AbstractIntegrationTest {
-
- @PersistenceContext
- protected EntityManager entityManager;
-
- @Autowired
- protected TargetRepository targetRepository;
-
- @Autowired
- protected ActionRepository actionRepository;
-
- @Autowired
- protected DistributionSetRepository distributionSetRepository;
-
- @Autowired
- protected SoftwareModuleRepository softwareModuleRepository;
-
- @Autowired
- protected TenantMetaDataRepository tenantMetaDataRepository;
-
- @Autowired
- protected DistributionSetTypeRepository distributionSetTypeRepository;
-
- @Autowired
- protected SoftwareModuleTypeRepository softwareModuleTypeRepository;
-
- @Autowired
- protected TargetTagRepository targetTagRepository;
-
- @Autowired
- protected DistributionSetTagRepository distributionSetTagRepository;
-
- @Autowired
- protected SoftwareModuleMetadataRepository softwareModuleMetadataRepository;
-
- @Autowired
- protected ActionStatusRepository actionStatusRepository;
-
- @Autowired
- protected LocalArtifactRepository artifactRepository;
-
- @Autowired
- protected TargetInfoRepository targetInfoRepository;
-
- @Autowired
- protected RolloutGroupRepository rolloutGroupRepository;
-
- @Autowired
- protected RolloutRepository rolloutRepository;
-
- @Autowired
- protected TenantAwareCacheManager cacheManager;
-
-}
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ArtifactManagementFailedMongoDBTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ArtifactManagementFailedMongoDBTest.java
deleted file mode 100644
index e28d1776a..000000000
--- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ArtifactManagementFailedMongoDBTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package org.eclipse.hawkbit.repository.jpa;
-
-import static org.fest.assertions.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.net.UnknownHostException;
-
-import org.eclipse.hawkbit.repository.exception.ArtifactDeleteFailedException;
-import org.eclipse.hawkbit.repository.exception.ArtifactUploadFailedException;
-import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
-import org.eclipse.hawkbit.repository.model.Artifact;
-import org.junit.After;
-import org.junit.Test;
-
-import ru.yandex.qatools.allure.annotations.Description;
-import ru.yandex.qatools.allure.annotations.Features;
-import ru.yandex.qatools.allure.annotations.Stories;
-
-@Features("Component Tests - Repository")
-@Stories("Artifact Management")
-public class ArtifactManagementFailedMongoDBTest extends AbstractJpaIntegrationTestWithMongoDB {
-
- @Test
- @Description("Trys and fails to delete or create local artifact with a down mongodb and checks if expected ArtifactDeleteFailedException is thrown.")
- public void deleteArtifactsWithNoMongoDb() throws UnknownHostException, IOException {
- // ensure baseline
- assertThat(artifactRepository.findAll()).isEmpty();
-
- // prepare test
- JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1",
- "version 1", null, null);
- sm = softwareModuleRepository.save(sm);
-
- final Artifact result = artifactManagement.createArtifact(new RandomGeneratedInputStream(5 * 1024), sm.getId(),
- "file1", false);
-
- assertThat(artifactRepository.findAll()).hasSize(1);
-
- mongodExecutable.stop();
- try {
- artifactManagement.deleteArtifact(result.getId());
- fail("deletion should have failed");
- } catch (final ArtifactDeleteFailedException e) {
-
- }
-
- try {
- artifactManagement.createArtifact(new RandomGeneratedInputStream(5 * 1024), sm.getId(), "file2", false);
- fail("Should not have worked with MongoDb down.");
- } catch (final ArtifactUploadFailedException e) {
-
- }
-
- assertThat(artifactRepository.findAll()).hasSize(1);
-
- }
-
- @Override
- @After
- public void cleanCurrentCollection() {
- // no need to clean, is stopped already
- }
-
-}
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ArtifactManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ArtifactManagementTest.java
index 63bffc0bd..0b9bee939 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ArtifactManagementTest.java
+++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ArtifactManagementTest.java
@@ -14,6 +14,7 @@ import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.io.IOUtils;
@@ -28,8 +29,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.test.util.HashGeneratorUtils;
import org.eclipse.hawkbit.repository.test.util.WithUser;
import org.junit.Test;
-import org.springframework.data.mongodb.core.query.Criteria;
-import org.springframework.data.mongodb.core.query.Query;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
@@ -44,7 +43,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
*/
@Features("Component Tests - Repository")
@Stories("Artifact Management")
-public class ArtifactManagementTest extends AbstractJpaIntegrationTestWithMongoDB {
+public class ArtifactManagementTest extends AbstractJpaIntegrationTest {
/**
* Test method for
@@ -151,25 +150,17 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTestWithMongoD
assertThat(result2.getId()).isNotNull();
assertThat(((JpaArtifact) result).getGridFsFileName())
.isNotEqualTo(((JpaArtifact) result2).getGridFsFileName());
- assertThat(operations.findOne(
- new Query().addCriteria(Criteria.where("filename").is(((JpaArtifact) result).getGridFsFileName()))))
- .isNotNull();
- assertThat(operations.findOne(
- new Query().addCriteria(Criteria.where("filename").is(((JpaArtifact) result2).getGridFsFileName()))))
- .isNotNull();
+
+ assertThat(binaryArtifactRepository.getArtifactBySha1(((JpaArtifact) result).getGridFsFileName())).isNotNull();
+ assertThat(binaryArtifactRepository.getArtifactBySha1(((JpaArtifact) result2).getGridFsFileName())).isNotNull();
artifactManagement.deleteArtifact(result.getId());
- assertThat(operations.findOne(
- new Query().addCriteria(Criteria.where("filename").is(((JpaArtifact) result).getGridFsFileName()))))
- .isNull();
- assertThat(operations.findOne(
- new Query().addCriteria(Criteria.where("filename").is(((JpaArtifact) result2).getGridFsFileName()))))
- .isNotNull();
+
+ assertThat(binaryArtifactRepository.getArtifactBySha1(((JpaArtifact) result).getGridFsFileName())).isNull();
+ assertThat(binaryArtifactRepository.getArtifactBySha1(((JpaArtifact) result2).getGridFsFileName())).isNotNull();
artifactManagement.deleteArtifact(result2.getId());
- assertThat(operations.findOne(
- new Query().addCriteria(Criteria.where("filename").is(((JpaArtifact) result2).getGridFsFileName()))))
- .isNull();
+ assertThat(binaryArtifactRepository.getArtifactBySha1(((JpaArtifact) result2).getGridFsFileName())).isNull();
assertThat(artifactRepository.findAll()).hasSize(0);
}
@@ -198,18 +189,12 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTestWithMongoD
assertThat(result2.getId()).isNotNull();
assertThat(((JpaArtifact) result).getGridFsFileName()).isEqualTo(((JpaArtifact) result2).getGridFsFileName());
- assertThat(operations.findOne(
- new Query().addCriteria(Criteria.where("filename").is(((JpaArtifact) result).getGridFsFileName()))))
- .isNotNull();
+ assertThat(binaryArtifactRepository.getArtifactBySha1(((JpaArtifact) result).getGridFsFileName())).isNotNull();
artifactManagement.deleteArtifact(result.getId());
- assertThat(operations.findOne(
- new Query().addCriteria(Criteria.where("filename").is(((JpaArtifact) result).getGridFsFileName()))))
- .isNotNull();
+ assertThat(binaryArtifactRepository.getArtifactBySha1(((JpaArtifact) result).getGridFsFileName())).isNotNull();
artifactManagement.deleteArtifact(result2.getId());
- assertThat(operations.findOne(
- new Query().addCriteria(Criteria.where("filename").is(((JpaArtifact) result).getGridFsFileName()))))
- .isNull();
+ assertThat(binaryArtifactRepository.getArtifactBySha1(((JpaArtifact) result).getGridFsFileName())).isNull();
}
/**
@@ -253,8 +238,10 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTestWithMongoD
final Artifact result = artifactManagement.createArtifact(new ByteArrayInputStream(random), sm.getId(), "file1",
false);
- assertTrue("The stored binary matches the given binary", IOUtils.contentEquals(new ByteArrayInputStream(random),
- artifactManagement.loadArtifactBinary(result).getFileInputStream()));
+ try (InputStream fileInputStream = artifactManagement.loadArtifactBinary(result).getFileInputStream()) {
+ assertTrue("The stored binary matches the given binary",
+ IOUtils.contentEquals(new ByteArrayInputStream(random), fileInputStream));
+ }
}
@Test
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SoftwareManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SoftwareManagementTest.java
index 895210da4..4d4577062 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SoftwareManagementTest.java
+++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SoftwareManagementTest.java
@@ -45,8 +45,6 @@ import org.eclipse.hawkbit.repository.test.util.WithUser;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
-import org.springframework.data.mongodb.core.query.Criteria;
-import org.springframework.data.mongodb.core.query.Query;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
@@ -57,7 +55,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("Software Management")
-public class SoftwareManagementTest extends AbstractJpaIntegrationTestWithMongoDB {
+public class SoftwareManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Try to update non updatable fields results in repository doing nothing.")
@@ -387,7 +385,7 @@ public class SoftwareManagementTest extends AbstractJpaIntegrationTestWithMongoD
}
@Test
- @Description("Deletes an artifact, which is assigned to a Distribution Set")
+ @Description("Deletes an artifact, which is assigned to a DistributionSet")
public void softDeleteOfAssignedArtifact() {
// Init DistributionSet
@@ -464,12 +462,9 @@ public class SoftwareManagementTest extends AbstractJpaIntegrationTestWithMongoD
}
@Test
- @Description("Delete an softwaremodule with an artifact, which is also used by another softwaremodule.")
+ @Description("Delete an softwaremodule with an artifact, which is alsoused by another softwaremodule.")
public void deleteSoftwareModulesWithSharedArtifact() throws IOException {
- // Precondition: Make sure MongoDB is Empty
- assertThat(operations.find(new Query())).hasSize(0);
-
// Init artifact binary data, target and DistributionSets
final byte[] source = RandomUtils.nextBytes(1024);
@@ -489,9 +484,6 @@ public class SoftwareManagementTest extends AbstractJpaIntegrationTestWithMongoD
moduleY = softwareManagement.findSoftwareModuleById(moduleY.getId());
final Artifact artifactY = moduleY.getArtifacts().iterator().next();
- // verify: that only one entry was created in mongoDB
- assertThat(operations.find(new Query())).hasSize(1);
-
// [STEP5]: Delete SoftwareModuleX
softwareManagement.deleteSoftwareModule(moduleX.getId());
@@ -515,9 +507,6 @@ public class SoftwareManagementTest extends AbstractJpaIntegrationTestWithMongoD
@Description("Delete two assigned softwaremodules which share an artifact.")
public void deleteMultipleSoftwareModulesWhichShareAnArtifact() throws IOException {
- // Precondition: Make sure MongoDB is Empty
- assertThat(operations.find(new Query())).hasSize(0);
-
// Init artifact binary data, target and DistributionSets
final byte[] source = RandomUtils.nextBytes(1024);
final Target target = targetManagement.createTarget(new JpaTarget("test123"));
@@ -540,9 +529,6 @@ public class SoftwareManagementTest extends AbstractJpaIntegrationTestWithMongoD
moduleY = softwareManagement.findSoftwareModuleById(moduleY.getId());
final Artifact artifactY = moduleY.getArtifacts().iterator().next();
- // verify: that only one entry was created in mongoDB
- assertThat(operations.find(new Query())).hasSize(1);
-
// [STEP3]: Assign SoftwareModuleX to DistributionSetX and to target
distributionSetManagement.assignSoftwareModules(disSetX, Sets.newHashSet(moduleX));
deploymentManagement.assignDistributionSet(disSetX, Lists.newArrayList(target));
@@ -611,17 +597,14 @@ public class SoftwareManagementTest extends AbstractJpaIntegrationTestWithMongoD
assertThat(artifactRepository.findAll()).hasSize(results.length);
for (final Artifact result : results) {
assertThat(result.getId()).isNotNull();
- assertThat(operations.findOne(
- new Query().addCriteria(Criteria.where("filename").is(((JpaArtifact) result).getGridFsFileName()))))
- .isNotNull();
+ assertThat(binaryArtifactRepository.getArtifactBySha1(((JpaArtifact) result).getGridFsFileName()))
+ .isNotNull();
}
}
private void assertArtfiactNull(final Artifact... results) {
for (final Artifact result : results) {
- assertThat(operations.findOne(
- new Query().addCriteria(Criteria.where("filename").is(((JpaArtifact) result).getGridFsFileName()))))
- .isNull();
+ assertThat(binaryArtifactRepository.getArtifactBySha1(((JpaArtifact) result).getGridFsFileName())).isNull();
}
}
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SystemManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SystemManagementTest.java
index 9cb937eea..4f6d5c91d 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SystemManagementTest.java
+++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SystemManagementTest.java
@@ -28,7 +28,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("System Management")
-public class SystemManagementTest extends AbstractJpaIntegrationTestWithMongoDB {
+public class SystemManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Ensures that findTenants returns all tenants and not only restricted to the tenant which currently is logged in")
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/TenantConfigurationManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/TenantConfigurationManagementTest.java
index 2065e9026..14f387ad1 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/TenantConfigurationManagementTest.java
+++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/TenantConfigurationManagementTest.java
@@ -30,7 +30,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("Tenant Configuration Management")
-public class TenantConfigurationManagementTest extends AbstractJpaIntegrationTestWithMongoDB {
+public class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Tests that tenant specific configuration can be persisted and in case the tenant does not have specific configuration the default from environment is used instead.")
diff --git a/hawkbit-repository/hawkbit-repository-test/pom.xml b/hawkbit-repository/hawkbit-repository-test/pom.xml
index 350896f74..c3351ca33 100644
--- a/hawkbit-repository/hawkbit-repository-test/pom.xml
+++ b/hawkbit-repository/hawkbit-repository-test/pom.xml
@@ -31,7 +31,7 @@
org.eclipse.hawkbit
- hawkbit-artifact-repository-mongo
+ hawkbit-artifact-repository-filesystem
${project.version}
@@ -43,8 +43,8 @@
spring-context-support
- de.flapdoodle.embed
- de.flapdoodle.embed.mongo
+ org.springframework
+ spring-tx
net._01001111
diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/TestConfiguration.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/TestConfiguration.java
index 738513989..e70ef2ca2 100644
--- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/TestConfiguration.java
+++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/TestConfiguration.java
@@ -13,6 +13,9 @@ import java.util.concurrent.Executors;
import org.eclipse.hawkbit.api.ArtifactUrlHandlerProperties;
import org.eclipse.hawkbit.api.PropertyBasedArtifactUrlHandler;
+import org.eclipse.hawkbit.artifact.repository.ArtifactFilesystemProperties;
+import org.eclipse.hawkbit.artifact.repository.ArtifactFilesystemRepository;
+import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
import org.eclipse.hawkbit.cache.DefaultDownloadIdCache;
import org.eclipse.hawkbit.cache.DownloadIdCache;
import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
@@ -53,7 +56,6 @@ import org.springframework.security.concurrent.DelegatingSecurityContextExecutor
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.util.AntPathMatcher;
-import com.mongodb.MongoClientOptions;
/**
* Spring context configuration required for Dev.Environment.
@@ -64,10 +66,16 @@ import com.mongodb.MongoClientOptions;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.PROXY, proxyTargetClass = false, securedEnabled = true)
@EnableConfigurationProperties({ HawkbitServerProperties.class, DdiSecurityProperties.class,
- ArtifactUrlHandlerProperties.class })
+ ArtifactUrlHandlerProperties.class, ArtifactFilesystemProperties.class })
@Profile("test")
@EnableAutoConfiguration
public class TestConfiguration implements AsyncConfigurer {
+
+ @Bean
+ public ArtifactRepository artifactRepository(final ArtifactFilesystemProperties artifactFilesystemProperties) {
+ return new ArtifactFilesystemRepository(artifactFilesystemProperties);
+ }
+
@Bean
public TestRepositoryManagement testRepositoryManagement(final SystemSecurityContext systemSecurityContext,
final SystemManagement systemManagement) {
@@ -85,13 +93,6 @@ public class TestConfiguration implements AsyncConfigurer {
return new PropertyBasedArtifactUrlHandler(urlHandlerProperties);
}
- @Bean
- public MongoClientOptions options() {
- return MongoClientOptions.builder().connectTimeout(500).maxWaitTime(500).connectionsPerHost(2)
- .serverSelectionTimeout(500).build();
-
- }
-
@Bean
public TenantAware tenantAware() {
return new SecurityContextTenantAware();
diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java
index caf56426c..7c8fb8150 100644
--- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java
+++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java
@@ -12,8 +12,15 @@ import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpre
import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.SYSTEM_ROLE;
import static org.junit.rules.RuleChain.outerRule;
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
import org.eclipse.hawkbit.ExcludePathAwareShallowETagFilter;
import org.eclipse.hawkbit.TestConfiguration;
+import org.eclipse.hawkbit.artifact.repository.ArtifactFilesystemProperties;
+import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
+import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.DeploymentManagement;
@@ -54,13 +61,10 @@ import org.springframework.core.env.Environment;
import org.springframework.data.auditing.AuditingHandler;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
-import org.springframework.data.mongodb.core.query.Query;
-import org.springframework.data.mongodb.gridfs.GridFsOperations;
import org.springframework.hateoas.MediaTypes;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
@@ -68,8 +72,6 @@ import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
-import de.flapdoodle.embed.mongo.MongodExecutable;
-
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ActiveProfiles({ "test" })
@@ -80,7 +82,6 @@ import de.flapdoodle.embed.mongo.MongodExecutable;
// refreshed we e.g. get two instances of CacheManager which leads to very
// strange test failures.
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
-@TestPropertySource(properties = { "spring.data.mongodb.port=0", "spring.mongodb.embedded.version=3.2.7" })
public abstract class AbstractIntegrationTest implements EnvironmentAware {
private final static Logger LOG = LoggerFactory.getLogger(AbstractIntegrationTest.class);
@@ -154,6 +155,15 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware {
@Autowired
protected SystemSecurityContext systemSecurityContext;
+ @Autowired
+ private ArtifactFilesystemProperties artifactFilesystemProperties;
+
+ @Autowired
+ protected ArtifactRepository binaryArtifactRepository;
+
+ @Autowired
+ protected TenantAwareCacheManager cacheManager;
+
protected MockMvc mvc;
protected SoftwareModuleType osType;
@@ -165,12 +175,6 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware {
@Autowired
protected TestdataFactory testdataFactory;
- @Autowired
- protected GridFsOperations operations;
-
- @Autowired
- protected MongodExecutable mongodExecutable;
-
@Autowired
protected ServiceMatcher serviceMatcher;
@@ -232,8 +236,8 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware {
}
@After
- public void cleanCurrentCollection() {
- operations.delete(new Query());
+ public void cleanCurrentCollection() throws IOException {
+ FileUtils.deleteDirectory(new File(artifactFilesystemProperties.getPath()));
}
protected DefaultMockMvcBuilder createMvcWebAppContext() {
diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java
index 5fc3c53a8..f85bc2b25 100644
--- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java
+++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java
@@ -180,9 +180,9 @@ public final class RestResourceConversionHelper {
response.setHeader(CONTENT_RANGE, "bytes " + r.getStart() + "-" + r.getEnd() + "/" + r.getTotal());
response.setHeader(CONTENT_LENGTH, String.valueOf(r.getLength()));
- try {
- copyStreams(file.getFileInputStream(), response.getOutputStream(), controllerManagement, statusId,
- r.getStart(), r.getLength());
+ try (InputStream inputStream = file.getFileInputStream()) {
+ copyStreams(inputStream, response.getOutputStream(), controllerManagement, statusId, r.getStart(),
+ r.getLength());
} catch (final IOException e) {
LOG.error("fullfileRequest of file ({}) failed!", artifact.getFilename(), e);
throw new FileSteamingFailedException(artifact.getFilename());
@@ -246,8 +246,9 @@ public final class RestResourceConversionHelper {
response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY);
response.setStatus(SC_PARTIAL_CONTENT);
- try {
- for (final ByteRange r : ranges) {
+ for (final ByteRange r : ranges) {
+ try (InputStream inputStream = file.getFileInputStream()) {
+
// Add multipart boundary and header fields for every range.
response.getOutputStream().println();
response.getOutputStream().println("--" + MULTIPART_BOUNDARY);
@@ -255,19 +256,26 @@ public final class RestResourceConversionHelper {
.println("Content-Range: bytes " + r.getStart() + "-" + r.getEnd() + "/" + r.getTotal());
// Copy single part range of multi part range.
- copyStreams(file.getFileInputStream(), response.getOutputStream(), controllerManagement, statusId,
- r.getStart(), r.getLength());
+ copyStreams(inputStream, response.getOutputStream(), controllerManagement, statusId, r.getStart(),
+ r.getLength());
+ } catch (final IOException e) {
+ throwFileStreamingFailedException(artifact, e);
}
-
+ }
+ try {
// End with final multipart boundary.
response.getOutputStream().println();
response.getOutputStream().print("--" + MULTIPART_BOUNDARY + "--");
} catch (final IOException e) {
- LOG.error("multipartRangeRequest of file ({}) failed!", artifact.getFilename(), e);
- throw new FileSteamingFailedException(artifact.getFilename());
+ throwFileStreamingFailedException(artifact, e);
}
}
+ private static void throwFileStreamingFailedException(final Artifact artifact, final IOException e) {
+ LOG.error("multipartRangeRequest of file ({}) failed!", artifact.getFilename(), e);
+ throw new FileSteamingFailedException(artifact.getFilename());
+ }
+
private static void handleStandardRangeRequest(final Artifact artifact, final HttpServletResponse response,
final DbArtifact file, final ControllerManagement controllerManagement, final Long statusId,
final List ranges) {
@@ -276,9 +284,9 @@ public final class RestResourceConversionHelper {
response.setHeader(CONTENT_LENGTH, String.valueOf(r.getLength()));
response.setStatus(SC_PARTIAL_CONTENT);
- try {
- copyStreams(file.getFileInputStream(), response.getOutputStream(), controllerManagement, statusId,
- r.getStart(), r.getLength());
+ try (InputStream inputStream = file.getFileInputStream()) {
+ copyStreams(inputStream, response.getOutputStream(), controllerManagement, statusId, r.getStart(),
+ r.getLength());
} catch (final IOException e) {
LOG.error("standardRangeRequest of file ({}) failed!", artifact.getFilename(), e);
throw new FileSteamingFailedException(artifact.getFilename());
diff --git a/hawkbit-rest-core/src/test/java/org/eclipse/hawkbit/rest/AbstractRestIntegrationTestWithMongoDB.java b/hawkbit-rest-core/src/test/java/org/eclipse/hawkbit/rest/AbstractRestIntegrationTestWithMongoDB.java
deleted file mode 100644
index 5974917ec..000000000
--- a/hawkbit-rest-core/src/test/java/org/eclipse/hawkbit/rest/AbstractRestIntegrationTestWithMongoDB.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package org.eclipse.hawkbit.rest;
-
-import org.eclipse.hawkbit.repository.test.util.AbstractIntegrationTest;
-import org.eclipse.hawkbit.rest.configuration.RestConfiguration;
-import org.eclipse.hawkbit.rest.util.FilterHttpResponse;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.SpringApplicationConfiguration;
-import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
-
-/**
- * Abstract Test for Rest tests.
- */
-@SpringApplicationConfiguration(classes = { RestConfiguration.class,
- org.eclipse.hawkbit.RepositoryApplicationConfiguration.class })
-public abstract class AbstractRestIntegrationTestWithMongoDB extends AbstractIntegrationTest {
-
- @Autowired
- private FilterHttpResponse filterHttpResponse;
-
- @Override
- protected DefaultMockMvcBuilder createMvcWebAppContext() {
- final DefaultMockMvcBuilder createMvcWebAppContext = super.createMvcWebAppContext();
- return createMvcWebAppContext.addFilter(filterHttpResponse);
- }
-}
diff --git a/hawkbit-ui/pom.xml b/hawkbit-ui/pom.xml
index c2de99b5f..d842a4814 100644
--- a/hawkbit-ui/pom.xml
+++ b/hawkbit-ui/pom.xml
@@ -271,11 +271,6 @@
fest-assert
test
-
- de.flapdoodle.embed
- de.flapdoodle.embed.mongo
- test
-
ru.yandex.qatools.allure
allure-junit-adaptor
diff --git a/pom.xml b/pom.xml
index f26a9f577..1fa28d57b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,7 +38,7 @@
hawkbit-security-integration
hawkbit-http-security
hawkbit-ui
- hawkbit-artifact-repository-mongo
+ hawkbit-artifact-repository-filesystem
hawkbit-autoconfigure
hawkbit-test-report
examples
@@ -670,11 +670,6 @@
json
${json.version}
-
- de.flapdoodle.embed
- de.flapdoodle.embed.mongo
- ${embedded-mongo.version}
-
org.easytesting
fest-assert