Search in sources :

Example 1 with RenditionCancelledException

use of org.alfresco.service.cmr.rendition.RenditionCancelledException in project alfresco-repository by Alfresco.

the class AbstractTransformationRenderingEngine method render.

/*
     * (non-Javadoc)
     * @see org.alfresco.repo.rendition.executer.AbstractRenderingEngine#render(org.alfresco.repo.rendition.executer.AbstractRenderingEngine.RenderingContext)
     */
@Override
protected void render(RenderingContext context) {
    ContentReader contentReader = context.makeContentReader();
    // There will have been an exception if there is no content data so contentReader is not null.
    String contentUrl = contentReader.getContentUrl();
    String sourceMimeType = contentReader.getMimetype();
    String targetMimeType = getTargetMimeType(context);
    // The child NodeRef gets created here
    TransformationOptions transformationOptions = getTransformOptions(context);
    long sourceSizeInBytes = contentReader.getSize();
    Map<String, String> options = converter.getOptions(transformationOptions, sourceMimeType, targetMimeType);
    NodeRef sourceNodeRef = transformationOptions.getSourceNodeRef();
    if (!synchronousTransformClient.isSupported(sourceMimeType, sourceSizeInBytes, contentUrl, targetMimeType, options, null, sourceNodeRef)) {
        String optionsString = TransformerDebug.toString(options);
        throw new RenditionServiceException(String.format(NOT_TRANSFORMABLE_MESSAGE_PATTERN, sourceMimeType, targetMimeType, optionsString));
    }
    long startTime = new Date().getTime();
    boolean actionCancelled = false;
    boolean actionCompleted = false;
    // Cache the execution summary to get details later
    ExecutionSummary executionSummary = null;
    try {
        executionSummary = getExecutionSummary(context);
    } catch (ActionServiceException e) {
        if (logger.isInfoEnabled()) {
            logger.info("Cancelling of multiple concurrent action instances " + "currently unsupported, this action can't be cancelled");
        }
    }
    // Call the transform in a different thread so we can move on if cancelled
    FutureTask<ContentWriter> transformTask = new FutureTask<ContentWriter>(new TransformationCallable(contentReader, targetMimeType, transformationOptions, context, AuthenticationUtil.getFullyAuthenticatedUser()));
    getExecutorService().execute(transformTask);
    // Start checking for cancellation or timeout
    while (true) {
        try {
            Thread.sleep(CANCELLED_ACTION_POLLING_INTERVAL);
            if (transformTask.isDone()) {
                actionCompleted = true;
                break;
            }
            // Check timeout in case transformer doesn't obey it
            if (transformationOptions.getTimeoutMs() > 0 && new Date().getTime() - startTime > (transformationOptions.getTimeoutMs() + CANCELLED_ACTION_POLLING_INTERVAL)) {
                // We hit a timeout, let the transform thread continue but results will be ignored
                if (logger.isDebugEnabled()) {
                    logger.debug("Transformation did not obey timeout limit, " + "rendition action is moving on");
                }
                break;
            }
            if (executionSummary != null) {
                ExecutionDetails executionDetails = actionTrackingService.getExecutionDetails(executionSummary);
                if (executionDetails != null) {
                    actionCancelled = executionDetails.isCancelRequested();
                    if (actionCancelled) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Cancelling transformation");
                        }
                        transformTask.cancel(true);
                        break;
                    }
                }
            }
        } catch (InterruptedException e) {
            // entire thread was asked to stop
            actionCancelled = true;
            transformTask.cancel(true);
            break;
        }
    }
    if (actionCancelled) {
        throw new RenditionCancelledException("Rendition action cancelled");
    }
    if (!actionCompleted && !actionCancelled) {
        throw new RenditionServiceException("Transformation failed to obey timeout limit");
    }
    if (actionCompleted) {
        // Copy content from temp writer to real writer
        ContentWriter writer = context.makeContentWriter();
        try {
            // We should not need another timeout here, things should be ready for us
            ContentWriter tempTarget = transformTask.get();
            if (tempTarget == null) {
                // We should never be in this state, but just in case
                throw new RenditionServiceException("Target of transformation not present");
            }
            writer.putContent(tempTarget.getReader().getContentInputStream());
        } catch (ExecutionException e) {
            // Unwrap our cause and throw that
            Throwable transformException = e.getCause();
            if (transformException instanceof RuntimeException) {
                throw (RuntimeException) e.getCause();
            }
            throw new RenditionServiceException(TRANSFORMING_ERROR_MESSAGE + e.getCause().getMessage(), e.getCause());
        } catch (InterruptedException e) {
            // We were asked to stop
            transformTask.cancel(true);
        }
    }
}
Also used : ContentReader(org.alfresco.service.cmr.repository.ContentReader) RenditionCancelledException(org.alfresco.service.cmr.rendition.RenditionCancelledException) ExecutionDetails(org.alfresco.service.cmr.action.ExecutionDetails) RenditionServiceException(org.alfresco.service.cmr.rendition.RenditionServiceException) Date(java.util.Date) TransformationOptions(org.alfresco.service.cmr.repository.TransformationOptions) ActionServiceException(org.alfresco.service.cmr.action.ActionServiceException) NodeRef(org.alfresco.service.cmr.repository.NodeRef) ContentWriter(org.alfresco.service.cmr.repository.ContentWriter) FutureTask(java.util.concurrent.FutureTask) ExecutionSummary(org.alfresco.service.cmr.action.ExecutionSummary) ExecutionException(java.util.concurrent.ExecutionException)

Example 2 with RenditionCancelledException

use of org.alfresco.service.cmr.rendition.RenditionCancelledException in project alfresco-repository by Alfresco.

the class RenditionServiceIntegrationTest method renderPdfDocumentLongRunningTest.

protected void renderPdfDocumentLongRunningTest(AbstractNodeModifyingRunnable nodeModifyingRunnable, boolean joinNodeModifyingThread) throws Exception {
    // Spawn a new thread that waits a bit then tries to modify the node
    Thread nodeModifyingThread = new Thread(nodeModifyingRunnable);
    nodeModifyingThread.start();
    // Start the long running rendition
    try {
        this.renditionNode = transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<NodeRef>() {

            public NodeRef execute() throws Throwable {
                // Initially the node that provides the content
                // should not have the rn:renditioned aspect on it.
                assertFalse("Source node has unexpected renditioned aspect.", nodeService.hasAspect(nodeWithDocContent, RenditionModel.ASPECT_RENDITIONED));
                RenditionDefinition action = makeReformatAction(null, TEST_LONG_RUNNING_MIME_TYPE);
                // Cancellation is only possible with tracking enabled
                action.setTrackStatus(true);
                // Render the content and put the result underneath the content node
                ChildAssociationRef renditionAssoc = renditionService.render(nodeWithDocContent, action);
                // Now the source content node should have the renditioned aspect
                assertTrue("Source node is missing renditioned aspect.", nodeService.hasAspect(nodeWithDocContent, RenditionModel.ASPECT_RENDITIONED));
                return renditionAssoc.getChildRef();
            }
        }, false, true);
    } catch (RenditionCancelledException e) {
    // expected cancellation exception
    }
    // Give a moment for roll back of rendition and commit of node modification to occur
    Thread.sleep(3000);
    if (joinNodeModifyingThread) {
        nodeModifyingThread.join();
    }
    // be false if there was a failure
    if (nodeModifyingRunnable.getModificationException() != null) {
        throw new RuntimeException("Modification of node during long running rendition failed", nodeModifyingRunnable.getModificationException());
    }
}
Also used : RetryingTransactionCallback(org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback) RenditionCancelledException(org.alfresco.service.cmr.rendition.RenditionCancelledException) RenditionDefinition(org.alfresco.service.cmr.rendition.RenditionDefinition) CompositeRenditionDefinition(org.alfresco.service.cmr.rendition.CompositeRenditionDefinition) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef)

Aggregations

RenditionCancelledException (org.alfresco.service.cmr.rendition.RenditionCancelledException)2 Date (java.util.Date)1 ExecutionException (java.util.concurrent.ExecutionException)1 FutureTask (java.util.concurrent.FutureTask)1 RetryingTransactionCallback (org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback)1 ActionServiceException (org.alfresco.service.cmr.action.ActionServiceException)1 ExecutionDetails (org.alfresco.service.cmr.action.ExecutionDetails)1 ExecutionSummary (org.alfresco.service.cmr.action.ExecutionSummary)1 CompositeRenditionDefinition (org.alfresco.service.cmr.rendition.CompositeRenditionDefinition)1 RenditionDefinition (org.alfresco.service.cmr.rendition.RenditionDefinition)1 RenditionServiceException (org.alfresco.service.cmr.rendition.RenditionServiceException)1 ChildAssociationRef (org.alfresco.service.cmr.repository.ChildAssociationRef)1 ContentReader (org.alfresco.service.cmr.repository.ContentReader)1 ContentWriter (org.alfresco.service.cmr.repository.ContentWriter)1 NodeRef (org.alfresco.service.cmr.repository.NodeRef)1 TransformationOptions (org.alfresco.service.cmr.repository.TransformationOptions)1