use of org.opencastproject.matterhorn.search.SortCriterion in project opencast by opencast.
the class UsersEndpoint method getUsers.
@GET
@Path("users.json")
@Produces(MediaType.APPLICATION_JSON)
@RestQuery(name = "allusers", description = "Returns a list of users", returnDescription = "Returns a JSON representation of the list of user accounts", restParameters = { @RestParameter(name = "filter", isRequired = false, description = "The filter used for the query. They should be formated like that: 'filter1:value1,filter2:value2'", type = STRING), @RestParameter(name = "sort", isRequired = false, description = "The sort order. May include any of the following: STATUS, NAME OR LAST_UPDATED. Add '_DESC' to reverse the sort order (e.g. STATUS_DESC).", type = STRING), @RestParameter(defaultValue = "100", description = "The maximum number of items to return per page.", isRequired = false, name = "limit", type = RestParameter.Type.STRING), @RestParameter(defaultValue = "0", description = "The page number.", isRequired = false, name = "offset", type = RestParameter.Type.STRING) }, reponses = { @RestResponse(responseCode = SC_OK, description = "The user accounts.") })
public Response getUsers(@QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("limit") int limit, @QueryParam("offset") int offset) throws IOException {
if (limit < 1)
limit = 100;
Option<String> optSort = Option.option(trimToNull(sort));
Option<String> filterName = Option.none();
Option<String> filterRole = Option.none();
Option<String> filterProvider = Option.none();
Option<String> filterText = Option.none();
Map<String, String> filters = RestUtils.parseFilter(filter);
for (String name : filters.keySet()) {
String value = filters.get(name);
if (UsersListQuery.FILTER_NAME_NAME.equals(name)) {
filterName = Option.some(value);
} else if (UsersListQuery.FILTER_ROLE_NAME.equals(name)) {
filterRole = Option.some(value);
} else if (UsersListQuery.FILTER_PROVIDER_NAME.equals(name)) {
filterProvider = Option.some(value);
} else if ((UsersListQuery.FILTER_TEXT_NAME.equals(name)) && (StringUtils.isNotBlank(value))) {
filterText = Option.some(value);
}
}
// Filter users by filter criteria
List<User> filteredUsers = new ArrayList<>();
for (Iterator<User> i = userDirectoryService.getUsers(); i.hasNext(); ) {
User user = i.next();
// Filter list
if (filterName.isSome() && !filterName.get().equals(user.getName()) || (filterRole.isSome() && !Stream.$(user.getRoles()).map(getRoleName).toSet().contains(filterRole.get())) || (filterProvider.isSome() && !filterProvider.get().equals(user.getProvider())) || (filterText.isSome() && !TextFilter.match(filterText.get(), user.getUsername(), user.getName(), user.getEmail(), user.getProvider()) && !TextFilter.match(filterText.get(), Stream.$(user.getRoles()).map(getRoleName).mkString(" ")))) {
continue;
}
filteredUsers.add(user);
}
int total = filteredUsers.size();
// Sort by name, description or role
if (optSort.isSome()) {
final Set<SortCriterion> sortCriteria = RestUtils.parseSortQueryParameter(optSort.get());
Collections.sort(filteredUsers, new Comparator<User>() {
@Override
public int compare(User user1, User user2) {
for (SortCriterion criterion : sortCriteria) {
Order order = criterion.getOrder();
switch(criterion.getFieldName()) {
case "name":
if (order.equals(Order.Descending))
return CASE_INSENSITIVE_ORDER.compare(trimToEmpty(user2.getName()), trimToEmpty(user1.getName()));
return CASE_INSENSITIVE_ORDER.compare(trimToEmpty(user1.getName()), trimToEmpty(user2.getName()));
case "username":
if (order.equals(Order.Descending))
return CASE_INSENSITIVE_ORDER.compare(trimToEmpty(user2.getUsername()), trimToEmpty(user1.getUsername()));
return CASE_INSENSITIVE_ORDER.compare(trimToEmpty(user1.getUsername()), trimToEmpty(user2.getUsername()));
case "email":
if (order.equals(Order.Descending))
return CASE_INSENSITIVE_ORDER.compare(trimToEmpty(user2.getEmail()), trimToEmpty(user1.getEmail()));
return CASE_INSENSITIVE_ORDER.compare(trimToEmpty(user1.getEmail()), trimToEmpty(user2.getEmail()));
case "roles":
String roles1 = Stream.$(user1.getRoles()).map(getRoleName).sort(sortByName).mkString(",");
String roles2 = Stream.$(user2.getRoles()).map(getRoleName).sort(sortByName).mkString(",");
if (order.equals(Order.Descending))
return CASE_INSENSITIVE_ORDER.compare(trimToEmpty(roles2), trimToEmpty(roles1));
return CASE_INSENSITIVE_ORDER.compare(trimToEmpty(roles1), trimToEmpty(roles2));
case "provider":
if (order.equals(Order.Descending))
return CASE_INSENSITIVE_ORDER.compare(trimToEmpty(user2.getProvider()), trimToEmpty(user1.getProvider()));
return CASE_INSENSITIVE_ORDER.compare(trimToEmpty(user1.getProvider()), trimToEmpty(user2.getProvider()));
default:
logger.info("Unkown sort type: {}", criterion.getFieldName());
return 0;
}
}
return 0;
}
});
}
// Apply Limit and offset
filteredUsers = new SmartIterator<User>(limit, offset).applyLimitAndOffset(filteredUsers);
List<JValue> usersJSON = new ArrayList<>();
for (User user : filteredUsers) {
usersJSON.add(generateJsonUser(user));
}
return okJsonList(usersJSON, offset, limit, total);
}
use of org.opencastproject.matterhorn.search.SortCriterion in project opencast by opencast.
the class RestUtils method parseSortQueryParameter.
/**
* Parse a sort query parameter to a set of {@link SortCriterion}. The parameter has to be of the following form:
* {@code <field name>:ASC|DESC}
*
* @param sort
* the parameter string to parse
* @return a set of sort criterion, never {@code null}
*/
public static Set<SortCriterion> parseSortQueryParameter(String sort) throws WebApplicationException {
Set<SortCriterion> sortOrders = new HashSet<SortCriterion>();
StringTokenizer tokenizer = new StringTokenizer(sort, ",");
while (tokenizer.hasMoreTokens()) {
try {
sortOrders.add(SortCriterionImpl.parse(tokenizer.nextToken()));
} catch (IllegalArgumentException e) {
throw new WebApplicationException(Status.BAD_REQUEST);
}
}
return sortOrders;
}
use of org.opencastproject.matterhorn.search.SortCriterion in project opencast by opencast.
the class JobEndpoint method getTasks.
@GET
@Path("tasks.json")
@Produces(MediaType.APPLICATION_JSON)
@RestQuery(description = "Returns the list of tasks", name = "tasks", restParameters = { @RestParameter(name = "limit", description = "The maximum number of items to return per page", isRequired = false, type = RestParameter.Type.INTEGER), @RestParameter(name = "offset", description = "The offset", isRequired = false, type = RestParameter.Type.INTEGER), @RestParameter(name = "status", isRequired = false, description = "Filter results by workflows' current state", type = STRING), @RestParameter(name = "q", isRequired = false, description = "Filter results by free text query", type = STRING), @RestParameter(name = "seriesId", isRequired = false, description = "Filter results by series identifier", type = STRING), @RestParameter(name = "seriesTitle", isRequired = false, description = "Filter results by series title", type = STRING), @RestParameter(name = "creator", isRequired = false, description = "Filter results by the mediapackage's creator", type = STRING), @RestParameter(name = "contributor", isRequired = false, description = "Filter results by the mediapackage's contributor", type = STRING), @RestParameter(name = "fromdate", isRequired = false, description = "Filter results by workflow start date.", type = STRING), @RestParameter(name = "todate", isRequired = false, description = "Filter results by workflow start date.", type = STRING), @RestParameter(name = "language", isRequired = false, description = "Filter results by mediapackage's language.", type = STRING), @RestParameter(name = "title", isRequired = false, description = "Filter results by mediapackage's title.", type = STRING), @RestParameter(name = "subject", isRequired = false, description = "Filter results by mediapackage's subject.", type = STRING), @RestParameter(name = "workflow", isRequired = false, description = "Filter results by workflow definition.", type = STRING), @RestParameter(name = "operation", isRequired = false, description = "Filter results by workflows' current operation.", type = STRING), @RestParameter(name = "sort", isRequired = false, description = "The sort order. May include any " + "of the following: DATE_CREATED, TITLE, SERIES_TITLE, SERIES_ID, MEDIA_PACKAGE_ID, WORKFLOW_DEFINITION_ID, CREATOR, " + "CONTRIBUTOR, LANGUAGE, LICENSE, SUBJECT. The suffix must be :ASC for ascending or :DESC for descending sort order (e.g. TITLE:DESC).", type = STRING) }, reponses = { @RestResponse(description = "Returns the list of tasks from Opencast", responseCode = HttpServletResponse.SC_OK) }, returnDescription = "The list of tasks as JSON")
public Response getTasks(@QueryParam("limit") final int limit, @QueryParam("offset") final int offset, @QueryParam("status") List<String> states, @QueryParam("q") String text, @QueryParam("seriesId") String seriesId, @QueryParam("seriesTitle") String seriesTitle, @QueryParam("creator") String creator, @QueryParam("contributor") String contributor, @QueryParam("fromdate") String fromDate, @QueryParam("todate") String toDate, @QueryParam("language") String language, @QueryParam("title") String title, @QueryParam("subject") String subject, @QueryParam("workflowdefinition") String workflowDefinitionId, @QueryParam("mp") String mediapackageId, @QueryParam("operation") List<String> currentOperations, @QueryParam("sort") String sort, @Context HttpHeaders headers) throws JobEndpointException {
WorkflowQuery query = new WorkflowQuery();
query.withStartPage(offset);
query.withCount(limit);
// Add filters
query.withText(text);
query.withSeriesId(seriesId);
query.withSeriesTitle(seriesTitle);
query.withSubject(subject);
query.withMediaPackage(mediapackageId);
query.withCreator(creator);
query.withContributor(contributor);
try {
query.withDateAfter(SolrUtils.parseDate(fromDate));
} catch (ParseException e) {
logger.error("Not able to parse the date {}: {}", fromDate, e.getMessage());
}
try {
query.withDateBefore(SolrUtils.parseDate(toDate));
} catch (ParseException e) {
logger.error("Not able to parse the date {}: {}", fromDate, e.getMessage());
}
query.withLanguage(language);
query.withTitle(title);
query.withWorkflowDefintion(workflowDefinitionId);
if (states != null && states.size() > 0) {
try {
for (String state : states) {
if (StringUtils.isBlank(state)) {
continue;
} else if (state.startsWith(NEGATE_PREFIX)) {
query.withoutState(WorkflowState.valueOf(state.substring(1).toUpperCase()));
} else {
query.withState(WorkflowState.valueOf(state.toUpperCase()));
}
}
} catch (IllegalArgumentException e) {
logger.debug("Unknown workflow state.", e);
}
}
if (currentOperations != null && currentOperations.size() > 0) {
for (String op : currentOperations) {
if (StringUtils.isBlank(op)) {
continue;
}
if (op.startsWith(NEGATE_PREFIX)) {
query.withoutCurrentOperation(op.substring(1));
} else {
query.withCurrentOperation(op);
}
}
}
// Sorting
if (StringUtils.isNotBlank(sort)) {
try {
SortCriterion sortCriterion = RestUtils.parseSortQueryParameter(sort).iterator().next();
Sort sortKey = Sort.valueOf(sortCriterion.getFieldName().toUpperCase());
boolean ascending = SearchQuery.Order.Ascending == sortCriterion.getOrder() || SearchQuery.Order.None == sortCriterion.getOrder();
query.withSort(sortKey, ascending);
} catch (WebApplicationException ex) {
logger.warn("Failed to parse sort criterion \"{}\", invalid format.", sort);
} catch (IllegalArgumentException ex) {
logger.warn("Can not apply sort criterion \"{}\", no field with this name.", sort);
}
}
JObject json;
try {
json = getTasksAsJSON(query);
} catch (NotFoundException e) {
return NOT_FOUND;
}
return Response.ok(stream(serializer.fn.toJson(json)), MediaType.APPLICATION_JSON_TYPE).build();
}
use of org.opencastproject.matterhorn.search.SortCriterion in project opencast by opencast.
the class JobEndpoint method getJobs.
@GET
@Path("jobs.json")
@Produces(MediaType.APPLICATION_JSON)
@RestQuery(description = "Returns the list of active jobs", name = "jobs", restParameters = { @RestParameter(name = "limit", description = "The maximum number of items to return per page", isRequired = false, type = RestParameter.Type.INTEGER), @RestParameter(name = "offset", description = "The offset", isRequired = false, type = RestParameter.Type.INTEGER), @RestParameter(name = "filter", description = "Filter results by hostname, status or free text query", isRequired = false, type = RestParameter.Type.STRING), @RestParameter(name = "sort", description = "The sort order. May include any of the following: CREATOR, OPERATION, PROCESSINGHOST, STATUS, STARTED, SUBMITTED or TYPE. " + "The suffix must be :ASC for ascending or :DESC for descending sort order (e.g. OPERATION:DESC)", isRequired = false, type = RestParameter.Type.STRING) }, reponses = { @RestResponse(description = "Returns the list of active jobs from Opencast", responseCode = HttpServletResponse.SC_OK) }, returnDescription = "The list of jobs as JSON")
public Response getJobs(@QueryParam("limit") final int limit, @QueryParam("offset") final int offset, @QueryParam("filter") final String filter, @QueryParam("sort") final String sort) {
JobsListQuery query = new JobsListQuery();
EndpointUtil.addRequestFiltersToQuery(filter, query);
query.setLimit(limit);
query.setOffset(offset);
String fHostname = null;
if (query.getHostname().isSome())
fHostname = StringUtils.trimToNull(query.getHostname().get());
String fStatus = null;
if (query.getStatus().isSome())
fStatus = StringUtils.trimToNull(query.getStatus().get());
String fFreeText = null;
if (query.getFreeText().isSome())
fFreeText = StringUtils.trimToNull(query.getFreeText().get());
List<Job> jobs = new ArrayList<>();
try {
for (Job job : serviceRegistry.getActiveJobs()) {
// filter workflow jobs
if (StringUtils.equals(WorkflowService.JOB_TYPE, job.getJobType()) && StringUtils.equals("START_WORKFLOW", job.getOperation()))
continue;
// filter by hostname
if (fHostname != null && !StringUtils.equalsIgnoreCase(job.getProcessingHost(), fHostname))
continue;
// filter by status
if (fStatus != null && !StringUtils.equalsIgnoreCase(job.getStatus().toString(), fStatus))
continue;
// fitler by user free text
if (fFreeText != null && !StringUtils.equalsIgnoreCase(job.getProcessingHost(), fFreeText) && !StringUtils.equalsIgnoreCase(job.getJobType(), fFreeText) && !StringUtils.equalsIgnoreCase(job.getOperation(), fFreeText) && !StringUtils.equalsIgnoreCase(job.getCreator(), fFreeText) && !StringUtils.equalsIgnoreCase(job.getStatus().toString(), fFreeText) && !StringUtils.equalsIgnoreCase(Long.toString(job.getId()), fFreeText) && (job.getRootJobId() != null && !StringUtils.equalsIgnoreCase(Long.toString(job.getRootJobId()), fFreeText)))
continue;
jobs.add(job);
}
} catch (ServiceRegistryException ex) {
logger.error("Failed to retrieve jobs list from service registry.", ex);
return RestUtil.R.serverError();
}
JobSort sortKey = JobSort.SUBMITTED;
boolean ascending = true;
if (StringUtils.isNotBlank(sort)) {
try {
SortCriterion sortCriterion = RestUtils.parseSortQueryParameter(sort).iterator().next();
sortKey = JobSort.valueOf(sortCriterion.getFieldName().toUpperCase());
ascending = SearchQuery.Order.Ascending == sortCriterion.getOrder() || SearchQuery.Order.None == sortCriterion.getOrder();
} catch (WebApplicationException ex) {
logger.warn("Failed to parse sort criterion \"{}\", invalid format.", sort);
} catch (IllegalArgumentException ex) {
logger.warn("Can not apply sort criterion \"{}\", no field with this name.", sort);
}
}
JobComparator comparator = new JobComparator(sortKey, ascending);
Collections.sort(jobs, comparator);
List<JValue> json = getJobsAsJSON(new SmartIterator(query.getLimit().getOrElse(0), query.getOffset().getOrElse(0)).applyLimitAndOffset(jobs));
return RestUtils.okJsonList(json, offset, limit, jobs.size());
}
use of org.opencastproject.matterhorn.search.SortCriterion in project opencast by opencast.
the class ServerEndpoint method getServers.
@GET
@Path("servers.json")
@Produces(MediaType.APPLICATION_JSON)
@RestQuery(description = "Returns the list of servers", name = "servers", restParameters = { @RestParameter(name = "limit", description = "The maximum number of items to return per page", isRequired = false, type = INTEGER), @RestParameter(name = "offset", description = "The offset", isRequired = false, type = INTEGER), @RestParameter(name = "filter", description = "Filter results by hostname, status or free text query", isRequired = false, type = STRING), @RestParameter(name = "sort", description = "The sort order. May include any " + "of the following: COMPLETED (jobs), CORES, HOSTNAME, MAINTENANCE, MEANQUEUETIME (mean for jobs), " + "MEANRUNTIME (mean for jobs), ONLINE, QUEUED (jobs), RUNNING (jobs)." + "The suffix must be :ASC for ascending or :DESC for descending sort order (e.g. HOSTNAME:DESC).", isRequired = false, type = STRING) }, reponses = { @RestResponse(description = "Returns the list of jobs from Opencast", responseCode = HttpServletResponse.SC_OK) }, returnDescription = "The list of servers")
public Response getServers(@QueryParam("limit") final int limit, @QueryParam("offset") final int offset, @QueryParam("filter") String filter, @QueryParam("sort") String sort) throws Exception {
ServersListQuery query = new ServersListQuery();
EndpointUtil.addRequestFiltersToQuery(filter, query);
query.setLimit(limit);
query.setOffset(offset);
List<JSONObject> servers = new ArrayList<>();
// Get service statistics for all hosts and services
List<ServiceStatistics> servicesStatistics = serviceRegistry.getServiceStatistics();
for (HostRegistration server : serviceRegistry.getHostRegistrations()) {
// Calculate statistics per server
long jobsCompleted = 0;
int jobsRunning = 0;
int jobsQueued = 0;
long sumMeanRuntime = 0;
long sumMeanQueueTime = 0;
int totalServiceOnHost = 0;
int offlineJobProducerServices = 0;
int totalJobProducerServices = 0;
Set<String> serviceTypes = new HashSet<>();
for (ServiceStatistics serviceStat : servicesStatistics) {
if (server.getBaseUrl().equals(serviceStat.getServiceRegistration().getHost())) {
totalServiceOnHost++;
jobsCompleted += serviceStat.getFinishedJobs();
jobsRunning += serviceStat.getRunningJobs();
jobsQueued += serviceStat.getQueuedJobs();
// mean time values are given in milliseconds,
// we should convert them to seconds,
// because the adminNG UI expect it in this format
sumMeanRuntime += TimeUnit.MILLISECONDS.toSeconds(serviceStat.getMeanRunTime());
sumMeanQueueTime += TimeUnit.MILLISECONDS.toSeconds(serviceStat.getMeanQueueTime());
if (!serviceStat.getServiceRegistration().isOnline() && serviceStat.getServiceRegistration().isJobProducer()) {
offlineJobProducerServices++;
totalJobProducerServices++;
} else if (serviceStat.getServiceRegistration().isJobProducer()) {
totalJobProducerServices++;
}
serviceTypes.add(serviceStat.getServiceRegistration().getServiceType());
}
}
long meanRuntime = totalServiceOnHost > 0 ? Math.round((double) sumMeanRuntime / totalServiceOnHost) : 0L;
long meanQueueTime = totalServiceOnHost > 0 ? Math.round((double) sumMeanQueueTime / totalServiceOnHost) : 0L;
boolean vOnline = server.isOnline();
boolean vMaintenance = server.isMaintenanceMode();
String vHostname = server.getBaseUrl();
int vCores = server.getCores();
if (query.getHostname().isSome() && !StringUtils.equalsIgnoreCase(vHostname, query.getHostname().get()))
continue;
if (query.getStatus().isSome()) {
if (StringUtils.equalsIgnoreCase(ServersListProvider.SERVER_STATUS_ONLINE, query.getStatus().get()) && !vOnline)
continue;
if (StringUtils.equalsIgnoreCase(ServersListProvider.SERVER_STATUS_OFFLINE, query.getStatus().get()) && vOnline)
continue;
if (StringUtils.equalsIgnoreCase(ServersListProvider.SERVER_STATUS_MAINTENANCE, query.getStatus().get()) && !vMaintenance)
continue;
}
if (query.getFreeText().isSome() && !StringUtils.containsIgnoreCase(vHostname, query.getFreeText().get()) && !StringUtils.containsIgnoreCase(server.getIpAddress(), query.getFreeText().get()))
continue;
JSONObject jsonServer = new JSONObject();
jsonServer.put(KEY_ONLINE, vOnline && offlineJobProducerServices <= totalJobProducerServices / 2);
jsonServer.put(KEY_MAINTENANCE, vMaintenance);
jsonServer.put(KEY_HOSTNAME, vHostname);
jsonServer.put(KEY_CORES, vCores);
jsonServer.put(KEY_RUNNING, jobsRunning);
jsonServer.put(KEY_QUEUED, jobsQueued);
jsonServer.put(KEY_COMPLETED, jobsCompleted);
jsonServer.put(KEY_MEAN_RUN_TIME, meanRuntime);
jsonServer.put(KEY_MEAN_QUEUE_TIME, meanQueueTime);
servers.add(jsonServer);
}
// Sorting
Sort sortKey = Sort.HOSTNAME;
Boolean ascending = true;
if (StringUtils.isNotBlank(sort)) {
try {
SortCriterion sortCriterion = RestUtils.parseSortQueryParameter(sort).iterator().next();
sortKey = Sort.valueOf(sortCriterion.getFieldName().toUpperCase());
ascending = SearchQuery.Order.Ascending == sortCriterion.getOrder() || SearchQuery.Order.None == sortCriterion.getOrder();
} catch (WebApplicationException ex) {
logger.warn("Failed to parse sort criterion \"{}\", invalid format.", sort);
} catch (IllegalArgumentException ex) {
logger.warn("Can not apply sort criterion \"{}\", no field with this name.", sort);
}
}
JSONArray jsonList = new JSONArray();
if (!servers.isEmpty()) {
Collections.sort(servers, new ServerComparator(sortKey, ascending));
jsonList.addAll(new SmartIterator(query.getLimit().getOrElse(0), query.getOffset().getOrElse(0)).applyLimitAndOffset(servers));
}
return RestUtils.okJsonList(getServersListAsJson(jsonList), query.getOffset().getOrElse(0), query.getLimit().getOrElse(0), servers.size());
}
Aggregations