use of org.opencastproject.matterhorn.search.SearchIndexException in project opencast by opencast.
the class ThemesEndpoint method getThemes.
@GET
@Produces({ MediaType.APPLICATION_JSON })
@Path("themes.json")
@RestQuery(name = "getThemes", description = "Return all of the known themes on the system", 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(defaultValue = "0", description = "The maximum number of items to return per page.", isRequired = false, name = "limit", type = RestParameter.Type.INTEGER), @RestParameter(defaultValue = "0", description = "The page number.", isRequired = false, name = "offset", type = RestParameter.Type.INTEGER), @RestParameter(name = "sort", isRequired = false, description = "The sort order. May include any of the following: NAME, CREATOR. Add '_DESC' to reverse the sort order (e.g. CREATOR_DESC).", type = STRING) }, reponses = { @RestResponse(description = "A JSON representation of the themes", responseCode = HttpServletResponse.SC_OK) }, returnDescription = "")
public Response getThemes(@QueryParam("filter") String filter, @QueryParam("limit") int limit, @QueryParam("offset") int offset, @QueryParam("sort") String sort) {
Option<Integer> optLimit = Option.option(limit);
Option<Integer> optOffset = Option.option(offset);
Option<String> optSort = Option.option(trimToNull(sort));
ThemeSearchQuery query = new ThemeSearchQuery(securityService.getOrganization().getId(), securityService.getUser());
// If the limit is set to 0, this is not taken into account
if (optLimit.isSome() && limit == 0) {
optLimit = Option.none();
}
if (optLimit.isSome())
query.withLimit(optLimit.get());
if (optOffset.isSome())
query.withOffset(offset);
Map<String, String> filters = RestUtils.parseFilter(filter);
for (String name : filters.keySet()) {
if (ThemesListQuery.FILTER_CREATOR_NAME.equals(name))
query.withCreator(filters.get(name));
if (ThemesListQuery.FILTER_TEXT_NAME.equals(name))
query.withText(QueryPreprocessor.sanitize(filters.get(name)));
}
if (optSort.isSome()) {
Set<SortCriterion> sortCriteria = RestUtils.parseSortQueryParameter(optSort.get());
for (SortCriterion criterion : sortCriteria) {
switch(criterion.getFieldName()) {
case ThemeIndexSchema.NAME:
query.sortByName(criterion.getOrder());
break;
case ThemeIndexSchema.DESCRIPTION:
query.sortByDescription(criterion.getOrder());
break;
case ThemeIndexSchema.CREATOR:
query.sortByCreator(criterion.getOrder());
break;
case ThemeIndexSchema.DEFAULT:
query.sortByDefault(criterion.getOrder());
break;
case ThemeIndexSchema.CREATION_DATE:
query.sortByCreatedDateTime(criterion.getOrder());
break;
default:
logger.info("Unknown sort criteria {}", criterion.getFieldName());
return Response.status(SC_BAD_REQUEST).build();
}
}
}
logger.trace("Using Query: " + query.toString());
SearchResult<org.opencastproject.index.service.impl.index.theme.Theme> results = null;
try {
results = searchIndex.getByQuery(query);
} catch (SearchIndexException e) {
logger.error("The admin UI Search Index was not able to get the themes list:", e);
return RestUtil.R.serverError();
}
List<JValue> themesJSON = new ArrayList<JValue>();
// If the results list if empty, we return already a response.
if (results.getPageSize() == 0) {
logger.debug("No themes match the given filters.");
return okJsonList(themesJSON, nul(offset).getOr(0), nul(limit).getOr(0), 0);
}
for (SearchResultItem<org.opencastproject.index.service.impl.index.theme.Theme> item : results.getItems()) {
org.opencastproject.index.service.impl.index.theme.Theme theme = item.getSource();
themesJSON.add(themeToJSON(theme, false));
}
return okJsonList(themesJSON, nul(offset).getOr(0), nul(limit).getOr(0), results.getHitCount());
}
use of org.opencastproject.matterhorn.search.SearchIndexException in project opencast by opencast.
the class EventsEndpoint method eventToJSON.
/**
* Transform an {@link Event} to Json
*
* @param event
* The event to transform into json
* @param withAcl
* Whether to add the acl information for the event
* @param withMetadata
* Whether to add all the metadata for the event
* @param withPublications
* Whether to add the publications
* @param withSignedUrls
* Whether to sign the urls if they are protected by stream security.
* @return The event in json format.
* @throws IndexServiceException
* Thrown if unable to get the metadata for the event.
* @throws SearchIndexException
* Thrown if unable to get event publications from search service
* @throws NotFoundException
* Thrown if unable to find all of the metadata
*/
protected JValue eventToJSON(Event event, Boolean withAcl, Boolean withMetadata, Boolean withPublications, Boolean withSignedUrls) throws IndexServiceException, SearchIndexException, NotFoundException {
List<Field> fields = new ArrayList<>();
if (event.getArchiveVersion() != null)
fields.add(f("archive_version", v(event.getArchiveVersion())));
fields.add(f("created", v(event.getCreated(), Jsons.BLANK)));
fields.add(f("creator", v(event.getCreator(), Jsons.BLANK)));
fields.add(f("contributor", arr($(event.getContributors()).map(Functions.stringToJValue))));
fields.add(f("description", v(event.getDescription(), Jsons.BLANK)));
fields.add(f("has_previews", v(event.hasPreview())));
fields.add(f("identifier", v(event.getIdentifier(), BLANK)));
fields.add(f("location", v(event.getLocation(), BLANK)));
fields.add(f("presenter", arr($(event.getPresenters()).map(Functions.stringToJValue))));
List<JValue> publicationIds = new ArrayList<>();
if (event.getPublications() != null) {
for (Publication publication : event.getPublications()) {
publicationIds.add(v(publication.getChannel()));
}
}
fields.add(f("publication_status", arr(publicationIds)));
fields.add(f("processing_state", v(event.getWorkflowState(), BLANK)));
fields.add(f("start", v(event.getTechnicalStartTime(), BLANK)));
if (event.getTechnicalEndTime() != null) {
long duration = new DateTime(event.getTechnicalEndTime()).getMillis() - new DateTime(event.getTechnicalStartTime()).getMillis();
fields.add(f("duration", v(duration)));
}
if (StringUtils.trimToNull(event.getSubject()) != null) {
fields.add(f("subjects", arr(splitSubjectIntoArray(event.getSubject()))));
} else {
fields.add(f("subjects", arr()));
}
fields.add(f("title", v(event.getTitle(), BLANK)));
if (withAcl != null && withAcl) {
AccessControlList acl = getAclFromEvent(event);
fields.add(f("acl", arr(AclUtils.serializeAclToJson(acl))));
}
if (withMetadata != null && withMetadata) {
try {
Opt<MetadataList> metadata = getEventMetadata(event);
if (metadata.isSome()) {
fields.add(f("metadata", metadata.get().toJSON()));
}
} catch (Exception e) {
logger.error("Unable to get metadata for event '{}' because: {}", event.getIdentifier(), ExceptionUtils.getStackTrace(e));
throw new IndexServiceException("Unable to add metadata to event", e);
}
}
if (withPublications != null && withPublications) {
List<JValue> publications = getPublications(event, withSignedUrls);
fields.add(f("publications", arr(publications)));
}
return obj(fields);
}
use of org.opencastproject.matterhorn.search.SearchIndexException in project opencast by opencast.
the class EventsEndpoint method updateEvent.
private Response updateEvent(String eventId, HttpServletRequest request) {
try {
Opt<String> startDatePattern = configuredMetadataFields.containsKey("startDate") ? configuredMetadataFields.get("startDate").getPattern() : Opt.none();
Opt<String> startTimePattern = configuredMetadataFields.containsKey("startTime") ? configuredMetadataFields.get("startTime").getPattern() : Opt.none();
for (final Event event : indexService.getEvent(eventId, externalIndex)) {
EventHttpServletRequest eventHttpServletRequest = EventHttpServletRequest.updateFromHttpServletRequest(event, request, getEventCatalogUIAdapters(), startDatePattern, startTimePattern);
if (eventHttpServletRequest.getMetadataList().isSome()) {
indexService.updateEventMetadata(eventId, eventHttpServletRequest.getMetadataList().get(), externalIndex);
}
if (eventHttpServletRequest.getAcl().isSome()) {
indexService.updateEventAcl(eventId, eventHttpServletRequest.getAcl().get(), externalIndex);
}
return ApiResponses.Json.noContent(ApiVersion.VERSION_1_0_0);
}
return ApiResponses.notFound("Cannot find an event with id '%s'.", eventId);
} catch (NotFoundException e) {
return ApiResponses.notFound("Cannot find an event with id '%s'.", eventId);
} catch (UnauthorizedException e) {
return Response.status(Status.UNAUTHORIZED).build();
} catch (IllegalArgumentException e) {
logger.debug("Unable to update event '{}' because: {}", eventId, ExceptionUtils.getStackTrace(e));
return RestUtil.R.badRequest(e.getMessage());
} catch (IndexServiceException e) {
logger.error("Unable to get multi part fields or file for event '{}' because: {}", eventId, ExceptionUtils.getStackTrace(e));
throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
} catch (SearchIndexException e) {
logger.error("Unable to update event '{}' because: {}", eventId, ExceptionUtils.getStackTrace(e));
throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
}
}
use of org.opencastproject.matterhorn.search.SearchIndexException in project opencast by opencast.
the class EventsEndpoint method getEvents.
@GET
@Path("/")
@Produces({ "application/json", "application/v1.0.0+json" })
@RestQuery(name = "getevents", description = "Returns a list of events. By setting the optional sign parameter to true, the method will pre-sign distribution urls if signing is turned on in Opencast. Remember to consider the maximum validity of signed URLs when caching this response.", returnDescription = "", restParameters = { @RestParameter(name = "sign", isRequired = false, description = "Whether public distribution urls should be signed.", type = Type.BOOLEAN), @RestParameter(name = "withacl", isRequired = false, description = "Whether the acl metadata should be included in the response.", type = Type.BOOLEAN), @RestParameter(name = "withmetadata", isRequired = false, description = "Whether the metadata catalogs should be included in the response.", type = Type.BOOLEAN), @RestParameter(name = "withpublications", isRequired = false, description = "Whether the publication ids and urls should be included in the response.", type = Type.BOOLEAN), @RestParameter(name = "filter", isRequired = false, description = "A comma seperated list of filters to limit the results with. A filter is the filter's name followed by a colon \":\" and then the value to filter with so it is the form <Filter Name>:<Value to Filter With>.", type = STRING), @RestParameter(name = "sort", description = "Sort the results based upon a list of comma seperated sorting criteria. In the comma seperated list each type of sorting is specified as a pair such as: <Sort Name>:ASC or <Sort Name>:DESC. Adding the suffix ASC or DESC sets the order as ascending or descending order and is mandatory.", isRequired = false, type = STRING), @RestParameter(name = "limit", description = "The maximum number of results to return for a single request.", isRequired = false, type = RestParameter.Type.INTEGER), @RestParameter(name = "offset", description = "Number of results to skip based on the limit. 0 is the first set of results up to the limit, 1 is the second set of results after the first limit, 2 is third set of results after skipping the first two sets of results etc.", isRequired = false, type = RestParameter.Type.INTEGER) }, reponses = { @RestResponse(description = "A (potentially empty) list of events is returned.", responseCode = HttpServletResponse.SC_OK) })
public Response getEvents(@HeaderParam("Accept") String acceptHeader, @QueryParam("id") String id, @QueryParam("commentReason") String reasonFilter, @QueryParam("commentResolution") String resolutionFilter, @QueryParam("filter") String filter, @QueryParam("sort") String sort, @QueryParam("offset") Integer offset, @QueryParam("limit") Integer limit, @QueryParam("sign") boolean sign, @QueryParam("withacl") Boolean withAcl, @QueryParam("withmetadata") Boolean withMetadata, @QueryParam("withpublications") Boolean withPublications) {
Option<Integer> optLimit = Option.option(limit);
Option<Integer> optOffset = Option.option(offset);
Option<String> optSort = Option.option(trimToNull(sort));
EventSearchQuery query = new EventSearchQuery(getSecurityService().getOrganization().getId(), getSecurityService().getUser());
// If the limit is set to 0, this is not taken into account
if (optLimit.isSome() && limit == 0) {
optLimit = Option.none();
}
// Parse the filters
if (StringUtils.isNotBlank(filter)) {
for (String f : filter.split(",")) {
String[] filterTuple = f.split(":");
if (filterTuple.length < 2) {
logger.info("No value for filter {} in filters list: {}", filterTuple[0], filter);
continue;
}
String name = filterTuple[0];
String value = filterTuple[1];
if ("presenters".equals(name))
query.withPresenter(value);
if ("contributors".equals(name))
query.withContributor(value);
if ("location".equals(name))
query.withLocation(value);
if ("textFilter".equals(name))
query.withText("*" + value + "*");
if ("series".equals(name))
query.withSeriesId(value);
if ("subject".equals(name))
query.withSubject(value);
}
}
if (optSort.isSome()) {
Set<SortCriterion> sortCriteria = RestUtils.parseSortQueryParameter(optSort.get());
for (SortCriterion criterion : sortCriteria) {
switch(criterion.getFieldName()) {
case EventIndexSchema.TITLE:
query.sortByTitle(criterion.getOrder());
break;
case EventIndexSchema.PRESENTER:
query.sortByPresenter(criterion.getOrder());
break;
case EventIndexSchema.TECHNICAL_START:
case "technical_date":
query.sortByTechnicalStartDate(criterion.getOrder());
break;
case EventIndexSchema.TECHNICAL_END:
query.sortByTechnicalEndDate(criterion.getOrder());
break;
case EventIndexSchema.START_DATE:
case "date":
query.sortByStartDate(criterion.getOrder());
break;
case EventIndexSchema.END_DATE:
query.sortByEndDate(criterion.getOrder());
break;
case EventIndexSchema.REVIEW_STATUS:
query.sortByReviewStatus(criterion.getOrder());
break;
case EventIndexSchema.WORKFLOW_STATE:
query.sortByWorkflowState(criterion.getOrder());
break;
case EventIndexSchema.SCHEDULING_STATUS:
query.sortBySchedulingStatus(criterion.getOrder());
break;
case EventIndexSchema.SERIES_NAME:
query.sortBySeriesName(criterion.getOrder());
break;
case EventIndexSchema.LOCATION:
query.sortByLocation(criterion.getOrder());
break;
default:
return RestUtil.R.badRequest(String.format("Unknown search criterion in request: %s", criterion.getFieldName()));
}
}
}
// TODO: Add the comment resolution filter to the query
CommentResolution resolution = null;
if (StringUtils.isNotBlank(resolutionFilter)) {
try {
resolution = CommentResolution.valueOf(resolutionFilter);
} catch (Exception e) {
logger.debug("Unable to parse comment resolution filter {}", resolutionFilter);
return Response.status(Status.BAD_REQUEST).build();
}
}
if (optLimit.isSome())
query.withLimit(optLimit.get());
if (optOffset.isSome())
query.withOffset(offset);
// TODO: Add other filters to the query
SearchResult<Event> results = null;
try {
results = externalIndex.getByQuery(query);
} catch (SearchIndexException e) {
logger.error("The External Search Index was not able to get the events list: {}", ExceptionUtils.getStackTrace(e));
throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
}
SearchResultItem<Event>[] items = results.getItems();
List<IndexObject> events = new ArrayList<>();
for (SearchResultItem<Event> item : items) {
Event source = item.getSource();
source.updatePreview(previewSubtype);
events.add(source);
}
try {
return getJsonEvents(acceptHeader, events, withAcl, withMetadata, withPublications, sign);
} catch (Exception e) {
logger.error("Unable to get events because: {}", ExceptionUtils.getStackTrace(e));
throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
}
}
use of org.opencastproject.matterhorn.search.SearchIndexException in project opencast by opencast.
the class GroupsEndpoint method addGroupMember.
@POST
@Path("{groupId}/members")
@Produces({ "application/json", "application/v1.0.0+json" })
@RestQuery(name = "addgroupmember", description = "Adds a member to a group.", returnDescription = "", pathParameters = { @RestParameter(name = "groupId", description = "The group id", isRequired = true, type = STRING) }, restParameters = { @RestParameter(name = "member", description = "Member Name", isRequired = true, type = STRING) }, reponses = { @RestResponse(description = "The member was already member of the group.", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "The member has been added.", responseCode = HttpServletResponse.SC_NO_CONTENT), @RestResponse(description = "The specified group does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) })
public Response addGroupMember(@HeaderParam("Accept") String acceptHeader, @PathParam("groupId") String id, @FormParam("member") String member) {
try {
Opt<Group> groupOpt = indexService.getGroup(id, externalIndex);
if (groupOpt.isSome()) {
Group group = groupOpt.get();
Set<String> members = group.getMembers();
if (!members.contains(member)) {
group.addMember(member);
return indexService.updateGroup(group.getIdentifier(), group.getName(), group.getDescription(), StringUtils.join(group.getRoles(), ","), StringUtils.join(group.getMembers(), ","));
} else {
return ApiResponses.Json.ok(ApiVersion.VERSION_1_0_0, "Member is already member of group");
}
} else {
return ApiResponses.notFound("Cannot find group with id '%s'.", id);
}
} catch (SearchIndexException e) {
logger.warn("The external search index was not able to retrieve the group with id '%s', reason: ", getStackTrace(e));
return ApiResponses.serverError("Could not retrieve group with id '%s', reason: '%s'", id, getMessage(e));
} catch (NotFoundException e) {
logger.warn("The external search index was not able to update the group with id {}, ", getStackTrace(e));
return ApiResponses.serverError("Could not update group with id '%s', reason: '%s'", id, getMessage(e));
}
}
Aggregations