Add filesystem artifact repository implementation (#336)

Signed-off-by: Michael Hirsch <michael.hirsch@bosch-si.com>
This commit is contained in:
Michael Hirsch
2016-11-14 11:23:50 +01:00
committed by Kai Zimmermann
parent 9b42c8cf57
commit 8be49a1184
48 changed files with 682 additions and 425 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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();
}
}

View File

@@ -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")

View File

@@ -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.")