Search in sources :

Example 1 with FailedThumbnailInfo

use of org.alfresco.service.cmr.thumbnail.FailedThumbnailInfo in project alfresco-repository by Alfresco.

the class ThumbnailServiceImpl method getFailedThumbnails.

@Override
public Map<String, FailedThumbnailInfo> getFailedThumbnails(NodeRef sourceNode) {
    Map<String, FailedThumbnailInfo> result = Collections.emptyMap();
    if (nodeService.hasAspect(sourceNode, ContentModel.ASPECT_FAILED_THUMBNAIL_SOURCE)) {
        List<ChildAssociationRef> failedThumbnailChildren = nodeService.getChildAssocs(sourceNode, ContentModel.ASSOC_FAILED_THUMBNAIL, RegexQNamePattern.MATCH_ALL);
        result = new HashMap<String, FailedThumbnailInfo>();
        for (ChildAssociationRef chAssRef : failedThumbnailChildren) {
            final QName failedThumbnailName = chAssRef.getQName();
            NodeRef failedThumbnailNode = chAssRef.getChildRef();
            Map<QName, Serializable> props = nodeService.getProperties(failedThumbnailNode);
            Date failureDateTime = (Date) props.get(ContentModel.PROP_FAILED_THUMBNAIL_TIME);
            int failureCount = (Integer) props.get(ContentModel.PROP_FAILURE_COUNT);
            final FailedThumbnailInfo failedThumbnailInfo = new FailedThumbnailInfo(failedThumbnailName.getLocalName(), failureDateTime, failureCount, failedThumbnailNode);
            result.put(failedThumbnailName.getLocalName(), failedThumbnailInfo);
        }
    } else {
        logger.debug(sourceNode + " does not have " + ContentModel.ASPECT_FAILED_THUMBNAIL_SOURCE + " aspect");
    }
    return result;
}
Also used : Serializable(java.io.Serializable) QName(org.alfresco.service.namespace.QName) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) Date(java.util.Date) FailedThumbnailInfo(org.alfresco.service.cmr.thumbnail.FailedThumbnailInfo) NodeRef(org.alfresco.service.cmr.repository.NodeRef)

Example 2 with FailedThumbnailInfo

use of org.alfresco.service.cmr.thumbnail.FailedThumbnailInfo in project alfresco-repository by Alfresco.

the class ThumbnailServiceImpl method onCreateNode.

public void onCreateNode(ChildAssociationRef childAssoc) {
    NodeRef thumbnailNodeRef = childAssoc.getChildRef();
    NodeRef sourceNodeRef = childAssoc.getParentRef();
    Map<QName, Serializable> props = nodeService.getProperties(thumbnailNodeRef);
    if (logger.isDebugEnabled()) {
        logger.debug("Thumbnail " + thumbnailNodeRef + " props " + props);
    }
    String thumbnailName = (String) nodeService.getProperty(thumbnailNodeRef, ContentModel.PROP_NAME);
    if (logger.isDebugEnabled()) {
        logger.debug("Thumbnail created " + childAssoc + " for sourceNodeRef " + sourceNodeRef + ", thumbnail " + thumbnailName + ", thumbnailNodeRef " + thumbnailNodeRef);
    }
    // in order to mark the update after the transactions that creates the thumbnail commits.
    if (nodeService.exists(thumbnailNodeRef)) {
        if (logger.isDebugEnabled()) {
            logger.debug("Caching " + childAssoc + " in transaction resources, thumbnail " + thumbnailName);
        }
        TransactionalResourceHelper.getSet(THUMBNAIL_PARENT_NODES).add(childAssoc);
        TransactionSupportUtil.bindListener(this.transactionListener, 0);
        // For new version/content the child association contains a temporary thumbnail node, that gets removed later.
        // We need to add the original thumbnail node to the TransactionalResourceHelper instead.
        QName thumbnailQname = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, thumbnailName);
        if (!childAssoc.getQName().equals(thumbnailQname)) {
            List<ChildAssociationRef> allAssocList = nodeService.getChildAssocs(childAssoc.getParentRef(), RegexQNamePattern.MATCH_ALL, thumbnailQname);
            for (ChildAssociationRef aChildAssoc : allAssocList) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Caching original thumbnail " + aChildAssoc + " in transaction resources, thumbnail " + thumbnailName);
                }
                TransactionalResourceHelper.getSet(THUMBNAIL_PARENT_NODES).add(aChildAssoc);
            }
        }
    } else {
        if (logger.isDebugEnabled()) {
            logger.debug("Thumbnail " + thumbnailNodeRef + " does not exist, thumbnail " + thumbnailName);
        }
    }
    // When a thumbnail succeeds, we must delete any existing thumbnail failure nodes
    // In fact there should only be zero or one such failedThumbnails
    Map<String, FailedThumbnailInfo> failures = getFailedThumbnails(sourceNodeRef);
    if (logger.isDebugEnabled()) {
        logger.debug("Thumbnail failures " + failures + " for sourceNodeRef " + sourceNodeRef + ", thumbnail " + thumbnailName);
    }
    FailedThumbnailInfo existingFailedThumbnail = failures.get(thumbnailName);
    if (logger.isDebugEnabled()) {
        logger.debug("Existing failed thumbnail " + existingFailedThumbnail + ", thumbnail " + thumbnailName);
    }
    if (existingFailedThumbnail != null) {
        if (logger.isDebugEnabled()) {
            StringBuilder msg = new StringBuilder();
            msg.append("Deleting failedThumbnail node ").append(existingFailedThumbnail.getFailedThumbnailNode());
            logger.debug(msg.toString());
        }
        nodeService.deleteNode(existingFailedThumbnail.getFailedThumbnailNode());
    }
}
Also used : NodeRef(org.alfresco.service.cmr.repository.NodeRef) FailedThumbnailInfo(org.alfresco.service.cmr.thumbnail.FailedThumbnailInfo) Serializable(java.io.Serializable) QName(org.alfresco.service.namespace.QName) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef)

Example 3 with FailedThumbnailInfo

use of org.alfresco.service.cmr.thumbnail.FailedThumbnailInfo in project alfresco-repository by Alfresco.

the class ThumbnailServiceImplTest method testCreateFailingThumbnail.

/**
 * @since 3.5.0
 */
@Test
public void testCreateFailingThumbnail() throws Exception {
    // see REPO-1528
    if (shouldTestBeSkippedForCurrentDB()) {
        return;
    }
    logger.debug("Starting testCreateFailingThumbnail");
    final NodeRef corruptNode = this.createCorruptedContent(folder);
    logger.debug("Running failing thumbnail on " + corruptNode);
    // Make sure the source node is correctly set up before we start
    // It should not be renditioned and should not be marked as having any failed thumbnails.
    assertFalse(secureNodeService.hasAspect(corruptNode, RenditionModel.ASPECT_RENDITIONED));
    assertFalse(secureNodeService.hasAspect(corruptNode, ContentModel.ASPECT_FAILED_THUMBNAIL_SOURCE));
    TestTransaction.flagForCommit();
    TestTransaction.end();
    // Attempt to perform a thumbnail that we know will fail.
    transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {

        public Void execute() throws Throwable {
            ThumbnailDefinition thumbnailDef = thumbnailService.getThumbnailRegistry().getThumbnailDefinition("doclib");
            Action createThumbnailAction = ThumbnailHelper.createCreateThumbnailAction(thumbnailDef, services);
            actionService.executeAction(createThumbnailAction, corruptNode, true, true);
            return null;
        }
    });
    // The thumbnail attempt has now failed. But a compensating action should have been scheduled that will mark the
    // source node with a failure aspect. As that is an asynchronous action, we need to wait for that to complete.
    // This should be long enough for the compensating action to run.
    Thread.sleep(3000);
    transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {

        public Void execute() throws Throwable {
            assertFalse("corrupt node should not have renditioned aspect", secureNodeService.hasAspect(corruptNode, RenditionModel.ASPECT_RENDITIONED));
            assertTrue("corrupt node should have failed thumbnails aspect", secureNodeService.hasAspect(corruptNode, ContentModel.ASPECT_FAILED_THUMBNAIL_SOURCE));
            Map<String, FailedThumbnailInfo> failedThumbnails = thumbnailService.getFailedThumbnails(corruptNode);
            assertEquals("Wrong number of failed thumbnails", 1, failedThumbnails.size());
            assertTrue("Missing QName for failed thumbnail", failedThumbnails.containsKey("doclib"));
            final FailedThumbnailInfo doclibFailureInfo = failedThumbnails.get("doclib");
            assertNotNull("Failure info was null", doclibFailureInfo);
            assertEquals("Failure count was wrong.", 1, doclibFailureInfo.getFailureCount());
            assertEquals("thumbnail name was wrong.", "doclib", doclibFailureInfo.getThumbnailDefinitionName());
            return null;
        }
    });
    // If you uncomment this line and set the timeout to a value greater than ${system.thumbnail.minimum.retry.period} * 1000.
    // Then the retry period will have passed, the below re-thumbnail attempt will be made and the test will fail with a
    // failureCount == 2.
    // 
    // Thread.sleep(150 * 1000);
    // Run the thumbnail again. It should not run because the action condition should prevent it.
    // We can check that it does not run by ensuring the failureCount does not change.
    transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {

        public Void execute() throws Throwable {
            ThumbnailDefinition thumbnailDef = thumbnailService.getThumbnailRegistry().getThumbnailDefinition("doclib");
            Action createThumbnailAction = ThumbnailHelper.createCreateThumbnailAction(thumbnailDef, services);
            actionService.executeAction(createThumbnailAction, corruptNode, true, true);
            return null;
        }
    });
    // Pause to let the async action be considered for running (but not run).
    Thread.sleep(3000);
    transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {

        public Void execute() throws Throwable {
            Map<String, FailedThumbnailInfo> failedThumbnails = thumbnailService.getFailedThumbnails(corruptNode);
            assertEquals("Wrong number of failed thumbnails", 1, failedThumbnails.size());
            assertTrue("Missing QName for failed thumbnail", failedThumbnails.containsKey("doclib"));
            final FailedThumbnailInfo doclibFailureInfo = failedThumbnails.get("doclib");
            assertNotNull("Failure info was null", doclibFailureInfo);
            assertEquals("Failure count was wrong.", 1, doclibFailureInfo.getFailureCount());
            assertEquals("thumbnail name was wrong.", "doclib", doclibFailureInfo.getThumbnailDefinitionName());
            return null;
        }
    });
}
Also used : NodeRef(org.alfresco.service.cmr.repository.NodeRef) FailedThumbnailInfo(org.alfresco.service.cmr.thumbnail.FailedThumbnailInfo) Action(org.alfresco.service.cmr.action.Action) RetryingTransactionHelper(org.alfresco.repo.transaction.RetryingTransactionHelper) Map(java.util.Map) MimetypeMap(org.alfresco.repo.content.MimetypeMap) HashMap(java.util.HashMap) BaseAlfrescoSpringTest(org.alfresco.util.BaseAlfrescoSpringTest) Test(org.junit.Test) AbstractContentTransformerTest(org.alfresco.repo.content.transform.AbstractContentTransformerTest)

Example 4 with FailedThumbnailInfo

use of org.alfresco.service.cmr.thumbnail.FailedThumbnailInfo in project alfresco-repository by Alfresco.

the class NodeEligibleForRethumbnailingEvaluator method evaluateImpl.

/**
 * @see ActionConditionEvaluatorAbstractBase#evaluateImpl(ActionCondition, NodeRef)
 */
public boolean evaluateImpl(ActionCondition actionCondition, NodeRef actionedUponNodeRef) {
    if (!this.nodeService.exists(actionedUponNodeRef)) {
        return false;
    }
    Serializable paramThumbnailDefnName = actionCondition.getParameterValue(PARAM_THUMBNAIL_DEFINITION_NAME);
    Serializable paramRetryPeriod = actionCondition.getParameterValue(PARAM_RETRY_PERIOD);
    Serializable paramRetryCount = actionCondition.getParameterValue(PARAM_RETRY_COUNT);
    Serializable paramQuietPeriod = actionCondition.getParameterValue(PARAM_QUIET_PERIOD);
    final Serializable parameterValue = actionCondition.getParameterValue(PARAM_QUIET_PERIOD_RETRIES_ENABLED);
    Serializable paramQuietPeriodRetriesEnabled = parameterValue != null ? parameterValue : FailureHandlingOptions.DEFAULT_QUIET_PERIOD_RETRIES_ENABLED;
    final QName thumbnailDefnQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, (String) paramThumbnailDefnName);
    // If there are no previous failed thumbnail attempts for this thumbnail definition,
    // then the node is always eligible for a first try.
    Map<String, FailedThumbnailInfo> failures = thumbnailService.getFailedThumbnails(actionedUponNodeRef);
    if (failures.isEmpty() || !failures.containsKey(thumbnailDefnQName.getLocalName())) {
        if (logger.isDebugEnabled()) {
            StringBuilder msg = new StringBuilder();
            msg.append("Node ").append(actionedUponNodeRef).append(" has no matching ").append(ContentModel.ASSOC_FAILED_THUMBNAIL).append(" child.");
            logger.debug(msg.toString());
        }
        return true;
    }
    final FailedThumbnailInfo failedThumbnailInfo = failures.get(thumbnailDefnQName.getLocalName());
    // thumbnail definition at some point.
    if (failedThumbnailInfo.getMostRecentFailure() == null) {
        // The property should never be null like this, but just in case.
        return true;
    }
    // So how long ago did the given thumbnail definition fail?
    long nowMs = new Date().getTime();
    long failureTimeMs = failedThumbnailInfo.getMostRecentFailure().getTime();
    final long timeSinceLastFailureMs = nowMs - failureTimeMs;
    // And how many failures have there been?
    final int failureCount = failedThumbnailInfo.getFailureCount();
    if (logger.isDebugEnabled()) {
        StringBuilder msg = new StringBuilder();
        msg.append("Comparing failure time of ").append(failedThumbnailInfo.getMostRecentFailure()).append(" to now. Difference is ").append(timeSinceLastFailureMs).append(" ms. ").append(failureCount).append(" existing failures.");
        logger.debug(msg.toString());
    }
    if (failureCount >= (Integer) paramRetryCount) {
        boolean quietPeriodRetriesEnabled = (Boolean) paramQuietPeriodRetriesEnabled;
        return quietPeriodRetriesEnabled && timeSinceFailureExceedsLimit(paramQuietPeriod, timeSinceLastFailureMs);
    } else {
        return timeSinceFailureExceedsLimit(paramRetryPeriod, timeSinceLastFailureMs);
    }
}
Also used : FailedThumbnailInfo(org.alfresco.service.cmr.thumbnail.FailedThumbnailInfo) Serializable(java.io.Serializable) QName(org.alfresco.service.namespace.QName) Date(java.util.Date)

Example 5 with FailedThumbnailInfo

use of org.alfresco.service.cmr.thumbnail.FailedThumbnailInfo in project alfresco-repository by Alfresco.

the class FailedThumbnailSourceAspect method deleteFailedThumbnailChildren.

/**
 * Delete all cm:failedThumbnail children as they represent a failure to thumbnail
 * the old content. By deleting all cm:failedThumbnail children, the cm:failedThumbnailSource
 * aspect will be automatically removed by a policy/behaviour in the ThumbnailService.
 *
 * This is necessary so that if a new version of a 'broken' document is uploaded, then
 * it will be thumbnailed in the normal way.
 */
private void deleteFailedThumbnailChildren(NodeRef nodeRef) {
    Map<String, FailedThumbnailInfo> failedThumbnails = thumbnailService.getFailedThumbnails(nodeRef);
    behaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_AUDITABLE);
    try {
        if (log.isDebugEnabled()) {
            log.debug("Deleting " + failedThumbnails.size() + " " + ContentModel.TYPE_FAILED_THUMBNAIL + " nodes");
        }
        for (Entry<String, FailedThumbnailInfo> entry : failedThumbnails.entrySet()) {
            FailedThumbnailInfo info = entry.getValue();
            nodeService.deleteNode(info.getFailedThumbnailNode());
        }
    } finally {
        behaviourFilter.enableBehaviour(nodeRef, ContentModel.ASPECT_AUDITABLE);
    }
}
Also used : FailedThumbnailInfo(org.alfresco.service.cmr.thumbnail.FailedThumbnailInfo)

Aggregations

FailedThumbnailInfo (org.alfresco.service.cmr.thumbnail.FailedThumbnailInfo)7 Serializable (java.io.Serializable)4 NodeRef (org.alfresco.service.cmr.repository.NodeRef)4 Date (java.util.Date)3 QName (org.alfresco.service.namespace.QName)3 Test (org.junit.Test)3 HashMap (java.util.HashMap)2 Map (java.util.Map)2 MimetypeMap (org.alfresco.repo.content.MimetypeMap)2 AbstractContentTransformerTest (org.alfresco.repo.content.transform.AbstractContentTransformerTest)2 RetryingTransactionHelper (org.alfresco.repo.transaction.RetryingTransactionHelper)2 Action (org.alfresco.service.cmr.action.Action)2 ActionCondition (org.alfresco.service.cmr.action.ActionCondition)2 ChildAssociationRef (org.alfresco.service.cmr.repository.ChildAssociationRef)2 BaseAlfrescoSpringTest (org.alfresco.util.BaseAlfrescoSpringTest)2 ActionConditionImpl (org.alfresco.repo.action.ActionConditionImpl)1 Rule (org.alfresco.service.cmr.rule.Rule)1 BaseSpringTest (org.alfresco.util.BaseSpringTest)1