TSK-1331: allowed multiple sortBy declarations in REST api
This commit is contained in:
parent
4bba93c5a9
commit
9e44ca6140
|
@ -6,6 +6,7 @@ import java.time.ZoneId;
|
|||
import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.PagedModel.PageMetadata;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
@ -19,10 +20,10 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import pro.taskana.TaskanaEngineConfiguration;
|
||||
import pro.taskana.common.api.BaseQuery;
|
||||
import pro.taskana.common.api.TimeInterval;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.rest.AbstractPagingController;
|
||||
import pro.taskana.common.rest.QueryHelper;
|
||||
import pro.taskana.simplehistory.impl.HistoryEventImpl;
|
||||
import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
|
||||
import pro.taskana.simplehistory.query.HistoryQuery;
|
||||
|
@ -42,97 +43,53 @@ public class TaskHistoryEventController extends AbstractPagingController {
|
|||
private static final Logger LOGGER = LoggerFactory.getLogger(TaskHistoryEventController.class);
|
||||
|
||||
private static final String LIKE = "%";
|
||||
|
||||
private static final String BUSINESS_PROCESS_ID = "business-process-id";
|
||||
|
||||
private static final String BUSINESS_PROCESS_ID_LIKE = "business-process-id-like";
|
||||
|
||||
private static final String PARENT_BUSINESS_PROCESS_ID = "parent-business-process-id";
|
||||
|
||||
private static final String PARENT_BUSINESS_PROCESS_ID_LIKE = "parent-business-process-id-like";
|
||||
|
||||
private static final String TASK_ID = "task-id";
|
||||
|
||||
private static final String TASK_ID_LIKE = "task-id-like";
|
||||
|
||||
private static final String EVENT_TYPE = "event-type";
|
||||
|
||||
private static final String EVENT_TYPE_LIKE = "event-type-like";
|
||||
|
||||
private static final String CREATED = "created";
|
||||
|
||||
private static final String USER_ID = "user-id";
|
||||
|
||||
private static final String USER_ID_LIKE = "user-id-like";
|
||||
|
||||
private static final String DOMAIN = "domain";
|
||||
|
||||
private static final String WORKBASKET_KEY = "workbasket-key";
|
||||
|
||||
private static final String WORKBASKET_KEY_LIKE = "workbasket-key-like";
|
||||
|
||||
private static final String POR_COMPANY = "por-company";
|
||||
|
||||
private static final String POR_COMPANY_LIKE = "por-company-like";
|
||||
|
||||
private static final String POR_SYSTEM = "por-system";
|
||||
|
||||
private static final String POR_SYSTEM_LIKE = "por-system-like";
|
||||
|
||||
private static final String POR_INSTANCE = "por-instance";
|
||||
|
||||
private static final String POR_INSTANCE_LIKE = "por-instance-like";
|
||||
|
||||
private static final String POR_TYPE = "por-type";
|
||||
|
||||
private static final String POR_TYPE_LIKE = "por-type-like";
|
||||
|
||||
private static final String POR_VALUE = "por-value";
|
||||
|
||||
private static final String POR_VALUE_LIKE = "por-value-like";
|
||||
|
||||
private static final String TASK_CLASSIFICATION_KEY = "task-classification-key";
|
||||
|
||||
private static final String TASK_CLASSIFICATION_KEY_LIKE = "task-classification-key-like";
|
||||
|
||||
private static final String TASK_CLASSIFICATION_CATEGORY = "task-classification-category";
|
||||
|
||||
private static final String TASK_CLASSIFICATION_CATEGORY_LIKE =
|
||||
"task-classification-category-like";
|
||||
|
||||
private static final String ATTACHMENT_CLASSIFICATION_KEY = "attachment-classification-key";
|
||||
|
||||
private static final String ATTACHMENT_CLASSIFICATION_KEY_LIKE =
|
||||
"attachment-classification-key-like";
|
||||
|
||||
private static final String CUSTOM_1 = "custom-1";
|
||||
|
||||
private static final String CUSTOM_1_LIKE = "custom-1-like";
|
||||
|
||||
private static final String CUSTOM_2 = "custom-2";
|
||||
|
||||
private static final String CUSTOM_2_LIKE = "custom-2-like";
|
||||
|
||||
private static final String CUSTOM_3 = "custom-3";
|
||||
|
||||
private static final String CUSTOM_3_LIKE = "custom-3-like";
|
||||
|
||||
private static final String CUSTOM_4 = "custom-4";
|
||||
|
||||
private static final String CUSTOM_4_LIKE = "custom-4-like";
|
||||
|
||||
private static final String SORT_BY = "sort-by";
|
||||
|
||||
private static final String SORT_DIRECTION = "order";
|
||||
|
||||
private static final String PAGING_PAGE = "page";
|
||||
|
||||
private static final String PAGING_PAGE_SIZE = "page-size";
|
||||
|
||||
private final SimpleHistoryServiceImpl simpleHistoryService;
|
||||
|
||||
private final TaskHistoryEventResourceAssembler taskHistoryEventResourceAssembler;
|
||||
|
||||
@Autowired
|
||||
public TaskHistoryEventController(
|
||||
TaskanaEngineConfiguration taskanaEngineConfiguration,
|
||||
SimpleHistoryServiceImpl simpleHistoryServiceImpl,
|
||||
|
@ -153,7 +110,7 @@ public class TaskHistoryEventController extends AbstractPagingController {
|
|||
|
||||
HistoryQuery query = simpleHistoryService.createHistoryQuery();
|
||||
query = applySortingParams(query, params);
|
||||
applyFilterParams(query, params);
|
||||
query = applyFilterParams(query, params);
|
||||
|
||||
PageMetadata pageMetadata = null;
|
||||
List<HistoryEventImpl> historyEvents;
|
||||
|
@ -214,90 +171,83 @@ public class TaskHistoryEventController extends AbstractPagingController {
|
|||
LOGGER.debug("Entry to applySortingParams(params= {})", params);
|
||||
}
|
||||
|
||||
String sortBy = params.getFirst(SORT_BY);
|
||||
if (sortBy != null) {
|
||||
BaseQuery.SortDirection sortDirection;
|
||||
if (params.getFirst(SORT_DIRECTION) != null
|
||||
&& "desc".equals(params.getFirst(SORT_DIRECTION))) {
|
||||
sortDirection = BaseQuery.SortDirection.DESCENDING;
|
||||
} else {
|
||||
sortDirection = BaseQuery.SortDirection.ASCENDING;
|
||||
}
|
||||
switch (sortBy) {
|
||||
case (BUSINESS_PROCESS_ID):
|
||||
query = query.orderByBusinessProcessId(sortDirection);
|
||||
break;
|
||||
case (PARENT_BUSINESS_PROCESS_ID):
|
||||
query = query.orderByParentBusinessProcessId(sortDirection);
|
||||
break;
|
||||
case (TASK_ID):
|
||||
query = query.orderByTaskId(sortDirection);
|
||||
break;
|
||||
case (EVENT_TYPE):
|
||||
query = query.orderByEventType(sortDirection);
|
||||
break;
|
||||
case (CREATED):
|
||||
query = query.orderByCreated(sortDirection);
|
||||
break;
|
||||
case (USER_ID):
|
||||
query = query.orderByUserId(sortDirection);
|
||||
break;
|
||||
case (DOMAIN):
|
||||
query = query.orderByDomain(sortDirection);
|
||||
break;
|
||||
case (WORKBASKET_KEY):
|
||||
query = query.orderByWorkbasketKey(sortDirection);
|
||||
break;
|
||||
case (POR_COMPANY):
|
||||
query = query.orderByPorCompany(sortDirection);
|
||||
break;
|
||||
case (POR_SYSTEM):
|
||||
query = query.orderByPorSystem(sortDirection);
|
||||
break;
|
||||
case (POR_INSTANCE):
|
||||
query = query.orderByPorInstance(sortDirection);
|
||||
break;
|
||||
case (POR_TYPE):
|
||||
query = query.orderByPorType(sortDirection);
|
||||
break;
|
||||
case (POR_VALUE):
|
||||
query = query.orderByPorValue(sortDirection);
|
||||
break;
|
||||
case (TASK_CLASSIFICATION_KEY):
|
||||
query = query.orderByTaskClassificationKey(sortDirection);
|
||||
break;
|
||||
case (TASK_CLASSIFICATION_CATEGORY):
|
||||
query = query.orderByTaskClassificationCategory(sortDirection);
|
||||
break;
|
||||
case (ATTACHMENT_CLASSIFICATION_KEY):
|
||||
query = query.orderByAttachmentClassificationKey(sortDirection);
|
||||
break;
|
||||
case (CUSTOM_1):
|
||||
query = query.orderByCustomAttribute(1, sortDirection);
|
||||
break;
|
||||
case (CUSTOM_2):
|
||||
query = query.orderByCustomAttribute(2, sortDirection);
|
||||
break;
|
||||
case (CUSTOM_3):
|
||||
query = query.orderByCustomAttribute(3, sortDirection);
|
||||
break;
|
||||
case (CUSTOM_4):
|
||||
query = query.orderByCustomAttribute(4, sortDirection);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown order '" + sortBy + "'");
|
||||
}
|
||||
}
|
||||
params.remove(SORT_BY);
|
||||
params.remove(SORT_DIRECTION);
|
||||
QueryHelper.applyAndRemoveSortingParams(
|
||||
params,
|
||||
(sortBy, sortDirection) -> {
|
||||
switch (sortBy) {
|
||||
case (BUSINESS_PROCESS_ID):
|
||||
query.orderByBusinessProcessId(sortDirection);
|
||||
break;
|
||||
case (PARENT_BUSINESS_PROCESS_ID):
|
||||
query.orderByParentBusinessProcessId(sortDirection);
|
||||
break;
|
||||
case (TASK_ID):
|
||||
query.orderByTaskId(sortDirection);
|
||||
break;
|
||||
case (EVENT_TYPE):
|
||||
query.orderByEventType(sortDirection);
|
||||
break;
|
||||
case (CREATED):
|
||||
query.orderByCreated(sortDirection);
|
||||
break;
|
||||
case (USER_ID):
|
||||
query.orderByUserId(sortDirection);
|
||||
break;
|
||||
case (DOMAIN):
|
||||
query.orderByDomain(sortDirection);
|
||||
break;
|
||||
case (WORKBASKET_KEY):
|
||||
query.orderByWorkbasketKey(sortDirection);
|
||||
break;
|
||||
case (POR_COMPANY):
|
||||
query.orderByPorCompany(sortDirection);
|
||||
break;
|
||||
case (POR_SYSTEM):
|
||||
query.orderByPorSystem(sortDirection);
|
||||
break;
|
||||
case (POR_INSTANCE):
|
||||
query.orderByPorInstance(sortDirection);
|
||||
break;
|
||||
case (POR_TYPE):
|
||||
query.orderByPorType(sortDirection);
|
||||
break;
|
||||
case (POR_VALUE):
|
||||
query.orderByPorValue(sortDirection);
|
||||
break;
|
||||
case (TASK_CLASSIFICATION_KEY):
|
||||
query.orderByTaskClassificationKey(sortDirection);
|
||||
break;
|
||||
case (TASK_CLASSIFICATION_CATEGORY):
|
||||
query.orderByTaskClassificationCategory(sortDirection);
|
||||
break;
|
||||
case (ATTACHMENT_CLASSIFICATION_KEY):
|
||||
query.orderByAttachmentClassificationKey(sortDirection);
|
||||
break;
|
||||
case (CUSTOM_1):
|
||||
query.orderByCustomAttribute(1, sortDirection);
|
||||
break;
|
||||
case (CUSTOM_2):
|
||||
query.orderByCustomAttribute(2, sortDirection);
|
||||
break;
|
||||
case (CUSTOM_3):
|
||||
query.orderByCustomAttribute(3, sortDirection);
|
||||
break;
|
||||
case (CUSTOM_4):
|
||||
query.orderByCustomAttribute(4, sortDirection);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown order '" + sortBy + "'");
|
||||
}
|
||||
});
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from applySortingParams(), returning {}", query);
|
||||
LOGGER.debug("Exit from applySortingParams(), returning: {}", query);
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
private void applyFilterParams(HistoryQuery query, MultiValueMap<String, String> params) {
|
||||
private HistoryQuery applyFilterParams(HistoryQuery query, MultiValueMap<String, String> params) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to applyFilterParams(query= {}, params= {})", query, params);
|
||||
}
|
||||
|
@ -485,6 +435,8 @@ public class TaskHistoryEventController extends AbstractPagingController {
|
|||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from applyFilterParams(), returning {}", query);
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
private TimeInterval getTimeIntervalOf(String[] created) {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package pro.taskana.common.internal.util;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface CheckedBiConsumer<T, U, E extends Throwable> {
|
||||
|
||||
void accept(T t, U u) throws E;
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@ package pro.taskana.classification.rest;
|
|||
import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.hateoas.PagedModel.PageMetadata;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
||||
|
@ -31,13 +32,13 @@ import pro.taskana.classification.rest.assembler.ClassificationRepresentationMod
|
|||
import pro.taskana.classification.rest.assembler.ClassificationSummaryRepresentationModelAssembler;
|
||||
import pro.taskana.classification.rest.models.ClassificationRepresentationModel;
|
||||
import pro.taskana.classification.rest.models.ClassificationSummaryRepresentationModel;
|
||||
import pro.taskana.common.api.BaseQuery.SortDirection;
|
||||
import pro.taskana.common.api.exceptions.ConcurrencyException;
|
||||
import pro.taskana.common.api.exceptions.DomainNotFoundException;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.rest.AbstractPagingController;
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.common.rest.QueryHelper;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModel;
|
||||
|
||||
/** Controller for all {@link Classification} related endpoints. */
|
||||
|
@ -48,56 +49,33 @@ public class ClassificationController extends AbstractPagingController {
|
|||
private static final Logger LOGGER = LoggerFactory.getLogger(ClassificationController.class);
|
||||
|
||||
private static final String LIKE = "%";
|
||||
|
||||
private static final String NAME = "name";
|
||||
|
||||
private static final String NAME_LIKE = "name-like";
|
||||
|
||||
private static final String KEY = "key";
|
||||
|
||||
private static final String DOMAIN = "domain";
|
||||
|
||||
private static final String CATEGORY = "category";
|
||||
|
||||
private static final String TYPE = "type";
|
||||
|
||||
private static final String CUSTOM_1_LIKE = "custom-1-like";
|
||||
|
||||
private static final String CUSTOM_2_LIKE = "custom-2-like";
|
||||
|
||||
private static final String CUSTOM_3_LIKE = "custom-3-like";
|
||||
|
||||
private static final String CUSTOM_4_LIKE = "custom-4-like";
|
||||
|
||||
private static final String CUSTOM_5_LIKE = "custom-5-like";
|
||||
|
||||
private static final String CUSTOM_6_LIKE = "custom-6-like";
|
||||
|
||||
private static final String CUSTOM_7_LIKE = "custom-7-like";
|
||||
|
||||
private static final String CUSTOM_8_LIKE = "custom-8-like";
|
||||
|
||||
private static final String SORT_BY = "sort-by";
|
||||
|
||||
private static final String SORT_DIRECTION = "order";
|
||||
|
||||
private final ClassificationService classificationService;
|
||||
private final ClassificationRepresentationModelAssembler modelAssembler;
|
||||
private final ClassificationSummaryRepresentationModelAssembler summaryModelAssembler;
|
||||
|
||||
private final ClassificationRepresentationModelAssembler
|
||||
classificationRepresentationModelAssembler;
|
||||
|
||||
private final ClassificationSummaryRepresentationModelAssembler
|
||||
classificationSummaryRepresentationModelAssembler;
|
||||
|
||||
@Autowired
|
||||
ClassificationController(
|
||||
ClassificationService classificationService,
|
||||
ClassificationRepresentationModelAssembler classificationRepresentationModelAssembler,
|
||||
ClassificationSummaryRepresentationModelAssembler
|
||||
classificationSummaryRepresentationModelAssembler) {
|
||||
ClassificationRepresentationModelAssembler modelAssembler,
|
||||
ClassificationSummaryRepresentationModelAssembler summaryModelAssembler) {
|
||||
this.classificationService = classificationService;
|
||||
this.classificationRepresentationModelAssembler = classificationRepresentationModelAssembler;
|
||||
this.classificationSummaryRepresentationModelAssembler =
|
||||
classificationSummaryRepresentationModelAssembler;
|
||||
this.modelAssembler = modelAssembler;
|
||||
this.summaryModelAssembler = summaryModelAssembler;
|
||||
}
|
||||
|
||||
@GetMapping(path = Mapping.URL_CLASSIFICATIONS)
|
||||
|
@ -110,16 +88,14 @@ public class ClassificationController extends AbstractPagingController {
|
|||
}
|
||||
|
||||
ClassificationQuery query = classificationService.createClassificationQuery();
|
||||
query = applyFilterParams(query, params);
|
||||
query = applySortingParams(query, params);
|
||||
applyFilterParams(query, params);
|
||||
|
||||
PageMetadata pageMetadata = getPageMetadata(params, query);
|
||||
List<ClassificationSummary> classificationSummaries = getQueryList(query, pageMetadata);
|
||||
|
||||
ResponseEntity<TaskanaPagedModel<ClassificationSummaryRepresentationModel>> response =
|
||||
ResponseEntity.ok(
|
||||
classificationSummaryRepresentationModelAssembler.toPageModel(
|
||||
classificationSummaries, pageMetadata));
|
||||
ResponseEntity.ok(summaryModelAssembler.toPageModel(classificationSummaries, pageMetadata));
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from getClassifications(), returning {}", response);
|
||||
}
|
||||
|
@ -137,7 +113,7 @@ public class ClassificationController extends AbstractPagingController {
|
|||
|
||||
Classification classification = classificationService.getClassification(classificationId);
|
||||
ResponseEntity<ClassificationRepresentationModel> response =
|
||||
ResponseEntity.ok(classificationRepresentationModelAssembler.toModel(classification));
|
||||
ResponseEntity.ok(modelAssembler.toModel(classification));
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from getClassification(), returning {}", response);
|
||||
}
|
||||
|
@ -154,13 +130,11 @@ public class ClassificationController extends AbstractPagingController {
|
|||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to createClassification(resource= {})", resource);
|
||||
}
|
||||
Classification classification =
|
||||
classificationRepresentationModelAssembler.toEntityModel(resource);
|
||||
Classification classification = modelAssembler.toEntityModel(resource);
|
||||
classification = classificationService.createClassification(classification);
|
||||
|
||||
ResponseEntity<ClassificationRepresentationModel> response =
|
||||
ResponseEntity.status(HttpStatus.CREATED)
|
||||
.body(classificationRepresentationModelAssembler.toModel(classification));
|
||||
ResponseEntity.status(HttpStatus.CREATED).body(modelAssembler.toModel(classification));
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from createClassification(), returning {}", response);
|
||||
}
|
||||
|
@ -184,11 +158,9 @@ public class ClassificationController extends AbstractPagingController {
|
|||
|
||||
ResponseEntity<ClassificationRepresentationModel> result;
|
||||
if (classificationId.equals(resource.getClassificationId())) {
|
||||
Classification classification =
|
||||
classificationRepresentationModelAssembler.toEntityModel(resource);
|
||||
Classification classification = modelAssembler.toEntityModel(resource);
|
||||
classification = classificationService.updateClassification(classification);
|
||||
result =
|
||||
ResponseEntity.ok(classificationRepresentationModelAssembler.toModel(classification));
|
||||
result = ResponseEntity.ok(modelAssembler.toModel(classification));
|
||||
} else {
|
||||
throw new InvalidArgumentException(
|
||||
"ClassificationId ('"
|
||||
|
@ -223,43 +195,35 @@ public class ClassificationController extends AbstractPagingController {
|
|||
LOGGER.debug("Entry to applySortingParams(query= {}, params= {})", query, params);
|
||||
}
|
||||
|
||||
// sorting
|
||||
String sortBy = params.getFirst(SORT_BY);
|
||||
if (sortBy != null) {
|
||||
SortDirection sortDirection;
|
||||
if (params.getFirst(SORT_DIRECTION) != null
|
||||
&& "desc".equals(params.getFirst(SORT_DIRECTION))) {
|
||||
sortDirection = SortDirection.DESCENDING;
|
||||
} else {
|
||||
sortDirection = SortDirection.ASCENDING;
|
||||
}
|
||||
switch (sortBy) {
|
||||
case (CATEGORY):
|
||||
query = query.orderByCategory(sortDirection);
|
||||
break;
|
||||
case (DOMAIN):
|
||||
query = query.orderByDomain(sortDirection);
|
||||
break;
|
||||
case (KEY):
|
||||
query = query.orderByKey(sortDirection);
|
||||
break;
|
||||
case (NAME):
|
||||
query = query.orderByName(sortDirection);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException("Unknown order '" + sortBy + "'");
|
||||
}
|
||||
}
|
||||
params.remove(SORT_BY);
|
||||
params.remove(SORT_DIRECTION);
|
||||
QueryHelper.applyAndRemoveSortingParams(
|
||||
params,
|
||||
(sortBy, sortDirection) -> {
|
||||
switch (sortBy) {
|
||||
case (CATEGORY):
|
||||
query.orderByCategory(sortDirection);
|
||||
break;
|
||||
case (DOMAIN):
|
||||
query.orderByDomain(sortDirection);
|
||||
break;
|
||||
case (KEY):
|
||||
query.orderByKey(sortDirection);
|
||||
break;
|
||||
case (NAME):
|
||||
query.orderByName(sortDirection);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException("Unknown order '" + sortBy + "'");
|
||||
}
|
||||
});
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from applySortingParams(), returning {}", query);
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
private void applyFilterParams(ClassificationQuery query, MultiValueMap<String, String> params)
|
||||
private ClassificationQuery applyFilterParams(
|
||||
ClassificationQuery query, MultiValueMap<String, String> params)
|
||||
throws InvalidArgumentException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to applyFilterParams(query= {}, params= {})", query, params);
|
||||
|
@ -330,5 +294,6 @@ public class ClassificationController extends AbstractPagingController {
|
|||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from applyFilterParams(), returning {}", query);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package pro.taskana.common.rest;
|
||||
|
||||
import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import pro.taskana.common.api.BaseQuery.SortDirection;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.internal.util.CheckedBiConsumer;
|
||||
|
||||
public class QueryHelper {
|
||||
|
||||
public static final String SORT_BY = "sort-by";
|
||||
public static final String ORDER_DIRECTION = "order";
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(QueryHelper.class);
|
||||
|
||||
private QueryHelper() {
|
||||
// no op
|
||||
}
|
||||
|
||||
public static void applyAndRemoveSortingParams(
|
||||
MultiValueMap<String, String> params,
|
||||
CheckedBiConsumer<String, SortDirection, InvalidArgumentException> consumer)
|
||||
throws InvalidArgumentException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to applyAndRemoveSortingParams(params= {})", params);
|
||||
}
|
||||
|
||||
if (params == null || consumer == null) {
|
||||
throw new InvalidArgumentException("params or consumer can't be null!");
|
||||
}
|
||||
List<String> allSortBy = params.remove(SORT_BY);
|
||||
List<String> allOrderBy = params.remove(ORDER_DIRECTION);
|
||||
|
||||
verifyNotOnlyOrderByExists(allSortBy, allOrderBy);
|
||||
verifyAmountOfSortByAndOrderByMatches(allSortBy, allOrderBy);
|
||||
|
||||
if (allSortBy != null) {
|
||||
for (int i = 0; i < allSortBy.size(); i++) {
|
||||
consumer.accept(allSortBy.get(i), getSortDirectionForIndex(allOrderBy, i));
|
||||
}
|
||||
}
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from applyAndRemoveSortingParams()");
|
||||
}
|
||||
}
|
||||
|
||||
private static SortDirection getSortDirectionForIndex(List<String> allOrderBy, int i) {
|
||||
SortDirection sortDirection = SortDirection.ASCENDING;
|
||||
if (allOrderBy != null && !allOrderBy.isEmpty() && "desc".equalsIgnoreCase(allOrderBy.get(i))) {
|
||||
sortDirection = SortDirection.DESCENDING;
|
||||
}
|
||||
return sortDirection;
|
||||
}
|
||||
|
||||
private static void verifyNotOnlyOrderByExists(List<String> allSortBy, List<String> allOrderBy)
|
||||
throws InvalidArgumentException {
|
||||
if (allSortBy == null && allOrderBy != null) {
|
||||
throw new InvalidArgumentException(
|
||||
String.format(
|
||||
"Only '%s' were provided. Please also provide '%s' parameter(s)",
|
||||
ORDER_DIRECTION, SORT_BY));
|
||||
}
|
||||
}
|
||||
|
||||
private static void verifyAmountOfSortByAndOrderByMatches(
|
||||
List<String> allSortBy, List<String> allOrderBy) throws InvalidArgumentException {
|
||||
if (allSortBy != null
|
||||
&& allOrderBy != null
|
||||
&& allSortBy.size() != allOrderBy.size()
|
||||
&& !allOrderBy.isEmpty()) {
|
||||
throw new InvalidArgumentException(
|
||||
String.format(
|
||||
"The amount of '%s' and '%s' does not match. "
|
||||
+ "Please specify an '%s' for each '%s' or no '%s' parameters at all.",
|
||||
SORT_BY, ORDER_DIRECTION, ORDER_DIRECTION, SORT_BY, ORDER_DIRECTION));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,106 +36,112 @@ import pro.taskana.workbasket.api.exceptions.WorkbasketInUseException;
|
|||
public class TaskanaRestExceptionHandler extends ResponseEntityExceptionHandler {
|
||||
|
||||
@ExceptionHandler(InvalidArgumentException.class)
|
||||
protected ResponseEntity<Object> handleInvalidArgument(
|
||||
protected ResponseEntity<TaskanaErrorData> handleInvalidArgument(
|
||||
InvalidArgumentException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.BAD_REQUEST, false);
|
||||
}
|
||||
|
||||
@ExceptionHandler(NotAuthorizedException.class)
|
||||
protected ResponseEntity<Object> handleNotAuthorized(NotAuthorizedException ex, WebRequest req) {
|
||||
protected ResponseEntity<TaskanaErrorData> handleNotAuthorized(
|
||||
NotAuthorizedException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@ExceptionHandler(NotFoundException.class)
|
||||
protected ResponseEntity<Object> handleTaskNotFound(NotFoundException ex, WebRequest req) {
|
||||
protected ResponseEntity<TaskanaErrorData> handleTaskNotFound(
|
||||
NotFoundException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
@ExceptionHandler(TaskAlreadyExistException.class)
|
||||
protected ResponseEntity<Object> handleTaskAlreadyExist(
|
||||
protected ResponseEntity<TaskanaErrorData> handleTaskAlreadyExist(
|
||||
TaskAlreadyExistException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
@ExceptionHandler(NotAuthorizedToQueryWorkbasketException.class)
|
||||
protected ResponseEntity<Object> handleNotAuthorizedToQueryWorkbasket(
|
||||
protected ResponseEntity<TaskanaErrorData> handleNotAuthorizedToQueryWorkbasket(
|
||||
NotAuthorizedToQueryWorkbasketException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@ExceptionHandler(InvalidStateException.class)
|
||||
protected ResponseEntity<Object> handleInvalidState(InvalidStateException ex, WebRequest req) {
|
||||
protected ResponseEntity<TaskanaErrorData> handleInvalidState(
|
||||
InvalidStateException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
@ExceptionHandler(InvalidOwnerException.class)
|
||||
protected ResponseEntity<Object> handleInvalidOwner(InvalidOwnerException ex, WebRequest req) {
|
||||
protected ResponseEntity<TaskanaErrorData> handleInvalidOwner(
|
||||
InvalidOwnerException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
@ExceptionHandler(ClassificationAlreadyExistException.class)
|
||||
protected ResponseEntity<Object> handleClassificationAlreadyExist(
|
||||
protected ResponseEntity<TaskanaErrorData> handleClassificationAlreadyExist(
|
||||
ClassificationAlreadyExistException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
@ExceptionHandler(DuplicateKeyException.class)
|
||||
protected ResponseEntity<Object> handleDuplicateKey(DuplicateKeyException ex, WebRequest req) {
|
||||
protected ResponseEntity<TaskanaErrorData> handleDuplicateKey(
|
||||
DuplicateKeyException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
@ExceptionHandler(ConcurrencyException.class)
|
||||
protected ResponseEntity<Object> handleConcurrencyException(
|
||||
protected ResponseEntity<TaskanaErrorData> handleConcurrencyException(
|
||||
ConcurrencyException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
@ExceptionHandler(WorkbasketInUseException.class)
|
||||
protected ResponseEntity<Object> handleWorkbasketInUse(
|
||||
protected ResponseEntity<TaskanaErrorData> handleWorkbasketInUse(
|
||||
WorkbasketInUseException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.LOCKED);
|
||||
}
|
||||
|
||||
@ExceptionHandler(WorkbasketAlreadyExistException.class)
|
||||
protected ResponseEntity<Object> handleWorkbasketAlreadyExist(
|
||||
protected ResponseEntity<TaskanaErrorData> handleWorkbasketAlreadyExist(
|
||||
WorkbasketAlreadyExistException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
@ExceptionHandler(WorkbasketAccessItemAlreadyExistException.class)
|
||||
protected ResponseEntity<Object> handleWorkbasketAccessItemAlreadyExist(
|
||||
protected ResponseEntity<TaskanaErrorData> handleWorkbasketAccessItemAlreadyExist(
|
||||
WorkbasketAccessItemAlreadyExistException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
@ExceptionHandler(InvalidWorkbasketException.class)
|
||||
protected ResponseEntity<Object> handleInvalidWorkbasket(
|
||||
protected ResponseEntity<TaskanaErrorData> handleInvalidWorkbasket(
|
||||
InvalidWorkbasketException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@ExceptionHandler(DomainNotFoundException.class)
|
||||
protected ResponseEntity<Object> handleDomainNotFound(
|
||||
protected ResponseEntity<TaskanaErrorData> handleDomainNotFound(
|
||||
DomainNotFoundException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@ExceptionHandler(MaxUploadSizeExceededException.class)
|
||||
protected ResponseEntity<Object> handleMaxUploadSizeExceededException(
|
||||
protected ResponseEntity<TaskanaErrorData> handleMaxUploadSizeExceededException(
|
||||
MaxUploadSizeExceededException ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.PAYLOAD_TOO_LARGE);
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
protected ResponseEntity<Object> handleGeneralException(Exception ex, WebRequest req) {
|
||||
protected ResponseEntity<TaskanaErrorData> handleGeneralException(Exception ex, WebRequest req) {
|
||||
return buildResponse(ex, req, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
private ResponseEntity<Object> buildResponse(Exception ex, WebRequest req, HttpStatus status) {
|
||||
private ResponseEntity<TaskanaErrorData> buildResponse(
|
||||
Exception ex, WebRequest req, HttpStatus status) {
|
||||
return buildResponse(ex, req, status, true);
|
||||
}
|
||||
|
||||
private ResponseEntity<Object> buildResponse(
|
||||
private ResponseEntity<TaskanaErrorData> buildResponse(
|
||||
Exception ex, WebRequest req, HttpStatus status, boolean logExceptionOnError) {
|
||||
TaskanaErrorData errorData = new TaskanaErrorData(status, ex, req);
|
||||
if (logExceptionOnError) {
|
||||
|
|
|
@ -20,10 +20,12 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import pro.taskana.common.api.BaseQuery.SortDirection;
|
||||
import pro.taskana.common.api.exceptions.ConcurrencyException;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.common.rest.QueryHelper;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModel;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.task.api.exceptions.TaskCommentNotFoundException;
|
||||
|
@ -39,8 +41,6 @@ public class TaskCommentController {
|
|||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TaskCommentController.class);
|
||||
|
||||
private static final String SORT_BY = "sort-by";
|
||||
private static final String SORT_DIRECTION = "order";
|
||||
private static final String CREATED = "created";
|
||||
private static final String MODIFIED = "modified";
|
||||
|
||||
|
@ -94,7 +94,7 @@ public class TaskCommentController {
|
|||
List<TaskComment> taskComments = taskService.getTaskComments(taskId);
|
||||
|
||||
// TODO Maybe introduce a query for task comments
|
||||
applySortingParams(taskComments, params);
|
||||
taskComments = applySortingParams(taskComments, params);
|
||||
|
||||
TaskanaPagedModel<TaskCommentRepresentationModel> taskCommentListResource =
|
||||
taskCommentRepresentationModelAssembler.toPageModel(taskComments, null);
|
||||
|
@ -204,42 +204,33 @@ public class TaskCommentController {
|
|||
private List<TaskComment> applySortingParams(
|
||||
List<TaskComment> taskComments, MultiValueMap<String, String> params)
|
||||
throws InvalidArgumentException {
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(
|
||||
"Entry to applySortingParams(taskComments= {}, params= {})", taskComments, params);
|
||||
}
|
||||
|
||||
String sortBy = params.getFirst(SORT_BY);
|
||||
|
||||
if (sortBy != null) {
|
||||
|
||||
switch (sortBy) {
|
||||
case (CREATED):
|
||||
if (params.getFirst(SORT_DIRECTION) != null
|
||||
&& "desc".equals(params.getFirst(SORT_DIRECTION))) {
|
||||
taskComments.sort(Comparator.comparing(TaskComment::getCreated).reversed());
|
||||
} else {
|
||||
taskComments.sort(Comparator.comparing(TaskComment::getCreated));
|
||||
QueryHelper.applyAndRemoveSortingParams(
|
||||
params,
|
||||
(sortBy, sortDirection) -> {
|
||||
Comparator<TaskComment> comparator;
|
||||
switch (sortBy) {
|
||||
case (CREATED):
|
||||
comparator = Comparator.comparing(TaskComment::getCreated);
|
||||
break;
|
||||
case (MODIFIED):
|
||||
comparator = Comparator.comparing(TaskComment::getModified);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException("Unknown sort attribute: " + sortBy);
|
||||
}
|
||||
break;
|
||||
case (MODIFIED):
|
||||
if (params.getFirst(SORT_DIRECTION) != null
|
||||
&& "desc".equals(params.getFirst(SORT_DIRECTION))) {
|
||||
taskComments.sort(Comparator.comparing(TaskComment::getModified).reversed());
|
||||
} else {
|
||||
taskComments.sort(Comparator.comparing(TaskComment::getModified));
|
||||
if (sortDirection == SortDirection.DESCENDING) {
|
||||
comparator = comparator.reversed();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException("Unknown sort attribute: " + sortBy);
|
||||
}
|
||||
}
|
||||
taskComments.sort(comparator);
|
||||
});
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from applySortingParams(), returning {}", taskComments);
|
||||
}
|
||||
|
||||
return taskComments;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import pro.taskana.classification.api.exceptions.ClassificationNotFoundException;
|
||||
import pro.taskana.common.api.BaseQuery.SortDirection;
|
||||
import pro.taskana.common.api.BulkOperationResults;
|
||||
import pro.taskana.common.api.KeyDomain;
|
||||
import pro.taskana.common.api.TimeInterval;
|
||||
|
@ -36,6 +35,7 @@ import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
|||
import pro.taskana.common.api.exceptions.TaskanaException;
|
||||
import pro.taskana.common.rest.AbstractPagingController;
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.common.rest.QueryHelper;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModel;
|
||||
import pro.taskana.task.api.TaskQuery;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
|
@ -92,9 +92,6 @@ public class TaskController extends AbstractPagingController {
|
|||
private static final String WILDCARD_SEARCH_FIELDS = "wildcard-search-fields";
|
||||
private static final String CUSTOM = "custom";
|
||||
|
||||
private static final String SORT_BY = "sort-by";
|
||||
private static final String SORT_DIRECTION = "order";
|
||||
|
||||
private static final String INDEFINITE = "";
|
||||
|
||||
private final TaskService taskService;
|
||||
|
@ -492,6 +489,9 @@ public class TaskController extends AbstractPagingController {
|
|||
LOGGER.debug("Exit from applyFilterParams(), returning {}", taskQuery);
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from applyFilterParams(), query: {}", taskQuery);
|
||||
}
|
||||
return taskQuery;
|
||||
}
|
||||
|
||||
|
@ -658,58 +658,50 @@ public class TaskController extends AbstractPagingController {
|
|||
return null;
|
||||
}
|
||||
|
||||
private TaskQuery applySortingParams(TaskQuery taskQuery, MultiValueMap<String, String> params)
|
||||
private TaskQuery applySortingParams(TaskQuery query, MultiValueMap<String, String> params)
|
||||
throws InvalidArgumentException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to applySortingParams(taskQuery= {}, params= {})", taskQuery, params);
|
||||
LOGGER.debug("Entry to applySortingParams(query= {}, params= {})", query, params);
|
||||
}
|
||||
|
||||
// sorting
|
||||
String sortBy = params.getFirst(SORT_BY);
|
||||
if (sortBy != null) {
|
||||
SortDirection sortDirection;
|
||||
if (params.getFirst(SORT_DIRECTION) != null
|
||||
&& "desc".equals(params.getFirst(SORT_DIRECTION))) {
|
||||
sortDirection = SortDirection.DESCENDING;
|
||||
} else {
|
||||
sortDirection = SortDirection.ASCENDING;
|
||||
}
|
||||
switch (sortBy) {
|
||||
case (CLASSIFICATION_KEY):
|
||||
taskQuery = taskQuery.orderByClassificationKey(sortDirection);
|
||||
break;
|
||||
case (POR_TYPE):
|
||||
taskQuery = taskQuery.orderByPrimaryObjectReferenceType(sortDirection);
|
||||
break;
|
||||
case (POR_VALUE):
|
||||
taskQuery = taskQuery.orderByPrimaryObjectReferenceValue(sortDirection);
|
||||
break;
|
||||
case (STATE):
|
||||
taskQuery = taskQuery.orderByState(sortDirection);
|
||||
break;
|
||||
case (NAME):
|
||||
taskQuery = taskQuery.orderByName(sortDirection);
|
||||
break;
|
||||
case (DUE):
|
||||
taskQuery = taskQuery.orderByDue(sortDirection);
|
||||
break;
|
||||
case (PLANNED):
|
||||
taskQuery = taskQuery.orderByPlanned(sortDirection);
|
||||
break;
|
||||
case (PRIORITY):
|
||||
taskQuery = taskQuery.orderByPriority(sortDirection);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException("Unknown filter attribute: " + sortBy);
|
||||
}
|
||||
}
|
||||
params.remove(SORT_BY);
|
||||
params.remove(SORT_DIRECTION);
|
||||
QueryHelper.applyAndRemoveSortingParams(
|
||||
params,
|
||||
(sortBy, sortDirection) -> {
|
||||
switch (sortBy) {
|
||||
case (CLASSIFICATION_KEY):
|
||||
query.orderByClassificationKey(sortDirection);
|
||||
break;
|
||||
case (POR_TYPE):
|
||||
query.orderByPrimaryObjectReferenceType(sortDirection);
|
||||
break;
|
||||
case (POR_VALUE):
|
||||
query.orderByPrimaryObjectReferenceValue(sortDirection);
|
||||
break;
|
||||
case (STATE):
|
||||
query.orderByState(sortDirection);
|
||||
break;
|
||||
case (NAME):
|
||||
query.orderByName(sortDirection);
|
||||
break;
|
||||
case (DUE):
|
||||
query.orderByDue(sortDirection);
|
||||
break;
|
||||
case (PLANNED):
|
||||
query.orderByPlanned(sortDirection);
|
||||
break;
|
||||
case (PRIORITY):
|
||||
query.orderByPriority(sortDirection);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException("Unknown filter attribute: " + sortBy);
|
||||
}
|
||||
});
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from applySortingParams(), returning {}", taskQuery);
|
||||
LOGGER.debug("Exit from applySortingParams(), returning {}", query);
|
||||
}
|
||||
|
||||
return taskQuery;
|
||||
return query;
|
||||
}
|
||||
|
||||
private int[] extractPriorities(String[] prioritiesInString) {
|
||||
|
|
|
@ -15,11 +15,11 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import pro.taskana.common.api.BaseQuery;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.rest.AbstractPagingController;
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.common.rest.QueryHelper;
|
||||
import pro.taskana.common.rest.ldap.LdapClient;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModel;
|
||||
import pro.taskana.workbasket.api.WorkbasketAccessItemQuery;
|
||||
|
@ -43,26 +43,18 @@ public class WorkbasketAccessItemController extends AbstractPagingController {
|
|||
private static final String ACCESS_ID_LIKE = "access-id-like";
|
||||
private static final String ACCESS_IDS = "access-ids";
|
||||
|
||||
private static final String SORT_BY = "sort-by";
|
||||
private static final String SORT_DIRECTION = "order";
|
||||
|
||||
final LdapClient ldapClient;
|
||||
|
||||
private final LdapClient ldapClient;
|
||||
private final WorkbasketService workbasketService;
|
||||
|
||||
private final WorkbasketAccessItemRepresentationModelAssembler
|
||||
workbasketAccessItemRepresentationModelAssembler;
|
||||
private final WorkbasketAccessItemRepresentationModelAssembler modelAssembler;
|
||||
|
||||
@Autowired
|
||||
public WorkbasketAccessItemController(
|
||||
LdapClient ldapClient,
|
||||
WorkbasketService workbasketService,
|
||||
WorkbasketAccessItemRepresentationModelAssembler
|
||||
workbasketAccessItemRepresentationModelAssembler) {
|
||||
WorkbasketAccessItemRepresentationModelAssembler modelAssembler) {
|
||||
this.ldapClient = ldapClient;
|
||||
this.workbasketService = workbasketService;
|
||||
this.workbasketAccessItemRepresentationModelAssembler =
|
||||
workbasketAccessItemRepresentationModelAssembler;
|
||||
this.modelAssembler = modelAssembler;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,16 +74,15 @@ public class WorkbasketAccessItemController extends AbstractPagingController {
|
|||
}
|
||||
|
||||
WorkbasketAccessItemQuery query = workbasketService.createWorkbasketAccessItemQuery();
|
||||
getAccessIds(query, params);
|
||||
applyFilterParams(query, params);
|
||||
query = applyAccessIdIn(query, params);
|
||||
query = applyFilterParams(query, params);
|
||||
query = applySortingParams(query, params);
|
||||
|
||||
PageMetadata pageMetadata = getPageMetadata(params, query);
|
||||
List<WorkbasketAccessItem> workbasketAccessItems = getQueryList(query, pageMetadata);
|
||||
|
||||
TaskanaPagedModel<WorkbasketAccessItemRepresentationModel> pagedResources =
|
||||
workbasketAccessItemRepresentationModelAssembler.toPageModel(
|
||||
workbasketAccessItems, pageMetadata);
|
||||
modelAssembler.toPageModel(workbasketAccessItems, pageMetadata);
|
||||
|
||||
ResponseEntity<TaskanaPagedModel<WorkbasketAccessItemRepresentationModel>> response =
|
||||
ResponseEntity.ok(pagedResources);
|
||||
|
@ -134,7 +125,8 @@ public class WorkbasketAccessItemController extends AbstractPagingController {
|
|||
return response;
|
||||
}
|
||||
|
||||
private void getAccessIds(WorkbasketAccessItemQuery query, MultiValueMap<String, String> params) {
|
||||
private WorkbasketAccessItemQuery applyAccessIdIn(
|
||||
WorkbasketAccessItemQuery query, MultiValueMap<String, String> params) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to getAccessIds(query= {}, params= {})", query, params);
|
||||
}
|
||||
|
@ -148,9 +140,10 @@ public class WorkbasketAccessItemController extends AbstractPagingController {
|
|||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from getAccessIds(), returning {}", query);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
private void applyFilterParams(
|
||||
private WorkbasketAccessItemQuery applyFilterParams(
|
||||
WorkbasketAccessItemQuery query, MultiValueMap<String, String> params) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to applyFilterParams(query= {}, params= {})", query, params);
|
||||
|
@ -174,9 +167,11 @@ public class WorkbasketAccessItemController extends AbstractPagingController {
|
|||
query.accessIdLike(LIKE + params.get(ACCESS_ID_LIKE).get(0) + LIKE);
|
||||
params.remove(ACCESS_ID_LIKE);
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from applyFilterParams(), returning {}", query);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
private WorkbasketAccessItemQuery applySortingParams(
|
||||
|
@ -186,33 +181,24 @@ public class WorkbasketAccessItemController extends AbstractPagingController {
|
|||
LOGGER.debug("Entry to applySortingParams(query= {}, params= {})", query, params);
|
||||
}
|
||||
|
||||
// sorting
|
||||
String sortBy = params.getFirst(SORT_BY);
|
||||
if (sortBy != null) {
|
||||
BaseQuery.SortDirection sortDirection;
|
||||
if (params.getFirst(SORT_DIRECTION) != null
|
||||
&& "desc".equals(params.getFirst(SORT_DIRECTION))) {
|
||||
sortDirection = BaseQuery.SortDirection.DESCENDING;
|
||||
} else {
|
||||
sortDirection = BaseQuery.SortDirection.ASCENDING;
|
||||
}
|
||||
switch (sortBy) {
|
||||
case (WORKBASKET_KEY):
|
||||
query = query.orderByWorkbasketKey(sortDirection);
|
||||
break;
|
||||
case (ACCESS_ID):
|
||||
query = query.orderByAccessId(sortDirection);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException("Unknown order '" + sortBy + "'");
|
||||
}
|
||||
}
|
||||
params.remove(SORT_BY);
|
||||
params.remove(SORT_DIRECTION);
|
||||
QueryHelper.applyAndRemoveSortingParams(
|
||||
params,
|
||||
(sortBy, sortDirection) -> {
|
||||
switch (sortBy) {
|
||||
case (WORKBASKET_KEY):
|
||||
query.orderByWorkbasketKey(sortDirection);
|
||||
break;
|
||||
case (ACCESS_ID):
|
||||
query.orderByAccessId(sortDirection);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException("Unknown order '" + sortBy + "'");
|
||||
}
|
||||
});
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from applySortingParams(), returning {}", query);
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,13 +21,13 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import pro.taskana.common.api.BaseQuery.SortDirection;
|
||||
import pro.taskana.common.api.exceptions.ConcurrencyException;
|
||||
import pro.taskana.common.api.exceptions.DomainNotFoundException;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.rest.AbstractPagingController;
|
||||
import pro.taskana.common.rest.Mapping;
|
||||
import pro.taskana.common.rest.QueryHelper;
|
||||
import pro.taskana.common.rest.models.TaskanaPagedModel;
|
||||
import pro.taskana.workbasket.api.WorkbasketPermission;
|
||||
import pro.taskana.workbasket.api.WorkbasketQuery;
|
||||
|
@ -68,9 +68,6 @@ public class WorkbasketController extends AbstractPagingController {
|
|||
private static final String TYPE = "type";
|
||||
private static final String DESCRIPTION = "description";
|
||||
|
||||
private static final String SORT_BY = "sort-by";
|
||||
private static final String SORT_DIRECTION = "order";
|
||||
|
||||
private final WorkbasketService workbasketService;
|
||||
|
||||
private final WorkbasketRepresentationModelAssembler workbasketRepresentationModelAssembler;
|
||||
|
@ -106,7 +103,7 @@ public class WorkbasketController extends AbstractPagingController {
|
|||
|
||||
WorkbasketQuery query = workbasketService.createWorkbasketQuery();
|
||||
query = applySortingParams(query, params);
|
||||
applyFilterParams(query, params);
|
||||
query = applyFilterParams(query, params);
|
||||
|
||||
PageMetadata pageMetadata = getPageMetadata(params, query);
|
||||
List<WorkbasketSummary> workbasketSummaries = getQueryList(query, pageMetadata);
|
||||
|
@ -348,47 +345,38 @@ public class WorkbasketController extends AbstractPagingController {
|
|||
LOGGER.debug("Entry to applySortingParams(query= {}, params={})", query, params);
|
||||
}
|
||||
|
||||
// sorting
|
||||
String sortBy = params.getFirst(SORT_BY);
|
||||
if (sortBy != null) {
|
||||
SortDirection sortDirection;
|
||||
if (params.getFirst(SORT_DIRECTION) != null
|
||||
&& "desc".equals(params.getFirst(SORT_DIRECTION))) {
|
||||
sortDirection = SortDirection.DESCENDING;
|
||||
} else {
|
||||
sortDirection = SortDirection.ASCENDING;
|
||||
}
|
||||
switch (sortBy) {
|
||||
case (NAME):
|
||||
query = query.orderByName(sortDirection);
|
||||
break;
|
||||
case (KEY):
|
||||
query = query.orderByKey(sortDirection);
|
||||
break;
|
||||
case (OWNER):
|
||||
query = query.orderByOwner(sortDirection);
|
||||
break;
|
||||
case (TYPE):
|
||||
query = query.orderByType(sortDirection);
|
||||
break;
|
||||
case (DESCRIPTION):
|
||||
query = query.orderByDescription(sortDirection);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException("Unknown order '" + sortBy + "'");
|
||||
}
|
||||
}
|
||||
params.remove(SORT_BY);
|
||||
params.remove(SORT_DIRECTION);
|
||||
QueryHelper.applyAndRemoveSortingParams(
|
||||
params,
|
||||
(sortBy, sortDirection) -> {
|
||||
switch (sortBy) {
|
||||
case (NAME):
|
||||
query.orderByName(sortDirection);
|
||||
break;
|
||||
case (KEY):
|
||||
query.orderByKey(sortDirection);
|
||||
break;
|
||||
case (OWNER):
|
||||
query.orderByOwner(sortDirection);
|
||||
break;
|
||||
case (TYPE):
|
||||
query.orderByType(sortDirection);
|
||||
break;
|
||||
case (DESCRIPTION):
|
||||
query.orderByDescription(sortDirection);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException("Unknown order '" + sortBy + "'");
|
||||
}
|
||||
});
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from applySortingParams(), returning {}", query);
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
private void applyFilterParams(WorkbasketQuery query, MultiValueMap<String, String> params)
|
||||
throws InvalidArgumentException {
|
||||
private WorkbasketQuery applyFilterParams(
|
||||
WorkbasketQuery query, MultiValueMap<String, String> params) throws InvalidArgumentException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Entry to applyFilterParams(query= {}, params= {})", query, params);
|
||||
}
|
||||
|
@ -428,82 +416,22 @@ public class WorkbasketController extends AbstractPagingController {
|
|||
query.domainIn(extractCommaSeparatedFields(params.get(DOMAIN)));
|
||||
params.remove(DOMAIN);
|
||||
}
|
||||
if (params.containsKey(TYPE)) {
|
||||
switch (params.getFirst(TYPE)) {
|
||||
case "PERSONAL":
|
||||
query.typeIn(WorkbasketType.PERSONAL);
|
||||
break;
|
||||
case "GROUP":
|
||||
query.typeIn(WorkbasketType.GROUP);
|
||||
break;
|
||||
case "CLEARANCE":
|
||||
query.typeIn(WorkbasketType.CLEARANCE);
|
||||
break;
|
||||
case "TOPIC":
|
||||
query.typeIn(WorkbasketType.TOPIC);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException(
|
||||
"Unknown Workbasket type '" + params.getFirst(TYPE) + "'");
|
||||
String type = params.getFirst(TYPE);
|
||||
if (type != null) {
|
||||
try {
|
||||
query.typeIn(WorkbasketType.valueOf(type));
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new InvalidArgumentException("Unknown Workbasket type '" + type + "'");
|
||||
}
|
||||
params.remove(TYPE);
|
||||
}
|
||||
if (params.containsKey(REQUIRED_PERMISSION)) {
|
||||
for (String authorization : params.getFirst(REQUIRED_PERMISSION).split(",")) {
|
||||
switch (authorization.trim()) {
|
||||
case "READ":
|
||||
query.callerHasPermission(WorkbasketPermission.READ);
|
||||
break;
|
||||
case "OPEN":
|
||||
query.callerHasPermission(WorkbasketPermission.OPEN);
|
||||
break;
|
||||
case "APPEND":
|
||||
query.callerHasPermission(WorkbasketPermission.APPEND);
|
||||
break;
|
||||
case "TRANSFER":
|
||||
query.callerHasPermission(WorkbasketPermission.TRANSFER);
|
||||
break;
|
||||
case "DISTRIBUTE":
|
||||
query.callerHasPermission(WorkbasketPermission.DISTRIBUTE);
|
||||
break;
|
||||
case "CUSTOM_1":
|
||||
query.callerHasPermission(WorkbasketPermission.CUSTOM_1);
|
||||
break;
|
||||
case "CUSTOM_2":
|
||||
query.callerHasPermission(WorkbasketPermission.CUSTOM_2);
|
||||
break;
|
||||
case "CUSTOM_3":
|
||||
query.callerHasPermission(WorkbasketPermission.CUSTOM_3);
|
||||
break;
|
||||
case "CUSTOM_4":
|
||||
query.callerHasPermission(WorkbasketPermission.CUSTOM_4);
|
||||
break;
|
||||
case "CUSTOM_5":
|
||||
query.callerHasPermission(WorkbasketPermission.CUSTOM_5);
|
||||
break;
|
||||
case "CUSTOM_6":
|
||||
query.callerHasPermission(WorkbasketPermission.CUSTOM_6);
|
||||
break;
|
||||
case "CUSTOM_7":
|
||||
query.callerHasPermission(WorkbasketPermission.CUSTOM_7);
|
||||
break;
|
||||
case "CUSTOM_8":
|
||||
query.callerHasPermission(WorkbasketPermission.CUSTOM_8);
|
||||
break;
|
||||
case "CUSTOM_9":
|
||||
query.callerHasPermission(WorkbasketPermission.CUSTOM_9);
|
||||
break;
|
||||
case "CUSTOM_10":
|
||||
query.callerHasPermission(WorkbasketPermission.CUSTOM_10);
|
||||
break;
|
||||
case "CUSTOM_11":
|
||||
query.callerHasPermission(WorkbasketPermission.CUSTOM_11);
|
||||
break;
|
||||
case "CUSTOM_12":
|
||||
query.callerHasPermission(WorkbasketPermission.CUSTOM_12);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException("Unknown authorization '" + authorization + "'");
|
||||
String permissions = params.getFirst(REQUIRED_PERMISSION);
|
||||
if (permissions != null) {
|
||||
for (String authorization : permissions.split(",")) {
|
||||
try {
|
||||
query.callerHasPermission(WorkbasketPermission.valueOf(authorization.trim()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new InvalidArgumentException("Unknown authorization '" + authorization + "'", e);
|
||||
}
|
||||
}
|
||||
params.remove(REQUIRED_PERMISSION);
|
||||
|
@ -511,5 +439,7 @@ public class WorkbasketController extends AbstractPagingController {
|
|||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Exit from applyFilterParams(), returning {}", query);
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
package pro.taskana.common.rest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static pro.taskana.common.rest.QueryHelper.applyAndRemoveSortingParams;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
import org.junit.jupiter.api.function.ThrowingConsumer;
|
||||
import org.mockito.InOrder;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import pro.taskana.common.api.BaseQuery.SortDirection;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.internal.util.CheckedBiConsumer;
|
||||
|
||||
class QueryHelperTest {
|
||||
|
||||
@Test
|
||||
void should_removeSortByAndOrderDirection_When_ApplyingSortingParams() throws Exception {
|
||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
map.put(QueryHelper.SORT_BY, Collections.singletonList("sort-by"));
|
||||
map.put(QueryHelper.ORDER_DIRECTION, Collections.singletonList("order"));
|
||||
|
||||
applyAndRemoveSortingParams(map, mock(MockBiConsumer.class));
|
||||
assertThat(map).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ignoreMapContent_When_ApplyingSortingParams() throws Exception {
|
||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
String key = "unknown";
|
||||
List<String> value = Collections.singletonList("sort-by");
|
||||
map.put(key, value);
|
||||
map.put(QueryHelper.SORT_BY, Collections.singletonList("sort-by"));
|
||||
|
||||
applyAndRemoveSortingParams(map, mock(MockBiConsumer.class));
|
||||
assertThat(map).containsExactly(new SimpleEntry<>(key, value));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_NotCallConsumer_When_MapDoesNotContainSortBy() throws Exception {
|
||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
MockBiConsumer consumer = mock(MockBiConsumer.class);
|
||||
|
||||
applyAndRemoveSortingParams(map, consumer);
|
||||
|
||||
verifyNoInteractions(consumer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_CallConsumerWithSortByValue_When_MapContainsOneSortBy() throws Exception {
|
||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
map.put(QueryHelper.SORT_BY, Collections.singletonList("sort-by-value"));
|
||||
MockBiConsumer consumer = mock(MockBiConsumer.class);
|
||||
|
||||
applyAndRemoveSortingParams(map, consumer);
|
||||
verify(consumer).accept(eq("sort-by-value"), any());
|
||||
verifyNoMoreInteractions(consumer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_CallConsumerWithAscSortDirection_When_MapDoesNotContainSortDirection()
|
||||
throws Exception {
|
||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
map.put(QueryHelper.SORT_BY, Collections.singletonList("sort-by-value"));
|
||||
MockBiConsumer consumer = mock(MockBiConsumer.class);
|
||||
|
||||
applyAndRemoveSortingParams(map, consumer);
|
||||
verify(consumer).accept(any(), eq(SortDirection.ASCENDING));
|
||||
verifyNoMoreInteractions(consumer);
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicTest>
|
||||
should_CallConsumerWithDescSortDirection_When_MapDoesContainsDescSortDirection() {
|
||||
Iterator<String> testCases = Arrays.asList("desc", "DESC", "Desc", "desC", "DeSc").iterator();
|
||||
ThrowingConsumer<String> test =
|
||||
desc -> {
|
||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
map.put(QueryHelper.SORT_BY, Collections.singletonList("sort-by-value"));
|
||||
map.put(QueryHelper.ORDER_DIRECTION, Collections.singletonList(desc));
|
||||
MockBiConsumer consumer = mock(MockBiConsumer.class);
|
||||
|
||||
applyAndRemoveSortingParams(map, consumer);
|
||||
verify(consumer).accept(any(), eq(SortDirection.DESCENDING));
|
||||
verifyNoMoreInteractions(consumer);
|
||||
};
|
||||
|
||||
return DynamicTest.stream(testCases, s -> "Order by: " + s, test);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_callConsumerMultipleTimes_When_MapContainsMultipleSortBy() throws Exception {
|
||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
map.put(QueryHelper.SORT_BY, Arrays.asList("sort-by-value1", "sort-by-value2"));
|
||||
MockBiConsumer consumer = mock(MockBiConsumer.class);
|
||||
|
||||
applyAndRemoveSortingParams(map, consumer);
|
||||
InOrder inOrder = inOrder(consumer);
|
||||
inOrder.verify(consumer).accept(eq("sort-by-value1"), any());
|
||||
inOrder.verify(consumer).accept(eq("sort-by-value2"), any());
|
||||
verifyNoMoreInteractions(consumer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_matchSortDirectionForEachSortBy_When_MapContainsMultipleSortByAndOrderBy()
|
||||
throws Exception {
|
||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
map.put(QueryHelper.SORT_BY, Arrays.asList("sort-by-value1", "sort-by-value2"));
|
||||
map.put(QueryHelper.ORDER_DIRECTION, Arrays.asList("desc", "asc"));
|
||||
MockBiConsumer consumer = mock(MockBiConsumer.class);
|
||||
|
||||
applyAndRemoveSortingParams(map, consumer);
|
||||
verify(consumer).accept("sort-by-value1", SortDirection.DESCENDING);
|
||||
verify(consumer).accept("sort-by-value2", SortDirection.ASCENDING);
|
||||
verifyNoMoreInteractions(consumer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_throwError_When_MapContainsOrderByButNoSortBy() {
|
||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
map.put(QueryHelper.ORDER_DIRECTION, Collections.singletonList("desc"));
|
||||
assertThatThrownBy(() -> applyAndRemoveSortingParams(map, mock(MockBiConsumer.class)))
|
||||
.isInstanceOf(InvalidArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_throwError_When_SortByAndOrderByCountDoesNotMatch() {
|
||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
map.put(QueryHelper.SORT_BY, Arrays.asList("1", "2"));
|
||||
map.put(QueryHelper.ORDER_DIRECTION, Collections.singletonList("desc"));
|
||||
assertThatThrownBy(() -> applyAndRemoveSortingParams(map, mock(MockBiConsumer.class)))
|
||||
.isInstanceOf(InvalidArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_throwError_When_ConsumerRaisesException() throws Exception {
|
||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
map.put(QueryHelper.SORT_BY, Collections.singletonList("1"));
|
||||
MockBiConsumer consumer = mock(MockBiConsumer.class);
|
||||
doThrow(new InvalidArgumentException("")).when(consumer).accept(any(), any());
|
||||
assertThatThrownBy(() -> applyAndRemoveSortingParams(map, consumer))
|
||||
.isInstanceOf(InvalidArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_throwError_When_ConsumerIsNull() {
|
||||
assertThatThrownBy(() -> applyAndRemoveSortingParams(new LinkedMultiValueMap<>(), null))
|
||||
.isInstanceOf(InvalidArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_throwError_When_MapIsNull() {
|
||||
assertThatThrownBy(() -> applyAndRemoveSortingParams(null, mock(MockBiConsumer.class)))
|
||||
.isInstanceOf(InvalidArgumentException.class);
|
||||
}
|
||||
|
||||
private abstract static class MockBiConsumer
|
||||
implements CheckedBiConsumer<String, SortDirection, InvalidArgumentException> {}
|
||||
}
|
Loading…
Reference in New Issue