separated clientConnection and clientConnectionData page filter and sort
This commit is contained in:
parent
3744e10406
commit
085ec45fb1
3 changed files with 153 additions and 32 deletions
|
@ -17,8 +17,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
|
|||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.GrantEntity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
|
@ -100,6 +102,26 @@ public class ClientConnectionData implements GrantEntity {
|
|||
return this.missingPing || this.pendingNotification;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public Double getIndicatorValue(final Long indicatorId) {
|
||||
return this.indicatorValues
|
||||
.stream()
|
||||
.filter(indicatorValue -> indicatorValue.getIndicatorId().equals(indicatorId))
|
||||
.findFirst()
|
||||
.map(iv -> iv.getValue())
|
||||
.orElse(Double.NaN);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public String getIndicatorDisplayValue(final Indicator indicator) {
|
||||
return this.indicatorValues
|
||||
.stream()
|
||||
.filter(indicatorValue -> indicatorValue.getIndicatorId().equals(indicator.id))
|
||||
.findFirst()
|
||||
.map(iv -> IndicatorValue.getDisplayValue(iv, indicator.type))
|
||||
.orElse(Constants.EMPTY_NOTE);
|
||||
}
|
||||
|
||||
public ClientConnection getClientConnection() {
|
||||
return this.clientConnection;
|
||||
}
|
||||
|
|
|
@ -10,14 +10,12 @@ package ch.ethz.seb.sebserver.gui.content.monitoring;
|
|||
|
||||
import java.util.Collection;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
|
@ -26,7 +24,6 @@ import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
|||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.IndicatorValue;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
|
@ -162,7 +159,7 @@ public class FinishedExam implements TemplateComposer {
|
|||
tableBuilder.withColumn(new ColumnDefinition<>(
|
||||
indicator.name,
|
||||
new LocTextKey(indicator.name),
|
||||
indicatorValueFunction(indicator)));
|
||||
cc -> cc.getIndicatorDisplayValue(indicator)));
|
||||
});
|
||||
|
||||
final EntityTable<ClientConnectionData> table = tableBuilder.compose(pageContext.copyOf(content));
|
||||
|
@ -175,15 +172,4 @@ public class FinishedExam implements TemplateComposer {
|
|||
.publishIf(isExamSupporter, false);
|
||||
}
|
||||
|
||||
public Function<ClientConnectionData, String> indicatorValueFunction(final Indicator indicator) {
|
||||
return clientConnectionData -> {
|
||||
return clientConnectionData.indicatorValues
|
||||
.stream()
|
||||
.filter(indicatorValue -> indicatorValue.getIndicatorId().equals(indicator.id))
|
||||
.findFirst()
|
||||
.map(iv -> IndicatorValue.getDisplayValue(iv, indicator.type))
|
||||
.orElse(Constants.EMPTY_NOTE);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -82,6 +82,73 @@ public class ClientConnectionController extends ReadonlyEntityController<ClientC
|
|||
this.sebClientConnectionService = sebClientConnectionService;
|
||||
}
|
||||
|
||||
/** The generic endpoint to get a Page of domain-entities of a specific type.
|
||||
* </p>
|
||||
* GET /{api}/{domain-entity-name}
|
||||
* </p>
|
||||
* For example for the "exam" domain-entity
|
||||
* GET /admin-api/v1/exam
|
||||
* GET /admin-api/v1/exam?page_number=2&page_size=10&sort=-name
|
||||
* GET /admin-api/v1/exam?name=seb&active=true
|
||||
* </p>
|
||||
* Sorting: the sort parameter to sort the list of entities before paging
|
||||
* the sort parameter is the name of the entity-model attribute to sort with a leading '-' sign for
|
||||
* descending sort order. Note that not all entity-model attribute are suited for sorting while the most
|
||||
* are.
|
||||
* </p>
|
||||
* Filter: The filter attributes accepted by this API depend on the actual entity model (domain object)
|
||||
* and are of the form [domain-attribute-name]=[filter-value]. E.g.: name=abc or type=EXAM. Usually
|
||||
* filter attributes of text type are treated as SQL wildcard with %[text]% to filter all text containing
|
||||
* a given text-snippet.
|
||||
*
|
||||
* @param institutionId The institution identifier of the request.
|
||||
* Default is the institution identifier of the institution of the current user
|
||||
* @param pageNumber the number of the page that is requested
|
||||
* @param pageSize the size of the page that is requested
|
||||
* @param sort the sort parameter to sort the list of entities before paging
|
||||
* the sort parameter is the name of the entity-model attribute to sort with a leading '-' sign for
|
||||
* descending sort order.
|
||||
* @param allRequestParams a MultiValueMap of all request parameter that is used for filtering.
|
||||
* @return Page of domain-model-entities of specified type */
|
||||
@Override
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public Page<ClientConnection> getPage(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = Page.ATTR_PAGE_NUMBER, required = false) final Integer pageNumber,
|
||||
@RequestParam(name = Page.ATTR_PAGE_SIZE, required = false) final Integer pageSize,
|
||||
@RequestParam(name = Page.ATTR_SORT, required = false) final String sort,
|
||||
@RequestParam final MultiValueMap<String, String> allRequestParams,
|
||||
final HttpServletRequest request) {
|
||||
|
||||
// at least current user must have read access for specified entity type within its own institution
|
||||
checkReadPrivilege(institutionId);
|
||||
|
||||
final FilterMap filterMap = new FilterMap(allRequestParams, request.getQueryString());
|
||||
populateFilterMap(filterMap, institutionId, sort);
|
||||
|
||||
if (StringUtils.isNotBlank(sort) || filterMap.containsAny(EXT_FILTER)) {
|
||||
|
||||
final Collection<ClientConnection> allConnections = getAll(filterMap)
|
||||
.getOrThrow();
|
||||
|
||||
return this.paginationService.buildPageFromList(
|
||||
pageNumber,
|
||||
pageSize,
|
||||
sort,
|
||||
allConnections,
|
||||
pageClientConnectionFunction(filterMap, sort));
|
||||
|
||||
} else {
|
||||
return super.getPage(institutionId, pageNumber, pageSize, sort, allRequestParams, request);
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
path = API.SEB_CLIENT_CONNECTION_DATA_ENDPOINT,
|
||||
method = RequestMethod.GET,
|
||||
|
@ -114,7 +181,7 @@ public class ClientConnectionController extends ReadonlyEntityController<ClientC
|
|||
pageSize,
|
||||
sort,
|
||||
allConnections,
|
||||
pageFunction(filterMap, sort));
|
||||
pageClientConnectionDataFunction(filterMap, sort));
|
||||
} else {
|
||||
|
||||
return this.paginationService.getPage(
|
||||
|
@ -138,18 +205,6 @@ public class ClientConnectionController extends ReadonlyEntityController<ClientC
|
|||
.getOrThrow();
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected Result<Collection<ClientConnection>> getAll(final FilterMap filterMap) {
|
||||
// final String infoFilter = filterMap.getString(ClientConnection.FILTER_ATTR_INFO);
|
||||
// if (StringUtils.isNotBlank(infoFilter)) {
|
||||
// return super.getAll(filterMap)
|
||||
// .map(all -> all.stream().filter(c -> c.getInfo() == null || c.getInfo().contains(infoFilter))
|
||||
// .collect(Collectors.toList()));
|
||||
// }
|
||||
//
|
||||
// return super.getAll(filterMap);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public Collection<EntityDependency> getDependencies(
|
||||
final String modelId,
|
||||
|
@ -198,15 +253,35 @@ public class ClientConnectionController extends ReadonlyEntityController<ClientC
|
|||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private Function<Collection<ClientConnectionData>, List<ClientConnectionData>> pageFunction(
|
||||
private Function<Collection<ClientConnection>, List<ClientConnection>> pageClientConnectionFunction(
|
||||
final FilterMap filterMap,
|
||||
final String sort) {
|
||||
|
||||
return connections -> {
|
||||
|
||||
final List<ClientConnectionData> filtered = connections.stream()
|
||||
.filter(getFilter(filterMap))
|
||||
final List<ClientConnection> filtered = connections
|
||||
.stream()
|
||||
.filter(getClientConnectionFilter(filterMap))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (StringUtils.isNotBlank(sort)) {
|
||||
filtered.sort(new ClientConnectionComparator(sort));
|
||||
}
|
||||
return filtered;
|
||||
};
|
||||
}
|
||||
|
||||
private Function<Collection<ClientConnectionData>, List<ClientConnectionData>> pageClientConnectionDataFunction(
|
||||
final FilterMap filterMap,
|
||||
final String sort) {
|
||||
|
||||
return connections -> {
|
||||
|
||||
final List<ClientConnectionData> filtered = connections
|
||||
.stream()
|
||||
.filter(getClientConnectionDataFilter(filterMap))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (StringUtils.isNotBlank(sort)) {
|
||||
filtered.sort(new ClientConnectionDataComparator(sort));
|
||||
}
|
||||
|
@ -214,7 +289,16 @@ public class ClientConnectionController extends ReadonlyEntityController<ClientC
|
|||
};
|
||||
}
|
||||
|
||||
private Predicate<ClientConnectionData> getFilter(final FilterMap filterMap) {
|
||||
private Predicate<ClientConnection> getClientConnectionFilter(final FilterMap filterMap) {
|
||||
final String infoFilter = filterMap.getString(ClientConnection.FILTER_ATTR_INFO);
|
||||
Predicate<ClientConnection> filter = Utils.truePredicate();
|
||||
if (StringUtils.isNotBlank(infoFilter)) {
|
||||
filter = c -> c.getInfo() == null || c.getInfo().contains(infoFilter);
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
private Predicate<ClientConnectionData> getClientConnectionDataFilter(final FilterMap filterMap) {
|
||||
final String infoFilter = filterMap.getString(ClientConnection.FILTER_ATTR_INFO);
|
||||
Predicate<ClientConnectionData> filter = Utils.truePredicate();
|
||||
if (StringUtils.isNotBlank(infoFilter)) {
|
||||
|
@ -223,6 +307,35 @@ public class ClientConnectionController extends ReadonlyEntityController<ClientC
|
|||
return filter;
|
||||
}
|
||||
|
||||
private static final class ClientConnectionComparator implements Comparator<ClientConnection> {
|
||||
|
||||
final String sortColumn;
|
||||
final boolean descending;
|
||||
|
||||
ClientConnectionComparator(final String sort) {
|
||||
this.sortColumn = PageSortOrder.decode(sort);
|
||||
this.descending = PageSortOrder.getSortOrder(sort) == PageSortOrder.DESCENDING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(final ClientConnection cc1, final ClientConnection cc2) {
|
||||
int result = 0;
|
||||
if (Domain.CLIENT_CONNECTION.ATTR_EXAM_USER_SESSION_ID.equals(this.sortColumn)) {
|
||||
result = cc1.userSessionId
|
||||
.compareTo(cc2.userSessionId);
|
||||
} else if (ClientConnection.ATTR_INFO.equals(this.sortColumn)) {
|
||||
result = cc1.getInfo().compareTo(cc2.getInfo());
|
||||
} else if (Domain.CLIENT_CONNECTION.ATTR_STATUS.equals(this.sortColumn)) {
|
||||
result = cc1.getStatus()
|
||||
.compareTo(cc2.getStatus());
|
||||
} else {
|
||||
result = cc1.userSessionId
|
||||
.compareTo(cc2.userSessionId);
|
||||
}
|
||||
return (this.descending) ? -result : result;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ClientConnectionDataComparator implements Comparator<ClientConnectionData> {
|
||||
|
||||
final String sortColumn;
|
||||
|
|
Loading…
Reference in a new issue