From cfdf1e9c5983525be5381829c308fba5865be49f Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Sun, 3 Aug 2025 20:40:09 -0300 Subject: [PATCH 01/12] feat: add AOP module with context and executor classes for handling pre and post invocation processes --- aop/build.gradle | 30 +++++++ .../context/AbstractInvocationContext.java | 66 ++++++++++++++ .../aop/context/PostInvocationContext.java | 17 ++++ .../aop/context/PreInvocationContext.java | 15 ++++ .../context/SimplePostInvocationContext.java | 86 +++++++++++++++++++ .../context/SimplePreInvocationContext.java | 52 +++++++++++ .../com/callv2/aop/executor/Executor.java | 9 ++ .../com/callv2/aop/executor/PostExecutor.java | 7 ++ .../com/callv2/aop/executor/PreExecutor.java | 7 ++ .../aop/executor/chain/ExecutorChain.java | 32 +++++++ .../chain/PostInvocationExecutorChain.java | 21 +++++ .../chain/PreInvocationExecutorChain.java | 19 ++++ .../chain/handler/ExecutorChainHandler.java | 10 +++ .../handler/SimpleExecutorChainHandler.java | 44 ++++++++++ .../SimpleExecutorChainHandlerBuilder.java | 73 ++++++++++++++++ settings.gradle | 2 +- 16 files changed, 489 insertions(+), 1 deletion(-) create mode 100644 aop/build.gradle create mode 100644 aop/src/main/java/com/callv2/aop/context/AbstractInvocationContext.java create mode 100644 aop/src/main/java/com/callv2/aop/context/PostInvocationContext.java create mode 100644 aop/src/main/java/com/callv2/aop/context/PreInvocationContext.java create mode 100644 aop/src/main/java/com/callv2/aop/context/SimplePostInvocationContext.java create mode 100644 aop/src/main/java/com/callv2/aop/context/SimplePreInvocationContext.java create mode 100644 aop/src/main/java/com/callv2/aop/executor/Executor.java create mode 100644 aop/src/main/java/com/callv2/aop/executor/PostExecutor.java create mode 100644 aop/src/main/java/com/callv2/aop/executor/PreExecutor.java create mode 100644 aop/src/main/java/com/callv2/aop/executor/chain/ExecutorChain.java create mode 100644 aop/src/main/java/com/callv2/aop/executor/chain/PostInvocationExecutorChain.java create mode 100644 aop/src/main/java/com/callv2/aop/executor/chain/PreInvocationExecutorChain.java create mode 100644 aop/src/main/java/com/callv2/aop/executor/chain/handler/ExecutorChainHandler.java create mode 100644 aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandler.java create mode 100644 aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java diff --git a/aop/build.gradle b/aop/build.gradle new file mode 100644 index 00000000..2bf2e09c --- /dev/null +++ b/aop/build.gradle @@ -0,0 +1,30 @@ +plugins { + id 'java-library' +} + +group = 'com.callv2' +version = '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + + implementation 'org.aspectj:aspectjrt:1.9.24' + + testImplementation 'org.junit.jupiter:junit-jupiter:5.11.4' + testImplementation 'org.mockito:mockito-junit-jupiter:5.15.2' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + +} + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/aop/src/main/java/com/callv2/aop/context/AbstractInvocationContext.java b/aop/src/main/java/com/callv2/aop/context/AbstractInvocationContext.java new file mode 100644 index 00000000..e6f06f3e --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/context/AbstractInvocationContext.java @@ -0,0 +1,66 @@ +package com.callv2.aop.context; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.reflect.SourceLocation; +import org.aspectj.runtime.internal.AroundClosure; + +public abstract class AbstractInvocationContext implements ProceedingJoinPoint { + + protected final ProceedingJoinPoint joinPoint; + + protected AbstractInvocationContext(final ProceedingJoinPoint joinPoint) { + this.joinPoint = joinPoint; + } + + @Override + public void set$AroundClosure(AroundClosure arc) { + this.joinPoint.set$AroundClosure(arc); + } + + @Override + public String toShortString() { + return this.joinPoint.toShortString(); + } + + @Override + public String toLongString() { + return this.joinPoint.toLongString(); + } + + @Override + public Object getThis() { + return this.joinPoint.getThis(); + } + + @Override + public Object getTarget() { + return this.joinPoint.getTarget(); + } + + @Override + public Object[] getArgs() { + return this.joinPoint.getArgs(); + } + + @Override + public Signature getSignature() { + return this.joinPoint.getSignature(); + } + + @Override + public SourceLocation getSourceLocation() { + return this.joinPoint.getSourceLocation(); + } + + @Override + public String getKind() { + return this.joinPoint.getKind(); + } + + @Override + public StaticPart getStaticPart() { + return this.joinPoint.getStaticPart(); + } + +} diff --git a/aop/src/main/java/com/callv2/aop/context/PostInvocationContext.java b/aop/src/main/java/com/callv2/aop/context/PostInvocationContext.java new file mode 100644 index 00000000..74ef6ea8 --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/context/PostInvocationContext.java @@ -0,0 +1,17 @@ +package com.callv2.aop.context; + +import java.time.Instant; + +import org.aspectj.lang.ProceedingJoinPoint; + +public interface PostInvocationContext extends ProceedingJoinPoint { + + Instant getProceededAt(); + + Object getResult(); + + Throwable getThrowable(); + + boolean wasSuccessful(); + +} \ No newline at end of file diff --git a/aop/src/main/java/com/callv2/aop/context/PreInvocationContext.java b/aop/src/main/java/com/callv2/aop/context/PreInvocationContext.java new file mode 100644 index 00000000..33387ab6 --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/context/PreInvocationContext.java @@ -0,0 +1,15 @@ +package com.callv2.aop.context; + +import java.time.Instant; + +import org.aspectj.lang.ProceedingJoinPoint; + +public interface PreInvocationContext extends ProceedingJoinPoint { + + Instant getContextedAt(); + + boolean proceeded(); + + PostInvocationContext proceedWithContext(); + +} diff --git a/aop/src/main/java/com/callv2/aop/context/SimplePostInvocationContext.java b/aop/src/main/java/com/callv2/aop/context/SimplePostInvocationContext.java new file mode 100644 index 00000000..1ed55e3b --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/context/SimplePostInvocationContext.java @@ -0,0 +1,86 @@ +package com.callv2.aop.context; + +import java.time.Instant; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.aspectj.lang.ProceedingJoinPoint; + +public final class SimplePostInvocationContext extends AbstractInvocationContext implements PostInvocationContext { + + private final Object result; + private final Throwable throwable; + private final Instant proceededAt; + private final AtomicBoolean successful; + + private SimplePostInvocationContext( + final ProceedingJoinPoint joinPoint, + final Object result, + final Throwable throwable, + final Instant proceededAt, + final boolean successful) { + super(joinPoint); + this.result = result; + this.throwable = throwable; + this.proceededAt = proceededAt; + this.successful = new AtomicBoolean(successful); + } + + protected static SimplePostInvocationContext from(final PreInvocationContext preInvocationContext) { + + Object result; + Throwable throwable; + boolean successful; + final Instant proceededAt; + + try { + result = preInvocationContext.proceed(); + throwable = null; + successful = true; + } catch (Throwable e) { + result = null; + throwable = e; + successful = false; + } finally { + proceededAt = Instant.now(); + } + + return new SimplePostInvocationContext( + preInvocationContext, + result, + throwable, + proceededAt, + successful); + + } + + @Override + public Object proceed() throws Throwable { + return this.joinPoint.proceed(); + } + + @Override + public Object proceed(Object[] args) throws Throwable { + return this.joinPoint.proceed(args); + } + + @Override + public Instant getProceededAt() { + return this.proceededAt; + } + + @Override + public Object getResult() { + return this.result; + } + + @Override + public Throwable getThrowable() { + return this.throwable; + } + + @Override + public boolean wasSuccessful() { + return this.successful.get(); + } + +} diff --git a/aop/src/main/java/com/callv2/aop/context/SimplePreInvocationContext.java b/aop/src/main/java/com/callv2/aop/context/SimplePreInvocationContext.java new file mode 100644 index 00000000..45adc925 --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/context/SimplePreInvocationContext.java @@ -0,0 +1,52 @@ +package com.callv2.aop.context; + +import java.time.Instant; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.aspectj.lang.ProceedingJoinPoint; + +public final class SimplePreInvocationContext extends AbstractInvocationContext implements PreInvocationContext { + + private final Instant contextedAt; + private final AtomicBoolean proceeded; + + private SimplePreInvocationContext(final ProceedingJoinPoint joinPoint) { + super(joinPoint); + this.contextedAt = Instant.now(); + this.proceeded = new AtomicBoolean(false); + } + + public static SimplePreInvocationContext of(final ProceedingJoinPoint joinPoint) { + return new SimplePreInvocationContext(joinPoint); + } + + @Override + public Object proceed() throws Throwable { + if (proceeded.getAndSet(true)) + throw new IllegalStateException("Method already proceeded"); + return joinPoint.proceed(); + } + + @Override + public Object proceed(Object[] args) throws Throwable { + if (proceeded.getAndSet(true)) + throw new IllegalStateException("Method already proceeded"); + return joinPoint.proceed(args); + } + + @Override + public Instant getContextedAt() { + return this.contextedAt; + } + + @Override + public boolean proceeded() { + return this.proceeded.get(); + } + + @Override + public PostInvocationContext proceedWithContext() { + return SimplePostInvocationContext.from(this); + } + +} diff --git a/aop/src/main/java/com/callv2/aop/executor/Executor.java b/aop/src/main/java/com/callv2/aop/executor/Executor.java new file mode 100644 index 00000000..27458aef --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/executor/Executor.java @@ -0,0 +1,9 @@ +package com.callv2.aop.executor; + +import org.aspectj.lang.ProceedingJoinPoint; + +public interface Executor { + + void execute(J joinPoint); + +} diff --git a/aop/src/main/java/com/callv2/aop/executor/PostExecutor.java b/aop/src/main/java/com/callv2/aop/executor/PostExecutor.java new file mode 100644 index 00000000..37642b05 --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/executor/PostExecutor.java @@ -0,0 +1,7 @@ +package com.callv2.aop.executor; + +import com.callv2.aop.context.PostInvocationContext; + +public interface PostExecutor extends Executor { + +} diff --git a/aop/src/main/java/com/callv2/aop/executor/PreExecutor.java b/aop/src/main/java/com/callv2/aop/executor/PreExecutor.java new file mode 100644 index 00000000..1fcf32b0 --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/executor/PreExecutor.java @@ -0,0 +1,7 @@ +package com.callv2.aop.executor; + +import com.callv2.aop.context.PreInvocationContext; + +public interface PreExecutor extends Executor { + +} diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/ExecutorChain.java b/aop/src/main/java/com/callv2/aop/executor/chain/ExecutorChain.java new file mode 100644 index 00000000..44397761 --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/executor/chain/ExecutorChain.java @@ -0,0 +1,32 @@ +package com.callv2.aop.executor.chain; + +import org.aspectj.lang.ProceedingJoinPoint; + +import com.callv2.aop.executor.Executor; + +public abstract class ExecutorChain> { + + private ExecutorChain next; + private final E executor; + + protected ExecutorChain(final E executor) { + this.executor = executor; + } + + public ExecutorChain setNext(final ExecutorChain executorChain) { + return this.next = executorChain; + } + + public final O execute(final J joinpoint) throws Throwable { + + this.executor.execute(joinpoint); + + if (next != null) + return next.execute(joinpoint); + + return resolve(joinpoint); + } + + protected abstract O resolve(J joinPoint) throws Throwable; + +} diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/PostInvocationExecutorChain.java b/aop/src/main/java/com/callv2/aop/executor/chain/PostInvocationExecutorChain.java new file mode 100644 index 00000000..d5ebe7d5 --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/executor/chain/PostInvocationExecutorChain.java @@ -0,0 +1,21 @@ +package com.callv2.aop.executor.chain; + +import com.callv2.aop.context.PostInvocationContext; +import com.callv2.aop.executor.Executor; + +public final class PostInvocationExecutorChain + extends ExecutorChain> { + + public PostInvocationExecutorChain(final Executor executor) { + super(executor); + } + + @Override + protected Object resolve(final PostInvocationContext joinPoint) throws Throwable { + if (joinPoint.wasSuccessful()) + return joinPoint.getResult(); + else + throw joinPoint.getThrowable(); + } + +} \ No newline at end of file diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/PreInvocationExecutorChain.java b/aop/src/main/java/com/callv2/aop/executor/chain/PreInvocationExecutorChain.java new file mode 100644 index 00000000..e2509df3 --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/executor/chain/PreInvocationExecutorChain.java @@ -0,0 +1,19 @@ +package com.callv2.aop.executor.chain; + +import com.callv2.aop.context.PostInvocationContext; +import com.callv2.aop.context.PreInvocationContext; +import com.callv2.aop.executor.Executor; + +public class PreInvocationExecutorChain + extends ExecutorChain> { + + public PreInvocationExecutorChain(final Executor executor) { + super(executor); + } + + @Override + protected PostInvocationContext resolve(final PreInvocationContext joinPoint) throws Throwable { + return joinPoint.proceedWithContext(); + } + +} diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/handler/ExecutorChainHandler.java b/aop/src/main/java/com/callv2/aop/executor/chain/handler/ExecutorChainHandler.java new file mode 100644 index 00000000..3d214c6b --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/executor/chain/handler/ExecutorChainHandler.java @@ -0,0 +1,10 @@ +package com.callv2.aop.executor.chain.handler; + +import org.aspectj.lang.ProceedingJoinPoint; + +@FunctionalInterface +public interface ExecutorChainHandler { + + Object handle(final ProceedingJoinPoint joinPoint) throws Throwable; + +} diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandler.java b/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandler.java new file mode 100644 index 00000000..cc4b31d3 --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandler.java @@ -0,0 +1,44 @@ +package com.callv2.aop.executor.chain.handler; + +import org.aspectj.lang.ProceedingJoinPoint; + +import com.callv2.aop.context.PostInvocationContext; +import com.callv2.aop.context.SimplePreInvocationContext; +import com.callv2.aop.executor.chain.PostInvocationExecutorChain; +import com.callv2.aop.executor.chain.PreInvocationExecutorChain; + +public final class SimpleExecutorChainHandler implements ExecutorChainHandler { + + private final PreInvocationExecutorChain preInvocationExecutorChain; + private final PostInvocationExecutorChain postInvocationExecutorChain; + private final PostInvocationExecutorChain errorInvocationExecutorChain; + + public SimpleExecutorChainHandler( + final PreInvocationExecutorChain preInvocationExecutorChain, + final PostInvocationExecutorChain postInvocationExecutorChain, + final PostInvocationExecutorChain errorInvocationExecutorChain) { + this.preInvocationExecutorChain = preInvocationExecutorChain; + this.postInvocationExecutorChain = postInvocationExecutorChain; + this.errorInvocationExecutorChain = errorInvocationExecutorChain; + } + + @Override + public Object handle(final ProceedingJoinPoint joinPoint) throws Throwable { + + final SimplePreInvocationContext preContext = SimplePreInvocationContext.of(joinPoint); + final PostInvocationContext postContext = preInvocationExecutorChain.execute(preContext); + + if (postContext.wasSuccessful()) + return postInvocationExecutorChain.execute(postContext); + else + errorInvocationExecutorChain.execute(postContext); + + final Throwable throwable = postContext.getThrowable(); + if (throwable != null) + throw throwable; + + throw new IllegalStateException("Invocation failed but no throwable was provided."); + + } + +} diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java b/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java new file mode 100644 index 00000000..0a30fbd4 --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java @@ -0,0 +1,73 @@ +package com.callv2.aop.executor.chain.handler; + +import java.util.Objects; + +import com.callv2.aop.context.PostInvocationContext; +import com.callv2.aop.context.PreInvocationContext; +import com.callv2.aop.executor.Executor; +import com.callv2.aop.executor.chain.PostInvocationExecutorChain; +import com.callv2.aop.executor.chain.PreInvocationExecutorChain; + +public class SimpleExecutorChainHandlerBuilder { + + private PreInvocationExecutorChain preInvocationExecutorChain; + private PostInvocationExecutorChain postInvocationExecutorChain; + private PostInvocationExecutorChain errorInvocationExecutorChain; + + public static SimpleExecutorChainHandlerBuilder create() { + return new SimpleExecutorChainHandlerBuilder(); + } + + public SimpleExecutorChainHandlerBuilder preExecutor(final Executor executor) { + + final PreInvocationExecutorChain preInvocationExecutorChain = new PreInvocationExecutorChain(executor); + + if (Objects.isNull(this.preInvocationExecutorChain)) { + this.preInvocationExecutorChain = preInvocationExecutorChain; + } else { + this.preInvocationExecutorChain = (PreInvocationExecutorChain) preInvocationExecutorChain + .setNext(preInvocationExecutorChain); + } + + return this; + + } + + public SimpleExecutorChainHandlerBuilder postExecutor(final Executor executor) { + + final PostInvocationExecutorChain postInvocationExecutorChain = new PostInvocationExecutorChain(executor); + + if (Objects.isNull(this.postInvocationExecutorChain)) { + this.postInvocationExecutorChain = postInvocationExecutorChain; + } else { + this.postInvocationExecutorChain = (PostInvocationExecutorChain) postInvocationExecutorChain + .setNext(postInvocationExecutorChain); + } + + return this; + + } + + public SimpleExecutorChainHandlerBuilder errorExecutor(final Executor executor) { + + final PostInvocationExecutorChain errorInvocationExecutorChain = new PostInvocationExecutorChain(executor); + + if (Objects.isNull(this.errorInvocationExecutorChain)) { + this.errorInvocationExecutorChain = errorInvocationExecutorChain; + } else { + this.errorInvocationExecutorChain = (PostInvocationExecutorChain) errorInvocationExecutorChain + .setNext(errorInvocationExecutorChain); + } + + return this; + + } + + public SimpleExecutorChainHandler build() { + return new SimpleExecutorChainHandler( + preInvocationExecutorChain, + postInvocationExecutorChain, + errorInvocationExecutorChain); + } + +} diff --git a/settings.gradle b/settings.gradle index 6ea23965..60ec077c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ rootProject.name = 'drive-api' -include('domain', 'application', 'infrastructure') \ No newline at end of file +include('domain', 'application', 'infrastructure', 'aop') \ No newline at end of file From a8540fe4c7b8f8f9ba13da325887336f920e3062 Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Sun, 3 Aug 2025 20:48:54 -0300 Subject: [PATCH 02/12] refactor: replace generic Executor with specific PostExecutor and PreExecutor in executor chains --- .../executor/chain/PostInvocationExecutorChain.java | 6 +++--- .../executor/chain/PreInvocationExecutorChain.java | 6 +++--- .../handler/SimpleExecutorChainHandlerBuilder.java | 11 +++++------ 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/PostInvocationExecutorChain.java b/aop/src/main/java/com/callv2/aop/executor/chain/PostInvocationExecutorChain.java index d5ebe7d5..0dedd463 100644 --- a/aop/src/main/java/com/callv2/aop/executor/chain/PostInvocationExecutorChain.java +++ b/aop/src/main/java/com/callv2/aop/executor/chain/PostInvocationExecutorChain.java @@ -1,12 +1,12 @@ package com.callv2.aop.executor.chain; import com.callv2.aop.context.PostInvocationContext; -import com.callv2.aop.executor.Executor; +import com.callv2.aop.executor.PostExecutor; public final class PostInvocationExecutorChain - extends ExecutorChain> { + extends ExecutorChain { - public PostInvocationExecutorChain(final Executor executor) { + public PostInvocationExecutorChain(final PostExecutor executor) { super(executor); } diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/PreInvocationExecutorChain.java b/aop/src/main/java/com/callv2/aop/executor/chain/PreInvocationExecutorChain.java index e2509df3..ed77a7df 100644 --- a/aop/src/main/java/com/callv2/aop/executor/chain/PreInvocationExecutorChain.java +++ b/aop/src/main/java/com/callv2/aop/executor/chain/PreInvocationExecutorChain.java @@ -2,12 +2,12 @@ import com.callv2.aop.context.PostInvocationContext; import com.callv2.aop.context.PreInvocationContext; -import com.callv2.aop.executor.Executor; +import com.callv2.aop.executor.PreExecutor; public class PreInvocationExecutorChain - extends ExecutorChain> { + extends ExecutorChain { - public PreInvocationExecutorChain(final Executor executor) { + public PreInvocationExecutorChain(final PreExecutor executor) { super(executor); } diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java b/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java index 0a30fbd4..45914c17 100644 --- a/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java +++ b/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java @@ -2,9 +2,8 @@ import java.util.Objects; -import com.callv2.aop.context.PostInvocationContext; -import com.callv2.aop.context.PreInvocationContext; -import com.callv2.aop.executor.Executor; +import com.callv2.aop.executor.PostExecutor; +import com.callv2.aop.executor.PreExecutor; import com.callv2.aop.executor.chain.PostInvocationExecutorChain; import com.callv2.aop.executor.chain.PreInvocationExecutorChain; @@ -18,7 +17,7 @@ public static SimpleExecutorChainHandlerBuilder create() { return new SimpleExecutorChainHandlerBuilder(); } - public SimpleExecutorChainHandlerBuilder preExecutor(final Executor executor) { + public SimpleExecutorChainHandlerBuilder preExecutor(final PreExecutor executor) { final PreInvocationExecutorChain preInvocationExecutorChain = new PreInvocationExecutorChain(executor); @@ -33,7 +32,7 @@ public SimpleExecutorChainHandlerBuilder preExecutor(final Executor executor) { + public SimpleExecutorChainHandlerBuilder postExecutor(final PostExecutor executor) { final PostInvocationExecutorChain postInvocationExecutorChain = new PostInvocationExecutorChain(executor); @@ -48,7 +47,7 @@ public SimpleExecutorChainHandlerBuilder postExecutor(final Executor executor) { + public SimpleExecutorChainHandlerBuilder errorExecutor(final PostExecutor executor) { final PostInvocationExecutorChain errorInvocationExecutorChain = new PostInvocationExecutorChain(executor); From e3361af3e70494dcd64bbb0658c95b2f025ae3fe Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Mon, 4 Aug 2025 00:29:20 -0300 Subject: [PATCH 03/12] feat: Introduce InvocationContext and related classes for AOP execution context management - Added InvocationContext interface to encapsulate context information during method invocation. - Refactored PostInvocationContext and PreInvocationContext to extend InvocationContext. - Implemented SimplePreInvocationContext and SimplePostInvocationContext to handle invocation context. - Updated SimpleExecutorChainHandlerBuilder to manage pre and post invocation executor chains using queues. - Created ApplicationLayerAspect to handle method execution with AOP. - Removed obsolete aspect-related classes and interfaces to streamline the AOP implementation. - Introduced logging executors for method arguments, signatures, and execution telemetry. - Configured AOP beans in AopConfig for logging and error handling during method execution. --- .../context/AbstractInvocationContext.java | 19 +++- .../callv2/aop/context/InvocationContext.java | 13 +++ .../aop/context/PostInvocationContext.java | 4 +- .../aop/context/PreInvocationContext.java | 10 +- .../context/SimplePreInvocationContext.java | 18 --- .../SimpleExecutorChainHandlerBuilder.java | 83 ++++++++------ infrastructure/build.gradle | 1 + .../aop/aspect/ApplicationLayerAspect.java | 25 +++++ .../aspects/chain/AspectExecutorChain.java | 76 ------------- .../MethodInvocationAspectExecutorChain.java | 23 ---- .../PostInvocationAspectExecutorChain.java | 25 ----- .../aop/aspects/chain/Proceeder.java | 10 -- .../AbstractMethodInvocationContext.java | 27 ----- .../AbstractPostInvocationContext.java | 44 -------- .../context/MethodInvocationContext.java | 19 ---- .../context/PostInvocationContext.java | 20 ---- .../SimpleMethodInvocationContext.java | 64 ----------- .../context/SimplePostInvocationContext.java | 104 ------------------ .../aop/aspects/executor/ArgsLogExecutor.java | 24 ---- .../aop/aspects/executor/AspectExecutor.java | 10 -- .../executor/IdentifiableAspectExecutor.java | 11 -- .../executor/MethodSignatureLogExecutor.java | 18 --- .../executor/PostTelemetryLogExecutor.java | 22 ---- .../executor/ThrowableLogExecutor.java | 30 ----- ...leMethodInterceptorWithContextHandler.java | 51 --------- .../Log4jLogger.java} | 8 +- .../aop/executor/LogErrorPostExecutor.java | 30 +++++ .../executor/LogMethodArgsPreExecutor.java | 31 ++++++ .../LogMethodSignaturePreExecutor.java | 25 +++++ .../executor/LogTelemetryPostExecutor.java | 29 +++++ .../configuration/aop/AopConfig.java | 29 +++++ .../aop/aspect/AspectConfig.java | 65 ----------- .../aspect/PointcutAdvisorProperties.java | 48 -------- 33 files changed, 253 insertions(+), 763 deletions(-) create mode 100644 aop/src/main/java/com/callv2/aop/context/InvocationContext.java create mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/AspectExecutorChain.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/MethodInvocationAspectExecutorChain.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/PostInvocationAspectExecutorChain.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/Proceeder.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/AbstractMethodInvocationContext.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/AbstractPostInvocationContext.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/MethodInvocationContext.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/PostInvocationContext.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/SimpleMethodInvocationContext.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/SimplePostInvocationContext.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/ArgsLogExecutor.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/AspectExecutor.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/IdentifiableAspectExecutor.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/MethodSignatureLogExecutor.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/PostTelemetryLogExecutor.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/ThrowableLogExecutor.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/handler/SimpleMethodInterceptorWithContextHandler.java rename infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/{aspects/executor/Log4jExecutor.java => executor/Log4jLogger.java} (79%) create mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java create mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java create mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java create mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogTelemetryPostExecutor.java create mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/aop/AopConfig.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/aop/aspect/AspectConfig.java delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/properties/aspect/PointcutAdvisorProperties.java diff --git a/aop/src/main/java/com/callv2/aop/context/AbstractInvocationContext.java b/aop/src/main/java/com/callv2/aop/context/AbstractInvocationContext.java index e6f06f3e..b9ebd0dc 100644 --- a/aop/src/main/java/com/callv2/aop/context/AbstractInvocationContext.java +++ b/aop/src/main/java/com/callv2/aop/context/AbstractInvocationContext.java @@ -1,16 +1,23 @@ package com.callv2.aop.context; +import java.time.Instant; +import java.util.concurrent.atomic.AtomicBoolean; + import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.reflect.SourceLocation; import org.aspectj.runtime.internal.AroundClosure; -public abstract class AbstractInvocationContext implements ProceedingJoinPoint { +public abstract class AbstractInvocationContext implements InvocationContext { protected final ProceedingJoinPoint joinPoint; + protected final AtomicBoolean proceeded; + private final Instant contextedAt; protected AbstractInvocationContext(final ProceedingJoinPoint joinPoint) { this.joinPoint = joinPoint; + this.proceeded = new AtomicBoolean(false); + this.contextedAt = Instant.now(); } @Override @@ -63,4 +70,14 @@ public StaticPart getStaticPart() { return this.joinPoint.getStaticPart(); } + @Override + public Instant getContextedAt() { + return this.contextedAt; + } + + @Override + public boolean proceeded() { + return this.proceeded.get(); + } + } diff --git a/aop/src/main/java/com/callv2/aop/context/InvocationContext.java b/aop/src/main/java/com/callv2/aop/context/InvocationContext.java new file mode 100644 index 00000000..84e485fd --- /dev/null +++ b/aop/src/main/java/com/callv2/aop/context/InvocationContext.java @@ -0,0 +1,13 @@ +package com.callv2.aop.context; + +import java.time.Instant; + +import org.aspectj.lang.ProceedingJoinPoint; + +public interface InvocationContext extends ProceedingJoinPoint { + + Instant getContextedAt(); + + boolean proceeded(); + +} diff --git a/aop/src/main/java/com/callv2/aop/context/PostInvocationContext.java b/aop/src/main/java/com/callv2/aop/context/PostInvocationContext.java index 74ef6ea8..f2a9f5b2 100644 --- a/aop/src/main/java/com/callv2/aop/context/PostInvocationContext.java +++ b/aop/src/main/java/com/callv2/aop/context/PostInvocationContext.java @@ -2,9 +2,7 @@ import java.time.Instant; -import org.aspectj.lang.ProceedingJoinPoint; - -public interface PostInvocationContext extends ProceedingJoinPoint { +public interface PostInvocationContext extends InvocationContext { Instant getProceededAt(); diff --git a/aop/src/main/java/com/callv2/aop/context/PreInvocationContext.java b/aop/src/main/java/com/callv2/aop/context/PreInvocationContext.java index 33387ab6..b2989833 100644 --- a/aop/src/main/java/com/callv2/aop/context/PreInvocationContext.java +++ b/aop/src/main/java/com/callv2/aop/context/PreInvocationContext.java @@ -1,14 +1,6 @@ package com.callv2.aop.context; -import java.time.Instant; - -import org.aspectj.lang.ProceedingJoinPoint; - -public interface PreInvocationContext extends ProceedingJoinPoint { - - Instant getContextedAt(); - - boolean proceeded(); +public interface PreInvocationContext extends InvocationContext { PostInvocationContext proceedWithContext(); diff --git a/aop/src/main/java/com/callv2/aop/context/SimplePreInvocationContext.java b/aop/src/main/java/com/callv2/aop/context/SimplePreInvocationContext.java index 45adc925..bbda8f5a 100644 --- a/aop/src/main/java/com/callv2/aop/context/SimplePreInvocationContext.java +++ b/aop/src/main/java/com/callv2/aop/context/SimplePreInvocationContext.java @@ -1,19 +1,11 @@ package com.callv2.aop.context; -import java.time.Instant; -import java.util.concurrent.atomic.AtomicBoolean; - import org.aspectj.lang.ProceedingJoinPoint; public final class SimplePreInvocationContext extends AbstractInvocationContext implements PreInvocationContext { - private final Instant contextedAt; - private final AtomicBoolean proceeded; - private SimplePreInvocationContext(final ProceedingJoinPoint joinPoint) { super(joinPoint); - this.contextedAt = Instant.now(); - this.proceeded = new AtomicBoolean(false); } public static SimplePreInvocationContext of(final ProceedingJoinPoint joinPoint) { @@ -34,16 +26,6 @@ public Object proceed(Object[] args) throws Throwable { return joinPoint.proceed(args); } - @Override - public Instant getContextedAt() { - return this.contextedAt; - } - - @Override - public boolean proceeded() { - return this.proceeded.get(); - } - @Override public PostInvocationContext proceedWithContext() { return SimplePostInvocationContext.from(this); diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java b/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java index 45914c17..cbba1e83 100644 --- a/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java +++ b/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java @@ -1,72 +1,83 @@ package com.callv2.aop.executor.chain.handler; -import java.util.Objects; +import java.util.Queue; +import org.aspectj.lang.ProceedingJoinPoint; + +import com.callv2.aop.context.PostInvocationContext; +import com.callv2.aop.context.PreInvocationContext; +import com.callv2.aop.executor.Executor; import com.callv2.aop.executor.PostExecutor; import com.callv2.aop.executor.PreExecutor; +import com.callv2.aop.executor.chain.ExecutorChain; import com.callv2.aop.executor.chain.PostInvocationExecutorChain; import com.callv2.aop.executor.chain.PreInvocationExecutorChain; public class SimpleExecutorChainHandlerBuilder { - private PreInvocationExecutorChain preInvocationExecutorChain; - private PostInvocationExecutorChain postInvocationExecutorChain; - private PostInvocationExecutorChain errorInvocationExecutorChain; + private final Queue> preInvocationExecutorChainQueue; + private final Queue> postInvocationExecutorChainQueue; + private final Queue> errorInvocationExecutorChainQueue; + + public SimpleExecutorChainHandlerBuilder() { + this.preInvocationExecutorChainQueue = new java.util.LinkedList<>(); + this.postInvocationExecutorChainQueue = new java.util.LinkedList<>(); + this.errorInvocationExecutorChainQueue = new java.util.LinkedList<>(); + } public static SimpleExecutorChainHandlerBuilder create() { return new SimpleExecutorChainHandlerBuilder(); } public SimpleExecutorChainHandlerBuilder preExecutor(final PreExecutor executor) { - - final PreInvocationExecutorChain preInvocationExecutorChain = new PreInvocationExecutorChain(executor); - - if (Objects.isNull(this.preInvocationExecutorChain)) { - this.preInvocationExecutorChain = preInvocationExecutorChain; - } else { - this.preInvocationExecutorChain = (PreInvocationExecutorChain) preInvocationExecutorChain - .setNext(preInvocationExecutorChain); - } - + this.preInvocationExecutorChainQueue.add(new PreInvocationExecutorChain(executor)); return this; - } public SimpleExecutorChainHandlerBuilder postExecutor(final PostExecutor executor) { + this.postInvocationExecutorChainQueue.add(new PostInvocationExecutorChain(executor)); + return this; + } - final PostInvocationExecutorChain postInvocationExecutorChain = new PostInvocationExecutorChain(executor); - - if (Objects.isNull(this.postInvocationExecutorChain)) { - this.postInvocationExecutorChain = postInvocationExecutorChain; - } else { - this.postInvocationExecutorChain = (PostInvocationExecutorChain) postInvocationExecutorChain - .setNext(postInvocationExecutorChain); - } - + public SimpleExecutorChainHandlerBuilder errorExecutor(final PostExecutor executor) { + this.errorInvocationExecutorChainQueue.add(new PostInvocationExecutorChain(executor)); return this; + } + private static PreInvocationExecutorChain buildPreInvocationChain( + final Queue> chains) { + + return (PreInvocationExecutorChain) buildInvocationChain(chains); } - public SimpleExecutorChainHandlerBuilder errorExecutor(final PostExecutor executor) { + private PostInvocationExecutorChain buildPostInvocationChain( + Queue> chains) { - final PostInvocationExecutorChain errorInvocationExecutorChain = new PostInvocationExecutorChain(executor); + return (PostInvocationExecutorChain) buildInvocationChain(chains); + } - if (Objects.isNull(this.errorInvocationExecutorChain)) { - this.errorInvocationExecutorChain = errorInvocationExecutorChain; - } else { - this.errorInvocationExecutorChain = (PostInvocationExecutorChain) errorInvocationExecutorChain - .setNext(errorInvocationExecutorChain); - } + private static > ExecutorChain buildInvocationChain( + final Queue> chains) { + if (chains.isEmpty()) + return null; - return this; + final var firstChain = chains.poll(); + var chain = firstChain; + do { + final var next = chains.poll(); + chain = chain.setNext(next); + } while (!chains.isEmpty()); + + return firstChain; } public SimpleExecutorChainHandler build() { + return new SimpleExecutorChainHandler( - preInvocationExecutorChain, - postInvocationExecutorChain, - errorInvocationExecutorChain); + buildPreInvocationChain(preInvocationExecutorChainQueue), + buildPostInvocationChain(postInvocationExecutorChainQueue), + buildPostInvocationChain(errorInvocationExecutorChainQueue)); } } diff --git a/infrastructure/build.gradle b/infrastructure/build.gradle index 5fadb191..c5ab35fc 100644 --- a/infrastructure/build.gradle +++ b/infrastructure/build.gradle @@ -20,6 +20,7 @@ dependencies { implementation(project(":domain")) implementation(project(":application")) + implementation(project(":aop")) implementation 'org.springframework.boot:spring-boot-starter-web' diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java new file mode 100644 index 00000000..b7c241bc --- /dev/null +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java @@ -0,0 +1,25 @@ +package com.callv2.drive.infrastructure.aop.aspect; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +import com.callv2.aop.executor.chain.handler.ExecutorChainHandler; + +@Aspect +@Component +public class ApplicationLayerAspect { + + private final ExecutorChainHandler chain; + + public ApplicationLayerAspect(final ExecutorChainHandler chain) { + this.chain = chain; + } + + @Around("execution(* com.callv2.drive.application..*.*(..))") + public Object aspect(ProceedingJoinPoint joinPoint) throws Throwable { + return chain.handle(joinPoint); + } + +} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/AspectExecutorChain.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/AspectExecutorChain.java deleted file mode 100644 index b7aa2c67..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/AspectExecutorChain.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.chain; - -import java.util.ArrayDeque; -import java.util.Queue; - -import org.aopalliance.intercept.Joinpoint; - -import com.callv2.drive.infrastructure.aop.aspects.executor.AspectExecutor; - -public abstract class AspectExecutorChain> { - - private AspectExecutorChain next; - private final E executor; - - protected AspectExecutorChain(final E executor) { - this.executor = executor; - } - - public final O execute(final J joinpoint) throws Throwable { - - executor.execute(joinpoint); - - if (next != null) - return next.execute(joinpoint); - - return callsProceed(joinpoint); - } - - protected abstract O callsProceed(J joinpoint) throws Throwable; - - @SuppressWarnings("unchecked") - protected AspectExecutorChain setNext(final AspectExecutorChain next) { - return this.next = (AspectExecutorChain) next; - } - - public static final class Builder> { - - private final Class clazz; - private final Queue chains; - - private Builder(final Class clazz) { - this.clazz = clazz; - this.chains = new ArrayDeque<>(); - } - - public static > Builder create(final Class clazz) { - return new Builder(clazz); - } - - public Builder add(final C chain) { - - if (chain.getClass() != clazz) - throw new IllegalArgumentException("Chain must be exactly of type " + clazz.getName()); - - this.chains.add(chain); - return this; - } - - @SuppressWarnings("unchecked") - public C build() { - if (chains.isEmpty()) - return null; - - final var firstChain = chains.poll(); - var chain = firstChain; - - do { - chain = (C) chain.setNext(chains.poll()); - } while (!chains.isEmpty()); - - return firstChain; - } - - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/MethodInvocationAspectExecutorChain.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/MethodInvocationAspectExecutorChain.java deleted file mode 100644 index 2f0e954d..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/MethodInvocationAspectExecutorChain.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.chain; - -import com.callv2.drive.infrastructure.aop.aspects.context.MethodInvocationContext; -import com.callv2.drive.infrastructure.aop.aspects.context.PostInvocationContext; -import com.callv2.drive.infrastructure.aop.aspects.executor.AspectExecutor; - -public final class MethodInvocationAspectExecutorChain extends - AspectExecutorChain> { - - private MethodInvocationAspectExecutorChain(final AspectExecutor executor) { - super(executor); - } - - public static MethodInvocationAspectExecutorChain with(final AspectExecutor executor) { - return new MethodInvocationAspectExecutorChain(executor); - } - - @Override - protected PostInvocationContext callsProceed(final MethodInvocationContext joinpoint) throws Throwable { - return joinpoint.proceedWithContext(); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/PostInvocationAspectExecutorChain.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/PostInvocationAspectExecutorChain.java deleted file mode 100644 index 8f4a953b..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/PostInvocationAspectExecutorChain.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.chain; - -import com.callv2.drive.infrastructure.aop.aspects.context.PostInvocationContext; -import com.callv2.drive.infrastructure.aop.aspects.executor.AspectExecutor; - -public final class PostInvocationAspectExecutorChain extends - AspectExecutorChain> { - - private PostInvocationAspectExecutorChain(final AspectExecutor executor) { - super(executor); - } - - public static PostInvocationAspectExecutorChain with(final AspectExecutor executor) { - return new PostInvocationAspectExecutorChain(executor); - } - - @Override - protected Object callsProceed(final PostInvocationContext joinpoint) throws Throwable { - if (joinpoint.wasSuccessful()) - return joinpoint.getResult(); - else - throw joinpoint.getThrowable(); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/Proceeder.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/Proceeder.java deleted file mode 100644 index 1dad486c..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/chain/Proceeder.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.chain; - -import org.aopalliance.intercept.Joinpoint; - -@FunctionalInterface -public interface Proceeder { - - O proceed(J joinpoint) throws Throwable; - -} \ No newline at end of file diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/AbstractMethodInvocationContext.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/AbstractMethodInvocationContext.java deleted file mode 100644 index 325ab18f..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/AbstractMethodInvocationContext.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.context; - -import java.time.Instant; - -import jakarta.annotation.Nonnull; - -public abstract class AbstractMethodInvocationContext implements MethodInvocationContext { - - private final Instant contextedAt; - - protected AbstractMethodInvocationContext() { - this.contextedAt = Instant.now(); - } - - @Override - @Nonnull - public Instant getContextedAt() { - return contextedAt; - } - - @Override - @Nonnull - public PostInvocationContext proceedWithContext() { - return SimplePostInvocationContext.captureFromExecution(this); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/AbstractPostInvocationContext.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/AbstractPostInvocationContext.java deleted file mode 100644 index bdeae37f..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/AbstractPostInvocationContext.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.context; - -import java.time.Instant; -import java.util.concurrent.atomic.AtomicBoolean; - -public abstract class AbstractPostInvocationContext implements PostInvocationContext { - - private final Object result; - private final Throwable throwable; - private final Instant proceededAt; - private final AtomicBoolean successful; - - protected AbstractPostInvocationContext( - final Object result, - final Throwable throwable, - final Instant proceededAt, - final boolean successful) { - this.result = result; - this.throwable = throwable; - this.proceededAt = proceededAt; - this.successful = new AtomicBoolean(successful); - } - - @Override - public Instant getProceededAt() { - return proceededAt; - } - - @Override - public Object getResult() { - return result; - } - - @Override - public Throwable getThrowable() { - return throwable; - } - - @Override - public boolean wasSuccessful() { - return successful.get(); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/MethodInvocationContext.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/MethodInvocationContext.java deleted file mode 100644 index 0a5b46a6..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/MethodInvocationContext.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.context; - -import java.time.Instant; - -import org.aopalliance.intercept.MethodInvocation; - -import jakarta.annotation.Nonnull; - -public interface MethodInvocationContext extends MethodInvocation { - - @Nonnull - Instant getContextedAt(); - - boolean proceeded(); - - @Nonnull - PostInvocationContext proceedWithContext(); - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/PostInvocationContext.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/PostInvocationContext.java deleted file mode 100644 index 125b22de..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/PostInvocationContext.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.context; - -import java.time.Instant; - -import jakarta.annotation.Nullable; - -public interface PostInvocationContext extends MethodInvocationContext { - - @Nullable - Instant getProceededAt(); - - @Nullable - Object getResult(); - - @Nullable - Throwable getThrowable(); - - boolean wasSuccessful(); - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/SimpleMethodInvocationContext.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/SimpleMethodInvocationContext.java deleted file mode 100644 index b5e5d4ea..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/SimpleMethodInvocationContext.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.context; - -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Method; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import org.aopalliance.intercept.MethodInvocation; - -public final class SimpleMethodInvocationContext extends AbstractMethodInvocationContext { - - private final AtomicBoolean proceeded; - private final MethodInvocation methodInvocation; - - private SimpleMethodInvocationContext(final MethodInvocation methodInvocation) { - super(); - this.proceeded = new AtomicBoolean(false); - this.methodInvocation = methodInvocation; - } - - public static SimpleMethodInvocationContext of(final MethodInvocation methodInvocation) { - return new SimpleMethodInvocationContext(methodInvocation); - } - - @Override - public boolean proceeded() { - return proceeded.get(); - } - - @Override - @Nonnull - public Method getMethod() { - return methodInvocation.getMethod(); - } - - @Override - @Nonnull - public Object[] getArguments() { - return methodInvocation.getArguments(); - } - - @Override - @Nullable - public Object proceed() throws Throwable { - if (proceeded.getAndSet(true)) - throw new IllegalStateException("Method already proceeded"); - return methodInvocation.proceed(); - } - - @Override - @Nullable - public Object getThis() { - return methodInvocation.getThis(); - } - - @Override - @Nonnull - public AccessibleObject getStaticPart() { - return methodInvocation.getStaticPart(); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/SimplePostInvocationContext.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/SimplePostInvocationContext.java deleted file mode 100644 index 30b55dfc..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/context/SimplePostInvocationContext.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.context; - -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Method; -import java.time.Instant; -import java.util.Objects; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public final class SimplePostInvocationContext extends AbstractPostInvocationContext { - - private final MethodInvocationContext methodInvocationContext; - - private SimplePostInvocationContext( - final Object result, - final Throwable throwable, - final Instant proceededAt, - final boolean successful, - final MethodInvocationContext methodInvocationContext) { - super(result, throwable, proceededAt, successful); - this.methodInvocationContext = Objects.requireNonNull(methodInvocationContext, - "'methodInvocationContext' must not be null"); - } - - public static final PostInvocationContext captureFromExecution( - final MethodInvocationContext methodInvocationContext) { - - Objects.requireNonNull(methodInvocationContext, "'methodInvocationContext' must not be null"); - - Object result; - Throwable throwable; - boolean successful; - final Instant proceededAt; - - try { - result = methodInvocationContext.proceed(); - throwable = null; - successful = true; - } catch (Throwable e) { - result = null; - throwable = e; - successful = false; - } finally { - proceededAt = Instant.now(); - } - - return new SimplePostInvocationContext( - result, - throwable, - proceededAt, - successful, - methodInvocationContext); - - } - - @Override - @Nonnull - public Instant getContextedAt() { - return methodInvocationContext.getContextedAt(); - } - - @Override - public boolean proceeded() { - return methodInvocationContext.proceeded(); - } - - @Override - @Nonnull - public PostInvocationContext proceedWithContext() { - return this; - } - - @Override - @Nonnull - public Method getMethod() { - return methodInvocationContext.getMethod(); - } - - @Override - @Nonnull - public Object[] getArguments() { - return methodInvocationContext.getArguments(); - } - - @Override - @Nullable - public Object proceed() throws Throwable { - return methodInvocationContext.proceed(); - } - - @Override - @Nullable - public Object getThis() { - return methodInvocationContext.getThis(); - } - - @Override - @Nonnull - public AccessibleObject getStaticPart() { - return methodInvocationContext.getStaticPart(); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/ArgsLogExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/ArgsLogExecutor.java deleted file mode 100644 index 8519ed3e..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/ArgsLogExecutor.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.executor; - -import java.util.Arrays; - -import org.apache.logging.log4j.Level; - -import com.callv2.drive.infrastructure.aop.aspects.context.MethodInvocationContext; - -public class ArgsLogExecutor extends Log4jExecutor { - - public ArgsLogExecutor(final Level level, final Class clazz) { - super(level, clazz); - } - - @Override - public void execute(final MethodInvocationContext context) { - final var args = context.getArguments(); - log("<> [{}] <> count:[{}] args: [{}]", - context.getMethod(), - args.length, - Arrays.toString(args)); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/AspectExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/AspectExecutor.java deleted file mode 100644 index 9b7cf5da..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/AspectExecutor.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.executor; - -import org.aopalliance.intercept.Joinpoint; - -@FunctionalInterface -public interface AspectExecutor { - - void execute(J joinPoint); - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/IdentifiableAspectExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/IdentifiableAspectExecutor.java deleted file mode 100644 index 8a96e709..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/IdentifiableAspectExecutor.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.executor; - -import org.aopalliance.intercept.Joinpoint; - -public interface IdentifiableAspectExecutor extends AspectExecutor { - - default String getId() { - return getClass().getSimpleName(); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/MethodSignatureLogExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/MethodSignatureLogExecutor.java deleted file mode 100644 index 4c8ec16b..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/MethodSignatureLogExecutor.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.executor; - -import org.apache.logging.log4j.Level; - -import com.callv2.drive.infrastructure.aop.aspects.context.MethodInvocationContext; - -public class MethodSignatureLogExecutor extends Log4jExecutor { - - public MethodSignatureLogExecutor(final Level level, final Class clazz) { - super(level, clazz); - } - - @Override - public void execute(final MethodInvocationContext context) { - log("<>: [{}]", context.getMethod().toString()); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/PostTelemetryLogExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/PostTelemetryLogExecutor.java deleted file mode 100644 index 48675064..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/PostTelemetryLogExecutor.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.executor; - -import java.time.Duration; - -import org.apache.logging.log4j.Level; - -import com.callv2.drive.infrastructure.aop.aspects.context.PostInvocationContext; - -public class PostTelemetryLogExecutor extends Log4jExecutor { - - public PostTelemetryLogExecutor(final Level logLevel, final Class clazz) { - super(logLevel, clazz); - } - - @Override - public void execute(final PostInvocationContext context) { - log("<> [{}] ms <> [{}]", - Duration.between(context.getContextedAt(), context.getProceededAt()).toMillis(), - context.getMethod().toString()); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/ThrowableLogExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/ThrowableLogExecutor.java deleted file mode 100644 index 72cebda8..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/ThrowableLogExecutor.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.executor; - -import com.callv2.drive.infrastructure.aop.aspects.context.PostInvocationContext; -import org.apache.logging.log4j.Level; - -public class ThrowableLogExecutor extends Log4jExecutor { - - private ThrowableLogExecutor(final Level level, final Class clazz) { - super(level, clazz); - } - - public static ThrowableLogExecutor defaultCreate(final Class clazz) { - return new ThrowableLogExecutor(Level.ERROR, clazz); - } - - public static ThrowableLogExecutor create(final Level level, final Class clazz) { - return new ThrowableLogExecutor(level, clazz); - } - - @Override - public void execute(final PostInvocationContext context) { - if (context.getThrowable() != null) - log("<> [{}] <> [{}] <> [{}]", - context.getThrowable().getClass().getName(), - context.getThrowable().getMessage(), - context.getMethod().toString(), - context.getThrowable()); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/handler/SimpleMethodInterceptorWithContextHandler.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/handler/SimpleMethodInterceptorWithContextHandler.java deleted file mode 100644 index 9c000fc3..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/handler/SimpleMethodInterceptorWithContextHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.callv2.drive.infrastructure.aop.aspects.handler; - -import javax.annotation.Nonnull; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import com.callv2.drive.infrastructure.aop.aspects.chain.MethodInvocationAspectExecutorChain; -import com.callv2.drive.infrastructure.aop.aspects.chain.PostInvocationAspectExecutorChain; -import com.callv2.drive.infrastructure.aop.aspects.context.MethodInvocationContext; -import com.callv2.drive.infrastructure.aop.aspects.context.PostInvocationContext; -import com.callv2.drive.infrastructure.aop.aspects.context.SimpleMethodInvocationContext; - -import jakarta.annotation.Nullable; - -public final class SimpleMethodInterceptorWithContextHandler implements MethodInterceptor { - - private final MethodInvocationAspectExecutorChain beforeChain; - private final PostInvocationAspectExecutorChain afterChain; - private final PostInvocationAspectExecutorChain errorChain; - - public SimpleMethodInterceptorWithContextHandler( - final MethodInvocationAspectExecutorChain beforeChain, - final PostInvocationAspectExecutorChain afterChain, - final PostInvocationAspectExecutorChain errorChain) { - this.beforeChain = beforeChain; - this.afterChain = afterChain; - this.errorChain = errorChain; - } - - @Override - @Nullable - public Object invoke(@Nonnull MethodInvocation invocation) throws Throwable { - - final MethodInvocationContext context = SimpleMethodInvocationContext.of(invocation); - - final PostInvocationContext postInvocationResult = beforeChain.execute(context); - - if (postInvocationResult.wasSuccessful()) - return afterChain.execute(postInvocationResult); - else - errorChain.execute(postInvocationResult); - - final Throwable throwable = postInvocationResult.getThrowable(); - if (throwable != null) - throw throwable; - - throw new IllegalStateException("Invocation failed but no throwable was provided."); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/Log4jExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/Log4jLogger.java similarity index 79% rename from infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/Log4jExecutor.java rename to infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/Log4jLogger.java index 16195a1f..e2a81d93 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspects/executor/Log4jExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/Log4jLogger.java @@ -1,18 +1,16 @@ -package com.callv2.drive.infrastructure.aop.aspects.executor; +package com.callv2.drive.infrastructure.aop.executor; -import org.aopalliance.intercept.Joinpoint; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.message.Message; -public abstract class Log4jExecutor implements IdentifiableAspectExecutor { +public class Log4jLogger { private final Logger logger; private final Level logLevel; - public Log4jExecutor(final Level logLevel, Class clazz) { - super(); + public Log4jLogger(final Level logLevel, final Class clazz) { this.logLevel = logLevel; this.logger = LogManager.getLogger(clazz); } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java new file mode 100644 index 00000000..f77913ab --- /dev/null +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java @@ -0,0 +1,30 @@ +package com.callv2.drive.infrastructure.aop.executor; + +import org.apache.logging.log4j.Level; + +import com.callv2.aop.context.PostInvocationContext; +import com.callv2.aop.executor.PostExecutor; + +public class LogErrorPostExecutor implements PostExecutor { + + private final Log4jLogger logger; + + public LogErrorPostExecutor(final Level logLevel) { + this.logger = new Log4jLogger(logLevel, LogTelemetryPostExecutor.class); + } + + public LogErrorPostExecutor(final Level logLevel, final Class clazz) { + this.logger = new Log4jLogger(logLevel, clazz); + } + + @Override + public void execute(final PostInvocationContext joinPoint) { + if (joinPoint.getThrowable() != null) + logger.log("<> [{}] <> [{}] <> [{}]", + joinPoint.getThrowable().getClass().getName(), + joinPoint.getThrowable().getMessage(), + joinPoint.getSignature().toString(), + joinPoint.getThrowable()); + } + +} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java new file mode 100644 index 00000000..e4c30dee --- /dev/null +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java @@ -0,0 +1,31 @@ +package com.callv2.drive.infrastructure.aop.executor; + +import java.util.Arrays; + +import org.apache.logging.log4j.Level; + +import com.callv2.aop.context.PreInvocationContext; +import com.callv2.aop.executor.PreExecutor; + +public class LogMethodArgsPreExecutor implements PreExecutor { + + private final Log4jLogger logger; + + public LogMethodArgsPreExecutor(final Level logLevel) { + this.logger = new Log4jLogger(logLevel, LogTelemetryPostExecutor.class); + } + + public LogMethodArgsPreExecutor(final Level logLevel, final Class clazz) { + this.logger = new Log4jLogger(logLevel, clazz); + } + + @Override + public void execute(final PreInvocationContext joinPoint) { + final var args = joinPoint.getArgs(); + logger.log("<> [{}] <> count:[{}] args: [{}]", + joinPoint.getSignature(), + args.length, + Arrays.toString(args)); + } + +} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java new file mode 100644 index 00000000..5033b64b --- /dev/null +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java @@ -0,0 +1,25 @@ +package com.callv2.drive.infrastructure.aop.executor; + +import org.apache.logging.log4j.Level; + +import com.callv2.aop.context.PreInvocationContext; +import com.callv2.aop.executor.PreExecutor; + +public class LogMethodSignaturePreExecutor implements PreExecutor { + + private final Log4jLogger logger; + + public LogMethodSignaturePreExecutor(final Level logLevel) { + this.logger = new Log4jLogger(logLevel, LogTelemetryPostExecutor.class); + } + + public LogMethodSignaturePreExecutor(final Level logLevel, final Class clazz) { + this.logger = new Log4jLogger(logLevel, clazz); + } + + @Override + public void execute(final PreInvocationContext joinPoint) { + logger.log("<>: [{}]", joinPoint.getSignature().toString()); + } + +} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogTelemetryPostExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogTelemetryPostExecutor.java new file mode 100644 index 00000000..fbfd60a8 --- /dev/null +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogTelemetryPostExecutor.java @@ -0,0 +1,29 @@ +package com.callv2.drive.infrastructure.aop.executor; + +import java.time.Duration; + +import org.apache.logging.log4j.Level; + +import com.callv2.aop.context.PostInvocationContext; +import com.callv2.aop.executor.PostExecutor; + +public class LogTelemetryPostExecutor implements PostExecutor { + + private final Log4jLogger logger; + + public LogTelemetryPostExecutor(final Level logLevel) { + this.logger = new Log4jLogger(logLevel, LogTelemetryPostExecutor.class); + } + + public LogTelemetryPostExecutor(final Level logLevel, final Class clazz) { + this.logger = new Log4jLogger(logLevel, clazz); + } + + @Override + public void execute(final PostInvocationContext joinPoint) { + logger.log("<> [{}] ms <> [{}]", + Duration.between(joinPoint.getContextedAt(), joinPoint.getProceededAt()).toMillis(), + joinPoint.getSignature().toString()); + } + +} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/aop/AopConfig.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/aop/AopConfig.java new file mode 100644 index 00000000..33df1772 --- /dev/null +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/aop/AopConfig.java @@ -0,0 +1,29 @@ +package com.callv2.drive.infrastructure.configuration.aop; + +import org.apache.logging.log4j.Level; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.callv2.aop.executor.chain.handler.ExecutorChainHandler; +import com.callv2.aop.executor.chain.handler.SimpleExecutorChainHandlerBuilder; +import com.callv2.drive.infrastructure.aop.executor.LogErrorPostExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogMethodArgsPreExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogMethodSignaturePreExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogTelemetryPostExecutor; + +@Configuration +public class AopConfig { + + @Bean + ExecutorChainHandler executorChainHandler() { + + return SimpleExecutorChainHandlerBuilder + .create() + .preExecutor(new LogMethodSignaturePreExecutor(Level.INFO)) + .preExecutor(new LogMethodArgsPreExecutor(Level.DEBUG)) + .postExecutor(new LogTelemetryPostExecutor(Level.INFO)) + .errorExecutor(new LogErrorPostExecutor(Level.ERROR)) + .build(); + } + +} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/aop/aspect/AspectConfig.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/aop/aspect/AspectConfig.java deleted file mode 100644 index e76fca6c..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/aop/aspect/AspectConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.callv2.drive.infrastructure.configuration.aop.aspect; - -import org.aopalliance.intercept.MethodInterceptor; -import org.apache.logging.log4j.Level; -import org.springframework.aop.Advisor; -import org.springframework.aop.aspectj.AspectJExpressionPointcut; -import org.springframework.aop.support.DefaultPointcutAdvisor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.callv2.drive.infrastructure.aop.aspects.chain.AspectExecutorChain; -import com.callv2.drive.infrastructure.aop.aspects.chain.MethodInvocationAspectExecutorChain; -import com.callv2.drive.infrastructure.aop.aspects.chain.PostInvocationAspectExecutorChain; -import com.callv2.drive.infrastructure.aop.aspects.executor.ArgsLogExecutor; -import com.callv2.drive.infrastructure.aop.aspects.executor.MethodSignatureLogExecutor; -import com.callv2.drive.infrastructure.aop.aspects.executor.PostTelemetryLogExecutor; -import com.callv2.drive.infrastructure.aop.aspects.executor.ThrowableLogExecutor; -import com.callv2.drive.infrastructure.aop.aspects.handler.SimpleMethodInterceptorWithContextHandler; - -@Configuration -public class AspectConfig { - - @Bean - Advisor applicationAdvisor() { - - final var beforeChain = AspectExecutorChain.Builder - .create(MethodInvocationAspectExecutorChain.class) - .add(MethodInvocationAspectExecutorChain - .with(new MethodSignatureLogExecutor(Level.DEBUG, MethodSignatureLogExecutor.class))) - .add(MethodInvocationAspectExecutorChain - .with(new ArgsLogExecutor(Level.DEBUG, ArgsLogExecutor.class))) - .build(); - - final var afterChain = AspectExecutorChain.Builder - .create(PostInvocationAspectExecutorChain.class) - .add(PostInvocationAspectExecutorChain - .with(new PostTelemetryLogExecutor(Level.DEBUG, PostTelemetryLogExecutor.class))) - .build(); - - final var errorChain = AspectExecutorChain.Builder - .create(PostInvocationAspectExecutorChain.class) - .add(PostInvocationAspectExecutorChain - .with(new PostTelemetryLogExecutor(Level.ERROR, PostTelemetryLogExecutor.class))) - .add(PostInvocationAspectExecutorChain - .with(ThrowableLogExecutor.defaultCreate(ThrowableLogExecutor.class))) - .build(); - - return applicationAdvisor( - "execution(* com.callv2.drive.application..*.*(..))", - new SimpleMethodInterceptorWithContextHandler(beforeChain, afterChain, errorChain)); - } - - private static Advisor applicationAdvisor( - final String expression, - final MethodInterceptor interceptor) { - - final AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); - pointcut.setExpression(expression); - - return new DefaultPointcutAdvisor( - pointcut, - interceptor); - } - -} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/properties/aspect/PointcutAdvisorProperties.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/properties/aspect/PointcutAdvisorProperties.java deleted file mode 100644 index c930113e..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/properties/aspect/PointcutAdvisorProperties.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.callv2.drive.infrastructure.configuration.properties.aspect; - -import java.util.List; - -public class PointcutAdvisorProperties { - - private String expression; - - private List before; - private List after; - private List error; - - public PointcutAdvisorProperties() { - } - - public String getExpression() { - return expression; - } - - public void setExpression(String expression) { - this.expression = expression; - } - - public List getBefore() { - return before; - } - - public void setBefore(List before) { - this.before = before; - } - - public List getAfter() { - return after; - } - - public void setAfter(List after) { - this.after = after; - } - - public List getError() { - return error; - } - - public void setError(List error) { - this.error = error; - } - -} From ca6bce59ce29f816634fe9d9565fdd5e906ea0d3 Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Mon, 4 Aug 2025 00:49:32 -0300 Subject: [PATCH 04/12] fix: enhance AbstractInvocationContext to accept PreInvocationContext for improved context management --- .../com/callv2/aop/context/AbstractInvocationContext.java | 6 ++++++ .../com/callv2/aop/context/SimplePostInvocationContext.java | 6 ++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/aop/src/main/java/com/callv2/aop/context/AbstractInvocationContext.java b/aop/src/main/java/com/callv2/aop/context/AbstractInvocationContext.java index b9ebd0dc..5f16443c 100644 --- a/aop/src/main/java/com/callv2/aop/context/AbstractInvocationContext.java +++ b/aop/src/main/java/com/callv2/aop/context/AbstractInvocationContext.java @@ -20,6 +20,12 @@ protected AbstractInvocationContext(final ProceedingJoinPoint joinPoint) { this.contextedAt = Instant.now(); } + protected AbstractInvocationContext(final PreInvocationContext preInvocationContext) { + this.joinPoint = preInvocationContext; + this.proceeded = new AtomicBoolean(preInvocationContext.proceeded()); + this.contextedAt = preInvocationContext.getContextedAt(); + } + @Override public void set$AroundClosure(AroundClosure arc) { this.joinPoint.set$AroundClosure(arc); diff --git a/aop/src/main/java/com/callv2/aop/context/SimplePostInvocationContext.java b/aop/src/main/java/com/callv2/aop/context/SimplePostInvocationContext.java index 1ed55e3b..bddecadd 100644 --- a/aop/src/main/java/com/callv2/aop/context/SimplePostInvocationContext.java +++ b/aop/src/main/java/com/callv2/aop/context/SimplePostInvocationContext.java @@ -3,8 +3,6 @@ import java.time.Instant; import java.util.concurrent.atomic.AtomicBoolean; -import org.aspectj.lang.ProceedingJoinPoint; - public final class SimplePostInvocationContext extends AbstractInvocationContext implements PostInvocationContext { private final Object result; @@ -13,12 +11,12 @@ public final class SimplePostInvocationContext extends AbstractInvocationContext private final AtomicBoolean successful; private SimplePostInvocationContext( - final ProceedingJoinPoint joinPoint, + final PreInvocationContext preInvocationContext, final Object result, final Throwable throwable, final Instant proceededAt, final boolean successful) { - super(joinPoint); + super(preInvocationContext); this.result = result; this.throwable = throwable; this.proceededAt = proceededAt; From ce49b423b9c0b5d64d929592b2229dd89b22575e Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Mon, 4 Aug 2025 11:37:25 -0300 Subject: [PATCH 05/12] refactor: consolidate AOP executor chain setup into ApplicationLayerAspect and remove AopConfig class --- .../aop/aspect/ApplicationLayerAspect.java | 20 +++++++++---- .../configuration/aop/AopConfig.java | 29 ------------------- 2 files changed, 14 insertions(+), 35 deletions(-) delete mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/aop/AopConfig.java diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java index b7c241bc..11674904 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java @@ -1,24 +1,32 @@ package com.callv2.drive.infrastructure.aop.aspect; +import org.apache.logging.log4j.Level; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import com.callv2.aop.executor.chain.handler.ExecutorChainHandler; +import com.callv2.aop.executor.chain.handler.SimpleExecutorChainHandlerBuilder; +import com.callv2.drive.infrastructure.aop.executor.LogErrorPostExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogMethodArgsPreExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogMethodSignaturePreExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogTelemetryPostExecutor; @Aspect @Component public class ApplicationLayerAspect { - private final ExecutorChainHandler chain; - - public ApplicationLayerAspect(final ExecutorChainHandler chain) { - this.chain = chain; - } + private final ExecutorChainHandler chain = SimpleExecutorChainHandlerBuilder + .create() + .preExecutor(new LogMethodSignaturePreExecutor(Level.INFO)) + .preExecutor(new LogMethodArgsPreExecutor(Level.DEBUG)) + .postExecutor(new LogTelemetryPostExecutor(Level.INFO)) + .errorExecutor(new LogErrorPostExecutor(Level.ERROR)) + .build(); @Around("execution(* com.callv2.drive.application..*.*(..))") - public Object aspect(ProceedingJoinPoint joinPoint) throws Throwable { + public Object aspect(final ProceedingJoinPoint joinPoint) throws Throwable { return chain.handle(joinPoint); } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/aop/AopConfig.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/aop/AopConfig.java deleted file mode 100644 index 33df1772..00000000 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/aop/AopConfig.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.callv2.drive.infrastructure.configuration.aop; - -import org.apache.logging.log4j.Level; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.callv2.aop.executor.chain.handler.ExecutorChainHandler; -import com.callv2.aop.executor.chain.handler.SimpleExecutorChainHandlerBuilder; -import com.callv2.drive.infrastructure.aop.executor.LogErrorPostExecutor; -import com.callv2.drive.infrastructure.aop.executor.LogMethodArgsPreExecutor; -import com.callv2.drive.infrastructure.aop.executor.LogMethodSignaturePreExecutor; -import com.callv2.drive.infrastructure.aop.executor.LogTelemetryPostExecutor; - -@Configuration -public class AopConfig { - - @Bean - ExecutorChainHandler executorChainHandler() { - - return SimpleExecutorChainHandlerBuilder - .create() - .preExecutor(new LogMethodSignaturePreExecutor(Level.INFO)) - .preExecutor(new LogMethodArgsPreExecutor(Level.DEBUG)) - .postExecutor(new LogTelemetryPostExecutor(Level.INFO)) - .errorExecutor(new LogErrorPostExecutor(Level.ERROR)) - .build(); - } - -} From cfd3e8a4ef25834a567aff9b855b4e09f9613bbe Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Mon, 4 Aug 2025 11:50:12 -0300 Subject: [PATCH 06/12] fix: enhance proceed methods in SimplePostInvocationContext to return result or throw throwable based on success --- .../aop/context/SimplePostInvocationContext.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/aop/src/main/java/com/callv2/aop/context/SimplePostInvocationContext.java b/aop/src/main/java/com/callv2/aop/context/SimplePostInvocationContext.java index bddecadd..d150913b 100644 --- a/aop/src/main/java/com/callv2/aop/context/SimplePostInvocationContext.java +++ b/aop/src/main/java/com/callv2/aop/context/SimplePostInvocationContext.java @@ -53,11 +53,25 @@ protected static SimplePostInvocationContext from(final PreInvocationContext pre @Override public Object proceed() throws Throwable { + if (this.proceeded.get()) { + if (successful.get()) + return result; + else + throw throwable; + } + return this.joinPoint.proceed(); } @Override public Object proceed(Object[] args) throws Throwable { + if (this.proceeded.get()) { + if (successful.get()) + return result; + else + throw throwable; + } + return this.joinPoint.proceed(args); } From daf01c6fe714bdd45f200aa5f1a75e4a07eaa0c1 Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Mon, 4 Aug 2025 11:54:29 -0300 Subject: [PATCH 07/12] refactor: mark PreInvocationExecutorChain and SimpleExecutorChainHandlerBuilder as final to prevent subclassing --- .../callv2/aop/executor/chain/PreInvocationExecutorChain.java | 2 +- .../chain/handler/SimpleExecutorChainHandlerBuilder.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/PreInvocationExecutorChain.java b/aop/src/main/java/com/callv2/aop/executor/chain/PreInvocationExecutorChain.java index ed77a7df..1f6e0b8f 100644 --- a/aop/src/main/java/com/callv2/aop/executor/chain/PreInvocationExecutorChain.java +++ b/aop/src/main/java/com/callv2/aop/executor/chain/PreInvocationExecutorChain.java @@ -4,7 +4,7 @@ import com.callv2.aop.context.PreInvocationContext; import com.callv2.aop.executor.PreExecutor; -public class PreInvocationExecutorChain +public final class PreInvocationExecutorChain extends ExecutorChain { public PreInvocationExecutorChain(final PreExecutor executor) { diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java b/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java index cbba1e83..6204e8c2 100644 --- a/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java +++ b/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandlerBuilder.java @@ -13,7 +13,7 @@ import com.callv2.aop.executor.chain.PostInvocationExecutorChain; import com.callv2.aop.executor.chain.PreInvocationExecutorChain; -public class SimpleExecutorChainHandlerBuilder { +public final class SimpleExecutorChainHandlerBuilder { private final Queue> preInvocationExecutorChainQueue; private final Queue> postInvocationExecutorChainQueue; From 608e21daf8ed0e915988bdecfc75bfccd94dee8f Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Mon, 4 Aug 2025 19:34:21 -0300 Subject: [PATCH 08/12] feat: add DomainLayerAspect and InfrastructureLayerAspect for AOP execution handling; enhance ApplicationLayerAspect with result logging refactor: update logging in LogErrorPostExecutor, LogMethodArgsPreExecutor, LogMethodResultPostExecutor, LogMethodSignaturePreExecutor, and LogTelemetryPostExecutor for consistency fix: implement toString method in FileJpaEntity for better logging --- .../aop/aspect/ApplicationLayerAspect.java | 6 ++- .../aop/aspect/DomainLayerAspect.java | 35 ++++++++++++++++ .../aop/aspect/InfrastructureLayerAspect.java | 40 +++++++++++++++++++ .../aop/executor/LogErrorPostExecutor.java | 6 ++- .../executor/LogMethodArgsPreExecutor.java | 9 ++--- .../executor/LogMethodResultPostExecutor.java | 31 ++++++++++++++ .../LogMethodSignaturePreExecutor.java | 2 +- .../executor/LogTelemetryPostExecutor.java | 6 +-- .../converter/JacksonCaster.java | 5 +-- .../file/persistence/FileJpaEntity.java | 7 ++++ 10 files changed, 130 insertions(+), 17 deletions(-) create mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/DomainLayerAspect.java create mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/InfrastructureLayerAspect.java create mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodResultPostExecutor.java diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java index 11674904..f803beaf 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java @@ -10,6 +10,7 @@ import com.callv2.aop.executor.chain.handler.SimpleExecutorChainHandlerBuilder; import com.callv2.drive.infrastructure.aop.executor.LogErrorPostExecutor; import com.callv2.drive.infrastructure.aop.executor.LogMethodArgsPreExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogMethodResultPostExecutor; import com.callv2.drive.infrastructure.aop.executor.LogMethodSignaturePreExecutor; import com.callv2.drive.infrastructure.aop.executor.LogTelemetryPostExecutor; @@ -17,17 +18,18 @@ @Component public class ApplicationLayerAspect { - private final ExecutorChainHandler chain = SimpleExecutorChainHandlerBuilder + private final ExecutorChainHandler chainHandler = SimpleExecutorChainHandlerBuilder .create() .preExecutor(new LogMethodSignaturePreExecutor(Level.INFO)) .preExecutor(new LogMethodArgsPreExecutor(Level.DEBUG)) + .postExecutor(new LogMethodResultPostExecutor(Level.DEBUG)) .postExecutor(new LogTelemetryPostExecutor(Level.INFO)) .errorExecutor(new LogErrorPostExecutor(Level.ERROR)) .build(); @Around("execution(* com.callv2.drive.application..*.*(..))") public Object aspect(final ProceedingJoinPoint joinPoint) throws Throwable { - return chain.handle(joinPoint); + return chainHandler.handle(joinPoint); } } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/DomainLayerAspect.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/DomainLayerAspect.java new file mode 100644 index 00000000..c6b77392 --- /dev/null +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/DomainLayerAspect.java @@ -0,0 +1,35 @@ +package com.callv2.drive.infrastructure.aop.aspect; + +import org.apache.logging.log4j.Level; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +import com.callv2.aop.executor.chain.handler.ExecutorChainHandler; +import com.callv2.aop.executor.chain.handler.SimpleExecutorChainHandlerBuilder; +import com.callv2.drive.infrastructure.aop.executor.LogErrorPostExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogMethodArgsPreExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogMethodResultPostExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogMethodSignaturePreExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogTelemetryPostExecutor; + +@Aspect +@Component +public class DomainLayerAspect { + + private final ExecutorChainHandler chainHandler = SimpleExecutorChainHandlerBuilder + .create() + .preExecutor(new LogMethodSignaturePreExecutor(Level.INFO)) + .preExecutor(new LogMethodArgsPreExecutor(Level.DEBUG)) + .postExecutor(new LogMethodResultPostExecutor(Level.DEBUG)) + .postExecutor(new LogTelemetryPostExecutor(Level.INFO)) + .errorExecutor(new LogErrorPostExecutor(Level.ERROR)) + .build(); + + @Around("execution(* com.callv2.drive.domain..*.*(..))") + public Object aspect(final ProceedingJoinPoint joinPoint) throws Throwable { + return chainHandler.handle(joinPoint); + } + +} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/InfrastructureLayerAspect.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/InfrastructureLayerAspect.java new file mode 100644 index 00000000..d846ada7 --- /dev/null +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/InfrastructureLayerAspect.java @@ -0,0 +1,40 @@ +package com.callv2.drive.infrastructure.aop.aspect; + +import org.apache.logging.log4j.Level; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +import com.callv2.aop.executor.chain.handler.ExecutorChainHandler; +import com.callv2.aop.executor.chain.handler.SimpleExecutorChainHandlerBuilder; +import com.callv2.drive.infrastructure.aop.executor.LogErrorPostExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogMethodArgsPreExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogMethodResultPostExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogMethodSignaturePreExecutor; +import com.callv2.drive.infrastructure.aop.executor.LogTelemetryPostExecutor; + +@Aspect +@Component +public class InfrastructureLayerAspect { + + private final ExecutorChainHandler chainHandler = SimpleExecutorChainHandlerBuilder + .create() + .preExecutor(new LogMethodSignaturePreExecutor(Level.INFO)) + .preExecutor(new LogMethodArgsPreExecutor(Level.DEBUG)) + .postExecutor(new LogMethodResultPostExecutor(Level.DEBUG)) + .postExecutor(new LogTelemetryPostExecutor(Level.INFO)) + .errorExecutor(new LogErrorPostExecutor(Level.ERROR)) + .build(); + + @Around("execution(* com.callv2.drive.infrastructure.api.controller..*.*(..))") + public Object controllerAspect(final ProceedingJoinPoint joinPoint) throws Throwable { + return chainHandler.handle(joinPoint); + } + + @Around("execution(* com.callv2.drive.infrastructure.messaging..*.*(..))") + public Object messagingAspect(final ProceedingJoinPoint joinPoint) throws Throwable { + return chainHandler.handle(joinPoint); + } + +} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java index f77913ab..4ea5adbd 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java @@ -20,11 +20,13 @@ public LogErrorPostExecutor(final Level logLevel, final Class clazz) { @Override public void execute(final PostInvocationContext joinPoint) { if (joinPoint.getThrowable() != null) - logger.log("<> [{}] <> [{}] <> [{}]", + logger.log("<> [{}] <> [{}] <> [{}]", + joinPoint.getSignature().toShortString(), joinPoint.getThrowable().getClass().getName(), joinPoint.getThrowable().getMessage(), - joinPoint.getSignature().toString(), joinPoint.getThrowable()); + else + logger.log("<> [{}] <>", joinPoint.getSignature().toShortString()); } } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java index e4c30dee..d18e3038 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java @@ -21,11 +21,10 @@ public LogMethodArgsPreExecutor(final Level logLevel, final Class clazz) { @Override public void execute(final PreInvocationContext joinPoint) { - final var args = joinPoint.getArgs(); - logger.log("<> [{}] <> count:[{}] args: [{}]", - joinPoint.getSignature(), - args.length, - Arrays.toString(args)); + + logger.log("<> [{}] <> [{}]", + joinPoint.getSignature().toShortString(), + Arrays.toString(joinPoint.getArgs())); } } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodResultPostExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodResultPostExecutor.java new file mode 100644 index 00000000..cb3e1b1e --- /dev/null +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodResultPostExecutor.java @@ -0,0 +1,31 @@ +package com.callv2.drive.infrastructure.aop.executor; + +import java.util.Arrays; + +import org.apache.logging.log4j.Level; + +import com.callv2.aop.context.PostInvocationContext; +import com.callv2.aop.executor.PostExecutor; + +public class LogMethodResultPostExecutor implements PostExecutor { + + private final Log4jLogger logger; + + public LogMethodResultPostExecutor(final Level logLevel) { + this.logger = new Log4jLogger(logLevel, LogMethodResultPostExecutor.class); + } + + public LogMethodResultPostExecutor(final Level logLevel, final Class clazz) { + this.logger = new Log4jLogger(logLevel, clazz); + } + + @Override + public void execute(final PostInvocationContext joinPoint) { + + logger.log("<> [{}] <> [{}] <> [{}]", + joinPoint.getSignature().toShortString(), + Arrays.toString(joinPoint.getArgs()), + joinPoint.getResult()); + } + +} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java index 5033b64b..fc83994f 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java @@ -19,7 +19,7 @@ public LogMethodSignaturePreExecutor(final Level logLevel, final Class clazz) @Override public void execute(final PreInvocationContext joinPoint) { - logger.log("<>: [{}]", joinPoint.getSignature().toString()); + logger.log("<>: [{}]", joinPoint.getSignature().toShortString()); } } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogTelemetryPostExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogTelemetryPostExecutor.java index fbfd60a8..8285d3e2 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogTelemetryPostExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogTelemetryPostExecutor.java @@ -21,9 +21,9 @@ public LogTelemetryPostExecutor(final Level logLevel, final Class clazz) { @Override public void execute(final PostInvocationContext joinPoint) { - logger.log("<> [{}] ms <> [{}]", - Duration.between(joinPoint.getContextedAt(), joinPoint.getProceededAt()).toMillis(), - joinPoint.getSignature().toString()); + logger.log("<>: [{}] <> [{}] ms", + joinPoint.getSignature().toShortString(), + Duration.between(joinPoint.getContextedAt(), joinPoint.getProceededAt()).toMillis()); } } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/converter/JacksonCaster.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/converter/JacksonCaster.java index d420a4f5..f7d0b9f7 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/converter/JacksonCaster.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/converter/JacksonCaster.java @@ -6,13 +6,10 @@ import com.callv2.drive.infrastructure.configuration.mapper.Mapper; @Component -public final class JacksonCaster implements Caster { +public class JacksonCaster implements Caster { private static final ObjectMapper mapper = Mapper.mapper(); - private JacksonCaster() { - } - @Override public T cast(Object value, Class targetType) { return mapper.convertValue(value, targetType); diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/file/persistence/FileJpaEntity.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/file/persistence/FileJpaEntity.java index 2785ce24..bdb06259 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/file/persistence/FileJpaEntity.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/file/persistence/FileJpaEntity.java @@ -166,4 +166,11 @@ public void setUpdatedAt(Instant updatedAt) { this.updatedAt = updatedAt; } + @Override + public String toString() { + return "FileJpaEntity [id=" + id + ", ownerId=" + ownerId + ", folderId=" + folderId + ", name=" + name + + ", contentType=" + contentType + ", contentLocation=" + contentLocation + ", contentSize=" + + contentSize + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + "]"; + } + } From 5417029cf8909c3cc245b636a0acaeccf5b29ebd Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Mon, 4 Aug 2025 23:31:47 -0300 Subject: [PATCH 09/12] fix: handle null cases in SimpleExecutorChainHandler constructor by providing no-op chains --- .../java/com/callv2/aop/executor/Executor.java | 1 + .../chain/handler/SimpleExecutorChainHandler.java | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/aop/src/main/java/com/callv2/aop/executor/Executor.java b/aop/src/main/java/com/callv2/aop/executor/Executor.java index 27458aef..f735e76e 100644 --- a/aop/src/main/java/com/callv2/aop/executor/Executor.java +++ b/aop/src/main/java/com/callv2/aop/executor/Executor.java @@ -2,6 +2,7 @@ import org.aspectj.lang.ProceedingJoinPoint; +@FunctionalInterface public interface Executor { void execute(J joinPoint); diff --git a/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandler.java b/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandler.java index cc4b31d3..1d7033d8 100644 --- a/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandler.java +++ b/aop/src/main/java/com/callv2/aop/executor/chain/handler/SimpleExecutorChainHandler.java @@ -13,13 +13,22 @@ public final class SimpleExecutorChainHandler implements ExecutorChainHandler { private final PostInvocationExecutorChain postInvocationExecutorChain; private final PostInvocationExecutorChain errorInvocationExecutorChain; + private final PreInvocationExecutorChain noOpPreInvocationExecutorChain = new PreInvocationExecutorChain(j -> { + }); + + private final PostInvocationExecutorChain noOpPostInvocationExecutorChain = new PostInvocationExecutorChain(j -> { + }); + public SimpleExecutorChainHandler( final PreInvocationExecutorChain preInvocationExecutorChain, final PostInvocationExecutorChain postInvocationExecutorChain, final PostInvocationExecutorChain errorInvocationExecutorChain) { - this.preInvocationExecutorChain = preInvocationExecutorChain; - this.postInvocationExecutorChain = postInvocationExecutorChain; - this.errorInvocationExecutorChain = errorInvocationExecutorChain; + this.preInvocationExecutorChain = preInvocationExecutorChain == null ? noOpPreInvocationExecutorChain + : preInvocationExecutorChain; + this.postInvocationExecutorChain = postInvocationExecutorChain == null ? noOpPostInvocationExecutorChain + : postInvocationExecutorChain; + this.errorInvocationExecutorChain = errorInvocationExecutorChain == null ? noOpPostInvocationExecutorChain + : errorInvocationExecutorChain; } @Override From 5252a47290ea172cfdb1d58ee857de229f7f8c6b Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Mon, 4 Aug 2025 23:32:32 -0300 Subject: [PATCH 10/12] feat: implement toString methods for File, FileID, Folder, FolderID, Member, and MemberID classes for better logging and debugging --- .../src/main/java/com/callv2/drive/domain/file/File.java | 6 ++++++ .../src/main/java/com/callv2/drive/domain/file/FileID.java | 5 +++++ .../main/java/com/callv2/drive/domain/folder/Folder.java | 7 +++++++ .../main/java/com/callv2/drive/domain/folder/FolderID.java | 5 +++++ .../main/java/com/callv2/drive/domain/member/Member.java | 7 +++++++ .../main/java/com/callv2/drive/domain/member/MemberID.java | 5 +++++ 6 files changed, 35 insertions(+) diff --git a/domain/src/main/java/com/callv2/drive/domain/file/File.java b/domain/src/main/java/com/callv2/drive/domain/file/File.java index 99f8679d..cdfdd044 100644 --- a/domain/src/main/java/com/callv2/drive/domain/file/File.java +++ b/domain/src/main/java/com/callv2/drive/domain/file/File.java @@ -136,4 +136,10 @@ private void selfValidate() { throw ValidationException.with("Validation fail has occoured", notification); } + @Override + public String toString() { + return "File [id=" + id + ", owner=" + owner + ", folder=" + folder + ", name=" + name + ", content=" + content + + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + "]"; + } + } \ No newline at end of file diff --git a/domain/src/main/java/com/callv2/drive/domain/file/FileID.java b/domain/src/main/java/com/callv2/drive/domain/file/FileID.java index 9bd05546..3d8de895 100644 --- a/domain/src/main/java/com/callv2/drive/domain/file/FileID.java +++ b/domain/src/main/java/com/callv2/drive/domain/file/FileID.java @@ -18,4 +18,9 @@ public static FileID unique() { return FileID.of(UUID.randomUUID()); } + @Override + public String toString() { + return "FileID [value=" + getValue() + "]"; + } + } diff --git a/domain/src/main/java/com/callv2/drive/domain/folder/Folder.java b/domain/src/main/java/com/callv2/drive/domain/folder/Folder.java index 35beb80d..9e1bc8fa 100644 --- a/domain/src/main/java/com/callv2/drive/domain/folder/Folder.java +++ b/domain/src/main/java/com/callv2/drive/domain/folder/Folder.java @@ -159,4 +159,11 @@ private void selfValidate() { throw ValidationException.with("Validation fail has occoured", notification); } + @Override + public String toString() { + return "Folder [id=" + id + ", rootFolder=" + rootFolder + ", owner=" + owner + ", name=" + name + + ", parentFolder=" + parentFolder + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + + ", deletedAt=" + deletedAt + "]"; + } + } diff --git a/domain/src/main/java/com/callv2/drive/domain/folder/FolderID.java b/domain/src/main/java/com/callv2/drive/domain/folder/FolderID.java index e5c4d642..eab47e85 100644 --- a/domain/src/main/java/com/callv2/drive/domain/folder/FolderID.java +++ b/domain/src/main/java/com/callv2/drive/domain/folder/FolderID.java @@ -18,4 +18,9 @@ public static FolderID unique() { return FolderID.of(UUID.randomUUID()); } + @Override + public String toString() { + return "FolderID [value=" + getValue() + "]"; + } + } diff --git a/domain/src/main/java/com/callv2/drive/domain/member/Member.java b/domain/src/main/java/com/callv2/drive/domain/member/Member.java index ff437a44..fd8529cd 100644 --- a/domain/src/main/java/com/callv2/drive/domain/member/Member.java +++ b/domain/src/main/java/com/callv2/drive/domain/member/Member.java @@ -172,4 +172,11 @@ public Long getSynchronizedVersion() { return synchronizedVersion; } + @Override + public String toString() { + return "Member [id=" + id + ", username=" + username + ", nickname=" + nickname + ", quota=" + quota + + ", quotaRequest=" + quotaRequest + ", hasSystemAccess=" + hasSystemAccess + ", createdAt=" + createdAt + + ", updatedAt=" + updatedAt + ", synchronizedVersion=" + synchronizedVersion + "]"; + } + } diff --git a/domain/src/main/java/com/callv2/drive/domain/member/MemberID.java b/domain/src/main/java/com/callv2/drive/domain/member/MemberID.java index 9310602a..2be9ec43 100644 --- a/domain/src/main/java/com/callv2/drive/domain/member/MemberID.java +++ b/domain/src/main/java/com/callv2/drive/domain/member/MemberID.java @@ -12,4 +12,9 @@ public static MemberID of(final String id) { return new MemberID(id); } + @Override + public String toString() { + return "MemberID [value=" + getValue() + "]"; + } + } From 5efb228adc51b54b4960a375efcf3c46606c62f3 Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Mon, 4 Aug 2025 23:46:07 -0300 Subject: [PATCH 11/12] fix: correct logger class reference in LogErrorPostExecutor, LogMethodArgsPreExecutor, and LogMethodSignaturePreExecutor constructors --- .../drive/infrastructure/aop/executor/LogErrorPostExecutor.java | 2 +- .../infrastructure/aop/executor/LogMethodArgsPreExecutor.java | 2 +- .../aop/executor/LogMethodSignaturePreExecutor.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java index 4ea5adbd..1ccbd6e1 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java @@ -10,7 +10,7 @@ public class LogErrorPostExecutor implements PostExecutor { private final Log4jLogger logger; public LogErrorPostExecutor(final Level logLevel) { - this.logger = new Log4jLogger(logLevel, LogTelemetryPostExecutor.class); + this.logger = new Log4jLogger(logLevel, LogErrorPostExecutor.class); } public LogErrorPostExecutor(final Level logLevel, final Class clazz) { diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java index d18e3038..b833443e 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java @@ -12,7 +12,7 @@ public class LogMethodArgsPreExecutor implements PreExecutor { private final Log4jLogger logger; public LogMethodArgsPreExecutor(final Level logLevel) { - this.logger = new Log4jLogger(logLevel, LogTelemetryPostExecutor.class); + this.logger = new Log4jLogger(logLevel, LogMethodArgsPreExecutor.class); } public LogMethodArgsPreExecutor(final Level logLevel, final Class clazz) { diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java index fc83994f..84c10f49 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java @@ -10,7 +10,7 @@ public class LogMethodSignaturePreExecutor implements PreExecutor { private final Log4jLogger logger; public LogMethodSignaturePreExecutor(final Level logLevel) { - this.logger = new Log4jLogger(logLevel, LogTelemetryPostExecutor.class); + this.logger = new Log4jLogger(logLevel, LogMethodSignaturePreExecutor.class); } public LogMethodSignaturePreExecutor(final Level logLevel, final Class clazz) { From c8df211b1896645b0526c7d6d513aca6287c7dbb Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Sat, 23 Aug 2025 18:00:51 -0300 Subject: [PATCH 12/12] refactor: update executor classes to use static factory methods for instantiation and extend Log4jLogger --- .../aop/aspect/ApplicationLayerAspect.java | 10 +++++----- .../aop/aspect/DomainLayerAspect.java | 10 +++++----- .../aop/aspect/InfrastructureLayerAspect.java | 10 +++++----- .../infrastructure/aop/executor/Log4jLogger.java | 4 ++-- .../aop/executor/LogErrorPostExecutor.java | 16 +++++++--------- .../aop/executor/LogMethodArgsPreExecutor.java | 14 ++++++-------- .../executor/LogMethodResultPostExecutor.java | 14 ++++++-------- .../executor/LogMethodSignaturePreExecutor.java | 14 ++++++-------- .../aop/executor/LogTelemetryPostExecutor.java | 14 ++++++-------- 9 files changed, 48 insertions(+), 58 deletions(-) diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java index f803beaf..4952cc9a 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/ApplicationLayerAspect.java @@ -20,11 +20,11 @@ public class ApplicationLayerAspect { private final ExecutorChainHandler chainHandler = SimpleExecutorChainHandlerBuilder .create() - .preExecutor(new LogMethodSignaturePreExecutor(Level.INFO)) - .preExecutor(new LogMethodArgsPreExecutor(Level.DEBUG)) - .postExecutor(new LogMethodResultPostExecutor(Level.DEBUG)) - .postExecutor(new LogTelemetryPostExecutor(Level.INFO)) - .errorExecutor(new LogErrorPostExecutor(Level.ERROR)) + .preExecutor(LogMethodSignaturePreExecutor.create(Level.INFO)) + .preExecutor(LogMethodArgsPreExecutor.create(Level.DEBUG)) + .postExecutor(LogMethodResultPostExecutor.create(Level.DEBUG)) + .postExecutor(LogTelemetryPostExecutor.create(Level.INFO)) + .errorExecutor(LogErrorPostExecutor.create(Level.ERROR)) .build(); @Around("execution(* com.callv2.drive.application..*.*(..))") diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/DomainLayerAspect.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/DomainLayerAspect.java index c6b77392..9a53f1b5 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/DomainLayerAspect.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/DomainLayerAspect.java @@ -20,11 +20,11 @@ public class DomainLayerAspect { private final ExecutorChainHandler chainHandler = SimpleExecutorChainHandlerBuilder .create() - .preExecutor(new LogMethodSignaturePreExecutor(Level.INFO)) - .preExecutor(new LogMethodArgsPreExecutor(Level.DEBUG)) - .postExecutor(new LogMethodResultPostExecutor(Level.DEBUG)) - .postExecutor(new LogTelemetryPostExecutor(Level.INFO)) - .errorExecutor(new LogErrorPostExecutor(Level.ERROR)) + .preExecutor(LogMethodSignaturePreExecutor.create(Level.INFO)) + .preExecutor(LogMethodArgsPreExecutor.create(Level.DEBUG)) + .postExecutor(LogMethodResultPostExecutor.create(Level.DEBUG)) + .postExecutor(LogTelemetryPostExecutor.create(Level.INFO)) + .errorExecutor(LogErrorPostExecutor.create(Level.ERROR)) .build(); @Around("execution(* com.callv2.drive.domain..*.*(..))") diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/InfrastructureLayerAspect.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/InfrastructureLayerAspect.java index d846ada7..8cfce871 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/InfrastructureLayerAspect.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/aspect/InfrastructureLayerAspect.java @@ -20,11 +20,11 @@ public class InfrastructureLayerAspect { private final ExecutorChainHandler chainHandler = SimpleExecutorChainHandlerBuilder .create() - .preExecutor(new LogMethodSignaturePreExecutor(Level.INFO)) - .preExecutor(new LogMethodArgsPreExecutor(Level.DEBUG)) - .postExecutor(new LogMethodResultPostExecutor(Level.DEBUG)) - .postExecutor(new LogTelemetryPostExecutor(Level.INFO)) - .errorExecutor(new LogErrorPostExecutor(Level.ERROR)) + .preExecutor(LogMethodSignaturePreExecutor.create(Level.INFO)) + .preExecutor(LogMethodArgsPreExecutor.create(Level.DEBUG)) + .postExecutor(LogMethodResultPostExecutor.create(Level.DEBUG)) + .postExecutor(LogTelemetryPostExecutor.create(Level.INFO)) + .errorExecutor(LogErrorPostExecutor.create(Level.ERROR)) .build(); @Around("execution(* com.callv2.drive.infrastructure.api.controller..*.*(..))") diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/Log4jLogger.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/Log4jLogger.java index e2a81d93..b4303d38 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/Log4jLogger.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/Log4jLogger.java @@ -5,12 +5,12 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.message.Message; -public class Log4jLogger { +public abstract class Log4jLogger { private final Logger logger; private final Level logLevel; - public Log4jLogger(final Level logLevel, final Class clazz) { + protected Log4jLogger(final Level logLevel, final Class clazz) { this.logLevel = logLevel; this.logger = LogManager.getLogger(clazz); } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java index 1ccbd6e1..943d3258 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogErrorPostExecutor.java @@ -5,28 +5,26 @@ import com.callv2.aop.context.PostInvocationContext; import com.callv2.aop.executor.PostExecutor; -public class LogErrorPostExecutor implements PostExecutor { +public class LogErrorPostExecutor extends Log4jLogger implements PostExecutor { - private final Log4jLogger logger; - - public LogErrorPostExecutor(final Level logLevel) { - this.logger = new Log4jLogger(logLevel, LogErrorPostExecutor.class); + private LogErrorPostExecutor(final Level logLevel, final Class clazz) { + super(logLevel, clazz); } - public LogErrorPostExecutor(final Level logLevel, final Class clazz) { - this.logger = new Log4jLogger(logLevel, clazz); + public static LogErrorPostExecutor create(final Level logLevel) { + return new LogErrorPostExecutor(logLevel, LogErrorPostExecutor.class); } @Override public void execute(final PostInvocationContext joinPoint) { if (joinPoint.getThrowable() != null) - logger.log("<> [{}] <> [{}] <> [{}]", + log("<> [{}] <> [{}] <> [{}]", joinPoint.getSignature().toShortString(), joinPoint.getThrowable().getClass().getName(), joinPoint.getThrowable().getMessage(), joinPoint.getThrowable()); else - logger.log("<> [{}] <>", joinPoint.getSignature().toShortString()); + log("<> [{}] <>", joinPoint.getSignature().toShortString()); } } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java index b833443e..705dbf1b 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodArgsPreExecutor.java @@ -7,22 +7,20 @@ import com.callv2.aop.context.PreInvocationContext; import com.callv2.aop.executor.PreExecutor; -public class LogMethodArgsPreExecutor implements PreExecutor { +public class LogMethodArgsPreExecutor extends Log4jLogger implements PreExecutor { - private final Log4jLogger logger; - - public LogMethodArgsPreExecutor(final Level logLevel) { - this.logger = new Log4jLogger(logLevel, LogMethodArgsPreExecutor.class); + private LogMethodArgsPreExecutor(final Level logLevel, final Class clazz) { + super(logLevel, clazz); } - public LogMethodArgsPreExecutor(final Level logLevel, final Class clazz) { - this.logger = new Log4jLogger(logLevel, clazz); + public static LogMethodArgsPreExecutor create(final Level logLevel) { + return new LogMethodArgsPreExecutor(logLevel, LogMethodArgsPreExecutor.class); } @Override public void execute(final PreInvocationContext joinPoint) { - logger.log("<> [{}] <> [{}]", + log("<> [{}] <> [{}]", joinPoint.getSignature().toShortString(), Arrays.toString(joinPoint.getArgs())); } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodResultPostExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodResultPostExecutor.java index cb3e1b1e..99ba0811 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodResultPostExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodResultPostExecutor.java @@ -7,22 +7,20 @@ import com.callv2.aop.context.PostInvocationContext; import com.callv2.aop.executor.PostExecutor; -public class LogMethodResultPostExecutor implements PostExecutor { +public class LogMethodResultPostExecutor extends Log4jLogger implements PostExecutor { - private final Log4jLogger logger; - - public LogMethodResultPostExecutor(final Level logLevel) { - this.logger = new Log4jLogger(logLevel, LogMethodResultPostExecutor.class); + private LogMethodResultPostExecutor(final Level logLevel, final Class clazz) { + super(logLevel, clazz); } - public LogMethodResultPostExecutor(final Level logLevel, final Class clazz) { - this.logger = new Log4jLogger(logLevel, clazz); + public static LogMethodResultPostExecutor create(final Level logLevel) { + return new LogMethodResultPostExecutor(logLevel, LogMethodResultPostExecutor.class); } @Override public void execute(final PostInvocationContext joinPoint) { - logger.log("<> [{}] <> [{}] <> [{}]", + log("<> [{}] <> [{}] <> [{}]", joinPoint.getSignature().toShortString(), Arrays.toString(joinPoint.getArgs()), joinPoint.getResult()); diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java index 84c10f49..90fef616 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogMethodSignaturePreExecutor.java @@ -5,21 +5,19 @@ import com.callv2.aop.context.PreInvocationContext; import com.callv2.aop.executor.PreExecutor; -public class LogMethodSignaturePreExecutor implements PreExecutor { +public class LogMethodSignaturePreExecutor extends Log4jLogger implements PreExecutor { - private final Log4jLogger logger; - - public LogMethodSignaturePreExecutor(final Level logLevel) { - this.logger = new Log4jLogger(logLevel, LogMethodSignaturePreExecutor.class); + private LogMethodSignaturePreExecutor(final Level logLevel, final Class clazz) { + super(logLevel, clazz); } - public LogMethodSignaturePreExecutor(final Level logLevel, final Class clazz) { - this.logger = new Log4jLogger(logLevel, clazz); + public static LogMethodSignaturePreExecutor create(final Level logLevel) { + return new LogMethodSignaturePreExecutor(logLevel, LogMethodSignaturePreExecutor.class); } @Override public void execute(final PreInvocationContext joinPoint) { - logger.log("<>: [{}]", joinPoint.getSignature().toShortString()); + log("<>: [{}]", joinPoint.getSignature().toShortString()); } } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogTelemetryPostExecutor.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogTelemetryPostExecutor.java index 8285d3e2..1bc4769b 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogTelemetryPostExecutor.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/aop/executor/LogTelemetryPostExecutor.java @@ -7,21 +7,19 @@ import com.callv2.aop.context.PostInvocationContext; import com.callv2.aop.executor.PostExecutor; -public class LogTelemetryPostExecutor implements PostExecutor { +public class LogTelemetryPostExecutor extends Log4jLogger implements PostExecutor { - private final Log4jLogger logger; - - public LogTelemetryPostExecutor(final Level logLevel) { - this.logger = new Log4jLogger(logLevel, LogTelemetryPostExecutor.class); + private LogTelemetryPostExecutor(final Level logLevel, final Class clazz) { + super(logLevel, clazz); } - public LogTelemetryPostExecutor(final Level logLevel, final Class clazz) { - this.logger = new Log4jLogger(logLevel, clazz); + public static LogTelemetryPostExecutor create(final Level logLevel) { + return new LogTelemetryPostExecutor(logLevel, LogTelemetryPostExecutor.class); } @Override public void execute(final PostInvocationContext joinPoint) { - logger.log("<>: [{}] <> [{}] ms", + log("<>: [{}] <> [{}] ms", joinPoint.getSignature().toShortString(), Duration.between(joinPoint.getContextedAt(), joinPoint.getProceededAt()).toMillis()); }