use of org.opencastproject.matterhorn.search.SearchIndexException in project opencast by opencast.
the class AbstractElasticsearchIndex method loadSettings.
/**
* Loads the settings for the elastic search configuration. An initial attempt is made to get the configuration from
* <code>${opencast.home}/etc/index/< index >/settings.yml</code>.
*
* @param index
* the index name
* @return the elastic search settings
* @throws IOException
* if the index cannot be created in case it is not there already
* @throws SearchIndexException
* if the index configuration cannot be found
*/
protected Settings loadSettings(String index, String indexSettingsPath) throws IOException, SearchIndexException {
Settings settings = null;
// Check if a local configuration file is present
File configFile = new File(PathSupport.concat(new String[] { indexSettingsPath, index, "settings.yml" }));
if (!configFile.isFile()) {
throw new SearchIndexException("Settings for search index '" + index + "' not found at " + configFile);
}
// Finally, try and load the index settings
FileInputStream fis = null;
try {
fis = new FileInputStream(configFile);
settings = ImmutableSettings.settingsBuilder().loadFromStream(configFile.getName(), fis).build();
} catch (FileNotFoundException e) {
throw new IOException("Unable to load elasticsearch settings from " + configFile.getAbsolutePath());
} finally {
IOUtils.closeQuietly(fis);
}
return settings;
}
use of org.opencastproject.matterhorn.search.SearchIndexException in project opencast by opencast.
the class AbstractElasticsearchIndex method update.
/**
* Posts the input document to the search index.
*
* @param documents
* the input documents
* @return the query response
* @throws SearchIndexException
* if posting to the index fails
*/
protected BulkResponse update(ElasticsearchDocument... documents) throws SearchIndexException {
BulkRequestBuilder bulkRequest = nodeClient.prepareBulk();
for (ElasticsearchDocument doc : documents) {
String type = doc.getType();
String uid = doc.getUID();
bulkRequest.add(nodeClient.prepareIndex(index, type, uid).setSource(doc));
}
// Make sure the operations are searchable immediately
bulkRequest.setRefresh(true);
try {
BulkResponse bulkResponse = bulkRequest.execute().actionGet();
// Check for errors
if (bulkResponse.hasFailures()) {
for (BulkItemResponse item : bulkResponse.getItems()) {
if (item.isFailed()) {
logger.warn("Error updating {}: {}", item, item.getFailureMessage());
throw new SearchIndexException(item.getFailureMessage());
}
}
}
return bulkResponse;
} catch (Throwable t) {
throw new SearchIndexException("Cannot update documents in index " + index, t);
}
}
use of org.opencastproject.matterhorn.search.SearchIndexException in project opencast by opencast.
the class AbstractElasticsearchIndex method createIndex.
/**
* Prepares Elasticsearch index to store data for the types (or mappings) as returned by {@link #getDocumenTypes()}.
*
* @param idx
* the index name
*
* @throws SearchIndexException
* if index and type creation fails
* @throws IOException
* if loading of the type definitions fails
*/
private void createIndex(String idx) throws SearchIndexException, IOException {
// Make sure the site index exists
try {
logger.debug("Trying to create index for '{}'", idx);
CreateIndexRequest indexCreateRequest = new CreateIndexRequest(idx);
String settings = getIndexSettings(idx);
if (settings != null)
indexCreateRequest.settings(settings);
CreateIndexResponse siteidxResponse = nodeClient.admin().indices().create(indexCreateRequest).actionGet();
if (!siteidxResponse.isAcknowledged()) {
throw new SearchIndexException("Unable to create index for '" + idx + "'");
}
} catch (IndexAlreadyExistsException e) {
logger.info("Detected existing index '{}'", idx);
}
// Store the correct mapping
for (String type : getDocumenTypes()) {
PutMappingRequest siteMappingRequest = new PutMappingRequest(idx);
siteMappingRequest.source(getIndexTypeDefinition(idx, type));
siteMappingRequest.type(type);
PutMappingResponse siteMappingResponse = nodeClient.admin().indices().putMapping(siteMappingRequest).actionGet();
if (!siteMappingResponse.isAcknowledged()) {
throw new SearchIndexException("Unable to install '" + type + "' mapping for index '" + idx + "'");
}
}
// See if the index version exists and check if it matches. The request will
// fail if there is no version index
boolean versionIndexExists = false;
GetRequestBuilder getRequestBuilder = nodeClient.prepareGet(idx, VERSION_TYPE, ROOT_ID);
try {
GetResponse response = getRequestBuilder.execute().actionGet();
if (response.isExists() && response.getField(VERSION) != null) {
int actualIndexVersion = Integer.parseInt((String) response.getField(VERSION).getValue());
if (indexVersion != actualIndexVersion)
throw new SearchIndexException("Search index is at version " + actualIndexVersion + ", but codebase expects " + indexVersion);
versionIndexExists = true;
logger.debug("Search index version is {}", indexVersion);
}
} catch (ElasticsearchException e) {
logger.debug("Version index has not been created");
}
// The index does not exist, let's create it
if (!versionIndexExists) {
logger.debug("Creating version index for site '{}'", idx);
IndexRequestBuilder requestBuilder = nodeClient.prepareIndex(idx, VERSION_TYPE, ROOT_ID);
logger.debug("Index version of site '{}' is {}", idx, indexVersion);
requestBuilder = requestBuilder.setSource(VERSION, Integer.toString(indexVersion));
requestBuilder.execute().actionGet();
}
preparedIndices.add(idx);
}
use of org.opencastproject.matterhorn.search.SearchIndexException in project opencast by opencast.
the class AbstractEventEndpoint method updateEventWorkflow.
@PUT
@Path("{eventId}/workflows")
@RestQuery(name = "updateEventWorkflow", description = "Update the workflow configuration for the scheduled event with the given id", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = RestParameter.Type.STRING) }, restParameters = { @RestParameter(name = "configuration", isRequired = true, description = "The workflow configuration as JSON", type = RestParameter.Type.TEXT) }, reponses = { @RestResponse(description = "Request executed succesfully", responseCode = HttpServletResponse.SC_NO_CONTENT), @RestResponse(description = "No event with this identifier was found.", responseCode = HttpServletResponse.SC_NOT_FOUND) }, returnDescription = "The method does not retrun any content.")
public Response updateEventWorkflow(@PathParam("eventId") String id, @FormParam("configuration") String configuration) throws SearchIndexException, UnauthorizedException {
Opt<Event> optEvent = getIndexService().getEvent(id, getIndex());
if (optEvent.isNone())
return notFound("Cannot find an event with id '%s'.", id);
if (!optEvent.get().hasRecordingStarted()) {
try {
JSONObject configJSON;
try {
configJSON = (JSONObject) new JSONParser().parse(configuration);
} catch (Exception e) {
logger.warn("Unable to parse the workflow configuration {}", configuration);
return badRequest();
}
Opt<Map<String, String>> caMetadataOpt = Opt.none();
Opt<Map<String, String>> workflowConfigOpt = Opt.none();
String workflowId = (String) configJSON.get("id");
Map<String, String> caMetadata = new HashMap<>(getSchedulerService().getCaptureAgentConfiguration(id));
if (!workflowId.equals(caMetadata.get(CaptureParameters.INGEST_WORKFLOW_DEFINITION))) {
caMetadata.put(CaptureParameters.INGEST_WORKFLOW_DEFINITION, workflowId);
caMetadataOpt = Opt.some(caMetadata);
}
Map<String, String> workflowConfig = new HashMap<>((JSONObject) configJSON.get("configuration"));
Map<String, String> oldWorkflowConfig = new HashMap<>(getSchedulerService().getWorkflowConfig(id));
if (!oldWorkflowConfig.equals(workflowConfig))
workflowConfigOpt = Opt.some(workflowConfig);
if (caMetadataOpt.isNone() && workflowConfigOpt.isNone())
return Response.noContent().build();
getSchedulerService().updateEvent(id, Opt.<Date>none(), Opt.<Date>none(), Opt.<String>none(), Opt.<Set<String>>none(), Opt.<MediaPackage>none(), workflowConfigOpt, caMetadataOpt, Opt.<Opt<Boolean>>none(), SchedulerService.ORIGIN);
return Response.noContent().build();
} catch (NotFoundException e) {
return notFound("Cannot find event %s in scheduler service", id);
} catch (SchedulerException e) {
logger.error("Unable to update scheduling workflow data for event with id {}", id);
throw new WebApplicationException(e, SC_INTERNAL_SERVER_ERROR);
}
} else {
return badRequest(String.format("Event %s workflow can not be updated as the recording already started.", id));
}
}
use of org.opencastproject.matterhorn.search.SearchIndexException in project opencast by opencast.
the class AbstractEventEndpoint method getEvents.
@GET
@Path("events.json")
@Produces(MediaType.APPLICATION_JSON)
@RestQuery(name = "getevents", description = "Returns all the events as JSON", returnDescription = "All the events as JSON", 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", description = "The order instructions used to sort the query result. Must be in the form '<field name>:(ASC|DESC)'", isRequired = false, type = STRING), @RestParameter(name = "limit", description = "The maximum number of items to return per page.", isRequired = false, type = RestParameter.Type.INTEGER), @RestParameter(name = "offset", description = "The page number.", isRequired = false, type = RestParameter.Type.INTEGER) }, reponses = { @RestResponse(description = "Returns all events as JSON", responseCode = HttpServletResponse.SC_OK) })
public Response getEvents(@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) {
Option<Integer> optLimit = Option.option(limit);
Option<Integer> optOffset = Option.option(offset);
Option<String> optSort = Option.option(trimToNull(sort));
ArrayList<JValue> eventsList = new ArrayList<>();
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();
}
Map<String, String> filters = RestUtils.parseFilter(filter);
for (String name : filters.keySet()) {
if (EventListQuery.FILTER_PRESENTERS_BIBLIOGRAPHIC_NAME.equals(name))
query.withPresenter(filters.get(name));
if (EventListQuery.FILTER_PRESENTERS_TECHNICAL_NAME.equals(name))
query.withTechnicalPresenters(filters.get(name));
if (EventListQuery.FILTER_CONTRIBUTORS_NAME.equals(name))
query.withContributor(filters.get(name));
if (EventListQuery.FILTER_LOCATION_NAME.equals(name))
query.withLocation(filters.get(name));
if (EventListQuery.FILTER_AGENT_NAME.equals(name))
query.withAgentId(filters.get(name));
if (EventListQuery.FILTER_TEXT_NAME.equals(name))
query.withText(QueryPreprocessor.sanitize(filters.get(name)));
if (EventListQuery.FILTER_SERIES_NAME.equals(name))
query.withSeriesId(filters.get(name));
if (EventListQuery.FILTER_STATUS_NAME.equals(name))
query.withEventStatus(filters.get(name));
if (EventListQuery.FILTER_OPTEDOUT_NAME.equals(name))
query.withOptedOut(Boolean.parseBoolean(filters.get(name)));
if (EventListQuery.FILTER_REVIEW_STATUS_NAME.equals(name))
query.withReviewStatus(filters.get(name));
if (EventListQuery.FILTER_COMMENTS_NAME.equals(name)) {
switch(Comments.valueOf(filters.get(name))) {
case NONE:
query.withComments(false);
break;
case OPEN:
query.withOpenComments(true);
break;
case RESOLVED:
query.withComments(true);
query.withOpenComments(false);
break;
default:
logger.info("Unknown comment {}", filters.get(name));
return Response.status(SC_BAD_REQUEST).build();
}
}
if (EventListQuery.FILTER_STARTDATE_NAME.equals(name)) {
try {
Tuple<Date, Date> fromAndToCreationRange = RestUtils.getFromAndToDateRange(filters.get(name));
query.withTechnicalStartFrom(fromAndToCreationRange.getA());
query.withTechnicalStartTo(fromAndToCreationRange.getB());
} catch (IllegalArgumentException e) {
return RestUtil.R.badRequest(e.getMessage());
}
}
}
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.PUBLICATION:
query.sortByPublicationIgnoringInternal(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.SERIES_NAME:
query.sortBySeriesName(criterion.getOrder());
break;
case EventIndexSchema.LOCATION:
query.sortByLocation(criterion.getOrder());
break;
case EventIndexSchema.EVENT_STATUS:
query.sortByEventStatus(criterion.getOrder());
break;
default:
throw new WebApplicationException(Status.BAD_REQUEST);
}
}
}
// TODO: Add the comment resolution filter to the query
EventCommentsListProvider.RESOLUTION resolution = null;
if (StringUtils.isNotBlank(resolutionFilter)) {
try {
resolution = EventCommentsListProvider.RESOLUTION.valueOf(resolutionFilter);
} catch (Exception e) {
logger.warn("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 = getIndex().getByQuery(query);
} catch (SearchIndexException e) {
logger.error("The admin UI Search Index was not able to get the events list:", e);
return RestUtil.R.serverError();
}
// If the results list if empty, we return already a response.
if (results.getPageSize() == 0) {
logger.debug("No events match the given filters.");
return okJsonList(eventsList, nul(offset).getOr(0), nul(limit).getOr(0), 0);
}
for (SearchResultItem<Event> item : results.getItems()) {
Event source = item.getSource();
source.updatePreview(getAdminUIConfiguration().getPreviewSubtype());
eventsList.add(eventToJSON(source));
}
return okJsonList(eventsList, nul(offset).getOr(0), nul(limit).getOr(0), results.getHitCount());
}
Aggregations