Merge branch 'master' into feature_boot_13_sec_41

Conflicts:
	hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/FreePortFileWriter.java
	hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/FreePortFileWriter.java


Signed-off-by: Kai Zimmermann <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2016-08-19 08:35:58 +02:00
211 changed files with 3171 additions and 2044 deletions

View File

@@ -1,63 +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.Assertions.assertThat;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;
import org.springframework.security.access.prepost.PreAuthorize;
public class MethodSecurityUtil {
private static final Set<String> METHOD_SECURITY_EXCLUSION = new HashSet<>();
static {
METHOD_SECURITY_EXCLUSION.add("equals");
METHOD_SECURITY_EXCLUSION.add("toString");
METHOD_SECURITY_EXCLUSION.add("hashCode");
METHOD_SECURITY_EXCLUSION.add("clone");
METHOD_SECURITY_EXCLUSION.add("setEnvironment");
// this method shouldn't be public on the DeploymentManagemeht but it is
METHOD_SECURITY_EXCLUSION.add("setOverrideObsoleteUpdateActions");
METHOD_SECURITY_EXCLUSION.add("isOverrideObsoleteUpdateActions");
// this method must be public accessible without security because it's
// necessary to acccess
// the security-token of a target without being authenticated because
// the security-token is
// the authentication process
// ControllerManagement#getSecurityTokenByControllerId()
METHOD_SECURITY_EXCLUSION.add("getSecurityTokenByControllerId");
}
/**
* asserts that the given methods are annotated with the
* {@link PreAuthorize} annotation for security. Inherited methods are not
* checked. The following methods are excluded due inherited from
* {@link Object}, like equals() or toString().
*
* @param clazz
* the class to retrieve the public declared methods
*/
public static void assertDeclaredMethodsContainsPreAuthorizeAnnotaions(final Class<?> clazz) {
final Method[] declaredMethods = clazz.getDeclaredMethods();
for (final Method method : declaredMethods) {
if (!METHOD_SECURITY_EXCLUSION.contains(method.getName()) && !method.isSynthetic()
&& Modifier.isPublic(method.getModifiers())) {
final PreAuthorize annotation = method.getAnnotation(PreAuthorize.class);
assertThat(annotation).as(
"The public method " + method.getName() + " is not annoated with @PreAuthorize, security leak?")
.isNotNull();
}
}
}
}

View File

@@ -34,13 +34,13 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorAction
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorCondition;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Description;
@@ -56,9 +56,6 @@ import ru.yandex.qatools.allure.annotations.Stories;
/**
* Junit tests for RolloutManagment.
*
* @author Michael Hirsch
*
*/
@Features("Component Tests - Repository")
@Stories("Rollout Management")

View File

@@ -14,10 +14,10 @@ import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.Random;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TenantMetaData;
import org.eclipse.hawkbit.repository.report.model.TenantUsage;
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
import org.junit.Test;
@@ -30,15 +30,6 @@ import ru.yandex.qatools.allure.annotations.Stories;
@Stories("System Management")
public class SystemManagementTest extends AbstractJpaIntegrationTestWithMongoDB {
@Test
@Description("Ensures that you can create a tenant without setting the necessary security context which holds a current tenant")
public void createInitialTenantWithoutSecurityContext() {
securityRule.clear();
final String tenantToBeCreated = "newTenantToCreate";
final TenantMetaData tenantMetadata = systemManagement.getTenantMetadata(tenantToBeCreated);
assertThat(tenantMetadata).isNotNull();
}
@Test
@Description("Ensures that findTenants returns all tenants and not only restricted to the tenant which currently is logged in")
public void findTenantsReturnsAllTenantsNotOnlyWhichLoggedIn() throws Exception {
@@ -109,26 +100,27 @@ public class SystemManagementTest extends AbstractJpaIntegrationTestWithMongoDB
for (int i = 0; i < tenants; i++) {
final String tenantname = "tenant" + i;
securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("bumlux", tenantname), () -> {
systemManagement.getTenantMetadata(tenantname);
if (artifactSize > 0) {
createTestArtifact(random);
createDeletedTestArtifact(random);
}
if (targets > 0) {
final List<Target> createdTargets = createTestTargets(targets);
if (updates > 0) {
for (int x = 0; x < updates; x++) {
final DistributionSet ds = testdataFactory.createDistributionSet("to be deployed" + x,
true);
deploymentManagement.assignDistributionSet(ds, createdTargets);
securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("bumlux", tenantname, true, true,
SpringEvalExpressions.SYSTEM_ROLE), () -> {
systemManagement.getTenantMetadata(tenantname);
if (artifactSize > 0) {
createTestArtifact(random);
createDeletedTestArtifact(random);
}
}
}
if (targets > 0) {
final List<Target> createdTargets = createTestTargets(targets);
if (updates > 0) {
for (int x = 0; x < updates; x++) {
final DistributionSet ds = testdataFactory
.createDistributionSet("to be deployed" + x, true);
return null;
});
deploymentManagement.assignDistributionSet(ds, createdTargets);
}
}
}
return null;
});
}
return random;

View File

@@ -0,0 +1,161 @@
/**
* 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.eventbus;
import static org.fest.assertions.Assertions.assertThat;
import java.net.URI;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.fest.assertions.api.Assertions;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
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("Entity Events")
public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Autowired
private EventBus eventBus;
private final MyEventListener eventListener = new MyEventListener();
@Before
public void beforeTest() {
eventListener.queue.clear();
eventBus.register(eventListener);
}
@Test
@Description("Verifies that the target created event is published when a target has been created")
public void targetCreatedEventIsPublished() throws InterruptedException {
final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345"));
final TargetCreatedEvent targetCreatedEvent = eventListener.waitForEvent(TargetCreatedEvent.class, 1,
TimeUnit.SECONDS);
assertThat(targetCreatedEvent).isNotNull();
assertThat(targetCreatedEvent.getEntity().getId()).isEqualTo(createdTarget.getId());
}
@Test
@Description("Verifies that the target update event is published when a target has been updated")
public void targetUpdateEventIsPublished() throws InterruptedException {
final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345"));
createdTarget.setName("updateName");
targetManagement.updateTarget(createdTarget);
final TargetUpdatedEvent targetUpdatedEvent = eventListener.waitForEvent(TargetUpdatedEvent.class, 1,
TimeUnit.SECONDS);
assertThat(targetUpdatedEvent).isNotNull();
assertThat(targetUpdatedEvent.getEntity().getId()).isEqualTo(createdTarget.getId());
}
@Test
@Description("Verifies that the target info update event is published when a target info has been updated")
public void targetInfoUpdateEventIsPublished() throws InterruptedException {
final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345"));
controllerManagament.updateTargetStatus(createdTarget.getTargetInfo(), TargetUpdateStatus.PENDING,
System.currentTimeMillis(), URI.create("http://127.0.0.1"));
final TargetInfoUpdateEvent targetInfoUpdatedEvent = eventListener.waitForEvent(TargetInfoUpdateEvent.class, 1,
TimeUnit.SECONDS);
assertThat(targetInfoUpdatedEvent).isNotNull();
assertThat(targetInfoUpdatedEvent.getEntity().getTarget().getId()).isEqualTo(createdTarget.getId());
}
@Test
@Description("Verifies that the target deleted event is published when a target has been deleted")
public void targetDeletedEventIsPublished() throws InterruptedException {
final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345"));
targetManagement.deleteTargets(createdTarget.getId());
final TargetDeletedEvent targetDeletedEvent = eventListener.waitForEvent(TargetDeletedEvent.class, 1,
TimeUnit.SECONDS);
assertThat(targetDeletedEvent).isNotNull();
assertThat(targetDeletedEvent.getTargetId()).isEqualTo(createdTarget.getId());
}
@Test
@Description("Verifies that the distribution set created event is published when a distribution set has been created")
public void distributionSetCreatedEventIsPublished() throws InterruptedException {
final DistributionSet generateDistributionSet = entityFactory.generateDistributionSet();
generateDistributionSet.setName("dsEventTest");
generateDistributionSet.setVersion("1");
final DistributionSet createDistributionSet = distributionSetManagement
.createDistributionSet(generateDistributionSet);
final DistributionCreatedEvent dsCreatedEvent = eventListener.waitForEvent(DistributionCreatedEvent.class, 1,
TimeUnit.SECONDS);
assertThat(dsCreatedEvent).isNotNull();
assertThat(dsCreatedEvent.getEntity().getId()).isEqualTo(createDistributionSet.getId());
}
@Test
@Description("Verifies that the distribution set deleted event is published when a distribution set has been deleted")
public void distributionSetDeletedEventIsPublished() throws InterruptedException {
final DistributionSet generateDistributionSet = entityFactory.generateDistributionSet();
generateDistributionSet.setName("dsEventTest");
generateDistributionSet.setVersion("1");
final DistributionSet createDistributionSet = distributionSetManagement
.createDistributionSet(generateDistributionSet);
distributionSetManagement.deleteDistributionSet(createDistributionSet);
final DistributionDeletedEvent dsDeletedEvent = eventListener.waitForEvent(DistributionDeletedEvent.class, 1,
TimeUnit.SECONDS);
assertThat(dsDeletedEvent).isNotNull();
assertThat(dsDeletedEvent.getDistributionSetId()).isEqualTo(createDistributionSet.getId());
}
private class MyEventListener {
private final BlockingQueue<Event> queue = new LinkedBlockingQueue<>();
@Subscribe
public void onEvent(final Event event) {
queue.offer(event);
}
public <T> T waitForEvent(final Class<T> eventType, final long timeout, final TimeUnit timeUnit)
throws InterruptedException {
Event event = null;
while ((event = queue.poll(timeout, timeUnit)) != null) {
if (event.getClass().isAssignableFrom(eventType)) {
return (T) event;
}
}
Assertions.fail("Missing event " + eventType + " within timeout " + timeout + " " + timeUnit);
return null;
}
}
}

View File

@@ -0,0 +1,186 @@
/**
* 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.model;
import static org.fest.assertions.Assertions.assertThat;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder;
import org.eclipse.hawkbit.repository.model.EntityInterceptor;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Target;
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;
/**
* Test the entity listener interceptor.
*/
@Features("Component Tests - Repository")
@Stories("Entity Listener Interceptor")
public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest {
@Override
public void after() {
EntityInterceptorHolder.getInstance().getEntityInterceptors().clear();
super.after();
}
@Test
@Description("Verfies that the pre persist is called after a entity creation.")
public void prePersistIsCalledWhenPersistingATarget() {
executePersistAndAssertCallbackResult(new PrePersistEntityListener());
}
@Test
@Description("Verfies that the post persist is called after a entity creation.")
public void postPersistIsCalledWhenPersistingATarget() {
executePersistAndAssertCallbackResult(new PostPersistEntityListener());
}
@Test
@Description("Verfies that the post load is called after a entity is loaded.")
public void postLoadIsCalledWhenLoadATarget() {
final PostLoadEntityListener postLoadEntityListener = new PostLoadEntityListener();
EntityInterceptorHolder.getInstance().getEntityInterceptors().add(postLoadEntityListener);
final Target targetToBeCreated = entityFactory.generateTarget("targetToBeCreated");
targetManagement.createTarget(targetToBeCreated);
final Target loadedTarget = targetManagement.findTargetByControllerID(targetToBeCreated.getControllerId());
assertThat(postLoadEntityListener.getEntity()).isNotNull();
assertThat(postLoadEntityListener.getEntity()).isEqualTo(loadedTarget);
}
@Test
@Description("Verfies that the pre update is called after a entity update.")
public void preUpdateIsCalledWhenUpdateATarget() {
executeUpdateAndAssertCallbackResult(new PreUpdateEntityListener());
}
@Test
@Description("Verfies that the post update is called after a entity update.")
public void postUpdateIsCalledWhenUpdateATarget() {
executeUpdateAndAssertCallbackResult(new PostUpdateEntityListener());
}
@Test
@Description("Verfies that the pre remove is called after a entity deletion.")
public void preRemoveIsCalledWhenDeletingATarget() {
executeDeleteAndAssertCallbackResult(new PreRemoveEntityListener());
}
@Test
@Description("Verfies that the post remove is called after a entity deletion.")
public void postRemoveIsCalledWhenDeletingATarget() {
executeDeleteAndAssertCallbackResult(new PostRemoveEntityListener());
}
private void executePersistAndAssertCallbackResult(final AbstractEntityListener entityInterceptor) {
final Target targetToBeCreated = entityFactory.generateTarget("targetToBeCreated");
addListenerAndCreateTarget(entityInterceptor, targetToBeCreated);
assertThat(entityInterceptor.getEntity()).isNotNull();
assertThat(entityInterceptor.getEntity()).isEqualTo(targetToBeCreated);
}
private void executeUpdateAndAssertCallbackResult(final AbstractEntityListener entityInterceptor) {
Target updateTarget = addListenerAndCreateTarget(entityInterceptor,
entityFactory.generateTarget("targetToBeCreated"));
updateTarget.setDescription("New");
updateTarget = targetManagement.updateTarget(updateTarget);
assertThat(entityInterceptor.getEntity()).isNotNull();
assertThat(entityInterceptor.getEntity()).isEqualTo(updateTarget);
}
private void executeDeleteAndAssertCallbackResult(final AbstractEntityListener entityInterceptor) {
EntityInterceptorHolder.getInstance().getEntityInterceptors().add(entityInterceptor);
final SoftwareModuleType type = softwareManagement
.createSoftwareModuleType(entityFactory.generateSoftwareModuleType("test", "test", "test", 1));
softwareManagement.deleteSoftwareModuleType(type);
assertThat(entityInterceptor.getEntity()).isNotNull();
assertThat(entityInterceptor.getEntity()).isEqualTo(type);
}
private Target addListenerAndCreateTarget(final AbstractEntityListener entityInterceptor,
final Target targetToBeCreated) {
EntityInterceptorHolder.getInstance().getEntityInterceptors().add(entityInterceptor);
return targetManagement.createTarget(targetToBeCreated);
}
private static abstract class AbstractEntityListener implements EntityInterceptor {
private Object entity;
public Object getEntity() {
return entity;
}
public void setEntity(final Object entity) {
this.entity = entity;
}
}
private static class PrePersistEntityListener extends AbstractEntityListener {
@Override
public void prePersist(final Object entity) {
setEntity(entity);
}
}
private static class PostPersistEntityListener extends AbstractEntityListener {
@Override
public void postPersist(final Object entity) {
setEntity(entity);
}
}
private static class PostLoadEntityListener extends AbstractEntityListener {
@Override
public void postLoad(final Object entity) {
setEntity(entity);
}
}
private static class PreUpdateEntityListener extends AbstractEntityListener {
@Override
public void preUpdate(final Object entity) {
setEntity(entity);
}
}
private static class PostUpdateEntityListener extends AbstractEntityListener {
@Override
public void postUpdate(final Object entity) {
setEntity(entity);
}
}
private static class PreRemoveEntityListener extends AbstractEntityListener {
@Override
public void preRemove(final Object entity) {
setEntity(entity);
}
}
private static class PostRemoveEntityListener extends AbstractEntityListener {
@Override
public void postRemove(final Object entity) {
setEntity(entity);
}
}
}