diff --git a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/relationship/RelationshipService.java b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/relationship/RelationshipService.java index 4f70d2914c2f..21dcb50ff303 100644 --- a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/relationship/RelationshipService.java +++ b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/relationship/RelationshipService.java @@ -27,8 +27,6 @@ */ package org.hisp.dhis.relationship; -import java.util.List; - /** * @author Abyot Asalefew */ @@ -42,6 +40,4 @@ public interface RelationshipService { * @return id of the added relationship. */ long addRelationship(Relationship relationship); - - List getRelationshipsByRelationshipType(RelationshipType relationshipType); } diff --git a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/relationship/RelationshipStore.java b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/relationship/RelationshipStore.java index 474254998fe1..d63b11a72ed4 100644 --- a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/relationship/RelationshipStore.java +++ b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/relationship/RelationshipStore.java @@ -36,8 +36,6 @@ public interface RelationshipStore extends IdentifiableObjectStore { String ID = RelationshipStore.class.getName(); - List getByRelationshipType(RelationshipType relationshipType); - List getUidsByRelationshipKeys(List relationshipKeyList); List getByUidsIncludeDeleted(List uids); diff --git a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/relationship/DefaultRelationshipService.java b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/relationship/DefaultRelationshipService.java index 5440c53512b8..00d1c50957f5 100644 --- a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/relationship/DefaultRelationshipService.java +++ b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/relationship/DefaultRelationshipService.java @@ -27,7 +27,6 @@ */ package org.hisp.dhis.relationship; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -52,10 +51,4 @@ public long addRelationship(Relationship relationship) { return relationship.getId(); } - - @Override - @Transactional(readOnly = true) - public List getRelationshipsByRelationshipType(RelationshipType relationshipType) { - return relationshipStore.getByRelationshipType(relationshipType); - } } diff --git a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/relationship/RelationshipDeletionHandler.java b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/relationship/RelationshipDeletionHandler.java index e7a5088e7d6e..1e42db2625d1 100644 --- a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/relationship/RelationshipDeletionHandler.java +++ b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/relationship/RelationshipDeletionHandler.java @@ -27,12 +27,10 @@ */ package org.hisp.dhis.relationship; -import static org.hisp.dhis.system.deletion.DeletionVeto.ACCEPT; - -import java.util.Collection; +import java.util.Map; import lombok.RequiredArgsConstructor; -import org.hisp.dhis.system.deletion.DeletionHandler; import org.hisp.dhis.system.deletion.DeletionVeto; +import org.hisp.dhis.system.deletion.IdObjectDeletionHandler; import org.springframework.stereotype.Component; /** @@ -40,20 +38,16 @@ */ @Component @RequiredArgsConstructor -public class RelationshipDeletionHandler extends DeletionHandler { - private static final DeletionVeto VETO = new DeletionVeto(Relationship.class); - - private final RelationshipService relationshipService; - +public class RelationshipDeletionHandler extends IdObjectDeletionHandler { @Override - protected void register() { + protected void registerHandler() { whenVetoing(RelationshipType.class, this::allowDeleteRelationshipType); } private DeletionVeto allowDeleteRelationshipType(RelationshipType relationshipType) { - Collection relationships = - relationshipService.getRelationshipsByRelationshipType(relationshipType); - - return relationships.isEmpty() ? ACCEPT : VETO; + return vetoIfExists( + VETO, + "select 1 from relationship where relationshiptypeid = :id limit 1", + Map.of("id", relationshipType.getId())); } } diff --git a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/relationship/hibernate/HibernateRelationshipStore.java b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/relationship/hibernate/HibernateRelationshipStore.java index abef0f7ebf79..1b196b9f22ee 100644 --- a/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/relationship/hibernate/HibernateRelationshipStore.java +++ b/dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/relationship/hibernate/HibernateRelationshipStore.java @@ -62,16 +62,6 @@ public HibernateRelationshipStore( super(entityManager, jdbcTemplate, publisher, Relationship.class, aclService, true); } - @Override - public List getByRelationshipType(RelationshipType relationshipType) { - CriteriaBuilder builder = getCriteriaBuilder(); - - return getList( - builder, - newJpaParameters() - .addPredicate(root -> builder.equal(root.join("relationshipType"), relationshipType))); - } - @Override @SuppressWarnings("unchecked") public List getUidsByRelationshipKeys(List relationshipKeyList) { diff --git a/dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/relationship/RelationshipDeletionHandlerTest.java b/dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/relationship/RelationshipDeletionHandlerTest.java deleted file mode 100644 index 328aa6b51f12..000000000000 --- a/dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/relationship/RelationshipDeletionHandlerTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2004-2022, University of Oslo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.hisp.dhis.relationship; - -import static java.util.Collections.singletonList; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - -import org.hisp.dhis.common.DeleteNotAllowedException; -import org.hisp.dhis.common.ObjectDeletionRequestedEvent; -import org.hisp.dhis.system.deletion.DefaultDeletionManager; -import org.hisp.dhis.system.deletion.DeletionManager; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class RelationshipDeletionHandlerTest { - - @Mock private RelationshipService relationshipService; - - private final DeletionManager deletionManager = new DefaultDeletionManager(); - - @BeforeEach - public void setUp() { - RelationshipDeletionHandler handler = new RelationshipDeletionHandler(relationshipService); - handler.setManager(deletionManager); - handler.init(); - } - - @Test - void allowDeleteRelationshipTypeWithData() { - when(relationshipService.getRelationshipsByRelationshipType(any())) - .thenReturn(singletonList(new Relationship())); - - ObjectDeletionRequestedEvent event = new ObjectDeletionRequestedEvent(new RelationshipType()); - Exception ex = - assertThrows(DeleteNotAllowedException.class, () -> deletionManager.onDeletion(event)); - assertEquals( - "Object could not be deleted because it is associated with another object: Relationship", - ex.getMessage()); - } -} diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/relationship/RelationshipDeletionHandlerTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/relationship/RelationshipDeletionHandlerTest.java new file mode 100644 index 000000000000..e05bbd47be22 --- /dev/null +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/relationship/RelationshipDeletionHandlerTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2004-2022, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.relationship; + +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.hisp.dhis.common.DeleteNotAllowedException; +import org.hisp.dhis.common.IdentifiableObjectManager; +import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.test.integration.PostgresIntegrationTestBase; +import org.hisp.dhis.trackedentity.TrackedEntity; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class RelationshipDeletionHandlerTest extends PostgresIntegrationTestBase { + private RelationshipType relationshipType; + + private RelationshipType deletableRelationshipType; + + private Relationship relationship; + + @Autowired private IdentifiableObjectManager manager; + + @BeforeAll + public void setUp() { + relationshipType = createRelationshipType('A'); + manager.save(relationshipType); + deletableRelationshipType = createRelationshipType('B'); + manager.save(deletableRelationshipType); + OrganisationUnit orgUnit = createOrganisationUnit('A'); + manager.save(orgUnit); + TrackedEntity trackedEntityFrom = createTrackedEntity(orgUnit); + manager.save(trackedEntityFrom); + TrackedEntity trackedEntityTo = createTrackedEntity(orgUnit); + manager.save(trackedEntityTo); + relationship = createTeToTeRelationship(trackedEntityFrom, trackedEntityTo, relationshipType); + manager.save(relationship); + } + + @Test + void shouldThrowExceptionWhenRelationshipTypeIsDeletedButARelationshipIsInTheDB() { + assertThrows(DeleteNotAllowedException.class, () -> manager.delete(relationshipType)); + } + + @Test + void shouldSuccessfullyDeleteRelationshipTypeWhenNoLinkedRelationshipIsInTheDB() { + manager.delete(deletableRelationshipType); + + assertNull(manager.get(RelationshipType.class, deletableRelationshipType.getUid())); + } +} diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/relationship/hibernate/RelationshipStoreTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/relationship/hibernate/RelationshipStoreTest.java deleted file mode 100644 index b210d954bbba..000000000000 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/relationship/hibernate/RelationshipStoreTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2004-2022, University of Oslo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.hisp.dhis.relationship.hibernate; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import org.hisp.dhis.attribute.Attribute; -import org.hisp.dhis.attribute.AttributeService; -import org.hisp.dhis.attribute.AttributeValue; -import org.hisp.dhis.category.CategoryService; -import org.hisp.dhis.common.IdentifiableObjectManager; -import org.hisp.dhis.common.ValueType; -import org.hisp.dhis.commons.util.RelationshipUtils; -import org.hisp.dhis.organisationunit.OrganisationUnit; -import org.hisp.dhis.organisationunit.OrganisationUnitService; -import org.hisp.dhis.program.ProgramService; -import org.hisp.dhis.program.ProgramStageService; -import org.hisp.dhis.relationship.Relationship; -import org.hisp.dhis.relationship.RelationshipItem; -import org.hisp.dhis.relationship.RelationshipService; -import org.hisp.dhis.relationship.RelationshipType; -import org.hisp.dhis.relationship.RelationshipTypeService; -import org.hisp.dhis.test.integration.PostgresIntegrationTestBase; -import org.hisp.dhis.trackedentity.TrackedEntity; -import org.hisp.dhis.trackedentity.TrackedEntityService; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; - -@Transactional -class RelationshipStoreTest extends PostgresIntegrationTestBase { - @Autowired private RelationshipService relationshipService; - - @Autowired private RelationshipTypeService relationshipTypeService; - - @Autowired private TrackedEntityService trackedEntityService; - - @Autowired private OrganisationUnitService organisationUnitService; - - @Autowired private ProgramService programService; - - @Autowired private ProgramStageService programStageService; - - @Autowired private AttributeService attributeService; - - @Autowired private IdentifiableObjectManager manager; - - @Autowired private CategoryService categoryService; - - private TrackedEntity trackedEntityA; - - private RelationshipType relationshipType; - - private OrganisationUnit organisationUnit; - - @BeforeEach - void setUp() { - relationshipType = createRelationshipType('A'); - relationshipTypeService.addRelationshipType(relationshipType); - organisationUnit = createOrganisationUnit("testOU"); - organisationUnitService.addOrganisationUnit(organisationUnit); - } - - @Test - void testGetByRelationshipType() { - Relationship teRelationship = addTeToTeRelationship(); - - List relationshipList = - relationshipService.getRelationshipsByRelationshipType(relationshipType); - - assertEquals(1, relationshipList.size()); - assertTrue(relationshipList.contains(teRelationship)); - } - - @Test - void testAddRelationshipTypeWithAttribute() { - Attribute attribute = createAttribute('A'); - attribute.setRelationshipTypeAttribute(true); - attribute.setValueType(ValueType.TEXT); - attributeService.addAttribute(attribute); - - relationshipType = createRelationshipType('A'); - relationshipType.getAttributeValues().add(new AttributeValue(attribute, "test")); - relationshipTypeService.addRelationshipType(relationshipType); - - RelationshipType saved = relationshipTypeService.getRelationshipType(relationshipType.getId()); - assertEquals("test", saved.getAttributeValue(attribute).getValue()); - } - - private Relationship addTeToTeRelationship() { - trackedEntityA = createTrackedEntity(organisationUnit); - TrackedEntity trackedEntityB = createTrackedEntity(organisationUnit); - - trackedEntityService.addTrackedEntity(trackedEntityA); - trackedEntityService.addTrackedEntity(trackedEntityB); - - Relationship teRelationship = new Relationship(); - - RelationshipItem relationshipItemFrom = new RelationshipItem(); - RelationshipItem relationshipItemTo = new RelationshipItem(); - relationshipItemFrom.setTrackedEntity(trackedEntityA); - relationshipItemTo.setTrackedEntity(trackedEntityB); - - teRelationship.setRelationshipType(relationshipType); - teRelationship.setFrom(relationshipItemFrom); - teRelationship.setTo(relationshipItemTo); - teRelationship.setKey(RelationshipUtils.generateRelationshipKey(teRelationship)); - teRelationship.setInvertedKey( - RelationshipUtils.generateRelationshipInvertedKey(teRelationship)); - relationshipService.addRelationship(teRelationship); - return teRelationship; - } -}