diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java index 15062f27f..1e9c39237 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.repository.jpa.model; +import java.util.function.Consumer; + import javax.persistence.PostLoad; import javax.persistence.PostPersist; import javax.persistence.PostRemove; @@ -17,53 +19,51 @@ import javax.persistence.PreRemove; import javax.persistence.PreUpdate; import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder; +import org.eclipse.hawkbit.repository.model.EntityInterceptor; /** - * Entity listener which calls all entity interceptor for the lifecyles - * callbacks. + * Entity listener which calls the callback's of all registered entity + * interceptors. */ public class EntityInterceptorListener { @PrePersist protected void prePersist(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.prePersist(entity)); + notifyAll(interceptor -> interceptor.prePersist(entity)); } @PostPersist protected void postPersist(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.postPersist(entity)); + notifyAll(interceptor -> interceptor.postPersist(entity)); } @PostRemove protected void postRemove(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.postRemove(entity)); + notifyAll(interceptor -> interceptor.postRemove(entity)); } @PreRemove protected void preRemove(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.preRemove(entity)); + notifyAll(interceptor -> interceptor.preRemove(entity)); } @PostLoad protected void postLoad(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.postLoad(entity)); + notifyAll(interceptor -> interceptor.postLoad(entity)); } @PreUpdate protected void preUpdate(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.preUpdate(entity)); + notifyAll(interceptor -> interceptor.preUpdate(entity)); } @PostUpdate protected void postUpdate(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.postUpdate(entity)); + notifyAll(interceptor -> interceptor.postUpdate(entity)); + } + + private void notifyAll(final Consumer action) { + EntityInterceptorHolder.getInstance().getEntityInterceptors().forEach(action); } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityInterceptorHolder.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityInterceptorHolder.java index 8153ddc32..c374f219a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityInterceptorHolder.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityInterceptorHolder.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.jpa.model.helper; +import java.util.ArrayList; import java.util.List; import org.eclipse.hawkbit.repository.model.EntityInterceptor; @@ -22,8 +23,8 @@ public final class EntityInterceptorHolder { private static final EntityInterceptorHolder SINGLETON = new EntityInterceptorHolder(); - @Autowired - private List entityInterceptors; + @Autowired(required = false) + private final List entityInterceptors = new ArrayList<>(); private EntityInterceptorHolder() { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java new file mode 100644 index 000000000..05e27ae08 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.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.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 { + + @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 postLoadIsCalledWhenLoadgATarget() { + 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()); + EntityInterceptorHolder.getInstance().getEntityInterceptors().remove(postLoadEntityListener); + 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 postRemoveIsCalledWhenDeletinggATarget() { + executeDeleteAndAssertCallbackResult(new PostRemoveEntityListener()); + } + + private void executePersistAndAssertCallbackResult(final AbstractEntityListener entityInterceptor) { + final Target targetToBeCreated = entityFactory.generateTarget("targetToBeCreated"); + addListenerAndCreateTarget(entityInterceptor, targetToBeCreated); + + EntityInterceptorHolder.getInstance().getEntityInterceptors().remove(entityInterceptor); + 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); + + EntityInterceptorHolder.getInstance().getEntityInterceptors().remove(entityInterceptor); + 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); + EntityInterceptorHolder.getInstance().getEntityInterceptors().remove(entityInterceptor); + + assertThat(entityInterceptor.getEntity()).isNotNull(); + assertThat(entityInterceptor.getEntity()).isEqualTo(type); + } + + private Target addListenerAndCreateTarget(final AbstractEntityListener entityInterceptor, + final Target targetToBeCreated) { + EntityInterceptorHolder.getInstance().getEntityInterceptors().add(entityInterceptor); + + final Target createTarget = targetManagement.createTarget(targetToBeCreated); + + return createTarget; + } + + 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); + } + } +} \ No newline at end of file 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 3d09fabc3..a101ac755 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 @@ -182,6 +182,9 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware { @After public void after() { testRepositoryManagement.clearTestRepository(); + + targetManagement.findAllTargetIds(); + } protected DefaultMockMvcBuilder createMvcWebAppContext() {