GH-14 - Remove Lombok from production sources.
Polished a lot of Javadoc.
This commit is contained in:
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.modulith.observability;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -31,11 +29,22 @@ import org.springframework.util.Assert;
|
||||
|
||||
import com.tngtech.archunit.core.domain.JavaClass;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
class DefaultObservedModule implements ObservedModule {
|
||||
|
||||
private final ApplicationModule module;
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultObservedModule} for the given {@link ApplicationModule}.
|
||||
*
|
||||
* @param module must not be {@literal null}.
|
||||
*/
|
||||
DefaultObservedModule(ApplicationModule module) {
|
||||
|
||||
Assert.notNull(module, "ApplicationModule must not be null!");
|
||||
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.modulith.observability.ObservedModule#getName()
|
||||
@@ -73,8 +82,8 @@ class DefaultObservedModule implements ObservedModule {
|
||||
|
||||
// For class-based proxies, use the target class
|
||||
|
||||
Advised advised = (Advised) ((ProxyMethodInvocation) invocation).getProxy();
|
||||
Class<?> targetClass = advised.getTargetClass();
|
||||
var advised = (Advised) ((ProxyMethodInvocation) invocation).getProxy();
|
||||
var targetClass = advised.getTargetClass();
|
||||
|
||||
if (module.contains(targetClass)) {
|
||||
return toString(targetClass, method, module);
|
||||
@@ -141,11 +150,11 @@ class DefaultObservedModule implements ObservedModule {
|
||||
|
||||
private static String toString(Class<?> type, Method method, ApplicationModule module) {
|
||||
|
||||
String typeName = module.getType(type.getName())
|
||||
var typeName = module.getType(type.getName())
|
||||
.map(FormatableType::of)
|
||||
.map(FormatableType::getAbbreviatedFullName)
|
||||
.orElseGet(() -> type.getName());
|
||||
|
||||
return String.format("%s.%s(…)", typeName, method.getName());
|
||||
return typeName + "." + method.getName() + "(…)";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,34 +15,44 @@
|
||||
*/
|
||||
package org.springframework.modulith.observability;
|
||||
|
||||
import io.micrometer.tracing.Baggage;
|
||||
import io.micrometer.tracing.Span;
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import io.micrometer.tracing.Tracer.SpanInScope;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
class ModuleEntryInterceptor implements MethodInterceptor {
|
||||
|
||||
private static Logger LOGGER = LoggerFactory.getLogger(ModuleEntryInterceptor.class);
|
||||
private static Map<String, ModuleEntryInterceptor> CACHE = new HashMap<>();
|
||||
|
||||
private final ObservedModule module;
|
||||
private final Tracer tracer;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ModuleEntryInterceptor} for the given {@link ObservedModule} and {@link Tracer}.
|
||||
*
|
||||
* @param module must not be {@literal null}.
|
||||
* @param tracer must not be {@literal null}.
|
||||
*/
|
||||
private ModuleEntryInterceptor(ObservedModule module, Tracer tracer) {
|
||||
|
||||
Assert.notNull(module, "ObservedModule must not be null!");
|
||||
Assert.notNull(tracer, "Tracer must not be null!");
|
||||
|
||||
this.module = module;
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
public static ModuleEntryInterceptor of(ObservedModule module, Tracer tracer) {
|
||||
|
||||
String name = module.getName();
|
||||
|
||||
return CACHE.computeIfAbsent(name, __ -> {
|
||||
return CACHE.computeIfAbsent(module.getName(), __ -> {
|
||||
return new ModuleEntryInterceptor(module, tracer);
|
||||
});
|
||||
}
|
||||
@@ -54,23 +64,23 @@ class ModuleEntryInterceptor implements MethodInterceptor {
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
|
||||
String moduleName = module.getName();
|
||||
Span currentSpan = tracer.currentSpan();
|
||||
var moduleName = module.getName();
|
||||
var currentSpan = tracer.currentSpan();
|
||||
|
||||
if (currentSpan != null) {
|
||||
|
||||
Baggage currentBaggage = tracer.getBaggage(ModuleTracingBeanPostProcessor.MODULE_BAGGAGE_KEY);
|
||||
var currentBaggage = tracer.getBaggage(ModuleTracingBeanPostProcessor.MODULE_BAGGAGE_KEY);
|
||||
|
||||
if (currentBaggage != null && moduleName.equals(currentBaggage.get())) {
|
||||
return invocation.proceed();
|
||||
}
|
||||
}
|
||||
|
||||
String invokedMethod = module.getInvokedMethod(invocation);
|
||||
var invokedMethod = module.getInvokedMethod(invocation);
|
||||
|
||||
LOG.trace("Entering {} via {}.", module.getDisplayName(), invokedMethod);
|
||||
LOGGER.trace("Entering {} via {}.", module.getDisplayName(), invokedMethod);
|
||||
|
||||
Span span = tracer.spanBuilder()
|
||||
var span = tracer.spanBuilder()
|
||||
.name(moduleName)
|
||||
.tag("module.method", invokedMethod)
|
||||
.tag(ModuleTracingBeanPostProcessor.MODULE_BAGGAGE_KEY, moduleName)
|
||||
@@ -84,7 +94,7 @@ class ModuleEntryInterceptor implements MethodInterceptor {
|
||||
|
||||
} finally {
|
||||
|
||||
LOG.trace("Leaving {}", module.getDisplayName());
|
||||
LOGGER.trace("Leaving {}", module.getDisplayName());
|
||||
|
||||
span.end();
|
||||
}
|
||||
|
||||
@@ -15,27 +15,39 @@
|
||||
*/
|
||||
package org.springframework.modulith.observability;
|
||||
|
||||
import io.micrometer.tracing.Span;
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.PayloadApplicationEvent;
|
||||
import org.springframework.modulith.model.ApplicationModule;
|
||||
import org.springframework.modulith.runtime.ApplicationModulesRuntime;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class ModuleEventListener implements ApplicationListener<ApplicationEvent> {
|
||||
|
||||
private final ApplicationModulesRuntime runtime;
|
||||
private final Supplier<Tracer> tracer;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ModuleEventListener} for the given {@link ApplicationModulesRuntime} and {@link Tracer}.
|
||||
*
|
||||
* @param runtime must not be {@literal null}.
|
||||
* @param tracer must not be {@literal null}.
|
||||
*/
|
||||
public ModuleEventListener(ApplicationModulesRuntime runtime, Supplier<Tracer> tracer) {
|
||||
|
||||
Assert.notNull(runtime, "ApplicationModulesRuntime must not be null!");
|
||||
Assert.notNull(tracer, "Tracer must not be null!");
|
||||
|
||||
this.runtime = runtime;
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
|
||||
@@ -43,19 +55,18 @@ public class ModuleEventListener implements ApplicationListener<ApplicationEvent
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
|
||||
if (!PayloadApplicationEvent.class.isInstance(event)) {
|
||||
if (!(event instanceof PayloadApplicationEvent<?> payloadEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PayloadApplicationEvent<?> foo = (PayloadApplicationEvent<?>) event;
|
||||
Object object = foo.getPayload();
|
||||
Class<? extends Object> payloadType = object.getClass();
|
||||
var object = payloadEvent.getPayload();
|
||||
var payloadType = object.getClass();
|
||||
|
||||
if (!runtime.isApplicationClass(payloadType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ApplicationModule moduleByType = runtime.get()
|
||||
var moduleByType = runtime.get()
|
||||
.getModuleByType(payloadType.getSimpleName())
|
||||
.orElse(null);
|
||||
|
||||
@@ -63,7 +74,7 @@ public class ModuleEventListener implements ApplicationListener<ApplicationEvent
|
||||
return;
|
||||
}
|
||||
|
||||
Span span = tracer.get().currentSpan();
|
||||
var span = tracer.get().currentSpan();
|
||||
|
||||
if (span == null) {
|
||||
return;
|
||||
|
||||
@@ -16,17 +16,13 @@
|
||||
package org.springframework.modulith.observability;
|
||||
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.support.ComposablePointcut;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.aop.support.StaticMethodMatcher;
|
||||
@@ -34,6 +30,7 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.modulith.model.ApplicationModules;
|
||||
import org.springframework.modulith.runtime.ApplicationModulesRuntime;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A {@link BeanPostProcessor} that decorates beans exposed by application modules with an interceptor that registers
|
||||
@@ -41,14 +38,30 @@ import org.springframework.modulith.runtime.ApplicationModulesRuntime;
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class ModuleTracingBeanPostProcessor extends ModuleTracingSupport implements BeanPostProcessor {
|
||||
|
||||
public static final String MODULE_BAGGAGE_KEY = "org.springframework.modulith.module";
|
||||
|
||||
private final ApplicationModulesRuntime runtime;
|
||||
private final Supplier<Tracer> tracer;
|
||||
private final Map<String, Advisor> advisors = new HashMap<>();
|
||||
private final Map<String, Advisor> advisors;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ModuleTracingBeanPostProcessor} for the given {@link ApplicationModulesRuntime} and
|
||||
* {@link Tracer}.
|
||||
*
|
||||
* @param runtime must not be {@literal null}.
|
||||
* @param tracer must not be {@literal null}.
|
||||
*/
|
||||
public ModuleTracingBeanPostProcessor(ApplicationModulesRuntime runtime, Supplier<Tracer> tracer) {
|
||||
|
||||
Assert.notNull(runtime, "ApplicationModulesRuntime must not be null!");
|
||||
Assert.notNull(tracer, "Tracer must not be null!");
|
||||
|
||||
this.runtime = runtime;
|
||||
this.tracer = tracer;
|
||||
this.advisors = new HashMap<>();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -69,7 +82,7 @@ public class ModuleTracingBeanPostProcessor extends ModuleTracingSupport impleme
|
||||
.map(DefaultObservedModule::new)
|
||||
.map(it -> {
|
||||
|
||||
ObservedModuleType moduleType = it.getObservedModuleType(type, modules);
|
||||
var moduleType = it.getObservedModuleType(type, modules);
|
||||
|
||||
return moduleType != null //
|
||||
? addAdvisor(bean, getOrBuildAdvisor(it, moduleType)) //
|
||||
@@ -82,19 +95,30 @@ public class ModuleTracingBeanPostProcessor extends ModuleTracingSupport impleme
|
||||
|
||||
return advisors.computeIfAbsent(module.getName(), __ -> {
|
||||
|
||||
Advice interceptor = ModuleEntryInterceptor.of(module, tracer.get());
|
||||
MethodMatcher matcher = new ObservableTypeMethodMatcher(type);
|
||||
Pointcut pointcut = new ComposablePointcut(matcher);
|
||||
var interceptor = ModuleEntryInterceptor.of(module, tracer.get());
|
||||
var matcher = new ObservableTypeMethodMatcher(type);
|
||||
var pointcut = new ComposablePointcut(matcher);
|
||||
|
||||
return new DefaultPointcutAdvisor(pointcut, interceptor);
|
||||
});
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
private static class ObservableTypeMethodMatcher extends StaticMethodMatcher {
|
||||
|
||||
private final ObservedModuleType type;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ObservableTypeMethodMatcher} for the given {@link ObservedModuleType}.
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
*/
|
||||
private ObservableTypeMethodMatcher(ObservedModuleType type) {
|
||||
|
||||
Assert.notNull(type, "ObservableModuleType must not be null!");
|
||||
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.aop.MethodMatcher#matches(java.lang.reflect.Method, java.lang.Class)
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.modulith.observability;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -28,6 +26,7 @@ import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.modulith.model.ApplicationModules;
|
||||
import org.springframework.modulith.model.ArchitecturallyEvidentType;
|
||||
import org.springframework.modulith.model.ArchitecturallyEvidentType.ReferenceMethod;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
@@ -35,7 +34,6 @@ import org.springframework.util.ReflectionUtils;
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class ObservedModuleType {
|
||||
|
||||
private static Collection<Class<?>> IGNORED_TYPES = List.of(Advised.class, TargetClassAware.class);
|
||||
@@ -44,6 +42,25 @@ public class ObservedModuleType {
|
||||
private final ObservedModule module;
|
||||
private final ArchitecturallyEvidentType type;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ObservedModuleType} for the given {@link ApplicationModules}, {@link ObservedModule} and
|
||||
* {@link ArchitecturallyEvidentType}.
|
||||
*
|
||||
* @param modules must not be {@literal null}.
|
||||
* @param module must not be {@literal null}.
|
||||
* @param type must not be {@literal null}.
|
||||
*/
|
||||
ObservedModuleType(ApplicationModules modules, ObservedModule module, ArchitecturallyEvidentType type) {
|
||||
|
||||
Assert.notNull(modules, "ApplicationModules must not be null!");
|
||||
Assert.notNull(module, "ObservedModule must not be null!");
|
||||
Assert.notNull(type, "ArchitecturallyEvidentType must not be null!");
|
||||
|
||||
this.modules = modules;
|
||||
this.module = module;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the type should be traced at all. Can be skipped for types not exposed by the module unless they
|
||||
* listen to events of other modules.
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.modulith.observability;
|
||||
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -33,16 +32,32 @@ import org.springframework.data.rest.webmvc.RootResourceInformation;
|
||||
import org.springframework.modulith.model.ApplicationModule;
|
||||
import org.springframework.modulith.model.ApplicationModules;
|
||||
import org.springframework.modulith.runtime.ApplicationModulesRuntime;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class SpringDataRestModuleTracingBeanPostProcessor extends ModuleTracingSupport implements BeanPostProcessor {
|
||||
|
||||
private final ApplicationModulesRuntime runtime;
|
||||
private final Supplier<Tracer> tracer;
|
||||
|
||||
/**
|
||||
* Creates a new {@link SpringDataRestModuleTracingBeanPostProcessor} for the given {@link ApplicationModulesRuntime}
|
||||
* and {@link Tracer}.
|
||||
*
|
||||
* @param runtime must not be {@literal null}.
|
||||
* @param tracer must not be {@literal null}.
|
||||
*/
|
||||
public SpringDataRestModuleTracingBeanPostProcessor(ApplicationModulesRuntime runtime, Supplier<Tracer> tracer) {
|
||||
|
||||
Assert.notNull(runtime, "ApplicationModulesRuntime must not be null!");
|
||||
Assert.notNull(tracer, "Tracer must not be null!");
|
||||
|
||||
this.runtime = runtime;
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
|
||||
@@ -62,12 +77,26 @@ public class SpringDataRestModuleTracingBeanPostProcessor extends ModuleTracingS
|
||||
return addAdvisor(bean, advisor, it -> it.setProxyTargetClass(true));
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
private static class DataRestControllerInterceptor implements MethodInterceptor {
|
||||
|
||||
private final Supplier<ApplicationModules> modules;
|
||||
private final Supplier<Tracer> tracer;
|
||||
|
||||
/**
|
||||
* Creates a new {@link DataRestControllerInterceptor} for the given {@link ApplicationModules} and {@link Tracer}.
|
||||
*
|
||||
* @param modules must not be {@literal null}.
|
||||
* @param tracer must not be {@literal null}.
|
||||
*/
|
||||
private DataRestControllerInterceptor(Supplier<ApplicationModules> modules, Supplier<Tracer> tracer) {
|
||||
|
||||
Assert.notNull(modules, "ApplicationModules must not be null!");
|
||||
Assert.notNull(tracer, "Tracer must not be null!");
|
||||
|
||||
this.modules = modules;
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
|
||||
@@ -75,13 +104,13 @@ public class SpringDataRestModuleTracingBeanPostProcessor extends ModuleTracingS
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
|
||||
ApplicationModule module = getModuleFrom(invocation.getArguments());
|
||||
var module = getModuleFrom(invocation.getArguments());
|
||||
|
||||
if (module == null) {
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
ObservedModule observed = new DefaultObservedModule(module);
|
||||
var observed = new DefaultObservedModule(module);
|
||||
|
||||
return ModuleEntryInterceptor.of(observed, tracer.get()).invoke(invocation);
|
||||
}
|
||||
@@ -90,17 +119,14 @@ public class SpringDataRestModuleTracingBeanPostProcessor extends ModuleTracingS
|
||||
|
||||
for (Object argument : arguments) {
|
||||
|
||||
if (!RootResourceInformation.class.isInstance(arguments)) {
|
||||
if (!(argument instanceof RootResourceInformation info)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RootResourceInformation info = (RootResourceInformation) argument;
|
||||
|
||||
return modules.get().getModuleByType(info.getDomainType().getName()).orElse(null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user