ACS-2002 Enhance T-Router debug (#867)

Modifications to allow the enterprise repo to add transform debug from the t-router to the repo's log.

Addition of TransformerDebugTest
This commit is contained in:
Alan Davis
2022-01-05 21:46:41 +00:00
committed by GitHub
parent b83cc149ad
commit 451a9d1f60
5 changed files with 569 additions and 191 deletions

View File

@@ -51,7 +51,7 @@
<dependency.alfresco-log-sanitizer.version>0.2</dependency.alfresco-log-sanitizer.version> <dependency.alfresco-log-sanitizer.version>0.2</dependency.alfresco-log-sanitizer.version>
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version> <dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
<dependency.activiti.version>5.23.0</dependency.activiti.version> <dependency.activiti.version>5.23.0</dependency.activiti.version>
<dependency.alfresco-transform-model.version>1.4.3</dependency.alfresco-transform-model.version> <dependency.alfresco-transform-model.version>1.4.5</dependency.alfresco-transform-model.version>
<dependency.alfresco-greenmail.version>6.2</dependency.alfresco-greenmail.version> <dependency.alfresco-greenmail.version>6.2</dependency.alfresco-greenmail.version>
<dependency.acs-event-model.version>0.0.13</dependency.acs-event-model.version> <dependency.acs-event-model.version>0.0.13</dependency.acs-event-model.version>

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2019 Alfresco Software Limited * Copyright (C) 2019 - 2022 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -181,9 +181,9 @@ public abstract class AbstractLocalTransform implements LocalTransform
Set<String> allowedMimetypes = strictMimetypeExceptions.get(declaredMimetype); Set<String> allowedMimetypes = strictMimetypeExceptions.get(declaredMimetype);
if (allowedMimetypes != null && allowedMimetypes.contains(detectedMimetype)) if (allowedMimetypes != null && allowedMimetypes.contains(detectedMimetype))
{ {
String fileName = transformerDebug.getFileName(sourceNodeRef, true, 0); String filename = transformerDebug.getFilename(sourceNodeRef, true);
String readerSourceMimetype = reader.getMimetype(); String readerSourceMimetype = reader.getMimetype();
String message = "Transformation of ("+fileName+ String message = "Transformation of ("+filename+
") has not taken place because the declared mimetype ("+ ") has not taken place because the declared mimetype ("+
readerSourceMimetype+") does not match the detected mimetype ("+ readerSourceMimetype+") does not match the detected mimetype ("+
detectedMimetype+")."; detectedMimetype+").";

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2020 Alfresco Software Limited * Copyright (C) 2005 - 2022 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -26,29 +26,22 @@
package org.alfresco.repo.content.transform; package org.alfresco.repo.content.transform;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.metadata.AsynchronousExtractor;
import org.alfresco.service.cmr.repository.MimetypeService; import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.util.EqualsHelper;
import org.alfresco.util.LogTee; import org.alfresco.util.LogTee;
import org.alfresco.util.PropertyCheck; import org.alfresco.util.PropertyCheck;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Deque; import java.util.Deque;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.StringJoiner; import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import static org.alfresco.repo.rendition2.RenditionDefinition2.SOURCE_ENCODING;
import static org.alfresco.repo.rendition2.RenditionDefinition2.SOURCE_NODE_REF;
import static org.alfresco.repo.rendition2.RenditionDefinition2.TARGET_ENCODING;
import static org.alfresco.repo.rendition2.RenditionDefinition2.TIMEOUT;
/** /**
* Debugs transformers selection and activity.<p> * Debugs transformers selection and activity.<p>
* *
@@ -60,16 +53,32 @@ import static org.alfresco.repo.rendition2.RenditionDefinition2.TIMEOUT;
*/ */
public class TransformerDebug public class TransformerDebug
{ {
public static final String TIMEOUT = "timeout";
public static final String SOURCE_ENCODING = "sourceEncoding";
public static final String SOURCE_NODE_REF = "sourceNodeRef";
public static final String TARGET_ENCODING = "targetEncoding";
public static final String TRANSFORM_NAMESPACE = "transform:";
public static final String MIMETYPE_METADATA_EXTRACT = "alfresco-metadata-extract";
public static final String MIMETYPE_METADATA_EMBED = "alfresco-metadata-embed";
protected static final String FINISHED_IN = "Finished in "; protected static final String FINISHED_IN = "Finished in ";
protected static final String NO_TRANSFORMERS = "No transformers"; protected static final String NO_TRANSFORMERS = "No transformers";
protected static final String TRANSFORM_SERVICE_NAME = "TransformService"; protected static final String TRANSFORM_SERVICE_NAME = "TransformService";
private Log info; private static final int REFERENCE_SIZE = 15;
protected Log logger;
protected ExtensionLookup extensionLookup;
private Log singleLineLog;
protected Log multiLineLog;
protected NodeService nodeService; protected NodeService nodeService;
protected MimetypeService mimetypeService; protected MimetypeService mimetypeService;
private final ThreadLocal<Integer> previousTransformId = ThreadLocal.withInitial(()->-1); private final ThreadLocal<Integer> previousTransformId = ThreadLocal.withInitial(()->-1);
public interface ExtensionLookup
{
String getExtension(String mimetype);
}
protected enum Call protected enum Call
{ {
AVAILABLE, AVAILABLE,
@@ -92,12 +101,12 @@ public class TransformerDebug
private final Deque<String> isTransformableStack = new ArrayDeque<String>(); private final Deque<String> isTransformableStack = new ArrayDeque<String>();
private boolean debugOutput = true; private boolean debugOutput = true;
private StringBuilder sb; private StringBuilder sb;
public static Deque<Frame> getStack() public static Deque<Frame> getStack()
{ {
return threadInfo.get().stack; return threadInfo.get().stack;
} }
public static boolean getDebugOutput() public static boolean getDebugOutput()
{ {
return threadInfo.get().debugOutput; return threadInfo.get().debugOutput;
@@ -107,7 +116,7 @@ public class TransformerDebug
{ {
return threadInfo.get().isTransformableStack; return threadInfo.get().isTransformableStack;
} }
public static boolean setDebugOutput(boolean debugOutput) public static boolean setDebugOutput(boolean debugOutput)
{ {
ThreadInfo thisThreadInfo = threadInfo.get(); ThreadInfo thisThreadInfo = threadInfo.get();
@@ -115,7 +124,7 @@ public class TransformerDebug
thisThreadInfo.debugOutput = debugOutput; thisThreadInfo.debugOutput = debugOutput;
return orig; return orig;
} }
public static StringBuilder getStringBuilder() public static StringBuilder getStringBuilder()
{ {
return threadInfo.get().sb; return threadInfo.get().sb;
@@ -143,11 +152,10 @@ public class TransformerDebug
private Call callType; private Call callType;
private Frame parent; private Frame parent;
private int childId; private int childId;
protected Set<UnavailableTransformer> unavailableTransformers;
private String failureReason; private String failureReason;
private long sourceSize; private long sourceSize;
private String transformerName; private String transformerName;
private Frame(Frame parent, String transformerName, String fromUrl, String sourceMimetype, String targetMimetype, private Frame(Frame parent, String transformerName, String fromUrl, String sourceMimetype, String targetMimetype,
long sourceSize, String renditionName, NodeRef sourceNodeRef, Call pushCall, boolean origDebugOutput) long sourceSize, String renditionName, NodeRef sourceNodeRef, Call pushCall, boolean origDebugOutput)
{ {
@@ -164,13 +172,18 @@ public class TransformerDebug
this.origDebugOutput = origDebugOutput; this.origDebugOutput = origDebugOutput;
start = System.currentTimeMillis(); start = System.currentTimeMillis();
} }
static void reset()
{
uniqueId.set(0);
}
private int getId() private int getId()
{ {
if (id == -1) if (id == -1)
{ {
id = parent == null ? uniqueId.getAndIncrement() : ++parent.childId; id = parent == null ? uniqueId.getAndIncrement() : ++parent.childId;
} }
return id; return id;
} }
@@ -210,65 +223,19 @@ public class TransformerDebug
} }
} }
@Deprecated public void setExtensionLookup(ExtensionLookup extensionLookup)
protected class UnavailableTransformer implements Comparable<UnavailableTransformer>
{ {
protected final String name; this.extensionLookup = extensionLookup;
protected final String priority;
protected final long maxSourceSizeKBytes;
protected final transient boolean debug;
UnavailableTransformer(String name, String priority, long maxSourceSizeKBytes, boolean debug)
{
this.name = name;
this.priority = priority;
this.maxSourceSizeKBytes = maxSourceSizeKBytes;
this.debug = debug;
}
@Override
public int hashCode()
{
int hashCode = 37 * name.hashCode();
hashCode += 37 * maxSourceSizeKBytes;
return hashCode;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
else if (obj instanceof UnavailableTransformer)
{
UnavailableTransformer that = (UnavailableTransformer) obj;
return
EqualsHelper.nullSafeEquals(name, that.name) &&
maxSourceSizeKBytes == that.maxSourceSizeKBytes;
}
else
{
return false;
}
}
@Override
public int compareTo(UnavailableTransformer o)
{
return name.compareTo(o.name);
}
} }
public void setTransformerLog(Log transformerLog) public void setTransformerLog(Log transformerLog)
{ {
info = new LogTee(LogFactory.getLog(TransformerLog.class), transformerLog); singleLineLog = new LogTee(LogFactory.getLog(TransformerLog.class), transformerLog);
} }
public void setTransformerDebugLog(Log transformerDebugLog) public void setTransformerDebugLog(Log transformerDebugLog)
{ {
logger = new LogTee(LogFactory.getLog(TransformerDebug.class), transformerDebugLog); multiLineLog = new LogTee(LogFactory.getLog(TransformerDebug.class), transformerDebugLog);
} }
public void setNodeService(NodeService nodeService) public void setNodeService(NodeService nodeService)
@@ -279,6 +246,7 @@ public class TransformerDebug
public void setMimetypeService(MimetypeService mimetypeService) public void setMimetypeService(MimetypeService mimetypeService)
{ {
this.mimetypeService = mimetypeService; this.mimetypeService = mimetypeService;
setExtensionLookup(mimetype -> mimetypeService.getExtension(mimetype));
} }
public void setPreviousTransformId(int id) public void setPreviousTransformId(int id)
@@ -295,8 +263,8 @@ public class TransformerDebug
{ {
PropertyCheck.mandatory(this, "nodeService", nodeService); PropertyCheck.mandatory(this, "nodeService", nodeService);
PropertyCheck.mandatory(this, "mimetypeService", mimetypeService); PropertyCheck.mandatory(this, "mimetypeService", mimetypeService);
PropertyCheck.mandatory(this, "transformerLog", info); PropertyCheck.mandatory(this, "transformerLog", singleLineLog);
PropertyCheck.mandatory(this, "transformerDebugLog", logger); PropertyCheck.mandatory(this, "transformerDebugLog", multiLineLog);
} }
public void pushTransform(String transformerName, String fromUrl, String sourceMimetype, public void pushTransform(String transformerName, String fromUrl, String sourceMimetype,
@@ -360,16 +328,16 @@ public class TransformerDebug
log(frame.fromUrl, false); log(frame.fromUrl, false);
} }
log(frame.sourceMimetype+' '+frame.targetMimetype, false); log(frame.sourceMimetype+' '+frame.targetMimetype, false);
String fileName = getFileName(frame.sourceNodeRef, firstLevel, sourceSize); String filename = getFilename(frame.sourceNodeRef, firstLevel);
log(getSourceAndTargetExt(frame.sourceMimetype, frame.targetMimetype) + log(getSourceAndTargetExt(frame.sourceMimetype, frame.targetMimetype) +
((fileName != null) ? fileName+' ' : "")+ ((filename != null) ? filename+' ' : "")+
((sourceSize >= 0) ? fileSize(sourceSize)+' ' : "") + ((sourceSize >= 0) ? fileSize(sourceSize)+' ' : "") +
(firstLevel ? getRenditionName(renditionName) : "") + message); (firstLevel ? getRenditionName(renditionName) : "") + message);
if (firstLevel) if (firstLevel)
{ {
log(options); log(options);
String nodeRef = getNodeRef(frame.sourceNodeRef, firstLevel, sourceSize); String nodeRef = getNodeRef(frame.sourceNodeRef);
if (!nodeRef.isEmpty()) if (!nodeRef.isEmpty())
{ {
log(nodeRef); log(nodeRef);
@@ -377,17 +345,6 @@ public class TransformerDebug
} }
} }
public void debug(String sourceMimetype, String targetMimetype, NodeRef sourceNodeRef, long sourceSize,
Map<String, String> options, String renditionName, String message)
{
String fileName = getFileName(sourceNodeRef, true, -1);
log(" "+ getSourceAndTargetExt(sourceMimetype, targetMimetype) +
((fileName != null) ? fileName+' ' : "")+
((sourceSize >= 0) ? fileSize(sourceSize)+' ' : "") +
(getRenditionName(renditionName)) + message);
log(options);
}
private void log(Map<String, String> options) private void log(Map<String, String> options)
{ {
if (options != null) if (options != null)
@@ -450,16 +407,16 @@ public class TransformerDebug
String ms = ms(System.currentTimeMillis() - frame.start); String ms = ms(System.currentTimeMillis() - frame.start);
logInfo(frame, size, ms); logInfo(frame, size, ms);
boolean firstLevel = size == 1; boolean firstLevel = size == 1;
if (!suppressFinish && (firstLevel || logger.isTraceEnabled())) if (!suppressFinish && (firstLevel || multiLineLog.isTraceEnabled()))
{ {
log(FINISHED_IN + ms + log(FINISHED_IN + ms +
(frame.callType == Call.AVAILABLE && !suppressChecking? " Just checking if a transformer is available" : "") + (frame.callType == Call.AVAILABLE && !suppressChecking? " Just checking if a transformer is available" : "") +
(firstLevel ? "\n" : ""), (firstLevel ? "\n" : ""),
firstLevel); firstLevel);
} }
setDebugOutput(frame.origDebugOutput); setDebugOutput(frame.origDebugOutput);
ourStack.pop(); ourStack.pop();
} }
@@ -470,12 +427,12 @@ public class TransformerDebug
private void logInfo(Frame frame, int size, String ms) private void logInfo(Frame frame, int size, String ms)
{ {
if (info.isDebugEnabled()) if (singleLineLog.isDebugEnabled())
{ {
String failureReason = frame.getFailureReason(); String failureReason = frame.getFailureReason();
boolean firstLevel = size == 1; boolean firstLevel = size == 1;
String sourceAndTargetExt = getSourceAndTargetExt(frame.sourceMimetype, frame.targetMimetype); String sourceAndTargetExt = getSourceAndTargetExt(frame.sourceMimetype, frame.targetMimetype);
String fileName = getFileName(frame.sourceNodeRef, firstLevel, frame.sourceSize); String filename = getFilename(frame.sourceNodeRef, firstLevel);
long sourceSize = frame.getSourceSize(); long sourceSize = frame.getSourceSize();
String transformerName = frame.getTransformerName(); String transformerName = frame.getTransformerName();
String renditionName = frame.getRenditionName(); String renditionName = frame.getRenditionName();
@@ -486,51 +443,31 @@ public class TransformerDebug
debug = firstLevel; debug = firstLevel;
level = "INFO"; level = "INFO";
failureReason = NO_TRANSFORMERS; failureReason = NO_TRANSFORMERS;
// If trace and trace is disabled do nothing
if (debug || info.isTraceEnabled())
{
// Work out size reason that there are no transformers
if (frame.unavailableTransformers != null)
{
level = "WARN";
long smallestMaxSourceSizeKBytes = Long.MAX_VALUE;
for (UnavailableTransformer unavailable: frame.unavailableTransformers)
{
if (smallestMaxSourceSizeKBytes > unavailable.maxSourceSizeKBytes && unavailable.maxSourceSizeKBytes > 0)
{
smallestMaxSourceSizeKBytes = unavailable.maxSourceSizeKBytes;
}
}
smallestMaxSourceSizeKBytes = smallestMaxSourceSizeKBytes == Long.MAX_VALUE ? 0 : smallestMaxSourceSizeKBytes;
failureReason = "No transformers as file is > "+fileSize(smallestMaxSourceSizeKBytes*1024);
}
}
} }
else if (frame.callType == Call.TRANSFORM) else if (frame.callType == Call.TRANSFORM)
{ {
level = failureReason == null || failureReason.length() == 0 ? "INFO" : "ERROR"; level = failureReason == null || failureReason.length() == 0 ? "INFO" : "ERROR";
// Use TRACE logging for all but the first TRANSFORM // Use TRACE logging for all but the first TRANSFORM
debug = size == 1 || (size == 2 && ThreadInfo.getStack().peekLast().callType != Call.TRANSFORM); debug = size == 1 || (size == 2 && ThreadInfo.getStack().peekLast().callType != Call.TRANSFORM);
} }
if (level != null) if (level != null)
{ {
infoLog(getReference(debug, false, false), sourceAndTargetExt, level, fileName, sourceSize, infoLog(getReference(firstLevel, false, false), sourceAndTargetExt, level, filename, sourceSize,
transformerName, renditionName, failureReason, ms, debug); transformerName, renditionName, failureReason, ms, debug);
} }
} }
} }
private void infoLog(String reference, String sourceAndTargetExt, String level, String fileName, private void infoLog(String reference, String sourceAndTargetExt, String level, String filename,
long sourceSize, String transformerName, String renditionName, String failureReason, String ms, boolean debug) long sourceSize, String transformerName, String renditionName, String failureReason, String ms, boolean debug)
{ {
String message = String message =
reference + reference +
sourceAndTargetExt + sourceAndTargetExt +
(level == null ? "" : level+' ') + (level == null ? "" : level+' ') +
(fileName == null ? "" : fileName) + (filename == null ? "" : filename) +
(sourceSize >= 0 ? ' '+fileSize(sourceSize) : "") + (sourceSize >= 0 ? ' '+fileSize(sourceSize) : "") +
(ms == null || ms.isEmpty() ? "" : ' '+ms)+ (ms == null || ms.isEmpty() ? "" : ' '+ms)+
(transformerName == null ? "" : ' '+transformerName) + (transformerName == null ? "" : ' '+transformerName) +
@@ -538,11 +475,11 @@ public class TransformerDebug
(failureReason == null ? "" : ' '+failureReason.trim()); (failureReason == null ? "" : ' '+failureReason.trim());
if (debug) if (debug)
{ {
info.debug(message); singleLineLog.debug(message);
} }
else else
{ {
info.trace(message); singleLineLog.trace(message);
} }
} }
@@ -552,11 +489,11 @@ public class TransformerDebug
public boolean isEnabled() public boolean isEnabled()
{ {
// Don't check ThreadInfo.getDebugOutput() as availableTransformers() may upgrade from trace to debug. // Don't check ThreadInfo.getDebugOutput() as availableTransformers() may upgrade from trace to debug.
return logger.isDebugEnabled() || info.isDebugEnabled() || ThreadInfo.getStringBuilder() != null; return multiLineLog.isDebugEnabled() || singleLineLog.isDebugEnabled() || ThreadInfo.getStringBuilder() != null;
} }
/** /**
* Enable or disable debug log output. Normally used to hide calls to * Enable or disable debug log output. Normally used to hide calls to
* getTransformer as trace rather than debug level log messages. There * getTransformer as trace rather than debug level log messages. There
* are lots of these and it makes it hard to see what is going on. * are lots of these and it makes it hard to see what is going on.
* @param debugOutput if {@code true} both debug and trace is generated. Otherwise all output is trace. * @param debugOutput if {@code true} both debug and trace is generated. Otherwise all output is trace.
@@ -616,8 +553,7 @@ public class TransformerDebug
{ {
log(message); log(message);
} }
Deque<Frame> ourStack = ThreadInfo.getStack(); Deque<Frame> ourStack = ThreadInfo.getStack();
if (!ourStack.isEmpty()) if (!ourStack.isEmpty())
{ {
@@ -635,7 +571,7 @@ public class TransformerDebug
t = cause; t = cause;
cause = t.getCause(); cause = t.getCause();
} }
String message = t.getMessage(); String message = t.getMessage();
if (message == null || message.length() == 0) if (message == null || message.length() == 0)
{ {
@@ -648,7 +584,7 @@ public class TransformerDebug
{ {
log(message, true); log(message, true);
} }
protected void log(String message, boolean debug) protected void log(String message, boolean debug)
{ {
log(message, null, debug); log(message, null, debug);
@@ -661,13 +597,13 @@ public class TransformerDebug
private void log(String message, Throwable t, boolean debug, boolean usePreviousRef) private void log(String message, Throwable t, boolean debug, boolean usePreviousRef)
{ {
if (debug && ThreadInfo.getDebugOutput() && logger.isDebugEnabled()) if (debug && ThreadInfo.getDebugOutput() && multiLineLog.isDebugEnabled())
{ {
logger.debug(getReference(false, false, usePreviousRef)+message, t); multiLineLog.debug(getReference(false, false, usePreviousRef)+message, t);
} }
else if (logger.isTraceEnabled()) else if (multiLineLog.isTraceEnabled())
{ {
logger.trace(getReference(false, false, usePreviousRef)+message, t); multiLineLog.trace(getReference(false, false, usePreviousRef)+message, t);
} }
if (debug) if (debug)
@@ -729,7 +665,7 @@ public class TransformerDebug
String ref = ""; String ref = "";
if (id >= 0) if (id >= 0)
{ {
ref = Integer.toString(id)+spaces(13); ref = Integer.toString(id)+spaces(REFERENCE_SIZE);
} }
return ref; return ref;
} }
@@ -775,77 +711,79 @@ public class TransformerDebug
} }
else else
{ {
sb.append(spaces(13-sb.length()+lengthOfFirstId)); // Try to pad to level 7 sb.append(spaces(REFERENCE_SIZE-sb.length()+lengthOfFirstId)); // Try to pad to level 7
} }
} }
return sb.toString(); return sb.toString();
} }
public String getFileName(NodeRef sourceNodeRef, boolean firstLevel, long sourceSize) public String getFilename(NodeRef sourceNodeRef, boolean firstLevel)
{ {
return getFileNameOrNodeRef(sourceNodeRef, firstLevel, sourceSize, true); String result = null;
}
private String getNodeRef(NodeRef sourceNodeRef, boolean firstLevel, long sourceSize)
{
return getFileNameOrNodeRef(sourceNodeRef, firstLevel, sourceSize, false);
}
private String getFileNameOrNodeRef(NodeRef sourceNodeRef, boolean firstLevel, long sourceSize, boolean getName)
{
String result = getName ? null : "";
if (sourceNodeRef != null) if (sourceNodeRef != null)
{ {
try try
{ {
result = getName result = (String)nodeService.getProperty(sourceNodeRef, ContentModel.PROP_NAME);
? (String)nodeService.getProperty(sourceNodeRef, ContentModel.PROP_NAME)
: sourceNodeRef.toString()+" ";
} }
catch (RuntimeException e) catch (RuntimeException e)
{ {
// ignore (normally InvalidNodeRefException) but we should ignore other RuntimeExceptions too // ignore (InvalidNodeRefException/MalformedNodeRefException) but we should ignore other RuntimeExceptions too
} }
} }
if (result == null) if (result == null && !firstLevel)
{ {
if (!firstLevel) result = "<<TemporaryFile>>";
{
result = getName ? "<<TemporaryFile>>" : "";
}
else if (sourceSize < 0)
{
// fileName = "<<AnyFile>>"; commented out as it does not add to debug readability
}
} }
return result; return result;
} }
private String getNodeRef(NodeRef sourceNodeRef)
{
return sourceNodeRef == null ? "" : sourceNodeRef.toString();
}
protected String getSourceAndTargetExt(String sourceMimetype, String targetMimetype) protected String getSourceAndTargetExt(String sourceMimetype, String targetMimetype)
{ {
String sourceExt = getMimetypeExt(sourceMimetype); String sourceExt = getMimetypeExt(sourceMimetype);
String targetExt = getMimetypeExt(targetMimetype); String targetExt = getMimetypeExt(targetMimetype);
targetExt = AsynchronousExtractor.getExtension(targetMimetype, sourceExt, targetExt); targetExt = replaceWithMetadataExtensionIfEmbedOrExtract(targetMimetype, sourceExt, targetExt);
return sourceExt + targetExt + spaces(1+4-targetExt.length()); return sourceExt + targetExt + spaces(1+4-targetExt.length());
} }
public static String replaceWithMetadataExtensionIfEmbedOrExtract(String targetMimetype, String sourceExtension, String targetExtension)
{
return isMetadataExtractMimetype(targetMimetype)
? "json"
: isMetadataEmbedMimetype(targetMimetype)
? sourceExtension
: targetExtension;
}
protected String getMimetypeExt(String mimetype) protected String getMimetypeExt(String mimetype)
{ {
StringBuilder sb = new StringBuilder(""); StringBuilder sb = new StringBuilder("");
if (mimetypeService == null) if (extensionLookup == null)
{ {
sb.append(mimetype); sb.append(mimetype);
} }
else else
{ {
String mimetypeExt = mimetypeService.getExtension(mimetype); String mimetypeExt = extensionLookup.getExtension(mimetype);
sb.append(mimetypeExt); if (mimetypeExt == null)
sb.append(spaces(4-mimetypeExt.length())); // Pad to normal max ext (4) {
sb.append(mimetype);
}
else
{
sb.append(mimetypeExt);
sb.append(spaces(4 - mimetypeExt.length())); // Pad to normal max ext (4)
}
} }
sb.append(' '); sb.append(' ');
return sb.toString(); return sb.toString();
} }
protected String spaces(int i) protected String spaces(int i)
{ {
StringBuilder sb = new StringBuilder(""); StringBuilder sb = new StringBuilder("");
@@ -855,12 +793,12 @@ public class TransformerDebug
} }
return sb.toString(); return sb.toString();
} }
public String ms(long time) public String ms(long time)
{ {
return String.format("%,d ms", time); return String.format("%,d ms", time);
} }
public String fileSize(long size) public String fileSize(long size)
{ {
if (size < 0) if (size < 0)
@@ -876,7 +814,7 @@ public class TransformerDebug
for(int i = 0; i < units.length-1; i++) for(int i = 0; i < units.length-1; i++)
{ {
long nextDivider = divider * 1024; long nextDivider = divider * 1024;
if(size < nextDivider) if (size < nextDivider)
{ {
return fileSizeFormat(size, divider, units[i]); return fileSizeFormat(size, divider, units[i]);
} }
@@ -884,12 +822,12 @@ public class TransformerDebug
} }
return fileSizeFormat(size, divider, units[units.length-1]); return fileSizeFormat(size, divider, units[units.length-1]);
} }
private String fileSizeFormat(long size, long divider, String unit) private String fileSizeFormat(long size, long divider, String unit)
{ {
size = size * 10 / divider; size = size * 10 / divider;
int decimalPoint = (int) size % 10; int decimalPoint = (int) size % 10;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(size/10); sb.append(size/10);
if (decimalPoint != 0) if (decimalPoint != 0)
@@ -907,7 +845,7 @@ public class TransformerDebug
* Debugs a request to the Transform Service * Debugs a request to the Transform Service
*/ */
public int debugTransformServiceRequest(String sourceMimetype, long sourceSize, NodeRef sourceNodeRef, public int debugTransformServiceRequest(String sourceMimetype, long sourceSize, NodeRef sourceNodeRef,
int contentHashcode, String fileName, String targetMimetype, int contentHashcode, String filename, String targetMimetype,
Map<String, String> options, String renditionName) Map<String, String> options, String renditionName)
{ {
if (isEnabled()) if (isEnabled())
@@ -915,42 +853,89 @@ public class TransformerDebug
pushMisc(); pushMisc();
String sourceAndTargetExt = getSourceAndTargetExt(sourceMimetype, targetMimetype); String sourceAndTargetExt = getSourceAndTargetExt(sourceMimetype, targetMimetype);
debug(sourceAndTargetExt + debug(sourceAndTargetExt +
((fileName != null) ? fileName + ' ' : "") + ((filename != null) ? filename + ' ' : "") +
((sourceSize >= 0) ? fileSize(sourceSize) + ' ' : "") + ((sourceSize >= 0) ? fileSize(sourceSize) + ' ' : "") +
getRenditionName(renditionName) + " "+ TRANSFORM_SERVICE_NAME); getRenditionName(renditionName) + " "+ TRANSFORM_SERVICE_NAME);
log(options);
log(sourceNodeRef.toString() + ' ' + contentHashcode);
String reference = getReference(true, false, false); String reference = getReference(true, false, false);
infoLog(reference, sourceAndTargetExt, null, fileName, sourceSize, TRANSFORM_SERVICE_NAME, infoLog(reference, sourceAndTargetExt, null, filename, sourceSize, TRANSFORM_SERVICE_NAME,
renditionName, null, "", true); renditionName, null, "", true);
} }
return pop(Call.AVAILABLE, true, false); return pop(Call.AVAILABLE, true, false);
} }
private String getRenditionName(String renditionName) String getRenditionName(String renditionName)
{ {
return renditionName != null return renditionName != null
? "-- "+ AsynchronousExtractor.getRenditionName(renditionName)+" -- " ? "-- "+ replaceWithMetadataRenditionNameIfEmbedOrExtract(renditionName)+" -- "
: ""; : "";
}
static String replaceWithMetadataRenditionNameIfEmbedOrExtract(String renditionName)
{
String transformName = getTransformName(renditionName);
return transformName != null && transformName.startsWith(MIMETYPE_METADATA_EXTRACT)
? "metadataExtract"
: transformName != null && transformName.startsWith(MIMETYPE_METADATA_EMBED)
? "metadataEmbed"
: renditionName;
}
static String getTransformName(String renditionName)
{
return renditionName == null || !renditionName.startsWith(TRANSFORM_NAMESPACE)
? null
: renditionName.substring(TRANSFORM_NAMESPACE.length());
}
public static boolean isMetadataExtractMimetype(String targetMimetype)
{
return MIMETYPE_METADATA_EXTRACT.equals(targetMimetype);
}
public static boolean isMetadataEmbedMimetype(String targetMimetype)
{
return MIMETYPE_METADATA_EMBED.equals(targetMimetype);
} }
/** /**
* Debugs a response to the Transform Service * Debugs a response to the Transform Service
*/ */
public void debugTransformServiceResponse(NodeRef sourceNodeRef, int contentHashcode, public void debugTransformServiceResponse(long requested, int id, String msg, Collection<String> debugLines)
long requested, int id, String sourceExt, String targetExt, String msg) {
boolean suppressFinish = debugTransformServiceResponsePreConsume(requested, id, msg, debugLines);
debugTransformServiceResponsePostConsume(suppressFinish);
}
/**
* Debugs a response to the Transform Service
*/
public boolean debugTransformServiceResponsePreConsume(long requested, int id, String msg, Collection<String> debugLines)
{ {
pushMisc();
Frame frame = ThreadInfo.getStack().getLast();
frame.id = id;
boolean suppressFinish = id == -1 || requested == -1; boolean suppressFinish = id == -1 || requested == -1;
if (!suppressFinish) if (isEnabled())
{ {
frame.start = requested; pushMisc();
Frame frame = ThreadInfo.getStack().getLast();
frame.id = id;
if (!suppressFinish)
{
frame.start = requested;
}
debug(msg);
debugLines.forEach(line -> multiLineLog.debug(line));
}
return suppressFinish;
}
/**
* Debugs a response to the Transform Service
*/
public void debugTransformServiceResponsePostConsume(boolean suppressFinish)
{
if (isEnabled())
{
pop(Call.AVAILABLE, suppressFinish, true);
} }
debug(msg);
debug(sourceNodeRef.toString() + ' ' +contentHashcode);
pop(Call.AVAILABLE, suppressFinish, true);
} }
/** /**

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited * Copyright (C) 2005 - 2022 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -191,6 +191,7 @@ import org.junit.runners.Suite;
org.alfresco.service.cmr.repository.TransformationOptionLimitsTest.class, org.alfresco.service.cmr.repository.TransformationOptionLimitsTest.class,
org.alfresco.service.cmr.repository.TransformationOptionPairTest.class, org.alfresco.service.cmr.repository.TransformationOptionPairTest.class,
org.alfresco.repo.content.transform.TransformerConfigTestSuite.class, org.alfresco.repo.content.transform.TransformerConfigTestSuite.class,
org.alfresco.repo.content.transform.TransformerDebugTest.class,
org.alfresco.service.cmr.repository.TemporalSourceOptionsTest.class, org.alfresco.service.cmr.repository.TemporalSourceOptionsTest.class,
org.alfresco.repo.content.metadata.MetadataExtracterLimitsTest.class, org.alfresco.repo.content.metadata.MetadataExtracterLimitsTest.class,
org.alfresco.repo.content.caching.quota.StandardQuotaStrategyMockTest.class, org.alfresco.repo.content.caching.quota.StandardQuotaStrategyMockTest.class,

View File

@@ -0,0 +1,392 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.content.transform;
import com.google.common.collect.ImmutableMap;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.util.LogAdapter;
import org.apache.commons.logging.Log;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
public class TransformerDebugTest
{
public static final String RENDITION_2B = "renditionName1";
public static final String TRANSFORMER_A2B = "transformerA2B";
public static final String TRANSFORMER_A2C = "transformerA2C";
public static final String TRANSFORMER_C2B = "transformerC2B";
private TransformerDebug transformerDebug;
public static final String MIMETYPE_A = "mimetypeA";
public static final String MIMETYPE_A_EXT = "a";
public static final String MIMETYPE_B = "mimetypeB";
public static final String MIMETYPE_B_EXT = "bbb";
public static final String MIMETYPE_C = "mimetypeC";
public static final String MIMETYPE_C_EXT = "ccc";
public static final String MIMETYPE_DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
public static final String MIMETYPE_DOCX_EXT = "docx";
public static final String MIMETYPE_LONGER = "mimetypeLonger";
public static final String MIMETYPE_LONGER_EXT = "longer";
private static final Map<String, String> testMimetypeService = ImmutableMap.of(
MIMETYPE_A, MIMETYPE_A_EXT,
MIMETYPE_B, MIMETYPE_B_EXT,
MIMETYPE_C, MIMETYPE_C_EXT,
MIMETYPE_DOCX, MIMETYPE_DOCX_EXT,
MIMETYPE_LONGER, MIMETYPE_LONGER_EXT);
private StringBuilder singleLine;
private StringBuilder multiLine;
private AtomicReference<LogLevel> singleLineLogLevel = new AtomicReference<>();
private AtomicReference<LogLevel> multiLineLogLevel = new AtomicReference<>();
private Map<String, String> options;
@Mock
private NodeService nodeService;
private NodeRef sourceNodeRef = new NodeRef("workspace://SpacesStore/parent");
@Before
public void setUp()
{
MockitoAnnotations.initMocks(this);
TransformerDebug.Frame.reset();
singleLine = new StringBuilder();
multiLine = new StringBuilder();
singleLineLogLevel.set(LogLevel.DEBUG);
multiLineLogLevel.set(LogLevel.DEBUG);
transformerDebug = new TransformerDebug();
transformerDebug.setExtensionLookup(mimetype -> testMimetypeService.get(mimetype));
transformerDebug.setTransformerDebugLog(new DummyLog(multiLine, multiLineLogLevel));
transformerDebug.setTransformerLog(new DummyLog(singleLine, singleLineLogLevel));
transformerDebug.setNodeService(nodeService);
options = ImmutableMap.of(
"option1", "value1",
"option2", "value2");
doReturn("filename1.a").when(nodeService).getProperty(sourceNodeRef, ContentModel.PROP_NAME);
}
private static String getSanitisedActual(StringBuilder debug)
{
return debug.toString()
.replaceAll(" [\\d,]+ ms", " nn ms"); // the time can change
}
@Test
public void testSingleLevelTransformDebug()
{
String expectedSingleLine =
"DEBUG 0 a bbb INFO filename1.a 1 KB nn ms transformerA2B -- renditionName1 -- ";
String expectedMultiLine =
"DEBUG 0 a bbb filename1.a 1 KB -- renditionName1 -- transformerA2B\n" +
"DEBUG 0 option1=\"value1\"\n" +
"DEBUG 0 option2=\"value2\"\n" +
"DEBUG 0 workspace://SpacesStore/parent\n" +
"DEBUG 0 Finished in nn ms\n";
testSingleLevelTransform(expectedSingleLine, expectedMultiLine);
}
@Test
public void testSingleLevelTransformTrace()
{
singleLineLogLevel.set(LogLevel.TRACE);
multiLineLogLevel.set(LogLevel.TRACE);
String expectedSingleLine =
"DEBUG 0 a bbb INFO filename1.a 1 KB nn ms transformerA2B -- renditionName1 -- ";
String expectedMultiLine =
"TRACE 0 fromUrl1\n" +
"TRACE 0 mimetypeA mimetypeB\n" +
"DEBUG 0 a bbb filename1.a 1 KB -- renditionName1 -- transformerA2B\n" +
"DEBUG 0 option1=\"value1\"\n" +
"DEBUG 0 option2=\"value2\"\n" +
"DEBUG 0 workspace://SpacesStore/parent\n" +
"DEBUG 0 Finished in nn ms\n";
testSingleLevelTransform(expectedSingleLine, expectedMultiLine);
}
@Test
public void testSingleLevelTransformInfo()
{
singleLineLogLevel.set(LogLevel.INFO);
multiLineLogLevel.set(LogLevel.INFO);
String expectedSingleLine = "";
String expectedMultiLine = "";
testSingleLevelTransform(expectedSingleLine, expectedMultiLine);
}
private void testSingleLevelTransform(String expectedSingleLine, String expectedMultiLine)
{
transformerDebug.pushTransform(TRANSFORMER_A2B, "fromUrl1", MIMETYPE_A, MIMETYPE_B,
1024, options, RENDITION_2B, sourceNodeRef);
transformerDebug.popTransform();
assertEquals(expectedSingleLine, getSanitisedActual(singleLine));
assertEquals(expectedMultiLine, getSanitisedActual(multiLine));
}
@Test
public void testMultiLevelTransformDebug()
{
String expectedSingleLine =
"DEBUG 0 a bbb INFO filename1.a 1 KB nn ms transformerA2B -- renditionName1 -- ";
String expectedMultiLine =
"DEBUG 0 a bbb filename1.a 1 KB -- renditionName1 -- transformerA2B\n" +
"DEBUG 0 option1=\"value1\"\n" +
"DEBUG 0 option2=\"value2\"\n" +
"DEBUG 0 workspace://SpacesStore/parent\n" +
"DEBUG 0.1 a ccc filename1.a 1 KB transformerA2C\n" +
"DEBUG 0.2 ccc bbb filename1.a 1 KB transformerC2B\n" +
"DEBUG 0 Finished in nn ms\n";
testMultiLevelTransform(expectedSingleLine, expectedMultiLine);
}
@Test
public void testMultiLevelTransformTrace()
{
singleLineLogLevel.set(LogLevel.TRACE);
multiLineLogLevel.set(LogLevel.TRACE);
String expectedSingleLine =
"TRACE 0.1 a ccc INFO filename1.a 1 KB nn ms transformerA2C -- renditionName1 -- \n" +
"TRACE 0.2 ccc bbb INFO filename1.a 1 KB nn ms transformerC2B -- renditionName1 -- \n" +
"DEBUG 0 a bbb INFO filename1.a 1 KB nn ms transformerA2B -- renditionName1 -- ";
String expectedMultiLine =
"TRACE 0 fromUrl1\n" +
"TRACE 0 mimetypeA mimetypeB\n" +
"DEBUG 0 a bbb filename1.a 1 KB -- renditionName1 -- transformerA2B\n" +
"DEBUG 0 option1=\"value1\"\n" +
"DEBUG 0 option2=\"value2\"\n" +
"DEBUG 0 workspace://SpacesStore/parent\n" +
"TRACE 0.1 fromUrl1\n" +
"TRACE 0.1 mimetypeA mimetypeC\n" +
"DEBUG 0.1 a ccc filename1.a 1 KB transformerA2C\n" +
"TRACE 0.1 Finished in nn ms\n" +
"TRACE 0.2 fromUrl1\n" +
"TRACE 0.2 mimetypeC mimetypeB\n" +
"DEBUG 0.2 ccc bbb filename1.a 1 KB transformerC2B\n" +
"TRACE 0.2 Finished in nn ms\n" +
"DEBUG 0 Finished in nn ms\n";
testMultiLevelTransform(expectedSingleLine, expectedMultiLine);
}
@Test
public void testMultiLevelTransformInfo()
{
singleLineLogLevel.set(LogLevel.INFO);
multiLineLogLevel.set(LogLevel.INFO);
String expectedSingleLine = "";
String expectedMultiLine = "";
testMultiLevelTransform(expectedSingleLine, expectedMultiLine);
}
private void testMultiLevelTransform(String expectedSingleLine, String expectedMultiLine)
{
transformerDebug.pushTransform(TRANSFORMER_A2B, "fromUrl1", MIMETYPE_A, MIMETYPE_B,
1024, options, RENDITION_2B, sourceNodeRef);
transformerDebug.pushTransform(TRANSFORMER_A2C, "fromUrl1", MIMETYPE_A, MIMETYPE_C,
1024, options, RENDITION_2B, sourceNodeRef);
transformerDebug.popTransform();
transformerDebug.pushTransform(TRANSFORMER_C2B, "fromUrl1", MIMETYPE_C, MIMETYPE_B,
1024, options, RENDITION_2B, sourceNodeRef);
transformerDebug.popTransform();
transformerDebug.popTransform();
assertEquals(expectedSingleLine, getSanitisedActual(singleLine));
assertEquals(expectedMultiLine, getSanitisedActual(multiLine));
}
@Test
public void testReplaceWithMetadataExtensionIfEmbedOrExtract()
{
assertEquals("json", transformerDebug.replaceWithMetadataExtensionIfEmbedOrExtract(
"alfresco-metadata-extract", "jpeg", "targetExtension"));
assertEquals("jpeg", transformerDebug.replaceWithMetadataExtensionIfEmbedOrExtract(
"alfresco-metadata-embed", "jpeg", "targetExtension"));
assertEquals(MIMETYPE_DOCX_EXT, transformerDebug.replaceWithMetadataExtensionIfEmbedOrExtract(
MIMETYPE_DOCX, "jpeg", MIMETYPE_DOCX_EXT));
}
@Test
public void testGetMimetypeExt()
{
assertEquals(MIMETYPE_A_EXT +" ", transformerDebug.getMimetypeExt(MIMETYPE_A));
assertEquals(MIMETYPE_B_EXT +" ", transformerDebug.getMimetypeExt(MIMETYPE_B));
assertEquals(MIMETYPE_DOCX_EXT +" ", transformerDebug.getMimetypeExt(MIMETYPE_DOCX));
assertEquals(MIMETYPE_LONGER_EXT+" ", transformerDebug.getMimetypeExt(MIMETYPE_LONGER)); // not padded to 4 spaces
assertEquals("unknown" +" ", transformerDebug.getMimetypeExt("unknown")); // not padded
assertEquals("x" +" ", transformerDebug.getMimetypeExt("x")); // not padded
}
@Test
public void testSpaces()
{
assertEquals("", transformerDebug.spaces(-1));
assertEquals("", transformerDebug.spaces(0));
assertEquals(" ", transformerDebug.spaces(1));
assertEquals(" ", transformerDebug.spaces(3));
assertEquals(" ", transformerDebug.spaces(5));
}
@Test
public void testMs()
{
assertEquals("-1 ms", transformerDebug.ms(-1));
assertEquals("0 ms", transformerDebug.ms(0));
assertEquals("1 ms", transformerDebug.ms(1));
assertEquals("2 ms", transformerDebug.ms(2));
assertEquals("123 ms", transformerDebug.ms(123));
assertEquals("1,234 ms", transformerDebug.ms(1234));
assertEquals("3,600,000 ms", transformerDebug.ms(3600000));
}
@Test
public void testFileSize()
{
assertEquals("unlimited", transformerDebug.fileSize(-1));
assertEquals("0 bytes", transformerDebug.fileSize(0));
assertEquals("1 byte", transformerDebug.fileSize(1));
assertEquals("2 bytes", transformerDebug.fileSize(2));
assertEquals("2 KB", transformerDebug.fileSize(2L*1024));
assertEquals("3 MB", transformerDebug.fileSize(3L*1024*1024));
assertEquals("4 GB", transformerDebug.fileSize(4L*1024*1024*1024));
assertEquals("5 TB", transformerDebug.fileSize(5L*1024*1024*1024*1024));
assertEquals("1.4 KB", transformerDebug.fileSize(1L*1024 + 511));
assertEquals("1.5 KB", transformerDebug.fileSize(1L*1024 + 512));
assertEquals("1.9 KB", transformerDebug.fileSize(2L*1024 - 1));
assertEquals("2.9 MB", transformerDebug.fileSize(3L*1024*1024 - 1));
assertEquals("3.9 GB", transformerDebug.fileSize(4L*1024*1024*1024 - 1));
assertEquals("4.9 TB", transformerDebug.fileSize(5L*1024*1024*1024*1024 - 1));
}
@Test
public void testGetRenditionName()
{
assertEquals("", transformerDebug.getRenditionName(null));
assertEquals("-- doclib -- ", transformerDebug.getRenditionName("doclib"));
assertEquals("-- metadataExtract -- ", transformerDebug.getRenditionName("transform:alfresco-metadata-extract"));
assertEquals("-- metadataEmbed -- ", transformerDebug.getRenditionName("transform:alfresco-metadata-embed"));
assertEquals("-- transform:customTransform -- ", transformerDebug.getRenditionName("transform:customTransform"));
}
@Test
public void testGetTransformName()
{
assertEquals(null, transformerDebug.getTransformName(null));
assertEquals(null, transformerDebug.getTransformName("doclib"));
assertEquals("alfresco-metadata-extract", transformerDebug.getTransformName("transform:alfresco-metadata-extract"));
assertEquals("alfresco-metadata-embed", transformerDebug.getTransformName("transform:alfresco-metadata-embed"));
assertEquals("customTransform", transformerDebug.getTransformName("transform:customTransform"));
}
private enum LogLevel
{
INFO, DEBUG, TRACE;
boolean isSet(LogLevel levelSet)
{
return levelSet != null && this.compareTo(levelSet) <= 0;
}
}
private class DummyLog extends LogAdapter
{
private final StringBuilder stringBuilder;
private final AtomicReference<LogLevel> logLevel;
public DummyLog(StringBuilder stringBuilder, AtomicReference<LogLevel> logLevel)
{
super(null);
this.stringBuilder = stringBuilder;
this.logLevel = logLevel;
}
@Override
public boolean isDebugEnabled()
{
return LogLevel.DEBUG.isSet(logLevel.get());
}
@Override
public boolean isTraceEnabled()
{
return LogLevel.TRACE.isSet(logLevel.get());
}
@Override
public void debug(Object message, Throwable throwable)
{
if (isDebugEnabled())
{
append(message, throwable, "DEBUG ");
}
}
@Override
public void trace(Object message, Throwable throwable)
{
if (isTraceEnabled())
{
append(message, throwable, "TRACE ");
}
}
private void append(Object message, Throwable throwable, String prefix)
{
if (stringBuilder.length() > 0)
{
stringBuilder.append('\n');
}
stringBuilder.append(prefix).append(message);
if (throwable != null)
{
stringBuilder.append("\n ").append(throwable.getMessage());
}
}
}
}