use of org.opencastproject.index.service.exception.IndexServiceException in project opencast by opencast.
the class IndexServiceImpl method updateEventAssets.
@Override
public String updateEventAssets(MediaPackage mp, HttpServletRequest request) throws IndexServiceException {
JSONObject metadataJson = null;
// regex for form field name matching an attachment or a catalog
// The first sub items identifies if the file is an attachment or catalog
// The second is the item flavor
// Example form field names: "catalog/captions/timedtext" and "attachment/captions/vtt"
// The prefix of field name for attachment and catalog
// The metadata is expected to contain a workflow definition id and
// asset metadata mapped to the asset field id.
List<String> assetList = new LinkedList<String>();
// 1. save assets with temporary flavors
try {
if (!ServletFileUpload.isMultipartContent(request)) {
throw new IllegalArgumentException("No multipart content");
}
for (FileItemIterator iter = new ServletFileUpload().getItemIterator(request); iter.hasNext(); ) {
FileItemStream item = iter.next();
String fieldName = item.getFieldName();
if (item.isFormField()) {
if ("metadata".equals(fieldName)) {
String metadata = Streams.asString(item.openStream());
try {
metadataJson = (JSONObject) parser.parse(metadata);
} catch (Exception e) {
logger.warn("Unable to parse metadata {}", metadata);
throw new IllegalArgumentException("Unable to parse metadata");
}
}
} else {
if (item.getFieldName().toLowerCase().matches(attachmentRegex)) {
assetList.add(item.getFieldName());
// Add attachment with field name as temporary flavor
mp = ingestService.addAttachment(item.openStream(), item.getName(), new MediaPackageElementFlavor(item.getFieldName(), "*"), mp);
} else if (item.getFieldName().toLowerCase().matches(catalogRegex)) {
assetList.add(item.getFieldName());
// Add catalog with field name as temporary flavor
mp = ingestService.addCatalog(item.openStream(), item.getName(), new MediaPackageElementFlavor(item.getFieldName(), "*"), mp);
} else {
logger.warn("Unknown field name found {}", item.getFieldName());
}
}
}
// and correct the temporary flavor to the new flavor.
try {
JSONArray assetMetadata = (JSONArray) ((JSONObject) metadataJson.get("assets")).get("options");
if (assetMetadata != null) {
mp = updateMpAssetFlavor(assetList, mp, assetMetadata, isOverwriteExistingAsset);
} else {
logger.warn("The asset option mapping parameter was not found");
throw new IndexServiceException("The asset option mapping parameter was not found");
}
} catch (Exception e) {
// Assuming a parse error versus a file error and logging the error type
logger.warn("Unable to process asset metadata {}", metadataJson.get("assets"), e);
throw new IllegalArgumentException("Unable to parse metadata", e);
}
return startAddAssetWorkflow(metadataJson, mp);
} catch (Exception e) {
logger.error("Unable to create event: {}", getStackTrace(e));
throw new IndexServiceException(e.getMessage());
}
}
use of org.opencastproject.index.service.exception.IndexServiceException in project opencast by opencast.
the class IndexServiceImpl method updateCommentCatalog.
@Override
public void updateCommentCatalog(final Event event, final List<EventComment> comments) throws Exception {
final SecurityContext securityContext = new SecurityContext(securityService, securityService.getOrganization(), securityService.getUser());
executorService.execute(new Runnable() {
@Override
public void run() {
securityContext.runInContext(new Effect0() {
@Override
protected void run() {
try {
MediaPackage mediaPackage = getEventMediapackage(event);
updateMediaPackageCommentCatalog(mediaPackage, comments);
switch(getEventSource(event)) {
case WORKFLOW:
logger.info("Update workflow mediapacakge {} with updated comments catalog.", event.getIdentifier());
Opt<WorkflowInstance> workflowInstance = getCurrentWorkflowInstance(event.getIdentifier());
if (workflowInstance.isNone()) {
logger.error("No workflow instance for event {} found!", event.getIdentifier());
throw new IndexServiceException("No workflow instance found for event " + event.getIdentifier());
}
WorkflowInstance instance = workflowInstance.get();
instance.setMediaPackage(mediaPackage);
updateWorkflowInstance(instance);
break;
case ARCHIVE:
logger.info("Update archive mediapacakge {} with updated comments catalog.", event.getIdentifier());
assetManager.takeSnapshot(DEFAULT_OWNER, mediaPackage);
break;
case SCHEDULE:
logger.info("Update scheduled mediapacakge {} with updated comments catalog.", event.getIdentifier());
schedulerService.updateEvent(event.getIdentifier(), Opt.<Date>none(), Opt.<Date>none(), Opt.<String>none(), Opt.<Set<String>>none(), Opt.some(mediaPackage), Opt.<Map<String, String>>none(), Opt.<Map<String, String>>none(), Opt.<Opt<Boolean>>none(), SchedulerService.ORIGIN);
break;
default:
logger.error("Unkown event source {}!", event.getSource().toString());
}
} catch (Exception e) {
logger.error("Unable to update event {} comment catalog: {}", event.getIdentifier(), getStackTrace(e));
}
}
});
}
});
}
use of org.opencastproject.index.service.exception.IndexServiceException in project opencast by opencast.
the class IndexServiceImpl method updateEventAcl.
@Override
public AccessControlList updateEventAcl(String id, AccessControlList acl, AbstractSearchIndex index) throws IllegalArgumentException, IndexServiceException, SearchIndexException, NotFoundException, UnauthorizedException {
Opt<Event> optEvent = getEvent(id, index);
if (optEvent.isNone())
throw new NotFoundException("Cannot find an event with id " + id);
Event event = optEvent.get();
MediaPackage mediaPackage = getEventMediapackage(event);
switch(getEventSource(event)) {
case WORKFLOW:
// Not updating the acl as the workflow might have already passed the point of distribution.
throw new IllegalArgumentException("Unable to update the ACL of this event as it is currently processing.");
case ARCHIVE:
mediaPackage = authorizationService.setAcl(mediaPackage, AclScope.Episode, acl).getA();
assetManager.takeSnapshot(DEFAULT_OWNER, mediaPackage);
return acl;
case SCHEDULE:
mediaPackage = authorizationService.setAcl(mediaPackage, AclScope.Episode, acl).getA();
try {
schedulerService.updateEvent(id, Opt.<Date>none(), Opt.<Date>none(), Opt.<String>none(), Opt.<Set<String>>none(), Opt.some(mediaPackage), Opt.<Map<String, String>>none(), Opt.<Map<String, String>>none(), Opt.<Opt<Boolean>>none(), SchedulerService.ORIGIN);
} catch (SchedulerException e) {
throw new IndexServiceException("Unable to update the acl for the scheduled event", e);
}
return acl;
default:
logger.error("Unknown event source '{}' unable to update ACL!", getEventSource(event));
throw new IndexServiceException(String.format("Unable to update the ACL as '{}' is an unknown event source.", getEventSource(event)));
}
}
use of org.opencastproject.index.service.exception.IndexServiceException in project opencast by opencast.
the class IndexServiceImpl method startAddAssetWorkflow.
/**
* Parses the processing information, including the workflowDefinitionId, from the metadataJson and starts the
* workflow with the passed mediapackage.
*
* TODO NOTE: This checks for running workflows, then takes a snapshot prior to starting a new workflow. This causes a
* potential race condition:
*
* 1. An existing workflow is running, the add asset workflow cannot start.
*
* 2. The snapshot(4x) archive(3x) is saved and the new workflow is started.
*
* 3. Possible race condition: No running workflow, a snapshot is saved but the workflow cannot start because another
* workflow has started between the time of checking and starting running.
*
* 4. If race condition: the Admin UI shows error that the workflow could not start.
*
* 5. If race condition: The interim snapshot(4x) archive(3x) is updated(4x-3x) by the running workflow's snapshots
* and resolves the inconsistency, eventually.
*
* Example of processing json:
*
* ...., "processing": { "workflow": "full", "configuration": { "videoPreview": "false", "trimHold": "false",
* "captionHold": "false", "archiveOp": "true", "publishEngage": "true", "publishHarvesting": "true" } }, ....
*
* @param metadataJson
* @param mp
* @return the created workflow instance id
* @throws IndexServiceException
*/
private String startAddAssetWorkflow(JSONObject metadataJson, MediaPackage mediaPackage) throws IndexServiceException {
String wfId = null;
String mpId = mediaPackage.getIdentifier().toString();
JSONObject processing = (JSONObject) metadataJson.get("processing");
if (processing == null)
throw new IllegalArgumentException("No processing field in metadata");
String workflowDefId = (String) processing.get("workflow");
if (workflowDefId == null)
throw new IllegalArgumentException("No workflow definition field in processing metadata");
JSONObject configJson = (JSONObject) processing.get("configuration");
try {
// 1. Check if any active workflows are running for this mediapackage id
WorkflowSet workflowSet = workflowService.getWorkflowInstances(new WorkflowQuery().withMediaPackage(mpId));
for (WorkflowInstance wf : Arrays.asList(workflowSet.getItems())) {
if (wf.isActive()) {
logger.warn("Unable to start new workflow '{}' on archived media package '{}', existing workfow {} is running", workflowDefId, mediaPackage, wf.getId());
throw new IllegalArgumentException("A workflow is already active for mp " + mpId + ", cannot start this workflow.");
}
}
// 2. Save the snapshot
assetManager.takeSnapshot(DEFAULT_OWNER, mediaPackage);
// 3. start the new workflow on the snapshot
// Workflow params are assumed to be String (not mixed with Number)
Map<String, String> params = new HashMap<String, String>();
if (configJson != null) {
for (Object key : configJson.keySet()) {
params.put((String) key, (String) configJson.get(key));
}
}
Set<String> mpIds = new HashSet<String>();
mpIds.add(mpId);
final Workflows workflows = new Workflows(assetManager, workspace, workflowService);
List<WorkflowInstance> wfList = workflows.applyWorkflowToLatestVersion(mpIds, ConfiguredWorkflow.workflow(workflowService.getWorkflowDefinitionById(workflowDefId), params)).toList();
wfId = wfList.size() > 0 ? Long.toString(wfList.get(0).getId()) : "Unknown";
logger.info("Asset update and publish workflow {} scheduled for mp {}", wfId, mpId);
} catch (AssetManagerException e) {
logger.warn("Unable to start workflow '{}' on archived media package '{}': {}", workflowDefId, mediaPackage, getStackTrace(e));
throw new IndexServiceException("Unable to start workflow " + workflowDefId + " on " + mpId);
} catch (WorkflowDatabaseException e) {
logger.warn("Unable to load workflow '{}' from workflow service: {}", wfId, getStackTrace(e));
} catch (NotFoundException e) {
logger.warn("Workflow '{}' not found", wfId);
}
return wfId;
}
use of org.opencastproject.index.service.exception.IndexServiceException in project opencast by opencast.
the class IndexServiceImpl method createSeries.
@Override
public String createSeries(MetadataList metadataList, Map<String, String> options, Opt<AccessControlList> optAcl, Opt<Long> optThemeId) throws IndexServiceException {
DublinCoreCatalog dc = DublinCores.mkOpencastSeries().getCatalog();
dc.set(PROPERTY_IDENTIFIER, UUID.randomUUID().toString());
dc.set(DublinCore.PROPERTY_CREATED, EncodingSchemeUtils.encodeDate(new Date(), Precision.Second));
for (Entry<String, String> entry : options.entrySet()) {
dc.set(new EName(DublinCores.OC_PROPERTY_NS_URI, entry.getKey()), entry.getValue());
}
Opt<MetadataCollection> seriesMetadata = metadataList.getMetadataByFlavor(MediaPackageElements.SERIES.toString());
if (seriesMetadata.isSome()) {
DublinCoreMetadataUtil.updateDublincoreCatalog(dc, seriesMetadata.get());
}
AccessControlList acl;
if (optAcl.isSome()) {
acl = optAcl.get();
} else {
acl = new AccessControlList();
}
String seriesId;
try {
DublinCoreCatalog createdSeries = seriesService.updateSeries(dc);
seriesId = createdSeries.getFirst(PROPERTY_IDENTIFIER);
seriesService.updateAccessControl(seriesId, acl);
for (Long id : optThemeId) seriesService.updateSeriesProperty(seriesId, THEME_PROPERTY_NAME, Long.toString(id));
} catch (Exception e) {
logger.error("Unable to create new series: {}", getStackTrace(e));
throw new IndexServiceException("Unable to create new series");
}
updateSeriesMetadata(seriesId, metadataList);
return seriesId;
}
Aggregations