TSK-22_start_working_on_a_task

This commit is contained in:
BerndBreier 2017-12-11 08:45:25 +01:00 committed by Holger Hagen
parent 8b9c5c7de0
commit 4d94684bf0
18 changed files with 125 additions and 39 deletions

View File

@ -1,6 +1,8 @@
package pro.taskana;
import pro.taskana.exceptions.ClassificationNotFoundException;
import pro.taskana.exceptions.InvalidOwnerException;
import pro.taskana.exceptions.InvalidStateException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.exceptions.WorkbasketNotFoundException;
@ -19,11 +21,11 @@ public class ExampleBootstrap {
private TaskanaEjb taskanaEjb;
@PostConstruct
public void init(@Observes @Initialized(ApplicationScoped.class) Object init) throws TaskNotFoundException, NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException {
public void init(@Observes @Initialized(ApplicationScoped.class) Object init) throws TaskNotFoundException, NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, InvalidStateException, InvalidOwnerException {
System.out.println("---------------------------> Start App");
Task task = taskanaEjb.getTaskService().createTask(new Task());
System.out.println("---------------------------> Task started: " + task.getId());
taskanaEjb.getTaskService().claim(task.getId(), "John Doe");
taskanaEjb.getTaskService().claim(task.getId());
System.out.println(
"---------------------------> Task claimed: "
+ taskanaEjb.getTaskService().getTaskById(task.getId()).getOwner());

View File

@ -1,6 +1,8 @@
package pro.taskana;
import pro.taskana.exceptions.ClassificationNotFoundException;
import pro.taskana.exceptions.InvalidOwnerException;
import pro.taskana.exceptions.InvalidStateException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.exceptions.WorkbasketNotFoundException;
@ -18,15 +20,28 @@ import java.util.List;
public interface TaskService {
/**
* Claim an existing task.
* Claim an existing task for the current user.
* @param id
* task id
* @param userName
* user who claims the task
* @return modified claimed Task
* @throws TaskNotFoundException TODO
* @throws TaskNotFoundException if the task with id was not found
* @throws InvalidStateException if the task state is not ready
* @throws InvalidOwnerException if the task is claimed by another user
*/
Task claim(String id, String userName) throws TaskNotFoundException;
Task claim(String id) throws TaskNotFoundException, InvalidStateException, InvalidOwnerException;
/**
* Claim an existing task for the current user.
* @param id
* task id
* @param forceClaim
* if true, claim is performed even if the task is already claimed by someone else
* @return modified claimed Task
* @throws TaskNotFoundException if the task with id was not found
* @throws InvalidStateException if the task state is not ready
* @throws InvalidOwnerException if the task is claimed by another user
*/
Task claim(String id, boolean forceClaim) throws TaskNotFoundException, InvalidStateException, InvalidOwnerException;
/**
* Set task to completed.

View File

@ -4,10 +4,9 @@ package pro.taskana.exceptions;
* Thrown in ConnectionManagementMode AUTOCOMMIT when an attempt to commit fails.
*
*/
@SuppressWarnings("serial")
public class AutocommitFailedException extends TaskanaRuntimeException {
public AutocommitFailedException(Throwable cause) {
super("Autocommit failed", cause);
}
private static final long serialVersionUID = 1L;
}

View File

@ -3,10 +3,11 @@ package pro.taskana.exceptions;
/**
* Thrown if a specific task is not in the database.
*/
@SuppressWarnings("serial")
public class ClassificationNotFoundException extends NotFoundException {
public ClassificationNotFoundException(String id) {
super("Classification '" + id + "' not found");
}
private static final long serialVersionUID = 1L;
}

View File

@ -4,11 +4,11 @@ package pro.taskana.exceptions;
* Thrown if ConnectionManagementMode is CONNECTION_MANAGED_EXTERNALLY and an attempt is made to call an API method before the setConnection() method has been called.
*
*/
@SuppressWarnings("serial")
public class ConnectionNotSetException extends TaskanaRuntimeException {
public ConnectionNotSetException() {
super("Connection not set");
}
private static final long serialVersionUID = 1L;
}

View File

@ -2,13 +2,14 @@ package pro.taskana.exceptions;
/**
* This exception is thrown when a method is called with invalid argument.
* @author bbr
*
* @author bbr
*/
@SuppressWarnings("serial")
public class InvalidArgumentException extends TaskanaException {
public InvalidArgumentException(String msg) {
super(msg);
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,14 @@
package pro.taskana.exceptions;
/**
* This exception is thrown when the task state doesn't allow the requested operation.
* @author bbr
*
*/
public class InvalidOwnerException extends TaskanaException {
public InvalidOwnerException(String msg) {
super(msg);
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,14 @@
package pro.taskana.exceptions;
/**
* This exception is thrown when the task state doesn't allow the requested operation.
* @author bbr
*
*/
public class InvalidStateException extends TaskanaException {
public InvalidStateException(String msg) {
super(msg);
}
private static final long serialVersionUID = 1L;
}

View File

@ -3,10 +3,11 @@ package pro.taskana.exceptions;
/**
* This exception is used to communicate a not authorized user.
*/
@SuppressWarnings("serial")
public class NotAuthorizedException extends TaskanaException {
public NotAuthorizedException(String msg) {
super(msg);
}
private static final long serialVersionUID = 1L;
}

View File

@ -3,10 +3,11 @@ package pro.taskana.exceptions;
/**
* This exception will be thrown if a specific object is not in the database.
*/
@SuppressWarnings("serial")
public class NotFoundException extends TaskanaException {
public NotFoundException(String id) {
super(id);
}
private static final long serialVersionUID = 1L;
}

View File

@ -3,10 +3,11 @@ package pro.taskana.exceptions;
/**
* This exception will be thrown if a specific task is not in the database.
*/
@SuppressWarnings("serial")
public class TaskNotFoundException extends NotFoundException {
public TaskNotFoundException(String id) {
super("Task '" + id + "' not found");
}
private static final long serialVersionUID = 1L;
}

View File

@ -2,10 +2,9 @@ package pro.taskana.exceptions;
/**
* common base class for Taskana's checked exceptions.
* @author bbr
*
* @author bbr
*/
@SuppressWarnings("serial")
public class TaskanaException extends Exception {
private static final long serialVersionUID = 123234345123412L;

View File

@ -2,10 +2,9 @@ package pro.taskana.exceptions;
/**
* Common base class for Taskana's runtime exceptions.
* @author bbr
*
* @author bbr
*/
@SuppressWarnings("serial")
public class TaskanaRuntimeException extends RuntimeException {
private static final long serialVersionUID = 1511142769801824L;
@ -27,7 +26,7 @@ public class TaskanaRuntimeException extends RuntimeException {
}
public TaskanaRuntimeException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}

View File

@ -3,10 +3,11 @@ package pro.taskana.exceptions;
/**
* This exception will be thrown if a specific workbasket is not in the database.
*/
@SuppressWarnings("serial")
public class WorkbasketNotFoundException extends NotFoundException {
public WorkbasketNotFoundException(String id) {
super("Workbasket with '" + id + "' not found");
}
private static final long serialVersionUID = 1L;
}

View File

@ -15,7 +15,10 @@ import pro.taskana.Classification;
import pro.taskana.TaskQuery;
import pro.taskana.TaskService;
import pro.taskana.TaskanaEngine;
import pro.taskana.WorkbasketService;
import pro.taskana.exceptions.ClassificationNotFoundException;
import pro.taskana.exceptions.InvalidOwnerException;
import pro.taskana.exceptions.InvalidStateException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.exceptions.WorkbasketNotFoundException;
@ -30,6 +33,7 @@ import pro.taskana.model.TaskSummary;
import pro.taskana.model.WorkbasketAuthorization;
import pro.taskana.model.mappings.ObjectReferenceMapper;
import pro.taskana.model.mappings.TaskMapper;
import pro.taskana.security.CurrentUserContext;
/**
* This is the implementation of TaskService.
@ -44,6 +48,7 @@ public class TaskServiceImpl implements TaskService {
private TaskanaEngine taskanaEngine;
private TaskanaEngineImpl taskanaEngineImpl;
private WorkbasketService workbasketService;
private TaskMapper taskMapper;
private ObjectReferenceMapper objectReferenceMapper;
@ -54,27 +59,48 @@ public class TaskServiceImpl implements TaskService {
this.taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine;
this.taskMapper = taskMapper;
this.objectReferenceMapper = objectReferenceMapper;
this.workbasketService = taskanaEngineImpl.getWorkbasketService();
}
@Override
public Task claim(String id, String userName) throws TaskNotFoundException {
public Task claim(String id) throws TaskNotFoundException, InvalidStateException, InvalidOwnerException {
return claim(id, false);
}
@Override
public Task claim(String id, boolean forceClaim) throws TaskNotFoundException, InvalidStateException, InvalidOwnerException {
String userName = CurrentUserContext.getUserid();
return claim(id, userName, forceClaim);
}
public Task claim(String id, String userName, boolean forceClaim) throws TaskNotFoundException, InvalidStateException, InvalidOwnerException {
LOGGER.debug("entry to claim(id = {}, userName = {})", id, userName);
Task task = null;
try {
taskanaEngineImpl.openConnection();
task = taskMapper.findById(id);
if (task != null) {
Timestamp now = new Timestamp(System.currentTimeMillis());
task.setOwner(userName);
task.setModified(now);
task.setClaimed(now);
task.setState(TaskState.CLAIMED);
taskMapper.update(task);
LOGGER.debug("Method claim() claimed task '{}' for user '{}'.", id, userName);
} else {
if (task == null) {
LOGGER.warn("Method claim() didn't find task with id {}. Throwing TaskNotFoundException", id);
throw new TaskNotFoundException(id);
}
TaskState state = task.getState();
if (state == TaskState.COMPLETED) {
LOGGER.warn("Method claim() found that task {} is already completed. Throwing InvalidStateException", id);
throw new InvalidStateException("Task is already completed");
}
if (state == TaskState.CLAIMED && !forceClaim) {
LOGGER.warn("Method claim() found that task {} is claimed by {} and forceClaim is false. Throwing InvalidOwnerException", id, task.getOwner());
throw new InvalidOwnerException("Task is already claimed by user " + task.getOwner());
}
Timestamp now = new Timestamp(System.currentTimeMillis());
task.setOwner(userName);
task.setModified(now);
task.setClaimed(now);
task.setRead(true);
task.setState(TaskState.CLAIMED);
taskMapper.update(task);
LOGGER.debug("Method claim() claimed task '{}' for user '{}'.", id, userName);
} finally {
taskanaEngineImpl.returnConnection();
LOGGER.debug("exit from claim()");
@ -369,4 +395,6 @@ public class TaskServiceImpl implements TaskService {
}
return taskSummaries;
}
}

View File

@ -331,7 +331,7 @@ public class TaskServiceImplTest {
Thread.sleep(SLEEP_TIME); // to have different timestamps
String expectedOwner = "John Does";
Task acturalTask = cut.claim(expectedTask.getId(), expectedOwner);
Task acturalTask = cut.claim(expectedTask.getId(), expectedOwner, true);
verify(taskanaEngineImpl, times(1)).openConnection();
verify(taskMapperMock, times(1)).findById(expectedTask.getId());
@ -347,12 +347,12 @@ public class TaskServiceImplTest {
}
@Test(expected = TaskNotFoundException.class)
public void testClaimThrowinTaskNotFoundException() throws TaskNotFoundException {
public void testClaimThrowinTaskNotFoundException() throws Exception {
try {
Task expectedTask = null;
Mockito.doReturn(expectedTask).when(taskMapperMock).findById(any());
cut.claim("1", "OWNER");
cut.claim("1", "OWNER", true);
} catch (Exception e) {
verify(taskanaEngineImpl, times(1)).openConnection();
verify(taskMapperMock, times(1)).findById(any());

View File

@ -4,6 +4,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import pro.taskana.exceptions.ClassificationNotFoundException;
import pro.taskana.exceptions.InvalidOwnerException;
import pro.taskana.exceptions.InvalidStateException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.exceptions.WorkbasketNotFoundException;
@ -19,14 +21,14 @@ public class ExampleBootstrap {
private TaskService taskService;
@PostConstruct
public void test() throws TaskNotFoundException, NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException {
public void test() throws TaskNotFoundException, NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, InvalidStateException, InvalidOwnerException {
System.out.println("---------------------------> Start App");
Task task = new Task();
task.setName("Spring example task");
task.setWorkbasketId("1");
task = taskService.createTask(task);
System.out.println("---------------------------> Task started: " + task.getId());
taskService.claim(task.getId(), "John Doe");
taskService.claim(task.getId());
System.out.println(
"---------------------------> Task claimed: " + taskService.getTaskById(task.getId()).getOwner());
// taskService.complete(task.getId());

View File

@ -20,6 +20,8 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import pro.taskana.TaskService;
import pro.taskana.exceptions.InvalidOwnerException;
import pro.taskana.exceptions.InvalidStateException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.exceptions.WorkbasketNotFoundException;
@ -85,13 +87,19 @@ public class TaskController {
public ResponseEntity<Task> claimTask(@PathVariable String taskId, @RequestBody String userName) {
// TODO verify user
try {
taskService.claim(taskId, userName);
taskService.claim(taskId);
Task updatedTask = taskService.getTaskById(taskId);
return ResponseEntity.status(HttpStatus.OK).body(updatedTask);
} catch (TaskNotFoundException e) {
logger.error("The given Task coundn´t be found/claimd or does not Exist.", e);
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
} catch (InvalidStateException e) {
logger.error("The given Task could not be claimed. Reason: {}", e);
return ResponseEntity.status(HttpStatus.CONFLICT).build();
} catch (InvalidOwnerException e) {
logger.error("The given Task could not be claimed. Reason: {}", e);
return ResponseEntity.status(HttpStatus.CONFLICT).build();
}
}
@RequestMapping(method = RequestMethod.POST, value = "/{taskId}/complete")