From dc916ecdd6a699e4a69b6f4043dbf5bcdf1fbd77 Mon Sep 17 00:00:00 2001 From: "Brian M. Long" Date: Wed, 7 Aug 2024 18:05:43 -0400 Subject: [PATCH] version upgrade; minor refactor --- metadata.keystore | Bin 0 -> 409 bytes pom.xml | 23 +++++++--- rad.sh | 2 +- .../alfresco/annotations/Asynchronous.java | 10 ++++ .../alfresco/annotations/Authorizable.java | 8 ++++ .../alfresco/annotations/Authorized.java | 23 ++++++++++ .../annotations/AuthorizedAsSystem.java | 8 ++++ .../IfChildAssociationIsPrimary.java | 5 ++ .../alfresco/annotations/IfNodeExists.java | 6 +++ .../alfresco/annotations/IfNodeHasAspect.java | 12 +++++ .../alfresco/annotations/IfNodeOfType.java | 12 +++++ .../alfresco/annotations/IfNotNull.java | 4 ++ ...Synchronized.java => JobSynchronized.java} | 2 +- .../alfresco/annotations/Threaded.java | 28 ++++++++++++ .../annotations/TransactionalRetryable.java | 31 +++++++++++-- .../aspect/AbstractMethodAspect.java | 33 +++++++++++++- .../aspect/AbstractWarnOnceService.java | 2 +- .../annotations/aspect/AsyncAspect.java | 7 ++- .../annotations/aspect/AuthorizedAspect.java | 10 ++-- .../aspect/ChildIsPrimaryAspect.java | 6 ++- ...hronizedAspect.java => JobLockAspect.java} | 35 +++++++------- .../annotations/aspect/NodeAspectAspect.java | 43 +++--------------- .../annotations/aspect/NodeTypeAspect.java | 42 ++--------------- .../annotations/aspect/NotNullAspect.java | 7 ++- .../aspect/OperableNodeAspect.java | 6 ++- .../annotations/aspect/QNameBasedAspect.java | 37 +++++++++++++++ .../aspect/RetryingTransactionAspect.java | 18 +++++++- .../annotations/aspect/ThreadedAspect.java | 18 ++++++-- .../impl/AlfrescoTransactionManager.java | 3 ++ .../service/impl/MqAsyncService.java | 18 +++----- .../service/impl/ThreadPoolAsyncService.java | 3 +- src/main/resources/META-INF/aop.xml | 2 +- .../log4j2.properties | 2 + .../module.properties | 7 ++- ...izedTest.java => JobSynchronizedTest.java} | 29 +++++++++--- .../alfresco/extension/debug-log4j.properties | 3 ++ .../extension/debug-log4j2.properties | 12 +++++ 37 files changed, 375 insertions(+), 142 deletions(-) create mode 100644 metadata.keystore rename src/main/java/com/inteligr8/alfresco/annotations/{ClusterSynchronized.java => JobSynchronized.java} (91%) rename src/main/java/com/inteligr8/alfresco/annotations/aspect/{ClusterSynchronizedAspect.java => JobLockAspect.java} (61%) create mode 100644 src/main/resources/alfresco/module/com.inteligr8.alfresco.annotations-platform-module/log4j2.properties rename src/test/java/com/inteligr8/alfresco/annotations/{ClusterSynchronizedTest.java => JobSynchronizedTest.java} (69%) create mode 100644 src/test/resources/alfresco/extension/debug-log4j2.properties diff --git a/metadata.keystore b/metadata.keystore new file mode 100644 index 0000000000000000000000000000000000000000..2c2a1d961273b300b1852d37d43e21676277feb5 GIT binary patch literal 409 zcmXqLVw}pv$ZXKWXwSx})#lOmotKfFaX}NK0ZS934p3MFh*eOfM1fL*Kw(}W=49iB z>f+&IWL?m>*`RR)vJlgP#sw^ma}6428Kl8YVdXW5G_XK$c?`5!L=N{!9_e#B605cle)lJ&&JDO?$*;d>UWc8v;Y=9$(Y z?eMAldWXglLl*;ixMMg)429$b7;+g>8A=!u8B%~4NE;|36o?v%un2`@=B6qbnj0A# zm>QXw8(SC}8Tc9)8t}rM#>B|Vz@jjH<;y>ndk;UBxGpCCrcU6NQrG?ks@Yqco;K

dmVXfd literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index 6662b2c..eb0a3ef 100644 --- a/pom.xml +++ b/pom.xml @@ -10,6 +10,14 @@ Annotations ACS Platform Module A module to support annotation-based development for Alfresco Content Services modules. + https://bitbucket.org/inteligr8/annotations-platform-module + + + + GNU GENERAL PUBLIC LICENSE, Version 3, 29 June 2007 + https://www.gnu.org/licenses/lgpl-3.0.txt + + scm:git:https://bitbucket.org/inteligr8/annotations-platform-module.git @@ -34,9 +42,10 @@ 8 8 - 4.2.0 - 6.2.0-ga - 1.9.4 + 4.8.0 + 7.4.2 + 22.22 + 1.9.19 -javaagent:/var/lib/tomcat/dev/lib/aspectjweaver-${aspectj.version}.jar @@ -63,7 +72,7 @@ com.inteligr8.alfresco aspectj-platform-module - 1.0-SNAPSHOT + 1.0.0 @@ -77,11 +86,11 @@ - com.inteligr8.ootbee:beedk-acs-platform-self-rad-tile:[1.0.0,1.1.0) + com.inteligr8.ootbee:beedk-acs-platform-self-rad-tile:[1.1.0,1.2.0) - com.inteligr8.ootbee:beedk-acs-platform-module-tile:[1.0.0,1.1.0) + com.inteligr8.ootbee:beedk-acs-platform-module-tile:[1.1.0,1.2.0) - com.inteligr8.ootbee:beedk-acs-platform-self-it-tile:[1.0.0,1.1.0) + com.inteligr8.ootbee:beedk-acs-platform-self-it-tile:[1.1.0,1.2.0) diff --git a/rad.sh b/rad.sh index aa08375..3c7c2fa 100644 --- a/rad.sh +++ b/rad.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh discoverArtifactId() { ARTIFACT_ID=`mvn -q -Dexpression=project.artifactId -DforceStdout help:evaluate | sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g'` diff --git a/src/main/java/com/inteligr8/alfresco/annotations/Asynchronous.java b/src/main/java/com/inteligr8/alfresco/annotations/Asynchronous.java index cd7b3c2..5a5c321 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/Asynchronous.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/Asynchronous.java @@ -5,10 +5,20 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation tells the framework to execute the annotated method + * asynchronously. The execution may be performed any number of ways, + * including a threaded execution or through a queuing service. + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Asynchronous { + /** + * Whether or not the execution is guaranteed. + * + * @return `true` if guaranteed; `false` otherwise + */ boolean durable() default true; } diff --git a/src/main/java/com/inteligr8/alfresco/annotations/Authorizable.java b/src/main/java/com/inteligr8/alfresco/annotations/Authorizable.java index 13c2d82..c2a1944 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/Authorizable.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/Authorizable.java @@ -1,7 +1,15 @@ package com.inteligr8.alfresco.annotations; +/** + * This interface provides a way to specify a user for expected authorizations. + * + * @see com.inteligr8.alfresco.annotations.Authorized + */ public interface Authorizable { + /** + * @return An ACS user ID. + */ String authorizeAsUser(); } diff --git a/src/main/java/com/inteligr8/alfresco/annotations/Authorized.java b/src/main/java/com/inteligr8/alfresco/annotations/Authorized.java index 8af3698..8c3b925 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/Authorized.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/Authorized.java @@ -5,10 +5,33 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation tells the framework to execute the annotated method + * inside an ACS authorized context. This is how the execution can be elevated + * to a service account or de-escalated to a user account. + * + * If the authorization is expected to be the same (the same user), then + * another layer of authorization is **not** added. + * + * Use the Authorizable interface to provide a dynamic user ID for the + * authorization context. + * + * @see com.inteligr8.alfresco.annotations.Authorizable + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Authorized { + /** + * The user ID to use for the authorization context. + * + * It is important to note that if the Authorizable interface is + * implemented, then the value returned from its method will take + * precedence over this one. This capability is useful for to support + * dynamic user authorization contexts. + * + * @return An ACS user ID; empty will be treated as `system`. + */ String value() default ""; } diff --git a/src/main/java/com/inteligr8/alfresco/annotations/AuthorizedAsSystem.java b/src/main/java/com/inteligr8/alfresco/annotations/AuthorizedAsSystem.java index 7ddecac..5e38357 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/AuthorizedAsSystem.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/AuthorizedAsSystem.java @@ -5,6 +5,14 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation tells the framework to execute the annotated method + * inside an ACS `system` authorized context. This is the highest privileged + * execution. + * + * If the authorization is expected to be the same (remains `system`), then + * another layer of authorization is **not** added. + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface AuthorizedAsSystem { diff --git a/src/main/java/com/inteligr8/alfresco/annotations/IfChildAssociationIsPrimary.java b/src/main/java/com/inteligr8/alfresco/annotations/IfChildAssociationIsPrimary.java index 97a8db1..deb3287 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/IfChildAssociationIsPrimary.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/IfChildAssociationIsPrimary.java @@ -5,6 +5,11 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation tells the framework to skip execution if the annotated + * parameter or any annotated method parameter is a child association that is + * not primary. + */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, diff --git a/src/main/java/com/inteligr8/alfresco/annotations/IfNodeExists.java b/src/main/java/com/inteligr8/alfresco/annotations/IfNodeExists.java index cdf27d9..e86c15f 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/IfNodeExists.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/IfNodeExists.java @@ -5,6 +5,12 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation tells the framework to skip execution if the annotated + * parameter or any annotated method parameter is a node reference and it does + * not exist. Unless cached, this will result in the framework consulting with + * the database. + */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, diff --git a/src/main/java/com/inteligr8/alfresco/annotations/IfNodeHasAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/IfNodeHasAspect.java index 723530b..c86a17f 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/IfNodeHasAspect.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/IfNodeHasAspect.java @@ -5,6 +5,15 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation tells the framework to skip execution if the annotated + * parameter or any annotated method parameter is a node reference and it does + * not have the specified aspect. Unless cached, this will result in the + * framework consulting with the database. + * + * This includes support for checking the child node reference of a + * parent-child association and both the source/target of a peer association. + */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, @@ -12,6 +21,9 @@ import java.lang.annotation.Target; }) public @interface IfNodeHasAspect { + /** + * @return An ACS aspect in the Alfresco QName prefixed format (e.g. `cm:auditable`). + */ String aspect() default ""; } diff --git a/src/main/java/com/inteligr8/alfresco/annotations/IfNodeOfType.java b/src/main/java/com/inteligr8/alfresco/annotations/IfNodeOfType.java index 2f03e1b..f403795 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/IfNodeOfType.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/IfNodeOfType.java @@ -5,6 +5,15 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation tells the framework to skip execution if the annotated + * parameter or any annotated method parameter is a node reference and it is + * not of the specified type. Unless cached, this will result in the framework + * consulting with the database. + * + * This includes support for checking the child node reference of a + * parent-child association and both the source/target of a peer association. + */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, @@ -12,6 +21,9 @@ import java.lang.annotation.Target; }) public @interface IfNodeOfType { + /** + * @return An ACS node type in the Alfresco QName prefixed format (e.g. `cm:content`). + */ String type() default ""; } diff --git a/src/main/java/com/inteligr8/alfresco/annotations/IfNotNull.java b/src/main/java/com/inteligr8/alfresco/annotations/IfNotNull.java index e03e5ca..c37b79e 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/IfNotNull.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/IfNotNull.java @@ -5,6 +5,10 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation tells the framework to skip execution if the annotated + * parameter or any annotated method parameter is `null`. + */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, diff --git a/src/main/java/com/inteligr8/alfresco/annotations/ClusterSynchronized.java b/src/main/java/com/inteligr8/alfresco/annotations/JobSynchronized.java similarity index 91% rename from src/main/java/com/inteligr8/alfresco/annotations/ClusterSynchronized.java rename to src/main/java/com/inteligr8/alfresco/annotations/JobSynchronized.java index 775f864..c718258 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/ClusterSynchronized.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/JobSynchronized.java @@ -7,7 +7,7 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) -public @interface ClusterSynchronized { +public @interface JobSynchronized { String value() default ""; diff --git a/src/main/java/com/inteligr8/alfresco/annotations/Threaded.java b/src/main/java/com/inteligr8/alfresco/annotations/Threaded.java index 438ab56..b243d3a 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/Threaded.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/Threaded.java @@ -5,20 +5,48 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation tells the framework to execute the annotated method inside a + * pool of threads. + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Threaded { + /** + * @return A name for the thread pool. + */ String name() default ""; + /** + * @return A number of threads to execute. + */ int threads() default 1; + /** + * @return A maximum number of threads to execute at any one time; the thread pool size. + */ int concurrency() default 0; + /** + * @return A Java thread priority for all the threads. + */ int priority() default Thread.NORM_PRIORITY; + /** + * Whether or not the calling thread should wait for all the threads to complete. + * + * @return `true` to wait; `false` to return immediately. + */ boolean join() default false; + /** + * How long the calling thread should wait before returning. If a timeout + * is reached, a TimeoutException will be thrown. If this is not desired, + * then `join()` should return `false`. + * + * @return A number of milliseconds to wait; 0 waits indefinitely + */ long joinWaitMillis() default 0L; } diff --git a/src/main/java/com/inteligr8/alfresco/annotations/TransactionalRetryable.java b/src/main/java/com/inteligr8/alfresco/annotations/TransactionalRetryable.java index 1d2aa79..2823e66 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/TransactionalRetryable.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/TransactionalRetryable.java @@ -5,16 +5,41 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.alfresco.repo.transaction.RetryingTransactionHelper; + +/** + * This annotation tells the framework to wrap the annotated method inside an + * ACS API retryable transaction. This may be used in conjunction with the + * Spring Transactional annotation. + * + * @see org.springframework.transaction.annotation.Transactional + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface TransactionalRetryable { + /** + * @return A number of retries; -1 for ACS API default (unlimited). + * @see RetryingTransactionHelper#setMaxRetries(int) + */ int maxRetries() default -1; - + + /** + * @return A minimum number of milliseconds to wait between retries; -1 for ACS API default (200 ms). + * @see RetryingTransactionHelper#setMinRetryWaitMs(int) + */ int minRetryWaitInMillis() default -1; - + + /** + * @return A maximum number of milliseconds to wait between retries; -1 for ACS API default (2000 ms). + * @see RetryingTransactionHelper#setMaxRetryWaitMs(int) + */ int maxRetryWaitInMillis() default -1; - + + /** + * @return A number of milliseconds to progressively add to the wait after each attempt; -1 for ACS API default (100 ms). + * @see RetryingTransactionHelper#setRetryWaitIncrementMs(int) + */ int incRetryWaitInMillis() default -1; } diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/AbstractMethodAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/AbstractMethodAspect.java index 60fcfbb..000c0d9 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/AbstractMethodAspect.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/AbstractMethodAspect.java @@ -2,11 +2,21 @@ package com.inteligr8.alfresco.annotations.aspect; import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import org.apache.commons.lang3.tuple.Pair; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public class AbstractMethodAspect extends AbstractWarnOnceService { +public abstract class AbstractMethodAspect extends AbstractWarnOnceService { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private Set> warned = new HashSet<>(); protected A getAnnotation(ProceedingJoinPoint joinPoint, Class annotationClass, boolean warnReturn, boolean warnThrows) { Method method = this.getMethod(joinPoint, annotationClass, warnReturn, warnThrows); @@ -49,5 +59,26 @@ public class AbstractMethodAspect extends AbstractWarnOnce return obj.toString(); } } + + protected boolean validate(ProceedingJoinPoint joinPoint, Class annotationClass, + Collection> ignoredAnnotationClasses, Collection> disallowedAnnotationClasses) { + Method method = this.getMethod(joinPoint, annotationClass, false, false); + + for (Class a : ignoredAnnotationClasses) { + if (method.isAnnotationPresent(a)) { + if (this.warned.add(Pair.of(a.getName(), annotationClass.getName()))) + this.logger.warn("@{} cannot be used on the same method as @{}; ignoring annotation", a.getSimpleName(), annotationClass.getSimpleName()); + } + } + + for (Class a : disallowedAnnotationClasses) { + if (method.isAnnotationPresent(a)) { + this.logger.error("@{} cannot be used on the same method as @{}", a.getSimpleName(), annotationClass.getSimpleName()); + return false; + } + } + + return true; + } } diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/AbstractWarnOnceService.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/AbstractWarnOnceService.java index d14e6f0..f0c7199 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/AbstractWarnOnceService.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/AbstractWarnOnceService.java @@ -6,7 +6,7 @@ import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class AbstractWarnOnceService { +public abstract class AbstractWarnOnceService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/AsyncAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/AsyncAspect.java index cd653c3..f882b99 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/AsyncAspect.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/AsyncAspect.java @@ -14,10 +14,13 @@ import org.springframework.beans.factory.annotation.Qualifier; import com.inteligr8.alfresco.annotations.Asynchronous; import com.inteligr8.alfresco.annotations.service.AsyncService; +/** + * This aspect implements the @Asynchronous annotation. + * + * @see com.inteligr8.alfresco.annotations.Asynchronous + */ @Aspect @DeclarePrecedence("com.inteligr8.alfresco.annotations.aspect.AsyncAspect, *") -//@Order(Ordered.HIGHEST_PRECEDENCE + Byte.MAX_VALUE) -//@Component public class AsyncAspect extends AbstractMethodAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/AuthorizedAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/AuthorizedAspect.java index 4d2ba02..f887e61 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/AuthorizedAspect.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/AuthorizedAspect.java @@ -18,10 +18,14 @@ import com.inteligr8.alfresco.annotations.Authorizable; import com.inteligr8.alfresco.annotations.Authorized; import com.inteligr8.alfresco.annotations.AuthorizedAsSystem; +/** + * This aspect implements the Authorized and AuthorizedAsSystem annotations. + * + * @see com.inteligr8.alfresco.annotations.Authorized + * @see com.inteligr8.alfresco.annotations.AuthorizedAsSystem + */ @Aspect @DeclarePrecedence("com.inteligr8.alfresco.annotations.aspect.AuthorizedAspect, com.inteligr8.alfresco.annotations.aspect.RetryingTransactionAspect") -//@Order(Ordered.HIGHEST_PRECEDENCE + Short.MAX_VALUE) -//@Component public class AuthorizedAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -73,7 +77,7 @@ public class AuthorizedAspect { Authorized runAsAnnotation = method.getAnnotation(Authorized.class); String runAs = StringUtils.trimToNull(runAsAnnotation.value()); - if (runAs != null) { + if (runAs != null && runAs.length() > 0) { this.logger.trace("The @Authorized method '{}' must run as: {}", method, runAs); return runAs; } diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/ChildIsPrimaryAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/ChildIsPrimaryAspect.java index 3a54f32..d793356 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/ChildIsPrimaryAspect.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/ChildIsPrimaryAspect.java @@ -12,8 +12,12 @@ import org.slf4j.LoggerFactory; import com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary; +/** + * This aspect implements the IfChildAssociationIsPrimary annotation. + * + * @see com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary + */ @Aspect -//@Component public class ChildIsPrimaryAspect extends AbstractMethodOrParameterAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/ClusterSynchronizedAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/JobLockAspect.java similarity index 61% rename from src/main/java/com/inteligr8/alfresco/annotations/aspect/ClusterSynchronizedAspect.java rename to src/main/java/com/inteligr8/alfresco/annotations/aspect/JobLockAspect.java index 2d48225..f80f3bb 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/ClusterSynchronizedAspect.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/JobLockAspect.java @@ -14,13 +14,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import com.inteligr8.alfresco.annotations.ClusterSynchronized; +import com.inteligr8.alfresco.annotations.JobSynchronized; +/** + * This aspect implements the JobSynchronized annotation. + * + * @see com.inteligr8.alfresco.annotations.JobSynchronized + */ @Aspect -@DeclarePrecedence("com.inteligr8.alfresco.annotations.aspect.RetryingTransactionAspect, com.inteligr8.alfresco.annotations.aspect.ClusterSynchronizedAspect") -//@Component -//@Order(Ordered.LOWEST_PRECEDENCE - Byte.MAX_VALUE) -public class ClusterSynchronizedAspect extends AbstractMethodAspect { +@DeclarePrecedence("com.inteligr8.alfresco.annotations.aspect.RetryingTransactionAspect, com.inteligr8.alfresco.annotations.aspect.JobLockAspect") +public class JobLockAspect extends AbstractMethodAspect { private static final String NS = "http://inteligr8.com/alfresco/model"; private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -28,33 +31,33 @@ public class ClusterSynchronizedAspect extends AbstractMethodAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -128,36 +128,5 @@ public class NodeAspectAspect extends QNameBasedAspect { } }); } - - private Collection extractNodeRefs(Object obj) { - if (obj instanceof NodeRef) { - NodeRef nodeRef = (NodeRef) obj; - return Collections.singleton(nodeRef); - } else if (obj instanceof ChildAssociationRef) { - ChildAssociationRef childAssocRef = (ChildAssociationRef) obj; - return Collections.singleton(childAssocRef.getChildRef()); - } else if (obj instanceof AssociationRef) { - AssociationRef assocRef = (AssociationRef) obj; - return Arrays.asList(assocRef.getSourceRef(), assocRef.getTargetRef()); - } else if (obj instanceof Collection) { - Set nodeRefs = new LinkedHashSet<>(); - for (Object o : ((Collection) obj)) { - Collection subNodeRefs = this.extractNodeRefs(o); - if (subNodeRefs != null) - nodeRefs.addAll(subNodeRefs); - } - return nodeRefs; - } else if (obj instanceof Object[]) { - Set nodeRefs = new LinkedHashSet<>(); - for (Object o : ((Object[]) obj)) { - Collection subNodeRefs = this.extractNodeRefs(o); - if (subNodeRefs != null) - nodeRefs.addAll(subNodeRefs); - } - return nodeRefs; - } else { - return null; - } - } } diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/NodeTypeAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/NodeTypeAspect.java index a89eb04..c631539 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/NodeTypeAspect.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/NodeTypeAspect.java @@ -1,16 +1,11 @@ package com.inteligr8.alfresco.annotations.aspect; import java.lang.reflect.Method; -import java.util.Arrays; import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; import java.util.Set; import org.alfresco.service.cmr.dictionary.ClassDefinition; import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.AssociationRef; -import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.QName; @@ -28,9 +23,13 @@ import org.springframework.beans.factory.annotation.Value; import com.inteligr8.alfresco.annotations.IfNodeOfType; import com.inteligr8.alfresco.annotations.NodeTypeConstrainable; +/** + * This aspect implements the IfNodeOfType annotation. + * + * @see com.inteligr8.alfresco.annotations.IfNodeOfType + */ @Aspect @DeclarePrecedence("com.inteligr8.alfresco.annotations.aspect.RetryingTransactionAspect, com.inteligr8.alfresco.annotations.aspect.NodeTypeAspect") -//@Component public class NodeTypeAspect extends QNameBasedAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -128,36 +127,5 @@ public class NodeTypeAspect extends QNameBasedAspect { } }); } - - private Collection extractNodeRefs(Object obj) { - if (obj instanceof NodeRef) { - NodeRef nodeRef = (NodeRef) obj; - return Collections.singleton(nodeRef); - } else if (obj instanceof ChildAssociationRef) { - ChildAssociationRef childAssocRef = (ChildAssociationRef) obj; - return Collections.singleton(childAssocRef.getChildRef()); - } else if (obj instanceof AssociationRef) { - AssociationRef assocRef = (AssociationRef) obj; - return Arrays.asList(assocRef.getSourceRef(), assocRef.getTargetRef()); - } else if (obj instanceof Collection) { - Set nodeRefs = new LinkedHashSet<>(); - for (Object o : ((Collection) obj)) { - Collection subNodeRefs = this.extractNodeRefs(o); - if (subNodeRefs != null) - nodeRefs.addAll(subNodeRefs); - } - return nodeRefs; - } else if (obj instanceof Object[]) { - Set nodeRefs = new LinkedHashSet<>(); - for (Object o : ((Object[]) obj)) { - Collection subNodeRefs = this.extractNodeRefs(o); - if (subNodeRefs != null) - nodeRefs.addAll(subNodeRefs); - } - return nodeRefs; - } else { - return null; - } - } } diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/NotNullAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/NotNullAspect.java index 3a13747..b32eb20 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/NotNullAspect.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/NotNullAspect.java @@ -12,9 +12,12 @@ import org.slf4j.LoggerFactory; import com.inteligr8.alfresco.annotations.IfNotNull; +/** + * This aspect implements the IfNotNull annotation. + * + * @see com.inteligr8.alfresco.annotations.IfNotNull + */ @Aspect -//@Order(Ordered.HIGHEST_PRECEDENCE + 64) -//@Component public class NotNullAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/OperableNodeAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/OperableNodeAspect.java index c477621..73130b4 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/OperableNodeAspect.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/OperableNodeAspect.java @@ -22,9 +22,13 @@ import org.springframework.beans.factory.annotation.Autowired; import com.inteligr8.alfresco.annotations.IfNodeExists; +/** + * This aspect implements the IfNodeExists annotation. + * + * @see com.inteligr8.alfresco.annotations.IfNodeExists + */ @Aspect @DeclarePrecedence("com.inteligr8.alfresco.annotations.aspect.RetryingTransactionAspect, com.inteligr8.alfresco.annotations.aspect.OperableNodeAspect") -//@Component public class OperableNodeAspect extends AbstractMethodOrParameterAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/QNameBasedAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/QNameBasedAspect.java index 2a944e7..fb66d38 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/QNameBasedAspect.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/QNameBasedAspect.java @@ -1,14 +1,20 @@ package com.inteligr8.alfresco.annotations.aspect; import java.lang.annotation.Annotation; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import javax.annotation.PostConstruct; import org.alfresco.repo.cache.DefaultSimpleCache; import org.alfresco.repo.cache.SimpleCache; +import org.alfresco.service.cmr.repository.AssociationRef; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QNamePattern; @@ -76,6 +82,37 @@ public abstract class QNameBasedAspect extends AbstractMet } } + protected Collection extractNodeRefs(Object obj) { + if (obj instanceof NodeRef) { + NodeRef nodeRef = (NodeRef) obj; + return Collections.singleton(nodeRef); + } else if (obj instanceof ChildAssociationRef) { + ChildAssociationRef childAssocRef = (ChildAssociationRef) obj; + return Collections.singleton(childAssocRef.getChildRef()); + } else if (obj instanceof AssociationRef) { + AssociationRef assocRef = (AssociationRef) obj; + return Arrays.asList(assocRef.getSourceRef(), assocRef.getTargetRef()); + } else if (obj instanceof Collection) { + Set nodeRefs = new LinkedHashSet<>(); + for (Object o : ((Collection) obj)) { + Collection subNodeRefs = this.extractNodeRefs(o); + if (subNodeRefs != null) + nodeRefs.addAll(subNodeRefs); + } + return nodeRefs; + } else if (obj instanceof Object[]) { + Set nodeRefs = new LinkedHashSet<>(); + for (Object o : ((Object[]) obj)) { + Collection subNodeRefs = this.extractNodeRefs(o); + if (subNodeRefs != null) + nodeRefs.addAll(subNodeRefs); + } + return nodeRefs; + } else { + return null; + } + } + public interface QNameBasedCallback { diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/RetryingTransactionAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/RetryingTransactionAspect.java index d5a6233..5de69e4 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/RetryingTransactionAspect.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/RetryingTransactionAspect.java @@ -21,10 +21,24 @@ import org.springframework.transaction.annotation.Transactional; import com.inteligr8.alfresco.annotations.TransactionalRetryable; +/** + * This aspect implements the @Transactional and @TransactionalRetryable + * annotations. + * + * Most notably, it implements the Spring @Transactional annotation, so it + * works when used within ACS modules. Both could be used; or just either one. + * Each situation has a different meaning. + * + * - Without @TransactionalRetryable, it will not automatically retry due to + * expected concurrency issues. + * - Without @Transactional, it will be like a readonly + * @Transactional(SUPPORTS) + * + * @see org.springframework.transaction.annotation.Transactional + * @see com.inteligr8.alfresco.annotations.TransactionalRetryable + */ @Aspect @DeclarePrecedence("com.inteligr8.alfresco.annotations.aspect.AuthorizedAspect, com.inteligr8.alfresco.annotations.aspect.RetryingTransactionAspect") -//@Component -//@Order(Ordered.LOWEST_PRECEDENCE - Short.MAX_VALUE) public class RetryingTransactionAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/src/main/java/com/inteligr8/alfresco/annotations/aspect/ThreadedAspect.java b/src/main/java/com/inteligr8/alfresco/annotations/aspect/ThreadedAspect.java index 2521f02..a2e0f03 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/aspect/ThreadedAspect.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/aspect/ThreadedAspect.java @@ -9,6 +9,7 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.function.Supplier; import org.aspectj.lang.ProceedingJoinPoint; @@ -24,10 +25,13 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.inteligr8.alfresco.annotations.Threadable; import com.inteligr8.alfresco.annotations.Threaded; +/** + * This aspect implements the @Threaded annotation. + * + * @see com.inteligr8.alfresco.annotations.Threaded + */ @Aspect @DeclarePrecedence("com.inteligr8.alfresco.annotations.aspect.AsyncAspect, com.inteligr8.alfresco.annotations.aspect.ThreadedAspect, *") -//@Order(Ordered.HIGHEST_PRECEDENCE + Byte.MAX_VALUE) -//@Component public class ThreadedAspect extends AbstractMethodAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -53,6 +57,7 @@ public class ThreadedAspect extends AbstractMethodAspect { this.logger.trace("threaded({})", joinPoint); Threaded threaded = this.getAnnotation(joinPoint, Threaded.class, true, true); + MergedThreadConfiguration threadConfig = new MergedThreadConfiguration(joinPoint, threaded); ThreadFactoryBuilder tfbuilder = new ThreadFactoryBuilder() @@ -86,13 +91,16 @@ public class ThreadedAspect extends AbstractMethodAspect { if (threaded.join()) { long waitMillis = threaded.joinWaitMillis() == 0L ? 300000L : threaded.joinWaitMillis(); - do { + while (true) { this.logger.debug("Blocking this thread until subthreads finish: {}", Thread.currentThread().getId()); - if (threadExecutor.awaitTermination(waitMillis, TimeUnit.MILLISECONDS)) { + if (!threadExecutor.awaitTermination(waitMillis, TimeUnit.MILLISECONDS)) { + if (threaded.joinWaitMillis() > 0L) + throw new TimeoutException(); + } else { this.logger.trace("Subthreads finished; unblocking this thread: {}", Thread.currentThread().getId()); break; } - } while (threaded.joinWaitMillis() == 0L); + } this.logger.debug("Subthreads running: {}; unblocking this thread: {}", threadExecutor.getActiveCount(), Thread.currentThread().getId()); } diff --git a/src/main/java/com/inteligr8/alfresco/annotations/service/impl/AlfrescoTransactionManager.java b/src/main/java/com/inteligr8/alfresco/annotations/service/impl/AlfrescoTransactionManager.java index f0f777f..4d8eb31 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/service/impl/AlfrescoTransactionManager.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/service/impl/AlfrescoTransactionManager.java @@ -17,6 +17,9 @@ import org.alfresco.service.transaction.TransactionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +/** + * This bean implements a standard TransactionManager for ACS. + */ @Component public class AlfrescoTransactionManager implements TransactionManager { diff --git a/src/main/java/com/inteligr8/alfresco/annotations/service/impl/MqAsyncService.java b/src/main/java/com/inteligr8/alfresco/annotations/service/impl/MqAsyncService.java index 9bf5c21..14f8fa4 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/service/impl/MqAsyncService.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/service/impl/MqAsyncService.java @@ -30,7 +30,6 @@ import javax.jms.MessageConsumer; import javax.jms.MessageProducer; import javax.jms.Queue; import javax.jms.Session; -import javax.transaction.TransactionManager; import org.alfresco.model.ContentModel; import org.alfresco.repo.cache.SimpleCache; @@ -48,8 +47,8 @@ import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.Pair; -import org.apache.activemq.ActiveMQXAConnectionFactory; -import org.apache.activemq.jms.pool.XaPooledConnectionFactory; +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.jms.pool.PooledConnectionFactory; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.reflect.MethodSignature; import org.quartz.JobKey; @@ -79,7 +78,7 @@ import com.inteligr8.alfresco.annotations.service.AsyncProcessException; import com.inteligr8.alfresco.annotations.service.AsyncService; /** - * This class provides integration with MQ for the asynchronous filing of nodes. + * This class provides integration with MQ for the asynchronous method executions. * * @author brian@inteligr8.com */ @@ -98,7 +97,6 @@ public class MqAsyncService extends AbstractLifecycleBean implements AsyncServic protected int workerThreads; @Value("${inteligr8.async.mq.url}") - //@Value("${messaging.broker.url}") protected String url; @Value("${inteligr8.async.mq.username}") @@ -137,12 +135,9 @@ public class MqAsyncService extends AbstractLifecycleBean implements AsyncServic @Autowired protected TransactionService txService; - @Autowired - protected TransactionManager txManager; - private String hostname; - private XaPooledConnectionFactory factory; + private PooledConnectionFactory factory; private SimpleCache, String>, Method> methodCache; @@ -164,12 +159,11 @@ public class MqAsyncService extends AbstractLifecycleBean implements AsyncServic this.hostname = "unknown"; } - ActiveMQXAConnectionFactory factory = new ActiveMQXAConnectionFactory(this.url); + ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(this.url); - XaPooledConnectionFactory pool = new XaPooledConnectionFactory(); + PooledConnectionFactory pool = new PooledConnectionFactory(); pool.setConnectionFactory(factory); pool.setMaxConnections(this.maxConnections); - pool.setTransactionManager(this.txManager); pool.start(); this.factory = pool; diff --git a/src/main/java/com/inteligr8/alfresco/annotations/service/impl/ThreadPoolAsyncService.java b/src/main/java/com/inteligr8/alfresco/annotations/service/impl/ThreadPoolAsyncService.java index 10941a7..70421be 100644 --- a/src/main/java/com/inteligr8/alfresco/annotations/service/impl/ThreadPoolAsyncService.java +++ b/src/main/java/com/inteligr8/alfresco/annotations/service/impl/ThreadPoolAsyncService.java @@ -33,7 +33,8 @@ import com.inteligr8.alfresco.annotations.service.AsyncProcessException; import com.inteligr8.alfresco.annotations.service.AsyncService; /** - * This class provides a non-persistent alternative to MQ for asynchronous execution. + * This class provides a non-persistent alternative to MQ for asynchronous method + * execution. * * @author brian@inteligr8.com */ diff --git a/src/main/resources/META-INF/aop.xml b/src/main/resources/META-INF/aop.xml index 4b13f64..b704794 100644 --- a/src/main/resources/META-INF/aop.xml +++ b/src/main/resources/META-INF/aop.xml @@ -7,7 +7,7 @@ - + diff --git a/src/main/resources/alfresco/module/com.inteligr8.alfresco.annotations-platform-module/log4j2.properties b/src/main/resources/alfresco/module/com.inteligr8.alfresco.annotations-platform-module/log4j2.properties new file mode 100644 index 0000000..fcb4e42 --- /dev/null +++ b/src/main/resources/alfresco/module/com.inteligr8.alfresco.annotations-platform-module/log4j2.properties @@ -0,0 +1,2 @@ +logger.inteligr8-annotations.name=com.inteligr8.alfresco.annotations +logger.inteligr8-annotations.level=info diff --git a/src/main/resources/alfresco/module/com.inteligr8.alfresco.annotations-platform-module/module.properties b/src/main/resources/alfresco/module/com.inteligr8.alfresco.annotations-platform-module/module.properties index 3f654aa..319aecb 100644 --- a/src/main/resources/alfresco/module/com.inteligr8.alfresco.annotations-platform-module/module.properties +++ b/src/main/resources/alfresco/module/com.inteligr8.alfresco.annotations-platform-module/module.properties @@ -1,4 +1,9 @@ -module.id=${project.artifactId} +module.id=${project.groupId}.${project.artifactId} module.title=${project.name} module.description=${project.description} module.version=${project.version} + +module.repo.version.min=6.0 +#module.repo.version.max= + +module.depends.aspectj-platform-module=1.0-* diff --git a/src/test/java/com/inteligr8/alfresco/annotations/ClusterSynchronizedTest.java b/src/test/java/com/inteligr8/alfresco/annotations/JobSynchronizedTest.java similarity index 69% rename from src/test/java/com/inteligr8/alfresco/annotations/ClusterSynchronizedTest.java rename to src/test/java/com/inteligr8/alfresco/annotations/JobSynchronizedTest.java index 471bc19..0011916 100644 --- a/src/test/java/com/inteligr8/alfresco/annotations/ClusterSynchronizedTest.java +++ b/src/test/java/com/inteligr8/alfresco/annotations/JobSynchronizedTest.java @@ -6,37 +6,52 @@ import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationEvent; import org.springframework.extensions.surf.util.AbstractLifecycleBean; import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; @Component -public class ClusterSynchronizedTest extends AbstractLifecycleBean { +public class JobSynchronizedTest extends AbstractLifecycleBean { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Override protected void onBootstrap(ApplicationEvent event) { MutableInt threadsRun = new MutableInt(); + this.simpleLock(); this.threadThenLock(threadsRun); + this.threadAndLock(threadsRun); } @Override protected void onShutdown(ApplicationEvent event) { } - @Threaded(name = "cluster-sync", threads = 5, join = true) - @Transactional - @ClusterSynchronized - private void threadThenLock(MutableInt threadsRun) { + @JobSynchronized + private void simpleLock() { + this.logger.debug("simpleLock()"); + } + + @Threaded(name = "job-sync", threads = 5, join = true) + @JobSynchronized + private void threadAndLock(MutableInt threadsRun) { this.lock(threadsRun); } + @Threaded(name = "job-sync", threads = 5, join = true) + private void threadThenLock(MutableInt threadsRun) { + this.lock(threadsRun); + } + + @JobSynchronized private void lock(MutableInt threadsRun) { + this.locked(threadsRun); + } + + private void locked(MutableInt threadsRun) { int t = threadsRun.intValue(); this.logger.debug("After start of a mutually exclusive execution block: {}", t); try { - Thread.sleep(200L); + Thread.sleep(100L); } catch (InterruptedException ie) { } diff --git a/src/test/resources/alfresco/extension/debug-log4j.properties b/src/test/resources/alfresco/extension/debug-log4j.properties index 70daf04..82e5f94 100644 --- a/src/test/resources/alfresco/extension/debug-log4j.properties +++ b/src/test/resources/alfresco/extension/debug-log4j.properties @@ -6,3 +6,6 @@ log4j.logger.org.springframework.extensions.webscripts.ScriptLogger=debug # non-WebScript JavaScript execution debugging log4j.logger.org.alfresco.repo.jscript.ScriptLogger=debug + +# Module importing +#log4j.logger.org.alfresco.repo.module.ImporterModuleComponent=trace diff --git a/src/test/resources/alfresco/extension/debug-log4j2.properties b/src/test/resources/alfresco/extension/debug-log4j2.properties new file mode 100644 index 0000000..930a7ff --- /dev/null +++ b/src/test/resources/alfresco/extension/debug-log4j2.properties @@ -0,0 +1,12 @@ +# Module debugging +logger.inteligr8-annotations.level=trace + +# WebScript debugging +logger.springframework-extensions-webscripts-ScriptLogger.level=debug + +# non-WebScript JavaScript execution debugging +logger.alfresco-repo-jscript-ScriptLogger.level=debug + +# Module importing +#logger.alfresco-repo-module-importer.name=org.alfresco.repo.module.ImporterModuleComponent +#logger.alfresco-repo-module-importer.level=trace