Skip to content

Commit

Permalink
try MethodHandles
Browse files Browse the repository at this point in the history
  • Loading branch information
Mateusz Rzeszutek committed Jan 24, 2022
1 parent e056a8c commit 0c36f17
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 100 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

package io.opentelemetry.javaagent.instrumentation.redisson;

import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;

import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
Expand All @@ -21,9 +21,6 @@ public RedissonInstrumentationModule() {

@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(
new CommandDataInstrumentation(),
new CommandDataInstrumentation(),
new RedisConnectionInstrumentation());
return singletonList(new RedisConnectionInstrumentation());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@
import io.netty.buffer.ByteBuf;
import io.opentelemetry.instrumentation.api.db.RedisCommandSanitizer;
import io.opentelemetry.instrumentation.api.field.VirtualField;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.redisson.client.protocol.CommandData;
import org.redisson.client.protocol.CommandsData;
import org.redisson.misc.RPromise;

@AutoValue
public abstract class RedissonRequest {
Expand Down Expand Up @@ -103,17 +108,46 @@ private static String normalizeSingleCommand(CommandData<?, ?> command) {
return RedisCommandSanitizer.sanitize(command.getCommand().getName(), args);
}

// in 3.16.8 CommandsData#getPromise() and CommandData#getPromise() return type was changed in
// a backwards-incompatible way from RPromise to CompletableStage - to avoid calling that method
// and triggering muzzle we have to get the promise using a VirtualField
@Nullable
public CompletionStage<?> getPromise() {
Object command = getCommand();
if (command instanceof CommandData) {
return commandDataPromiseField.get((CommandData<?, ?>) command);
} else if (command instanceof CommandsData) {
return commandsDataPromiseField.get((CommandsData) command);
if (command instanceof CommandData && COMMAND_DATA_GET_PROMISE != null) {
try {
return (CompletionStage<?>) COMMAND_DATA_GET_PROMISE.invoke(command);
} catch (Throwable ignored) {
return null;
}
} else if (command instanceof CommandsData && COMMANDS_DATA_GET_PROMISE != null) {
try {
return (CompletionStage<?>) COMMANDS_DATA_GET_PROMISE.invoke(command);
} catch (Throwable ignored) {
return null;
}
}
return null;
}

private static final MethodHandle COMMAND_DATA_GET_PROMISE =
findGetPromiseMethod(CommandData.class);
private static final MethodHandle COMMANDS_DATA_GET_PROMISE =
findGetPromiseMethod(CommandsData.class);

private static MethodHandle findGetPromiseMethod(Class<?> commandClass) {
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
try {
// try versions older than 3.16.8
return lookup.findVirtual(commandClass, "getPromise", MethodType.methodType(RPromise.class));
} catch (NoSuchMethodException e) {
// in 3.16.8 CommandsData#getPromise() and CommandData#getPromise() return type was changed in
// a backwards-incompatible way from RPromise to CompletableFuture
try {
return lookup.findVirtual(
commandClass, "getPromise", MethodType.methodType(CompletableFuture.class));
} catch (NoSuchMethodException | IllegalAccessException ignored) {
return null;
}
} catch (IllegalAccessException ignored) {
return null;
}
}
}

0 comments on commit 0c36f17

Please sign in to comment.