use of org.opencastproject.assetmanager.api.AssetManagerException in project opencast by opencast.
the class IndexServiceImpl method removeEvent.
@Override
public boolean removeEvent(String id) throws NotFoundException, UnauthorizedException {
boolean unauthorizedScheduler = false;
boolean notFoundScheduler = false;
boolean removedScheduler = true;
try {
schedulerService.removeEvent(id);
} catch (NotFoundException e) {
notFoundScheduler = true;
} catch (UnauthorizedException e) {
unauthorizedScheduler = true;
} catch (SchedulerException e) {
removedScheduler = false;
logger.error("Unable to remove the event '{}' from scheduler service: {}", id, getStackTrace(e));
}
boolean unauthorizedWorkflow = false;
boolean notFoundWorkflow = false;
boolean removedWorkflow = true;
try {
WorkflowQuery workflowQuery = new WorkflowQuery().withMediaPackage(id);
WorkflowSet workflowSet = workflowService.getWorkflowInstances(workflowQuery);
if (workflowSet.size() == 0)
notFoundWorkflow = true;
for (WorkflowInstance instance : workflowSet.getItems()) {
workflowService.stop(instance.getId());
workflowService.remove(instance.getId());
}
} catch (NotFoundException e) {
notFoundWorkflow = true;
} catch (UnauthorizedException e) {
unauthorizedWorkflow = true;
} catch (WorkflowDatabaseException e) {
removedWorkflow = false;
logger.error("Unable to remove the event '{}' because removing workflow failed: {}", id, getStackTrace(e));
} catch (WorkflowException e) {
removedWorkflow = false;
logger.error("Unable to remove the event '{}' because removing workflow failed: {}", id, getStackTrace(e));
}
boolean unauthorizedArchive = false;
boolean notFoundArchive = false;
boolean removedArchive = true;
try {
final AQueryBuilder q = assetManager.createQuery();
final Predicate p = q.organizationId().eq(securityService.getOrganization().getId()).and(q.mediaPackageId(id));
final AResult r = q.select(q.nothing()).where(p).run();
if (r.getSize() > 0)
q.delete(DEFAULT_OWNER, q.snapshot()).where(p).run();
} catch (AssetManagerException e) {
if (e.getCause() instanceof UnauthorizedException) {
unauthorizedArchive = true;
} else if (e.getCause() instanceof NotFoundException) {
notFoundArchive = true;
} else {
removedArchive = false;
logger.error("Unable to remove the event '{}' from the archive: {}", id, getStackTrace(e));
}
}
if (notFoundScheduler && notFoundWorkflow && notFoundArchive)
throw new NotFoundException("Event id " + id + " not found.");
if (unauthorizedScheduler || unauthorizedWorkflow || unauthorizedArchive)
throw new UnauthorizedException("Not authorized to remove event id " + id);
try {
eventCommentService.deleteComments(id);
} catch (EventCommentException e) {
logger.error("Unable to remove comments for event '{}': {}", id, getStackTrace(e));
}
return removedScheduler && removedWorkflow && removedArchive;
}
use of org.opencastproject.assetmanager.api.AssetManagerException 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.assetmanager.api.AssetManagerException in project opencast by opencast.
the class AssetManagerUpdatedEventHandler method handleEvent.
public void handleEvent(final SeriesItem seriesItem) {
// A series or its ACL has been updated. Find any mediapackages with that series, and update them.
logger.debug("Handling {}", seriesItem);
String seriesId = seriesItem.getSeriesId();
// We must be an administrative user to make this query
final User prevUser = securityService.getUser();
final Organization prevOrg = securityService.getOrganization();
try {
securityService.setUser(SecurityUtil.createSystemUser(systemAccount, prevOrg));
final AQueryBuilder q = assetManager.createQuery();
final AResult result = q.select(q.snapshot()).where(q.seriesId().eq(seriesId).and(q.version().isLatest())).run();
for (Snapshot snapshot : enrich(result).getSnapshots()) {
final String orgId = snapshot.getOrganizationId();
final Organization organization = organizationDirectoryService.getOrganization(orgId);
if (organization == null) {
logger.warn("Skipping update of episode {} since organization {} is unknown", snapshot.getMediaPackage().getIdentifier().compact(), orgId);
continue;
}
securityService.setOrganization(organization);
MediaPackage mp = snapshot.getMediaPackage();
// Update the series XACML file
if (SeriesItem.Type.UpdateAcl.equals(seriesItem.getType())) {
// Build a new XACML file for this mediapackage
authorizationService.setAcl(mp, AclScope.Series, seriesItem.getAcl());
}
// Update the series dublin core or extended metadata
if (SeriesItem.Type.UpdateCatalog.equals(seriesItem.getType()) || SeriesItem.Type.UpdateElement.equals(seriesItem.getType())) {
DublinCoreCatalog seriesDublinCore = null;
MediaPackageElementFlavor catalogType = null;
if (SeriesItem.Type.UpdateCatalog.equals(seriesItem.getType())) {
seriesDublinCore = seriesItem.getMetadata();
mp.setSeriesTitle(seriesDublinCore.getFirst(DublinCore.PROPERTY_TITLE));
catalogType = MediaPackageElements.SERIES;
} else {
seriesDublinCore = seriesItem.getExtendedMetadata();
catalogType = MediaPackageElementFlavor.flavor(seriesItem.getElementType(), "series");
}
// Update the series dublin core
Catalog[] seriesCatalogs = mp.getCatalogs(catalogType);
if (seriesCatalogs.length == 1) {
Catalog c = seriesCatalogs[0];
String filename = FilenameUtils.getName(c.getURI().toString());
URI uri = workspace.put(mp.getIdentifier().toString(), c.getIdentifier(), filename, dublinCoreService.serialize(seriesDublinCore));
c.setURI(uri);
// setting the URI to a new source so the checksum will most like be invalid
c.setChecksum(null);
}
}
// Remove the series catalogs and isPartOf from episode catalog
if (SeriesItem.Type.Delete.equals(seriesItem.getType())) {
mp.setSeries(null);
mp.setSeriesTitle(null);
for (Catalog seriesCatalog : mp.getCatalogs(MediaPackageElements.SERIES)) {
mp.remove(seriesCatalog);
}
authorizationService.removeAcl(mp, AclScope.Series);
for (Catalog episodeCatalog : mp.getCatalogs(MediaPackageElements.EPISODE)) {
DublinCoreCatalog episodeDublinCore = DublinCoreUtil.loadDublinCore(workspace, episodeCatalog);
episodeDublinCore.remove(DublinCore.PROPERTY_IS_PART_OF);
String filename = FilenameUtils.getName(episodeCatalog.getURI().toString());
URI uri = workspace.put(mp.getIdentifier().toString(), episodeCatalog.getIdentifier(), filename, dublinCoreService.serialize(episodeDublinCore));
episodeCatalog.setURI(uri);
// setting the URI to a new source so the checksum will most like be invalid
episodeCatalog.setChecksum(null);
}
// here we don't know the series extended metadata types,
// we assume that all series catalog flavors have a fixed subtype: series
MediaPackageElementFlavor seriesFlavor = MediaPackageElementFlavor.flavor("*", "series");
for (Catalog catalog : mp.getCatalogs()) {
if (catalog.getFlavor().matches(seriesFlavor))
mp.remove(catalog);
}
}
try {
// Update the asset manager with the modified mediapackage
assetManager.takeSnapshot(snapshot.getOwner(), mp);
} catch (AssetManagerException e) {
logger.error("Error updating mediapackage {}", mp.getIdentifier().compact(), e);
}
}
} catch (NotFoundException e) {
logger.warn(e.getMessage());
} catch (IOException e) {
logger.warn(e.getMessage());
} finally {
securityService.setOrganization(prevOrg);
securityService.setUser(prevUser);
}
}
Aggregations