use of org.alfresco.service.cmr.action.ActionServiceTransientException in project alfresco-repository by Alfresco.
the class CreateThumbnailActionExecuter method executeImpl.
/**
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
protected void executeImpl(Action action, NodeRef actionedUponNodeRef) {
// Check if thumbnailing is generally disabled
if (!thumbnailService.getThumbnailsEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Thumbnail transformations are not enabled");
}
return;
}
if (this.nodeService.exists(actionedUponNodeRef) == true) {
// Get the thumbnail Name
String thumbnailName = (String) action.getParameterValue(PARAM_THUMBANIL_NAME);
// Get the details of the thumbnail
ThumbnailRegistry registry = this.thumbnailService.getThumbnailRegistry();
ThumbnailDefinition details = registry.getThumbnailDefinition(thumbnailName);
if (details == null) {
// Throw exception
throw new AlfrescoRuntimeException("The thumbnail name '" + thumbnailName + "' is not registered");
}
// Get the content property
QName contentProperty = (QName) action.getParameterValue(PARAM_CONTENT_PROPERTY);
if (contentProperty == null) {
contentProperty = ContentModel.PROP_CONTENT;
}
// If there isn't a currently active transformer for this, log and skip
Serializable contentProp = nodeService.getProperty(actionedUponNodeRef, contentProperty);
if (contentProp == null) {
logger.info("Creation of thumbnail, null content for " + details.getName());
return;
}
if (contentProp instanceof ContentData) {
ContentData content = (ContentData) contentProp;
String mimetype = content.getMimetype();
if (!registry.isThumbnailDefinitionAvailable(content.getContentUrl(), mimetype, content.getSize(), actionedUponNodeRef, details)) {
logger.debug("Unable to create thumbnail '" + details.getName() + "' for " + mimetype + " as no transformer is currently available");
return;
}
if (mimetypeMaxSourceSizeKBytes != null) {
Long maxSourceSizeKBytes = mimetypeMaxSourceSizeKBytes.get(mimetype);
if (maxSourceSizeKBytes != null && maxSourceSizeKBytes >= 0 && maxSourceSizeKBytes < (content.getSize() / 1024L)) {
logger.debug("Unable to create thumbnail '" + details.getName() + "' for " + mimetype + " as content is too large (" + (content.getSize() / 1024L) + "K > " + maxSourceSizeKBytes + "K)");
// avoid transform
return;
}
}
}
// Create the thumbnail
try {
TransformationOptions options = details.getTransformationOptions();
this.thumbnailService.createThumbnail(actionedUponNodeRef, contentProperty, details.getMimetype(), options, thumbnailName, null);
} catch (ContentServiceTransientException cste) {
// any transient failures in the thumbnail creation must be handled as transient failures of the action to execute.
StringBuilder msg = new StringBuilder();
msg.append("Creation of thumbnail '").append(details.getName()).append("' declined");
if (logger.isDebugEnabled()) {
logger.debug(msg.toString());
}
throw new ActionServiceTransientException(msg.toString(), cste);
} catch (Exception exception) {
final String msg = "Creation of thumbnail '" + details.getName() + "' failed";
logger.info(msg);
// See AddFailedThumbnailActionExecuter
throw new AlfrescoRuntimeException(msg, exception);
}
}
}
use of org.alfresco.service.cmr.action.ActionServiceTransientException in project alfresco-repository by Alfresco.
the class ActionServiceImpl method executeActionImpl.
@Override
public void executeActionImpl(Action action, NodeRef actionedUponNodeRef, boolean checkConditions, boolean executedAsynchronously, Set<String> actionChain) {
if (logger.isDebugEnabled() == true) {
StringBuilder builder = new StringBuilder("Execute action impl action chain = ");
if (actionChain == null) {
builder.append("null");
} else {
for (String value : actionChain) {
builder.append(value).append(" ");
}
}
logger.debug(builder.toString());
logger.debug("Current action = " + action.getId());
}
// MNT-15365
if (actionedUponNodeRef != null && !this.nodeService.exists(actionedUponNodeRef)) {
if (logger.isDebugEnabled() == true) {
logger.debug("Node = " + actionedUponNodeRef.getId() + " skip action because node doesn't exist");
}
return;
}
// get the current user early in case the process fails and we are
// unable to do it later
String currentUserName = this.authenticationContext.getCurrentUserName();
if (actionChain == null || actionChain.contains(action.getId()) == false) {
if (logger.isDebugEnabled() == true) {
logger.debug("Doing executeActionImpl");
}
try {
Set<String> origActionChain = null;
if (actionChain == null) {
actionChain = new HashSet<String>();
} else {
origActionChain = new HashSet<String>(actionChain);
}
actionChain.add(action.getId());
this.currentActionChain.set(actionChain);
if (logger.isDebugEnabled() == true) {
logger.debug("Adding " + action.getActionDefinitionName() + ", " + action.getId() + " to action chain.");
}
try {
// Check and execute now
if (checkConditions == false || evaluateAction(action, actionedUponNodeRef) == true) {
if (getTrackStatus(action)) {
// Mark the action as starting
actionTrackingService.recordActionExecuting(action, actionedUponNodeRef);
}
RunningAction runningAction = monitor.actionStarted(action);
try {
// Execute the action
directActionExecution(action, actionedUponNodeRef);
} catch (Throwable e) {
runningAction.setException(e);
throw e;
} finally {
monitor.actionCompleted(runningAction);
}
if (getTrackStatus(action)) {
// Mark it as having worked
actionTrackingService.recordActionComplete(action);
}
}
} finally {
if (origActionChain == null) {
this.currentActionChain.remove();
} else {
this.currentActionChain.set(origActionChain);
}
if (logger.isDebugEnabled() == true) {
logger.debug("Resetting the action chain.");
}
}
} catch (ActionServiceTransientException transientException) {
// but which will not lead to the execution of any compensating action
if (getTrackStatus(action)) {
actionTrackingService.recordActionFailure(action, transientException);
}
} catch (Throwable exception) {
// which can handle the rethrown exception.
if (executedAsynchronously == true) {
// If one is specified, queue the compensating action ready
// for execution
Action compensatingAction = action.getCompensatingAction();
if (compensatingAction != null) {
// Set the current user & tenant. These should be the same for the primary action and the compensating action.
((ActionImpl) compensatingAction).setRunAsUser(currentUserName);
((ActionImpl) compensatingAction).setTenantId(((ActionImpl) action).getTenantId());
queueAction(compensatingAction, actionedUponNodeRef);
}
}
if (getTrackStatus(action)) {
// Have the failure logged on the action
actionTrackingService.recordActionFailure(action, exception);
}
// Rethrow the exception
if (exception instanceof RuntimeException) {
throw (RuntimeException) exception;
} else {
throw new ActionServiceException(ERR_FAIL, exception);
}
}
}
}
use of org.alfresco.service.cmr.action.ActionServiceTransientException in project alfresco-repository by Alfresco.
the class ActionTrackingServiceImpl method recordActionFailure.
/**
* Schedule the recording of the action failure to occur in another
* transaction
*/
public void recordActionFailure(Action action, final Throwable exception) {
if (logger.isDebugEnabled() == true) {
if (exception instanceof ActionCancelledException) {
logger.debug("Will shortly record completed cancellation of action " + action);
} else if (exception instanceof ActionServiceTransientException) {
logger.debug("Will shortly record transient failure of action " + action);
} else {
logger.debug("Will shortly record failure of action " + action + " due to " + exception.getMessage());
}
}
// Record when it finished
((ActionImpl) action).setExecutionEndDate(new Date());
// Record it as Failed or Cancelled, depending on the exception
if (exception instanceof ActionCancelledException) {
((ActionImpl) action).setExecutionStatus(ActionStatus.Cancelled);
((ActionImpl) action).setExecutionFailureMessage(null);
} else if (exception instanceof ActionServiceTransientException) {
((ActionImpl) action).setExecutionStatus(ActionStatus.Declined);
((ActionImpl) action).setExecutionFailureMessage(exception.getMessage());
} else {
((ActionImpl) action).setExecutionStatus(ActionStatus.Failed);
((ActionImpl) action).setExecutionFailureMessage(exception.getMessage());
}
// Remove it from the cache, as it's no longer running
String key = generateCacheKey(action);
executingActionsCache.remove(key);
// Do we need to update the persisted details?
if (action.getNodeRef() != null) {
// Take a local copy of the details
// (That way, if someone has a reference to the
// action and plays with it, we still save the
// correct information)
final String actionId = action.getId();
final Date startedAt = action.getExecutionStartDate();
final Date endedAt = action.getExecutionEndDate();
final String message = action.getExecutionFailureMessage();
final NodeRef actionNode = action.getNodeRef();
// Have the details updated on the action as soon
// as the transaction has finished rolling back
AlfrescoTransactionSupport.bindListener(new TransactionListenerAdapter() {
public void afterRollback() {
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Object>() {
public Object execute() throws Throwable {
// Update the action as the system user
return AuthenticationUtil.runAs(new RunAsWork<Action>() {
public Action doWork() throws Exception {
// Grab the latest version of the
// action
ActionImpl action = (ActionImpl) runtimeActionService.createAction(actionNode);
// Update it
if (exception instanceof ActionCancelledException) {
action.setExecutionStatus(ActionStatus.Cancelled);
action.setExecutionFailureMessage(null);
} else {
action.setExecutionStatus(ActionStatus.Failed);
action.setExecutionFailureMessage(exception.getMessage());
}
action.setExecutionStartDate(startedAt);
action.setExecutionEndDate(endedAt);
runtimeActionService.saveActionImpl(actionNode, action);
if (logger.isDebugEnabled() == true) {
logger.debug("Recorded failure of action " + actionId + ", node " + actionNode + " due to " + message);
}
// All done
return action;
}
}, AuthenticationUtil.SYSTEM_USER_NAME);
}
}, false, true);
}
});
}
}
Aggregations