diff --git a/inspectit-gepard-agent/build.gradle b/inspectit-gepard-agent/build.gradle index de864d7..a7d04d4 100644 --- a/inspectit-gepard-agent/build.gradle +++ b/inspectit-gepard-agent/build.gradle @@ -114,12 +114,13 @@ dependencies { testImplementation("org.mock-server:mockserver-junit-jupiter:5.15.0") testImplementation 'org.testcontainers:mockserver:1.20.0' testImplementation 'org.testcontainers:junit-jupiter:1.20.0' + testImplementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.24.0' testImplementation 'org.mock-server:mockserver-netty:5.15.0' testImplementation("com.squareup.okhttp3:okhttp:4.12.0") testImplementation("io.opentelemetry.proto:opentelemetry-proto:1.3.2-alpha") testImplementation("com.google.protobuf:protobuf-java-util:3.25.4") // Reading Files from Resources easier - implementation 'commons-io:commons-io:2.16.1' + testImplementation 'commons-io:commons-io:2.16.1' // Otel Java instrumentation that we use and extend during integration tests otel("io.opentelemetry.javaagent:opentelemetry-javaagent:${versions.opentelemetryJavaagent}") diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/HookManager.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/HookManager.java deleted file mode 100644 index 3d63d3b..0000000 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/HookManager.java +++ /dev/null @@ -1,43 +0,0 @@ -/* (C) 2024 */ -package rocks.inspectit.gepard.agent; - -import rocks.inspectit.gepard.bootstrap.Instances; -import rocks.inspectit.gepard.bootstrap.instrumentation.IHookManager; -import rocks.inspectit.gepard.bootstrap.instrumentation.IMethodHook; -import rocks.inspectit.gepard.bootstrap.instrumentation.noop.NoopHookManager; - -/** - * TODO implement - * - *

Note: In inspectIT Ocelot we don't implement {@link IHookManager} directly, but instead pass - * over {@link #getHook} as lambda to {@link Instances}. This should avoid issues with spring - * annotation scanning. However, since we don't use Spring at the moment, we directly implement the - * interface. - */ -public class HookManager implements IHookManager { - - private HookManager() {} - - /** - * Factory method to create an {@link HookManager} - * - * @return the created manager - */ - public static HookManager create() { - HookManager hookManager = new HookManager(); - Instances.hookManager = hookManager; - addShutdownHook(); - return hookManager; - } - - @Override - public IMethodHook getHook(Class clazz, String methodSignature) { - // TODO implement - return null; - } - - /** Destroy at shutdown */ - private static void addShutdownHook() { - Instances.hookManager = NoopHookManager.INSTANCE; - } -} diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/InspectitAgentExtension.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/InspectitAgentExtension.java index 36e50bb..bd66974 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/InspectitAgentExtension.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/InspectitAgentExtension.java @@ -7,13 +7,14 @@ import net.bytebuddy.agent.builder.AgentBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import rocks.inspectit.gepard.agent.bootstrap.InspectitBootstrapManager; +import rocks.inspectit.gepard.agent.bootstrap.BootstrapManager; import rocks.inspectit.gepard.agent.configuration.ConfigurationManager; import rocks.inspectit.gepard.agent.instrumentation.InstrumentationManager; +import rocks.inspectit.gepard.agent.instrumentation.hook.MethodHookManager; +import rocks.inspectit.gepard.agent.instrumentation.state.InstrumentationState; +import rocks.inspectit.gepard.agent.instrumentation.state.configuration.ConfigurationResolver; +import rocks.inspectit.gepard.agent.instrumentation.state.configuration.InspectitConfigurationHolder; import rocks.inspectit.gepard.agent.notification.NotificationManager; -import rocks.inspectit.gepard.agent.state.ConfigurationResolver; -import rocks.inspectit.gepard.agent.state.InspectitConfigurationHolder; -import rocks.inspectit.gepard.agent.state.InstrumentationState; import rocks.inspectit.gepard.agent.transformation.TransformationManager; @SuppressWarnings("unused") @@ -34,33 +35,34 @@ public AgentBuilder extend(AgentBuilder agentBuilder, ConfigProperties config) { log.info("Starting inspectIT Gepard agent extension ..."); // Append the bootstrap classloader with inspectIT interfaces - InspectitBootstrapManager bootstrapManager = InspectitBootstrapManager.create(); + BootstrapManager bootstrapManager = BootstrapManager.create(); bootstrapManager.appendToBootstrapClassLoader(); // Notify configuration server about this agent NotificationManager notificationManager = NotificationManager.create(); notificationManager.sendStartNotification(); + // Set up methods hooks to execute inspectIT code inside target applications + MethodHookManager methodHookManager = MethodHookManager.create(); + // Prepare instrumentation state tracking InspectitConfigurationHolder configurationHolder = InspectitConfigurationHolder.create(); ConfigurationResolver configurationResolver = ConfigurationResolver.create(configurationHolder); - InstrumentationState instrumentationState = InstrumentationState.create(configurationResolver); - - // Set up methods hooks to execute inspectIT code inside target applications - HookManager hookManager = HookManager.create(); + InstrumentationState instrumentationState = + InstrumentationState.create(configurationResolver, methodHookManager); // Modify the OTel AgentBuilder with our transformer TransformationManager transformationManager = TransformationManager.create(instrumentationState); agentBuilder = transformationManager.modify(agentBuilder); - // Set up instrumentation + // Set up dynamic instrumentation InstrumentationManager instrumentationManager = InstrumentationManager.create(); instrumentationManager.createConfigurationReceiver(); instrumentationManager.startClassDiscovery(); instrumentationManager.startBatchInstrumentation(instrumentationState); - // Start loading the inspectit configuration + // Start loading the inspectIT configuration ConfigurationManager configurationManager = ConfigurationManager.create(); configurationManager.loadConfiguration(); diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/bootstrap/InspectitBootstrapManager.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/bootstrap/BootstrapManager.java similarity index 84% rename from inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/bootstrap/InspectitBootstrapManager.java rename to inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/bootstrap/BootstrapManager.java index c6869e6..66402c5 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/bootstrap/InspectitBootstrapManager.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/bootstrap/BootstrapManager.java @@ -13,25 +13,25 @@ import org.slf4j.LoggerFactory; /** - * This manager should append our bootstrap classes to the bootstrap classloader, so there are + * This manager should append our bootstrap classes to the bootstrap classloader, so they are * accessible globally in the target application as well as this agent. */ -public class InspectitBootstrapManager { - private static final Logger log = LoggerFactory.getLogger(InspectitBootstrapManager.class); +public class BootstrapManager { + private static final Logger log = LoggerFactory.getLogger(BootstrapManager.class); private static final String INSPECTIT_BOOTSTRAP_JAR_PATH = "/inspectit-gepard-bootstrap.jar"; private static final String INSPECTIT_BOOTSTRAP_JAR_TEMP_PREFIX = "gepard-bootstrap-"; - private InspectitBootstrapManager() {} + private BootstrapManager() {} /** - * Factory method to create an {@link InspectitBootstrapManager} + * Factory method to create an {@link BootstrapManager} * * @return the created manager */ - public static InspectitBootstrapManager create() { - return new InspectitBootstrapManager(); + public static BootstrapManager create() { + return new BootstrapManager(); } /** Appends our inspectit-gepard-bootstrap.jar to the bootstrap-classloader */ @@ -57,8 +57,7 @@ public synchronized void appendToBootstrapClassLoader() { */ @VisibleForTesting JarFile copyJarFile(String resourcePath, String prefix) throws IOException { - try (InputStream inputStream = - InspectitBootstrapManager.class.getResourceAsStream(resourcePath)) { + try (InputStream inputStream = BootstrapManager.class.getResourceAsStream(resourcePath)) { File targetFile = prepareTempFile(prefix); Files.copy(inputStream, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING); diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/InstrumentationManager.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/InstrumentationManager.java index 8601961..79ef034 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/InstrumentationManager.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/InstrumentationManager.java @@ -10,9 +10,9 @@ import rocks.inspectit.gepard.agent.instrumentation.cache.input.ClassDiscoveryService; import rocks.inspectit.gepard.agent.instrumentation.cache.input.ConfigurationReceiver; import rocks.inspectit.gepard.agent.instrumentation.cache.process.BatchInstrumenter; +import rocks.inspectit.gepard.agent.instrumentation.state.InstrumentationState; import rocks.inspectit.gepard.agent.internal.configuration.observer.ConfigurationReceivedEvent; import rocks.inspectit.gepard.agent.internal.schedule.InspectitScheduler; -import rocks.inspectit.gepard.agent.state.InstrumentationState; /** Responsible component for setting up and executing instrumentation. */ public class InstrumentationManager { diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/cache/process/BatchInstrumenter.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/cache/process/BatchInstrumenter.java index 87e1b99..82bdf14 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/cache/process/BatchInstrumenter.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/cache/process/BatchInstrumenter.java @@ -7,8 +7,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rocks.inspectit.gepard.agent.instrumentation.cache.PendingClassesCache; +import rocks.inspectit.gepard.agent.instrumentation.state.InstrumentationState; import rocks.inspectit.gepard.agent.internal.schedule.NamedRunnable; -import rocks.inspectit.gepard.agent.state.InstrumentationState; /** * Responsible for retransforming classes in batches. The batch size is fixed to 1000. This is @@ -67,17 +67,16 @@ Set> getNextBatch(int batchSize) { try { boolean shouldRetransform = instrumentationState.shouldRetransform(clazz); - if (shouldRetransform) classesToRetransform.add(clazz); } catch (Exception e) { - log.error("Could not check instrumentation status for {}", clazz.getName(), e); + log.error("Could not check instrumentation state for {}", clazz.getName(), e); } if (checkedClassesCount >= batchSize) break; } log.debug( - "Checked configuration of {} classes, {} classes left to check", + "Checked instrumentation state of {} classes, {} classes left to check", checkedClassesCount, pendingClassesCache.getSize()); diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/MethodHook.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/MethodHook.java new file mode 100644 index 0000000..a8879e1 --- /dev/null +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/MethodHook.java @@ -0,0 +1,37 @@ +/* (C) 2024 */ +package rocks.inspectit.gepard.agent.instrumentation.hook; + +import java.util.Objects; +import rocks.inspectit.gepard.bootstrap.instrumentation.IMethodHook; + +/** + * Each {@link MethodHook} instance defines for a single method which actions are performed. This + * defines for example which generic actions are executed or which metrics are collected. Currently, + * we just log our method calls. + */ +public class MethodHook implements IMethodHook { + + @Override + public void onEnter(Object[] instrumentedMethodArgs, Object thiz) { + // Using our log4j does not work here... + String message = + String.format( + "inspectIT: Enter MethodHook with %d args in %s", + instrumentedMethodArgs.length, thiz.getClass().getName()); + System.out.println(message); + System.out.println("HELLO GEPARD"); + } + + @Override + public void onExit( + Object[] instrumentedMethodArgs, Object thiz, Object returnValue, Throwable thrown) { + // Using our log4j does not work here... + String exceptionMessage = Objects.nonNull(thrown) ? thrown.getMessage() : "no exception"; + String message = + String.format( + "inspectIT: Exit MethodHook who returned %s and threw %s", + returnValue.toString(), exceptionMessage); + System.out.println(message); + System.out.println("BYE GEPARD"); + } +} diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/MethodHookManager.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/MethodHookManager.java new file mode 100644 index 0000000..55db1cd --- /dev/null +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/MethodHookManager.java @@ -0,0 +1,155 @@ +/* (C) 2024 */ +package rocks.inspectit.gepard.agent.instrumentation.hook; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import rocks.inspectit.gepard.agent.instrumentation.hook.configuration.ClassHookConfiguration; +import rocks.inspectit.gepard.agent.instrumentation.hook.configuration.HookedMethods; +import rocks.inspectit.gepard.agent.internal.instrumentation.model.ClassInstrumentationConfiguration; +import rocks.inspectit.gepard.bootstrap.Instances; +import rocks.inspectit.gepard.bootstrap.instrumentation.IHookManager; +import rocks.inspectit.gepard.bootstrap.instrumentation.IMethodHook; +import rocks.inspectit.gepard.bootstrap.instrumentation.noop.NoopHookManager; +import rocks.inspectit.gepard.bootstrap.instrumentation.noop.NoopMethodHook; + +/** + * TODO implement, add java doc + * + *

Note: In inspectIT Ocelot we don't implement {@link IHookManager} directly, but instead pass + * over {@link #getHook} as lambda to {@link Instances}. This should avoid issues with spring + * annotation scanning. However, since we don't use Spring at the moment, we directly implement the + * interface. + */ +public class MethodHookManager implements IHookManager { + private static final Logger log = LoggerFactory.getLogger(MethodHookManager.class); + + /** Stores classes and all of their hooked methods. Will be kept up-to-date during runtime. */ + private final Cache, HookedMethods> hooks; + + private MethodHookManager() { + hooks = Caffeine.newBuilder().weakKeys().build(); + } + + /** + * Factory method to create an {@link MethodHookManager}. + * + * @return the created manager + */ + public static MethodHookManager create() { + log.debug("Creating MethodHookManager..."); + if (!Instances.hookManager.equals(NoopHookManager.INSTANCE)) + throw new IllegalStateException("Global HookManager already set"); + + MethodHookManager methodHookManager = new MethodHookManager(); + Instances.hookManager = methodHookManager; + addShutdownHook(); + return methodHookManager; + } + + @Override + public IMethodHook getHook(Class clazz, String methodSignature) { + HookedMethods hookedMethods = hooks.getIfPresent(clazz); + if (Objects.nonNull(hookedMethods)) return hookedMethods.getActiveHook(methodSignature); + return NoopMethodHook.INSTANCE; + } + + public void updateHooksFor(Class clazz, ClassInstrumentationConfiguration configuration) { + log.info("Updating hooks for {}", clazz.getName()); + ElementMatcher.Junction methodMatcher = configuration.methodMatcher(); + TypeDescription type = TypeDescription.ForLoadedType.of(clazz); + Set matchedMethods = + type.getDeclaredMethods().stream() + .filter(methodMatcher::matches) + .collect(Collectors.toSet()); + + ClassHookConfiguration classConfiguration = new ClassHookConfiguration(); + if (!matchedMethods.isEmpty()) matchedMethods.forEach(classConfiguration::putHookConfiguration); + + removeObsoleteHooks(clazz, matchedMethods); + updateHooks(clazz, classConfiguration); + } + + private void removeObsoleteHooks( + Class clazz, Set matchedMethods) { + Set matchedSignatures = + matchedMethods.stream().map(this::getSignature).collect(Collectors.toSet()); + + HookedMethods hookedMethods = hooks.get(clazz, c -> new HookedMethods()); + Set methodSignatures = hookedMethods.getMethodSignatures(); + + AtomicInteger operationCounter = new AtomicInteger(0); + methodSignatures.stream() + .filter(signature -> !matchedSignatures.contains(signature)) + .forEach( + signature -> { + removeHook(clazz, signature); + operationCounter.addAndGet(1); + }); + log.debug("Removed {} obsolete method hooks for {}", operationCounter.get(), clazz.getName()); + } + + private void updateHooks(Class clazz, ClassHookConfiguration classConfiguration) { + AtomicInteger operationCounter = new AtomicInteger(0); + classConfiguration + .asMap() + .forEach( + (method, active) -> { + // Currently always true, later we should compare the current with the new config + if (active) { + String signature = getSignature(method); + Optional maybeHook = getCurrentHook(clazz, signature); + if (maybeHook.isEmpty()) { + setHook(clazz, signature, new MethodHook()); + operationCounter.addAndGet(1); + } + } + }); + log.info("Updated {} method hooks for {}", operationCounter.get(), clazz.getName()); + } + + // TODO Alternativen suchen + Methode auslagern + // Wichtig, dass die Signaturen mit denen von ByteBuddy passen! + private String getSignature(MethodDescription methodDescription) { + String methodName = methodDescription.getName(); + String parameters = + methodDescription.getParameters().asTypeList().stream() + .map(type -> type.asErasure().getTypeName()) + .collect(Collectors.joining(",")); + return methodName + "(" + parameters + ")"; + } + + private void setHook(Class declaringClass, String methodSignature, MethodHook newHook) { + hooks + .asMap() + .computeIfAbsent(declaringClass, (v) -> new HookedMethods()) + .putMethod(methodSignature, newHook); + } + + private void removeHook(Class declaringClass, String methodSignature) { + HookedMethods hookedMethods = hooks.getIfPresent(declaringClass); + if (Objects.nonNull(hookedMethods)) { + hookedMethods.removeMethod(methodSignature); + if (hookedMethods.noActiveHooks()) hooks.invalidate(declaringClass); + } + } + + private Optional getCurrentHook(Class clazz, String methodSignature) { + HookedMethods hookedMethods = hooks.getIfPresent(clazz); + return Optional.ofNullable(hookedMethods) + .map(methods -> methods.getActiveHook(methodSignature)); + } + + /** Remove at shutdown */ + private static void addShutdownHook() { + Runtime.getRuntime() + .addShutdownHook(new Thread(() -> Instances.hookManager = NoopHookManager.INSTANCE)); + } +} diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/MethodHookUtil.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/MethodHookUtil.java new file mode 100644 index 0000000..c7d2c18 --- /dev/null +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/MethodHookUtil.java @@ -0,0 +1,4 @@ +/* (C) 2024 */ +package rocks.inspectit.gepard.agent.instrumentation.hook; + +public class MethodHookUtil {} diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/configuration/ClassHookConfiguration.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/configuration/ClassHookConfiguration.java new file mode 100644 index 0000000..2f0bf11 --- /dev/null +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/configuration/ClassHookConfiguration.java @@ -0,0 +1,29 @@ +/* (C) 2024 */ +package rocks.inspectit.gepard.agent.instrumentation.hook.configuration; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import net.bytebuddy.description.method.MethodDescription; + +public class ClassHookConfiguration { + + /** Set of methods and their hook configuration. Currently, just true. */ + private final Map hookConfigurations; + + public ClassHookConfiguration() { + this.hookConfigurations = new HashMap<>(); + } + + public Map asMap() { + return hookConfigurations; + } + + public Set getMethods() { + return hookConfigurations.keySet(); + } + + public void putHookConfiguration(MethodDescription method) { + hookConfigurations.put(method, true); + } +} diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/configuration/HookedMethods.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/configuration/HookedMethods.java new file mode 100644 index 0000000..cb1ef64 --- /dev/null +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/hook/configuration/HookedMethods.java @@ -0,0 +1,37 @@ +/* (C) 2024 */ +package rocks.inspectit.gepard.agent.instrumentation.hook.configuration; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import rocks.inspectit.gepard.agent.instrumentation.hook.MethodHook; + +public class HookedMethods { + + /** A set of methodSignatures and their method hook. */ + private final Map activeHooks; + + public HookedMethods() { + this.activeHooks = new ConcurrentHashMap<>(); + } + + public MethodHook getActiveHook(String methodSignature) { + return activeHooks.get(methodSignature); + } + + public Set getMethodSignatures() { + return activeHooks.keySet(); + } + + public void putMethod(String methodSignature, MethodHook methodHook) { + activeHooks.put(methodSignature, methodHook); + } + + public void removeMethod(String methodSignature) { + activeHooks.remove(methodSignature); + } + + public boolean noActiveHooks() { + return activeHooks.isEmpty(); + } +} diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/InstrumentationState.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/InstrumentationState.java similarity index 53% rename from inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/InstrumentationState.java rename to inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/InstrumentationState.java index 64b7f22..abfbf98 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/InstrumentationState.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/InstrumentationState.java @@ -1,24 +1,32 @@ /* (C) 2024 */ -package rocks.inspectit.gepard.agent.state; +package rocks.inspectit.gepard.agent.instrumentation.state; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; -import java.util.Map; import java.util.Objects; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import rocks.inspectit.gepard.agent.instrumentation.hook.MethodHookManager; +import rocks.inspectit.gepard.agent.instrumentation.state.configuration.ConfigurationResolver; import rocks.inspectit.gepard.agent.internal.instrumentation.InstrumentedType; import rocks.inspectit.gepard.agent.internal.instrumentation.model.ClassInstrumentationConfiguration; /** Stores the instrumentation configuration of all instrumented classes. */ public class InstrumentationState { + private static final Logger log = LoggerFactory.getLogger(InstrumentationState.class); /** Store for every instrumented class */ private final Cache activeInstrumentations; private final ConfigurationResolver configurationResolver; - private InstrumentationState(ConfigurationResolver configurationResolver) { + private final MethodHookManager methodHookManager; + + private InstrumentationState( + ConfigurationResolver configurationResolver, MethodHookManager methodHookManager) { this.activeInstrumentations = Caffeine.newBuilder().build(); this.configurationResolver = configurationResolver; + this.methodHookManager = methodHookManager; } /** @@ -26,29 +34,32 @@ private InstrumentationState(ConfigurationResolver configurationResolver) { * * @return the created state */ - public static InstrumentationState create(ConfigurationResolver configurationResolver) { - return new InstrumentationState(configurationResolver); + public static InstrumentationState create( + ConfigurationResolver configurationResolver, MethodHookManager methodHookManager) { + return new InstrumentationState(configurationResolver, methodHookManager); } /** * Checks, if the provided class should be retransformed. A retransformation is necessary, if the - * new configuration differs from the current configuration. + * new configuration differs from the current configuration. Additionally, we trigger the update + * of the classes method hooks, if necessary. * * @param clazz the class * @return true, if the provided class should be retransformed */ public boolean shouldRetransform(Class clazz) { - ClassInstrumentationConfiguration activeConfig = - activeInstrumentations.asMap().entrySet().stream() - .filter(entry -> entry.getKey().isEqualTo(clazz)) // find class - .map(Map.Entry::getValue) // get configuration - .findAny() - .orElse(null); - + InstrumentedType type = new InstrumentedType(clazz.getName(), clazz.getClassLoader()); + ClassInstrumentationConfiguration currentConfig = activeInstrumentations.getIfPresent(type); ClassInstrumentationConfiguration newConfig = configurationResolver.getClassInstrumentationConfiguration(clazz); - if (Objects.nonNull(activeConfig)) return !activeConfig.equals(newConfig); + try { + updateHooks(clazz, currentConfig, newConfig); + } catch (Exception e) { + log.error("Could not update method hooks", e); + } + + if (Objects.nonNull(currentConfig)) return !currentConfig.equals(newConfig); return newConfig.isActive(); } @@ -93,4 +104,24 @@ public void addInstrumentedType( public void invalidateInstrumentedType(InstrumentedType type) { activeInstrumentations.invalidate(type); } + + /** + * Checks, if the instrumentation configurations of the provided class require method hooks. If + * one of the configurations is active, we require method hooks for them. Then we should update + * the method hooks. + * + * @param clazz the current class + * @param currentConfig the current instrumentation configuration of the class + * @param newConfig the new instrumentation configuration of the class + */ + private void updateHooks( + Class clazz, + ClassInstrumentationConfiguration currentConfig, + ClassInstrumentationConfiguration newConfig) { + boolean newConfigRequiresHooks = newConfig.isActive(); + boolean currentConfigRequiresHooks = Objects.nonNull(currentConfig) && currentConfig.isActive(); + + if (newConfigRequiresHooks || currentConfigRequiresHooks) + methodHookManager.updateHooksFor(clazz, newConfig); + } } diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/ConfigurationResolver.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/ConfigurationResolver.java similarity index 94% rename from inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/ConfigurationResolver.java rename to inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/ConfigurationResolver.java index 23c862a..a47905f 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/ConfigurationResolver.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/ConfigurationResolver.java @@ -1,14 +1,14 @@ /* (C) 2024 */ -package rocks.inspectit.gepard.agent.state; +package rocks.inspectit.gepard.agent.instrumentation.state.configuration; import java.util.Set; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; +import rocks.inspectit.gepard.agent.instrumentation.state.configuration.scope.ScopeResolver; import rocks.inspectit.gepard.agent.internal.configuration.model.instrumentation.InstrumentationConfiguration; import rocks.inspectit.gepard.agent.internal.instrumentation.InstrumentedType; import rocks.inspectit.gepard.agent.internal.instrumentation.model.ClassInstrumentationConfiguration; import rocks.inspectit.gepard.agent.internal.instrumentation.model.InstrumentationScope; -import rocks.inspectit.gepard.agent.state.scope.ScopeResolver; /** * Utility class to resolve the {@link InstrumentationConfiguration} and determine whether class diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/InspectitConfigurationHolder.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/InspectitConfigurationHolder.java similarity index 95% rename from inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/InspectitConfigurationHolder.java rename to inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/InspectitConfigurationHolder.java index d30032b..26b84d2 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/InspectitConfigurationHolder.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/InspectitConfigurationHolder.java @@ -1,5 +1,5 @@ /* (C) 2024 */ -package rocks.inspectit.gepard.agent.state; +package rocks.inspectit.gepard.agent.instrumentation.state.configuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/matcher/CustomElementMatchers.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/matcher/CustomElementMatchers.java similarity index 93% rename from inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/matcher/CustomElementMatchers.java rename to inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/matcher/CustomElementMatchers.java index 1288b55..784c32b 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/matcher/CustomElementMatchers.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/matcher/CustomElementMatchers.java @@ -1,5 +1,5 @@ /* (C) 2024 */ -package rocks.inspectit.gepard.agent.state.matcher; +package rocks.inspectit.gepard.agent.instrumentation.state.configuration.matcher; import net.bytebuddy.description.NamedElement; import net.bytebuddy.matcher.ElementMatcher; diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/matcher/MatcherChainBuilder.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/matcher/MatcherChainBuilder.java similarity index 96% rename from inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/matcher/MatcherChainBuilder.java rename to inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/matcher/MatcherChainBuilder.java index 7e0fbf4..83372c1 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/matcher/MatcherChainBuilder.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/matcher/MatcherChainBuilder.java @@ -1,5 +1,5 @@ /* (C) 2024 */ -package rocks.inspectit.gepard.agent.state.matcher; +package rocks.inspectit.gepard.agent.instrumentation.state.configuration.matcher; import static net.bytebuddy.matcher.ElementMatchers.not; diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/scope/ScopeResolver.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/scope/ScopeResolver.java similarity index 91% rename from inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/scope/ScopeResolver.java rename to inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/scope/ScopeResolver.java index 1a785f3..13a58fe 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/state/scope/ScopeResolver.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/scope/ScopeResolver.java @@ -1,17 +1,17 @@ /* (C) 2024 */ -package rocks.inspectit.gepard.agent.state.scope; +package rocks.inspectit.gepard.agent.instrumentation.state.configuration.scope; import java.util.*; import java.util.stream.Collectors; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatchers; +import rocks.inspectit.gepard.agent.instrumentation.state.configuration.InspectitConfigurationHolder; +import rocks.inspectit.gepard.agent.instrumentation.state.configuration.matcher.CustomElementMatchers; +import rocks.inspectit.gepard.agent.instrumentation.state.configuration.matcher.MatcherChainBuilder; import rocks.inspectit.gepard.agent.internal.configuration.model.instrumentation.InstrumentationConfiguration; import rocks.inspectit.gepard.agent.internal.configuration.model.instrumentation.Scope; import rocks.inspectit.gepard.agent.internal.instrumentation.model.InstrumentationScope; -import rocks.inspectit.gepard.agent.state.InspectitConfigurationHolder; -import rocks.inspectit.gepard.agent.state.matcher.CustomElementMatchers; -import rocks.inspectit.gepard.agent.state.matcher.MatcherChainBuilder; /** * This class is used to resolve the {@link Scope} based on the {@link Scope} List, contained in the diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/internal/instrumentation/model/ClassInstrumentationConfiguration.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/internal/instrumentation/model/ClassInstrumentationConfiguration.java index e8ca032..28ae375 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/internal/instrumentation/model/ClassInstrumentationConfiguration.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/internal/instrumentation/model/ClassInstrumentationConfiguration.java @@ -10,7 +10,7 @@ /** * Stores the instrumentation configuration for a specific class. Currently, a class can only be - * instrumented or not. Later, we could add a list of active rules for example. + * instrumented or not. */ public record ClassInstrumentationConfiguration( Set activeScopes, diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/transformation/DynamicTransformer.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/transformation/DynamicTransformer.java index 32bbd04..079ebd2 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/transformation/DynamicTransformer.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/transformation/DynamicTransformer.java @@ -11,10 +11,10 @@ import net.bytebuddy.utility.JavaModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import rocks.inspectit.gepard.agent.instrumentation.state.InstrumentationState; +import rocks.inspectit.gepard.agent.instrumentation.state.configuration.ConfigurationResolver; import rocks.inspectit.gepard.agent.internal.instrumentation.InstrumentedType; import rocks.inspectit.gepard.agent.internal.instrumentation.model.ClassInstrumentationConfiguration; -import rocks.inspectit.gepard.agent.state.ConfigurationResolver; -import rocks.inspectit.gepard.agent.state.InstrumentationState; import rocks.inspectit.gepard.agent.transformation.advice.InspectitAdvice; /** diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/transformation/TransformationManager.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/transformation/TransformationManager.java index 35b1617..85649ec 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/transformation/TransformationManager.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/transformation/TransformationManager.java @@ -4,7 +4,7 @@ import static net.bytebuddy.matcher.ElementMatchers.any; import net.bytebuddy.agent.builder.AgentBuilder; -import rocks.inspectit.gepard.agent.state.InstrumentationState; +import rocks.inspectit.gepard.agent.instrumentation.state.InstrumentationState; /** Responsible component for setting up class transformation for instrumentation */ public class TransformationManager { diff --git a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/transformation/advice/InspectitAdvice.java b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/transformation/advice/InspectitAdvice.java index fb71cb0..5b3db4f 100644 --- a/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/transformation/advice/InspectitAdvice.java +++ b/inspectit-gepard-agent/src/main/java/rocks/inspectit/gepard/agent/transformation/advice/InspectitAdvice.java @@ -11,7 +11,7 @@ public class InspectitAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( + public static IMethodHook onEnter( @Advice.AllArguments Object[] args, @Advice.This Object thiz, @Advice.Origin("#t") Class declaringClass, @@ -21,9 +21,9 @@ public static void onEnter( + signature + " of class: " + thiz.getClass().getName()); - System.out.println("HELLO GEPARD"); IMethodHook hook = Instances.hookManager.getHook(declaringClass, signature); hook.onEnter(args, thiz); + return hook; } @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) @@ -33,13 +33,12 @@ public static void onExit( @Advice.Thrown Throwable throwable, @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returnValue, @Advice.Origin("#m#s") String signature, - @Advice.Local("hook") IMethodHook hook) { + @Advice.Enter IMethodHook hook) { System.out.println( "Executing Exit Advice in method: " + signature + " of class: " + thiz.getClass().getName()); - System.out.println("BYE GEPARD"); hook.onExit(args, thiz, returnValue, throwable); } } diff --git a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/bootstrap/InspectitBootstrapManagerTest.java b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/bootstrap/BootstrapManagerTest.java similarity index 89% rename from inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/bootstrap/InspectitBootstrapManagerTest.java rename to inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/bootstrap/BootstrapManagerTest.java index 86098f6..6e0c48b 100644 --- a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/bootstrap/InspectitBootstrapManagerTest.java +++ b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/bootstrap/BootstrapManagerTest.java @@ -16,7 +16,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -class InspectitBootstrapManagerTest { +class BootstrapManagerTest { @Mock private Instrumentation instrumentation; @@ -29,7 +29,7 @@ void beforeEach() { @Test void bootstrapClassesAreAvailable() throws IOException { - InspectitBootstrapManager manager = Mockito.spy(InspectitBootstrapManager.class); + BootstrapManager manager = Mockito.spy(BootstrapManager.class); Mockito.doReturn(jarFile).when(manager).copyJarFile(anyString(), anyString()); manager.appendToBootstrapClassLoader(); diff --git a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/cache/process/BatchInstrumenterTest.java b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/cache/process/BatchInstrumenterTest.java index 9549bd9..54ca4fa 100644 --- a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/cache/process/BatchInstrumenterTest.java +++ b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/cache/process/BatchInstrumenterTest.java @@ -15,7 +15,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import rocks.inspectit.gepard.agent.instrumentation.cache.PendingClassesCache; -import rocks.inspectit.gepard.agent.state.InstrumentationState; +import rocks.inspectit.gepard.agent.instrumentation.state.InstrumentationState; @ExtendWith(MockitoExtension.class) class BatchInstrumenterTest { diff --git a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/InstrumentationStateTest.java b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/InstrumentationStateTest.java similarity index 59% rename from inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/InstrumentationStateTest.java rename to inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/InstrumentationStateTest.java index 5bacaae..47f1ad5 100644 --- a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/InstrumentationStateTest.java +++ b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/InstrumentationStateTest.java @@ -1,5 +1,5 @@ /* (C) 2024 */ -package rocks.inspectit.gepard.agent.state; +package rocks.inspectit.gepard.agent.instrumentation.state; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -10,6 +10,8 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import rocks.inspectit.gepard.agent.instrumentation.hook.MethodHookManager; +import rocks.inspectit.gepard.agent.instrumentation.state.configuration.ConfigurationResolver; import rocks.inspectit.gepard.agent.internal.instrumentation.InstrumentedType; import rocks.inspectit.gepard.agent.internal.instrumentation.model.ClassInstrumentationConfiguration; @@ -18,9 +20,11 @@ class InstrumentationStateTest { @Mock private ConfigurationResolver resolver; + @Mock private MethodHookManager hookState; + @Mock private ClassInstrumentationConfiguration configuration; - private InstrumentationState state; + private InstrumentationState instrumentationState; private static final Class TEST_CLASS = InstrumentationStateTest.class; @@ -29,12 +33,12 @@ class InstrumentationStateTest { @BeforeEach void beforeEach() { - state = InstrumentationState.create(resolver); + instrumentationState = InstrumentationState.create(resolver, hookState); } @Test void typeIsNotInstrumented() { - boolean isActive = state.isActive(TEST_TYPE); + boolean isActive = instrumentationState.isActive(TEST_TYPE); assertFalse(isActive); } @@ -43,9 +47,9 @@ void typeIsNotInstrumented() { void typeIsNotInstrumentedWithConfiguration() { when(configuration.isActive()).thenReturn(false); - state.addInstrumentedType(TEST_TYPE, configuration); + instrumentationState.addInstrumentedType(TEST_TYPE, configuration); - boolean isActive = state.isActive(TEST_TYPE); + boolean isActive = instrumentationState.isActive(TEST_TYPE); assertFalse(isActive); } @@ -54,19 +58,19 @@ void typeIsNotInstrumentedWithConfiguration() { void typeIsInstrumented() { when(configuration.isActive()).thenReturn(true); - state.addInstrumentedType(TEST_TYPE, configuration); + instrumentationState.addInstrumentedType(TEST_TYPE, configuration); - boolean isActive = state.isActive(TEST_TYPE); + boolean isActive = instrumentationState.isActive(TEST_TYPE); assertTrue(isActive); } @Test void typeIsDeinstrumented() { - state.addInstrumentedType(TEST_TYPE, configuration); - state.invalidateInstrumentedType(TEST_TYPE); + instrumentationState.addInstrumentedType(TEST_TYPE, configuration); + instrumentationState.invalidateInstrumentedType(TEST_TYPE); - boolean isActive = state.isActive(TEST_TYPE); + boolean isActive = instrumentationState.isActive(TEST_TYPE); assertFalse(isActive); } diff --git a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/ConfigurationResolverTest.java b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/ConfigurationResolverTest.java similarity index 97% rename from inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/ConfigurationResolverTest.java rename to inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/ConfigurationResolverTest.java index fccc79f..9a67dfe 100644 --- a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/ConfigurationResolverTest.java +++ b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/ConfigurationResolverTest.java @@ -1,5 +1,5 @@ /* (C) 2024 */ -package rocks.inspectit.gepard.agent.state; +package rocks.inspectit.gepard.agent.instrumentation.state.configuration; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.when; diff --git a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/InspectitConfigurationHolderTest.java b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/InspectitConfigurationHolderTest.java similarity index 95% rename from inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/InspectitConfigurationHolderTest.java rename to inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/InspectitConfigurationHolderTest.java index d0febd5..f310981 100644 --- a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/InspectitConfigurationHolderTest.java +++ b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/InspectitConfigurationHolderTest.java @@ -1,5 +1,5 @@ /* (C) 2024 */ -package rocks.inspectit.gepard.agent.state; +package rocks.inspectit.gepard.agent.instrumentation.state.configuration; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/matcher/CustomElementMatchersTest.java b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/matcher/CustomElementMatchersTest.java similarity index 92% rename from inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/matcher/CustomElementMatchersTest.java rename to inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/matcher/CustomElementMatchersTest.java index 5dd70da..7548df1 100644 --- a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/matcher/CustomElementMatchersTest.java +++ b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/matcher/CustomElementMatchersTest.java @@ -1,5 +1,5 @@ /* (C) 2024 */ -package rocks.inspectit.gepard.agent.state.matcher; +package rocks.inspectit.gepard.agent.instrumentation.state.configuration.matcher; import static org.junit.jupiter.api.Assertions.*; import static rocks.inspectit.gepard.agent.testutils.CustomAssertions.assertNamedElementMatcherMatches; diff --git a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/matcher/MatcherChainBuilderTest.java b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/matcher/MatcherChainBuilderTest.java similarity index 97% rename from inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/matcher/MatcherChainBuilderTest.java rename to inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/matcher/MatcherChainBuilderTest.java index 1eee847..d5e5e87 100644 --- a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/matcher/MatcherChainBuilderTest.java +++ b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/matcher/MatcherChainBuilderTest.java @@ -1,5 +1,5 @@ /* (C) 2024 */ -package rocks.inspectit.gepard.agent.state.matcher; +package rocks.inspectit.gepard.agent.instrumentation.state.configuration.matcher; import static net.bytebuddy.matcher.ElementMatchers.not; import static org.junit.jupiter.api.Assertions.*; diff --git a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/scope/ScopeResolverTest.java b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/scope/ScopeResolverTest.java similarity index 95% rename from inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/scope/ScopeResolverTest.java rename to inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/scope/ScopeResolverTest.java index 5a19162..5dc811c 100644 --- a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/state/scope/ScopeResolverTest.java +++ b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/instrumentation/state/configuration/scope/ScopeResolverTest.java @@ -1,5 +1,5 @@ /* (C) 2024 */ -package rocks.inspectit.gepard.agent.state.scope; +package rocks.inspectit.gepard.agent.instrumentation.state.configuration.scope; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; @@ -18,10 +18,10 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import rocks.inspectit.gepard.agent.instrumentation.state.configuration.InspectitConfigurationHolder; import rocks.inspectit.gepard.agent.internal.configuration.model.InspectitConfiguration; import rocks.inspectit.gepard.agent.internal.configuration.model.instrumentation.Scope; import rocks.inspectit.gepard.agent.internal.instrumentation.model.InstrumentationScope; -import rocks.inspectit.gepard.agent.state.InspectitConfigurationHolder; @ExtendWith(MockitoExtension.class) class ScopeResolverTest { diff --git a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/transformation/DynamicTransformerTest.java b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/transformation/DynamicTransformerTest.java index bba0821..1a9d38c 100644 --- a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/transformation/DynamicTransformerTest.java +++ b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/transformation/DynamicTransformerTest.java @@ -10,9 +10,9 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import rocks.inspectit.gepard.agent.instrumentation.state.InstrumentationState; import rocks.inspectit.gepard.agent.internal.instrumentation.InstrumentedType; import rocks.inspectit.gepard.agent.internal.instrumentation.model.ClassInstrumentationConfiguration; -import rocks.inspectit.gepard.agent.state.InstrumentationState; @ExtendWith(MockitoExtension.class) class DynamicTransformerTest { diff --git a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/transformation/TransformationManagerTest.java b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/transformation/TransformationManagerTest.java index dfd6fa5..83f1271 100644 --- a/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/transformation/TransformationManagerTest.java +++ b/inspectit-gepard-agent/src/test/java/rocks/inspectit/gepard/agent/transformation/TransformationManagerTest.java @@ -13,7 +13,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import rocks.inspectit.gepard.agent.state.InstrumentationState; +import rocks.inspectit.gepard.agent.instrumentation.state.InstrumentationState; @ExtendWith(MockitoExtension.class) class TransformationManagerTest { diff --git a/inspectit-gepard-bootstrap/src/main/java/rocks/inspectit/gepard/bootstrap/Instances.java b/inspectit-gepard-bootstrap/src/main/java/rocks/inspectit/gepard/bootstrap/Instances.java index 3bf349f..e7a38da 100644 --- a/inspectit-gepard-bootstrap/src/main/java/rocks/inspectit/gepard/bootstrap/Instances.java +++ b/inspectit-gepard-bootstrap/src/main/java/rocks/inspectit/gepard/bootstrap/Instances.java @@ -6,12 +6,13 @@ /** * Accessor for implementations of shared interfaces. These interfaces should be accessible in the - * target application as well as the gepard agent. The values are replaced by the actual + * target application as well as the gepard agent. The values will be replaced by the actual * implementations when a gepard-agent is started. */ public class Instances { private Instances() {} + // Must not be final public static IHookManager hookManager = NoopHookManager.INSTANCE; }