Skip to content

Commit

Permalink
TSK-843: moved report structure ajustment from client to rest service.
Browse files Browse the repository at this point in the history
  • Loading branch information
mustaphazorgati authored and holgerhagen committed Apr 30, 2019
1 parent d8b1829 commit c5d00c0
Show file tree
Hide file tree
Showing 25 changed files with 383 additions and 574 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,12 @@ public abstract class Report<I extends QueryItem, H extends ColumnHeader<? super
protected List<H> columnHeaders;
private Map<String, Row<I>> reportRows = new LinkedHashMap<>();
private Row<I> sumRow;
private String rowDesc;
private String[] expandableHeaders;
private String[] rowDesc;

protected Report(List<H> columnHeaders, String rowDesc, String[] expandableHeaders) {
protected Report(List<H> columnHeaders, String[] rowDesc) {
this.rowDesc = rowDesc;
sumRow = createRow(columnHeaders.size());
this.columnHeaders = new ArrayList<>(columnHeaders);
this.expandableHeaders = expandableHeaders;
}

protected Report(List<H> columnHeaders, String rowDesc) {
this(columnHeaders, rowDesc, new String[0]);
}

public final Map<String, Row<I>> getRows() {
Expand All @@ -50,14 +44,10 @@ public final List<H> getColumnHeaders() {
return columnHeaders;
}

public final String getRowDesc() {
public final String[] getRowDesc() {
return rowDesc;
}

public final String[] getExpandableHeaders() {
return expandableHeaders;
}

public Row<I> getRow(String key) {
return reportRows.get(key);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
public class CategoryReport extends Report<MonitorQueryItem, TimeIntervalColumnHeader> {

public CategoryReport(List<TimeIntervalColumnHeader> timeIntervalColumnHeaders) {
super(timeIntervalColumnHeaders, "CLASSIFICATION CATEGORIES");
super(timeIntervalColumnHeaders, new String[] {"CLASSIFICATION CATEGORIES"});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
public class ClassificationReport extends Report<MonitorQueryItem, TimeIntervalColumnHeader> {

public ClassificationReport(List<TimeIntervalColumnHeader> timeIntervalColumnHeaders) {
super(timeIntervalColumnHeaders, "CLASSIFICATION KEYS");
super(timeIntervalColumnHeaders, new String[] {"CLASSIFICATION KEYS"});
}

/**
Expand Down Expand Up @@ -52,7 +52,7 @@ public static class DetailedClassificationReport
extends Report<DetailedMonitorQueryItem, TimeIntervalColumnHeader> {

public DetailedClassificationReport(List<TimeIntervalColumnHeader> workbasketLevelReportColumnHeaders) {
super(workbasketLevelReportColumnHeaders, "TASK CLASSIFICATION KEYS");
super(workbasketLevelReportColumnHeaders, new String[] {"TASK CLASSIFICATION KEYS", "ATTACHMENT"});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
public class CustomFieldValueReport extends Report<MonitorQueryItem, TimeIntervalColumnHeader> {

public CustomFieldValueReport(List<TimeIntervalColumnHeader> timeIntervalColumnHeaders) {
super(timeIntervalColumnHeaders, "CUSTOM FIELDS");
super(timeIntervalColumnHeaders, new String[] {"CUSTOM FIELDS"});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class TaskStatusReport extends Report<TaskQueryItem, TaskStatusColumnHead
public TaskStatusReport(List<TaskState> filter) {
super((filter != null ? filter.stream() : Stream.of(TaskState.values()))
.map(TaskStatusColumnHeader::new)
.collect(Collectors.toList()), "DOMAINS");
.collect(Collectors.toList()), new String[] {"DOMAINS"});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
public class TimestampReport extends Report<TimestampQueryItem, TimeIntervalColumnHeader> {

public TimestampReport(List<TimeIntervalColumnHeader> dates) {
super(dates, "STATES", new String[] {"ORG LEVEL 1", "ORG LEVEL 2", "ORG LEVEL 3", "ORG LEVEL 4"});
super(dates, new String[] {"STATES", "ORG LEVEL 1", "ORG LEVEL 2", "ORG LEVEL 3", "ORG LEVEL 4"});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
public class WorkbasketReport extends Report<MonitorQueryItem, TimeIntervalColumnHeader> {

public WorkbasketReport(List<TimeIntervalColumnHeader> timeIntervalColumnHeaders) {
super(timeIntervalColumnHeaders, "WORKBASKET KEYS");
super(timeIntervalColumnHeaders, new String[] {"WORKBASKET KEYS"});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class ReportTest {

@Before
public void before() {
this.report = new Report<MonitorQueryItem, TimeIntervalColumnHeader>(HEADERS, "rowDesc") {
this.report = new Report<MonitorQueryItem, TimeIntervalColumnHeader>(HEADERS, new String[] {"rowDesc"}) {

};

Expand Down Expand Up @@ -116,7 +116,8 @@ public void testInsertSameItemMultipleTimesWithPreProcessor() {
@Test
public void testInsertItemWithNoColumnHeaders() {
//given
report = new Report<MonitorQueryItem, TimeIntervalColumnHeader>(Collections.emptyList(), "rowDesc") {
report = new Report<MonitorQueryItem, TimeIntervalColumnHeader>(Collections.emptyList(),
new String[] {"rowDesc"}) {

};

Expand Down Expand Up @@ -148,7 +149,7 @@ public void testInsertItemWhichIsInMultipleHeaderScopes() {
//given
List<TimeIntervalColumnHeader> headers = new ArrayList<>(HEADERS);
headers.add(new TimeIntervalColumnHeader(0, 3));
report = new Report<MonitorQueryItem, TimeIntervalColumnHeader>(headers, "rowDesc") {
report = new Report<MonitorQueryItem, TimeIntervalColumnHeader>(headers, new String[] {"rowDesc"}) {

};
item.setAgeInDays(2);
Expand Down
16 changes: 16 additions & 0 deletions rest/taskana-rest-spring-test/src/main/asciidoc/rest-api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,22 @@ include::../../../{snippets}/GetTaskClassificationReportDocTest/http-response.ad

Same as task status report

=== Get a timestamp report

A `GET` request is used to get the number of tasks sorted by a task timestamp.

==== Example Request

include::../../../{snippets}/GetTimestampReportDocTest/http-request.adoc[]

==== Example Response

include::../../../{snippets}/GetTimestampReportDocTest/http-response.adoc[]

==== Response Structure

Same as task status report

== Other Resources (using the TaskanaEngineController)

These resources are directly connected to the Taskana Engine endpoint.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,15 @@ public void setUp() {
fieldWithPath("meta.name").description("Name of the report"),
fieldWithPath("meta.date").description("Date of the report creation"),
fieldWithPath("meta.header").description("Column-headers of the report"),
fieldWithPath("meta.expHeader").description(
"Expandable Column-headers which match the depth of the foldable rows within the report."),
fieldWithPath("meta.rowDesc").description("Descriptions for the rows the report"),
fieldWithPath("meta.totalDesc").description("Description for the report itself"),
subsectionWithPath("rows").description("Object holding the rows of the report.\n"
+ "For the exact structure please check the example response above"),
fieldWithPath("sumRow").description("Object holding the sums in the columns over all rows"),
subsectionWithPath("sumRow.cells")
.description("Contains the accumulated numbers over all columns defined in meta.header.\n"
+ "For the exact structure please check the example response above"),
fieldWithPath("sumRow.total").description("Total number of tasks"),
fieldWithPath("meta.totalDesc").description("Description for the sum column"),
fieldWithPath("rows").description("Array holding the rows of the report."),
fieldWithPath("rows[].cells").description("Array holding all the cell values of the given row"),
fieldWithPath("rows[].total").description("Sum of all values of the given row"),
fieldWithPath("rows[].depth").description("Depth of the row. If the depth is > 0, then this row is a sub-row of a prior row"),
fieldWithPath("rows[].desc").description("Array containing description of the row."),
fieldWithPath("rows[].display").description("Boolean identifying if the given row should be initially displayed or not."),
subsectionWithPath("sumRow").description("Array holding the sums in the columns over all rows. Structure same as 'rows'"),
fieldWithPath("_links.self.href").ignored()
};
}
Expand Down Expand Up @@ -115,4 +113,15 @@ public void tasksClassificationReport() throws Exception {
.andDo(MockMvcRestDocumentation.document("GetTaskClassificationReportDocTest",
responseFields(taskReportFieldDescriptors)));
}

@Test
public void getTimestampReport() throws Exception {
this.mockMvc.perform(RestDocumentationRequestBuilders
.get("http://127.0.0.1:" + port + "/v1/monitor/timestamp-report")
.accept("application/hal+json")
.header("Authorization", "Basic YWRtaW46YWRtaW4="))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcRestDocumentation.document("GetTimestampReportDocTest",
responseFields(taskReportFieldDescriptors)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;

import java.time.Instant;
import java.util.HashMap;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -80,65 +82,52 @@ <I extends QueryItem, H extends ColumnHeader<? super I>> ReportResource toReport
report.getClass().getSimpleName(),
time.toString(),
header,
report.getExpandableHeaders(), report.getRowDesc());
report.getRowDesc());

// iterate over each Row and transform it to a RowResource while keeping the domain key.
Map<String, ReportResource.RowResource> rows = report.getRows()
List<ReportResource.RowResource> rows = report.getRows()
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, i -> transformRow(i.getValue(), header)));
.sorted(Comparator.comparing(e -> e.getKey().toLowerCase()))
.map(i -> transformRow(i.getValue(), i.getKey(), new String[report.getRowDesc().length], 0))
.flatMap(Collection::stream)
.collect(Collectors.toList());

ReportResource.RowResource sumRow = transformRow(report.getSumRow(), header);
List<ReportResource.RowResource> sumRow = transformRow(report.getSumRow(), meta.getTotalDesc(),
new String[report.getRowDesc().length], 0);

return new ReportResource(meta, rows, sumRow);
}

private <I extends QueryItem> ReportResource.RowResource transformRow(Row<I> row, String[] header) {
private <I extends QueryItem> List<ReportResource.RowResource> transformRow(Row<I> row, String currentDesc,
String[] desc, int depth) {
// This is a very dirty solution.. Personally I'd prefer to use a visitor-like pattern here.
// The issue with that: Addition of the visitor code within taskana-core - and having clean code is not
// a reason to append code somewhere where it doesn't belong.
if (row.getClass() == SingleRow.class) {
return transformSingleRow((SingleRow<I>) row, header);
return Collections.singletonList(transformSingleRow((SingleRow<I>) row, currentDesc, desc, depth));
}
return transformFoldableRow((FoldableRow<I>) row, header);
return transformFoldableRow((FoldableRow<I>) row, currentDesc, desc, depth);
}

private <I extends QueryItem> ReportResource.SingleRowResource transformSingleRow(SingleRow<I> row,
String[] header) {
Map<String, Integer> result = new HashMap<>();
int[] cells = row.getCells();
for (int i = 0; i < cells.length; i++) {
result.put(header[i], cells[i]);
}
return new ReportResource.SingleRowResource(result, row.getTotalValue());
private <I extends QueryItem> ReportResource.RowResource transformSingleRow(SingleRow<I> row, String currentDesc,
String[] previousRowDesc, int depth) {
String[] rowDesc = new String[previousRowDesc.length];
System.arraycopy(previousRowDesc, 0, rowDesc, 0, depth);
rowDesc[depth] = currentDesc;
return new ReportResource.RowResource(row.getCells(), row.getTotalValue(), depth, rowDesc, depth == 0);
}

private <I extends QueryItem> ReportResource.FoldableRowResource transformFoldableRow(FoldableRow<I> row,
String[] header) {
ReportResource.FoldableRowResource base = new ReportResource.FoldableRowResource(
transformSingleRow(row, header));
private <I extends QueryItem> List<ReportResource.RowResource> transformFoldableRow(FoldableRow<I> row,
String currentDesc, String[] previousRowDesc, int depth) {
ReportResource.RowResource baseRow = transformSingleRow(row, currentDesc, previousRowDesc, depth);
List<ReportResource.RowResource> rowList = new LinkedList<>();
rowList.add(baseRow);
row.getFoldableRowKeySet().stream()
.map(k -> new Pair<>(k, row.getFoldableRow(k)))
.map(p -> new Pair<>(p.key, transformRow(p.value, header)))
.forEachOrdered(p -> base.addRow(p.key, p.value));
return base;
}

/**
* Simple Pair (tuple).
* @param <K> key
* @param <V> value
*/
private class Pair<K, V> {

private final K key;
private final V value;

Pair(K key, V value) {
this.key = key;
this.value = value;
}

.sorted(String.CASE_INSENSITIVE_ORDER)
.map(s -> transformRow(row.getFoldableRow(s), s, baseRow.getDesc(), depth + 1))
.flatMap(Collection::stream)
.forEachOrdered(rowList::add);
return rowList;
}

}
Loading

0 comments on commit c5d00c0

Please sign in to comment.