TSK-341: No Exception when Classification-parent for ID does not exist

This commit is contained in:
Marcel Lengl 2018-02-28 14:27:04 +01:00 committed by Holger Hagen
parent d9bb89248b
commit e32a1acbc6
8 changed files with 155 additions and 72 deletions

View File

@ -65,20 +65,22 @@ public interface ClassificationService {
* when the classification does already exists at the given domain.
* @throws NotAuthorizedException
* if the current user is not member of role BUSINESS_ADMIN or ADMIN
* @throws ClassificationNotFoundException
* if the current parentId is not NULL/EMPTY and can not be found.
*/
Classification createClassification(Classification classification)
throws ClassificationAlreadyExistException, NotAuthorizedException;
throws ClassificationAlreadyExistException, NotAuthorizedException, ClassificationNotFoundException;
/**
* Update a Classification.
* Updates a Classification.
*
* @param classification
* the Classification to update
* @return the updated Classification.
* @throws ClassificationNotFoundException
* when the classification does not exist already.
* when the classification OR it´s parent does not exist.
* @throws NotAuthorizedException
* when a user got no permissions for WB content tasks.
* when the caller got no ADMIN or BUSINESS_ADMIN permissions.
* @throws ConcurrencyException
* when the Classification was modified meanwhile and is not latest anymore.
*/

View File

@ -46,7 +46,7 @@ public class ClassificationServiceImpl implements ClassificationService {
@Override
public Classification createClassification(Classification classification)
throws ClassificationAlreadyExistException, NotAuthorizedException {
throws ClassificationAlreadyExistException, NotAuthorizedException, ClassificationNotFoundException {
LOGGER.debug("entry to createClassification(classification = {})", classification);
taskanaEngine.checkRoleMembership(TaskanaRole.BUSINESS_ADMIN, TaskanaRole.ADMIN);
ClassificationImpl classificationImpl;
@ -54,7 +54,6 @@ public class ClassificationServiceImpl implements ClassificationService {
try {
taskanaEngine.openConnection();
isClassificationExisting = doesClassificationExist(classification.getKey(), classification.getDomain());
if (isClassificationExisting) {
throw new ClassificationAlreadyExistException(classification);
}
@ -63,8 +62,11 @@ public class ClassificationServiceImpl implements ClassificationService {
classificationImpl.setModified(classificationImpl.getCreated());
this.initDefaultClassificationValues(classificationImpl);
if (classificationImpl.getParentId() != null && !classificationImpl.getParentId().isEmpty()) {
this.getClassification(classificationImpl.getParentId());
}
classificationMapper.insert(classificationImpl);
LOGGER.debug("Method createClassification created classification {}.", classification);
LOGGER.debug("Method createClassification created classification {}.", classificationImpl);
if (!classification.getDomain().isEmpty()) {
addClassificationToRootDomain(classificationImpl);
@ -113,59 +115,49 @@ public class ClassificationServiceImpl implements ClassificationService {
@Override
public Classification updateClassification(Classification classification)
throws NotAuthorizedException, ConcurrencyException {
throws NotAuthorizedException, ConcurrencyException, ClassificationNotFoundException {
LOGGER.debug("entry to updateClassification(Classification = {})", classification);
taskanaEngine.checkRoleMembership(TaskanaRole.BUSINESS_ADMIN, TaskanaRole.ADMIN);
ClassificationImpl classificationImpl = null;
try {
taskanaEngine.openConnection();
classificationImpl = (ClassificationImpl) classification;
// UPDATE/INSERT classification
try {
Classification oldClassification = this.getClassification(classificationImpl.getKey(),
classificationImpl.getDomain());
if (!oldClassification.getModified().equals(classificationImpl.getModified())) {
throw new ConcurrencyException(
"The current Classification has been modified while editing. The values can not be updated. Classification="
+ classificationImpl.toString());
// Check if current object is based on the newest (by modified)
Classification oldClassification = this.getClassification(classificationImpl.getKey(),
classificationImpl.getDomain());
if (!oldClassification.getModified().equals(classificationImpl.getModified())) {
throw new ConcurrencyException(
"The current Classification has been modified while editing. The values can not be updated. Classification="
+ classificationImpl.toString());
}
classificationImpl.setModified(Instant.now());
this.initDefaultClassificationValues(classificationImpl);
// Update classification fields used by tasks
if (oldClassification.getCategory() != classificationImpl.getCategory()) {
List<TaskSummary> taskSumamries = taskanaEngine.getTaskService()
.createTaskQuery()
.classificationKeyIn(oldClassification.getKey())
.classificationCategoryIn(oldClassification.getCategory())
.list();
if (!taskSumamries.isEmpty()) {
List<String> taskIds = new ArrayList<>();
taskSumamries.stream().forEach(ts -> taskIds.add(ts.getTaskId()));
taskMapper.updateClassificationCategoryOnChange(taskIds, classificationImpl.getCategory());
}
classificationImpl.setModified(Instant.now());
this.initDefaultClassificationValues(classificationImpl);
// Update classification fields used by tasks
if (oldClassification.getCategory() != classificationImpl.getCategory()) {
List<TaskSummary> taskSumamries = taskanaEngine.getTaskService()
.createTaskQuery()
.classificationKeyIn(oldClassification.getKey())
.classificationCategoryIn(oldClassification.getCategory())
.list();
if (!taskSumamries.isEmpty()) {
List<String> taskIds = new ArrayList<>();
taskSumamries.stream().forEach(ts -> taskIds.add(ts.getTaskId()));
taskMapper.updateClassificationCategoryOnChange(taskIds, classificationImpl.getCategory());
}
}
classificationMapper.update(classificationImpl);
LOGGER.debug("Method updateClassification() updated the classification {}.",
classificationImpl);
} catch (ClassificationNotFoundException e) {
classificationImpl.setCreated(classification.getModified());
classificationMapper.insert(classificationImpl);
LOGGER.debug(
"Method updateClassification() inserted a unpersisted classification which was wanted to be updated {}.",
classificationImpl);
}
// CHECK if classification does exist now
try {
Classification updatedClassification = this.getClassification(classificationImpl.getKey(),
classificationImpl.getDomain());
return updatedClassification;
} catch (ClassificationNotFoundException e) {
LOGGER.debug(
"Throwing SystemException because updateClassification didn't find new classification {} after update",
classification);
throw new SystemException("updateClassification didn't find new classification after update");
// Check if parentId changed and object does exist
if (!oldClassification.getParentId().equals(classificationImpl.getParentId())) {
if (classificationImpl.getParentId() != null && !classificationImpl.getParentId().isEmpty()) {
this.getClassification(classificationImpl.getParentId());
}
}
classificationMapper.update(classificationImpl);
LOGGER.debug("Method updateClassification() updated the classification {}.",
classificationImpl);
return classification;
} finally {
taskanaEngine.returnConnection();
LOGGER.debug("exit from updateClassification().");

View File

@ -98,7 +98,7 @@ public class CreateClassificationAccTest extends AbstractAccTest {
groupNames = {"group_1", "businessadmin"})
@Test
public void testCreateClassificationWithInvalidValues()
throws ClassificationAlreadyExistException, NotAuthorizedException {
throws ClassificationAlreadyExistException, NotAuthorizedException, ClassificationNotFoundException {
long amountOfClassificationsBefore = classificationService.createClassificationQuery().count();
// Check key NULL
@ -135,12 +135,23 @@ public class CreateClassificationAccTest extends AbstractAccTest {
groupNames = {"group_1", "businessadmin"})
@Test(expected = ClassificationAlreadyExistException.class)
public void testCreateClassificationAlreadyExisting()
throws ClassificationAlreadyExistException, NotAuthorizedException {
throws ClassificationAlreadyExistException, NotAuthorizedException, ClassificationNotFoundException {
Classification classification = classificationService.newClassification("Key3", "", "TASK");
classification = classificationService.createClassification(classification);
classification = classificationService.createClassification(classification);
}
@WithAccessId(
userName = "teamlead_1",
groupNames = {"group_1", "businessadmin"})
@Test(expected = ClassificationNotFoundException.class)
public void testCreateClassificationWithInvalidParent()
throws ClassificationAlreadyExistException, NotAuthorizedException, ClassificationNotFoundException {
Classification classification = classificationService.newClassification("Key4", "", "TASK");
classification.setParentId("ID WHICH CANT BE FOUND");
classification = classificationService.createClassification(classification);
}
@AfterClass
public static void cleanUpClass() {
FileUtils.deleteRecursive("~/data", true);

View File

@ -62,7 +62,7 @@ public class UpdateClassificationAccTest extends AbstractAccTest {
classification.setDescription("newDescription");
classification.setIsValidInDomain(false);
classification.setName(newName);
classification.setParentId("T2000");
classification.setParentId("CLI:100000000000000000000000000000000004");
classification.setPriority(1000);
classification.setServiceLevel("P2DT3H4M");
@ -156,6 +156,19 @@ public class UpdateClassificationAccTest extends AbstractAccTest {
fail("The Classification should not be updated, because it was modified while editing.");
}
@WithAccessId(
userName = "teamlead_1",
groupNames = {"group_1", "businessadmin"})
@Test(expected = ClassificationNotFoundException.class)
public void testUpdateClassificationParentToInvalid()
throws NotAuthorizedException, ClassificationNotFoundException,
ConcurrencyException {
ClassificationService classificationService = taskanaEngine.getClassificationService();
Classification classification = classificationService.getClassification("T2100", "DOMAIN_A");
classification.setParentId("ID WHICH CANT BE FOUND");
classification = classificationService.updateClassification(classification);
}
@AfterClass
public static void cleanUpClass() {
FileUtils.deleteRecursive("~/data", true);

View File

@ -78,6 +78,30 @@ public class ClassificationServiceImplTest {
}
}
@Test(expected = ClassificationNotFoundException.class)
public void testCreateClassificationParentNotExisting()
throws ClassificationAlreadyExistException, ClassificationNotFoundException, NotAuthorizedException {
Classification classification = createDummyClassification();
classification.setParentId("NOT EXISTING ID");
doReturn(null).when(classificationMapperMock).findByKeyAndDomain(classification.getKey(),
classification.getDomain());
doReturn(null).when(classificationMapperMock).findById(classification.getParentId());
try {
cutSpy.createClassification(classification);
} catch (ClassificationNotFoundException e) {
verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any());
verify(taskanaEngineImplMock, times(2)).openConnection();
verify(classificationMapperMock, times(1)).findByKeyAndDomain(classification.getKey(),
classification.getDomain());
verify(cutSpy, times(1)).getClassification(classification.getParentId());
verify(classificationMapperMock, times(1)).findById(classification.getParentId());
verify(taskanaEngineImplMock, times(2)).returnConnection();
verifyNoMoreInteractions(classificationMapperMock, taskanaEngineImplMock, classificationQueryImplMock);
throw e;
}
}
@Test
public void testCreateClassificationInOwnDomainButExistingInRoot()
throws ClassificationAlreadyExistException, ClassificationNotFoundException, InterruptedException,
@ -111,7 +135,7 @@ public class ClassificationServiceImplTest {
@Test
public void testCreateClassificationInOwnDomainAndCopyInRootDomain()
throws ClassificationAlreadyExistException, NotAuthorizedException {
throws ClassificationAlreadyExistException, NotAuthorizedException, ClassificationNotFoundException {
Classification classification = createDummyClassification();
String domain = classification.getDomain();
String key = classification.getKey();
@ -135,7 +159,7 @@ public class ClassificationServiceImplTest {
@Test
public void testCreateClassificationIntoRootDomain()
throws ClassificationAlreadyExistException, NotAuthorizedException {
throws ClassificationAlreadyExistException, NotAuthorizedException, ClassificationNotFoundException {
ClassificationImpl classification = (ClassificationImpl) createDummyClassification();
classification.setDomain("");
doReturn(null).when(classificationMapperMock).findByKeyAndDomain(classification.getKey(),
@ -166,13 +190,44 @@ public class ClassificationServiceImplTest {
classification = cutSpy.updateClassification(classification);
verify(taskanaEngineImplMock, times(1)).openConnection();
verify(cutSpy, times(2)).getClassification(classification.getKey(), classification.getDomain());
verify(cutSpy, times(1)).getClassification(classification.getKey(), classification.getDomain());
verify(classificationMapperMock, times(1)).update(any());
verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any());
verify(taskanaEngineImplMock, times(1)).returnConnection();
verifyNoMoreInteractions(classificationMapperMock, taskanaEngineImplMock, classificationQueryImplMock);
}
@Test(expected = ClassificationNotFoundException.class)
public void testUpdateClassificationParentNotExisting()
throws ClassificationAlreadyExistException, ClassificationNotFoundException, NotAuthorizedException,
ConcurrencyException {
Instant now = Instant.now();
ClassificationImpl oldClassification = (ClassificationImpl) createDummyClassification();
oldClassification.setParentId("SOME ID");
oldClassification.setCreated(now);
oldClassification.setModified(now);
Classification classification = createDummyClassification();
classification.setParentId("DIFFERENT ID - FOR CHECKING PARENT");
((ClassificationImpl) classification).setCreated(oldClassification.getCreated());
((ClassificationImpl) classification).setModified(oldClassification.getModified());
doReturn(oldClassification).when(cutSpy).getClassification(classification.getKey(), classification.getDomain());
doReturn(null).when(classificationMapperMock).findById(classification.getParentId());
try {
cutSpy.updateClassification(classification);
} catch (ClassificationNotFoundException e) {
verify(taskanaEngineImplMock, times(1)).checkRoleMembership(any());
verify(taskanaEngineImplMock, times(2)).openConnection();
verify(cutSpy, times(1)).getClassification(classification.getKey(),
classification.getDomain());
verify(cutSpy, times(1)).getClassification(classification.getParentId());
verify(classificationMapperMock, times(1)).findById(classification.getParentId());
verify(taskanaEngineImplMock, times(2)).returnConnection();
verifyNoMoreInteractions(classificationMapperMock, taskanaEngineImplMock, classificationQueryImplMock);
throw e;
}
}
@Test
public void testGetClassificationFromDomain() throws ClassificationNotFoundException {
Classification expectedClassification = createDummyClassification();

View File

@ -160,7 +160,8 @@ public class ClassificationServiceImplIntAutoCommitTest {
}
@Test
public void testFindAllClassifications() throws ClassificationAlreadyExistException, NotAuthorizedException {
public void testFindAllClassifications()
throws ClassificationAlreadyExistException, NotAuthorizedException, ClassificationNotFoundException {
Classification classification0 = this.createDummyClassificationWithUniqueKey("", "type1");
classificationService.createClassification(classification0);
Classification classification1 = this.createDummyClassificationWithUniqueKey("", "type1");
@ -227,7 +228,7 @@ public class ClassificationServiceImplIntAutoCommitTest {
@Test
public void testFindWithClassificationMapperDomainAndCategory()
throws ClassificationAlreadyExistException, NotAuthorizedException {
throws ClassificationAlreadyExistException, NotAuthorizedException, ClassificationNotFoundException {
Classification classification1 = this.createDummyClassificationWithUniqueKey("domain1", "type1");
classification1.setCategory("category1");
classificationService.createClassification(classification1);
@ -249,7 +250,7 @@ public class ClassificationServiceImplIntAutoCommitTest {
@Test
public void testFindWithClassificationMapperCustomAndCategory()
throws ClassificationAlreadyExistException, NotAuthorizedException {
throws ClassificationAlreadyExistException, NotAuthorizedException, ClassificationNotFoundException {
Classification classification1 = this.createDummyClassificationWithUniqueKey("", "type1");
classification1.setDescription("DESC1");
classification1.setCategory("category1");
@ -286,26 +287,27 @@ public class ClassificationServiceImplIntAutoCommitTest {
@Test
public void testFindWithClassificationMapperPriorityTypeAndParent()
throws ClassificationAlreadyExistException, NumberFormatException, NotAuthorizedException {
throws ClassificationAlreadyExistException, NumberFormatException, NotAuthorizedException,
ClassificationNotFoundException {
Classification classification = this.createDummyClassificationWithUniqueKey("", "type1");
classification.setPriority(Integer.decode("5"));
classificationService.createClassification(classification);
Classification classification1 = this.createDummyClassificationWithUniqueKey("", "type1");
classification1.setPriority(Integer.decode("3"));
classification1.setParentId(classification.getKey());
classification1.setParentId(classification.getId());
classificationService.createClassification(classification1);
Classification classification2 = this.createDummyClassificationWithUniqueKey("", "type2");
classification2.setPriority(Integer.decode("5"));
classification2.setParentId(classification.getKey());
classification2.setParentId(classification.getId());
classificationService.createClassification(classification2);
Classification classification3 = this.createDummyClassificationWithUniqueKey("", "type1");
classification3.setPriority(Integer.decode("5"));
classification3.setParentId(classification1.getKey());
classification3.setParentId(classification1.getId());
classificationService.createClassification(classification3);
List<ClassificationSummary> list = classificationService.createClassificationQuery()
.parentIdIn(classification.getKey())
.parentIdIn(classification.getId())
.list();
Assert.assertEquals(2, list.size());
list = classificationService.createClassificationQuery().typeIn("type1").priorityIn(Integer.decode("5")).list();
@ -313,14 +315,14 @@ public class ClassificationServiceImplIntAutoCommitTest {
list = classificationService.createClassificationQuery()
.priorityIn(Integer.decode("5"))
.typeIn("type1")
.parentIdIn(classification1.getKey())
.parentIdIn(classification1.getId())
.list();
Assert.assertEquals(1, list.size());
}
@Test
public void testFindWithClassificationMapperServiceLevelNameAndDescription()
throws ClassificationAlreadyExistException, NotAuthorizedException {
throws ClassificationAlreadyExistException, NotAuthorizedException, ClassificationNotFoundException {
int all = 0;
Classification classification = this.createDummyClassificationWithUniqueKey("", "type1");
classification.setServiceLevel("P1D");
@ -366,7 +368,7 @@ public class ClassificationServiceImplIntAutoCommitTest {
Classification classification1 = this.createDummyClassificationWithUniqueKey("UNIQUE-DOMAIN", "type1");
classification1 = classificationService.createClassification(classification1);
classification1.setParentId(classification.getKey());
classification1.setParentId(classification.getId());
classification1 = classificationService.updateClassification(classification1);
List<ClassificationSummary> list = classificationService.createClassificationQuery()

View File

@ -171,7 +171,8 @@ public class ClassificationServiceImplIntExplicitTest {
@Test
public void testFindAllClassifications()
throws SQLException, ClassificationAlreadyExistException, NotAuthorizedException {
throws SQLException, ClassificationAlreadyExistException, NotAuthorizedException,
ClassificationNotFoundException {
Connection connection = dataSource.getConnection();
taskanaEngineImpl.setConnection(connection);
Classification classification0 = this.createNewClassificationWithUniqueKey("", "t1");
@ -208,7 +209,8 @@ public class ClassificationServiceImplIntExplicitTest {
@Test
public void testInsertAndClassificationQuery()
throws SQLException, ClassificationAlreadyExistException, NotAuthorizedException {
throws SQLException, ClassificationAlreadyExistException, NotAuthorizedException,
ClassificationNotFoundException {
Connection connection = dataSource.getConnection();
taskanaEngineImpl.setConnection(connection);
Classification classification = this.createNewClassificationWithUniqueKey("UNIQUE-DOMAIN", "t1");
@ -251,7 +253,8 @@ public class ClassificationServiceImplIntExplicitTest {
@Test
public void testFindWithClassificationMapperDomainAndCategory()
throws SQLException, ClassificationAlreadyExistException, NotAuthorizedException {
throws SQLException, ClassificationAlreadyExistException, NotAuthorizedException,
ClassificationNotFoundException {
Connection connection = dataSource.getConnection();
taskanaEngineImpl.setConnection(connection);
Classification classification1 = this.createNewClassificationWithUniqueKey("domain1", "t1");
@ -277,7 +280,8 @@ public class ClassificationServiceImplIntExplicitTest {
@Test
public void testFindWithClassificationMapperCustomAndCategory()
throws SQLException, ClassificationAlreadyExistException, NotAuthorizedException {
throws SQLException, ClassificationAlreadyExistException, NotAuthorizedException,
ClassificationNotFoundException {
Connection connection = dataSource.getConnection();
taskanaEngineImpl.setConnection(connection);
Classification classification1 = this.createNewClassificationWithUniqueKey("", "t1");
@ -317,7 +321,8 @@ public class ClassificationServiceImplIntExplicitTest {
@Test
public void testFindWithClassificationMapperPriorityTypeAndParent()
throws SQLException, ClassificationAlreadyExistException, NotAuthorizedException {
throws SQLException, ClassificationAlreadyExistException, NotAuthorizedException,
ClassificationNotFoundException {
Connection connection = dataSource.getConnection();
taskanaEngineImpl.setConnection(connection);
Classification classification = this.createNewClassificationWithUniqueKey("", "type1");

View File

@ -90,6 +90,9 @@ public class ClassificationController {
} catch (NotAuthorizedException e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
} catch (ClassificationNotFoundException e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
}