Created
May 6, 2021 03:39
-
-
Save ldaley/6cc6031cf90882100545342cf94ed7a6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/CustomSessionModule.java b/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/CustomSessionModule.java | |
index 779a08fa6c2..e9d287631b2 100644 | |
--- a/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/CustomSessionModule.java | |
+++ b/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/CustomSessionModule.java | |
@@ -6,6 +6,7 @@ import com.google.inject.Provides; | |
import com.google.inject.util.Modules; | |
import com.gradle.ratpack.appmeta.mode.ApplicationEnv; | |
import com.gradle.ratpack.appmeta.mode.ApplicationMode; | |
+import com.gradle.ratpack.feature.Feature; | |
import com.gradle.ratpack.util.UnhandledSwitchValueException; | |
import com.gradle.ratpack.util.uuid.UniqueId; | |
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; | |
@@ -32,6 +33,12 @@ public final class CustomSessionModule extends AbstractModule { | |
@Override | |
protected void configure() { | |
+ Feature.of(NewSessionFormatFeature.class, binder(), s -> s | |
+ .optionalInAllEnvs() | |
+ .defaultEnabled(m -> false) | |
+ .allowRequestOverride(m -> true) | |
+ ); | |
+ | |
switch (storageType) { | |
case CLIENT: | |
install( | |
@@ -55,7 +62,9 @@ public final class CustomSessionModule extends AbstractModule { | |
@Override | |
protected void configure() { | |
- bind(JavaSessionSerializer.class).to(ObfuscationAwareKryoSessionSerializer.class); | |
+ bind(JavaSessionSerializer.class).to(TogglingSessionSerializer.class); | |
+ bind(ObfuscationAwareKryoSessionSerializer.class); | |
+ bind(KryoSessionSerializer.class); | |
} | |
} | |
diff --git a/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/KryoSessionSerializer.java b/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/KryoSessionSerializer.java | |
new file mode 100644 | |
index 00000000000..493ea2d4c98 | |
--- /dev/null | |
+++ b/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/KryoSessionSerializer.java | |
@@ -0,0 +1,57 @@ | |
+package com.gradle.ratpack.session; | |
+ | |
+import com.esotericsoftware.kryo.Kryo; | |
+import com.esotericsoftware.kryo.io.Input; | |
+import com.esotericsoftware.kryo.io.KryoObjectInput; | |
+import com.esotericsoftware.kryo.io.KryoObjectOutput; | |
+import com.esotericsoftware.kryo.io.Output; | |
+import com.google.inject.Singleton; | |
+import com.gradle.obfuscation.ObfuscationControl; | |
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; | |
+import io.netty.util.concurrent.FastThreadLocal; | |
+import org.objenesis.strategy.StdInstantiatorStrategy; | |
+import ratpack.session.JavaSessionSerializer; | |
+ | |
+import java.io.IOException; | |
+import java.io.InputStream; | |
+import java.io.ObjectInput; | |
+import java.io.ObjectOutput; | |
+import java.io.OutputStream; | |
+ | |
+@Singleton | |
+final class KryoSessionSerializer implements JavaSessionSerializer { | |
+ | |
+ private static final FastThreadLocal<Kryo> KRYO = new FastThreadLocal<Kryo>() { | |
+ @Override | |
+ protected Kryo initialValue() { | |
+ Kryo kryo = new Kryo(); | |
+ kryo.setInstantiatorStrategy(new StdInstantiatorStrategy()); | |
+ kryo.setClassLoader(Thread.currentThread().getContextClassLoader()); | |
+ return kryo; | |
+ } | |
+ }; | |
+ | |
+ @Override | |
+ @SuppressWarnings("deprecation") | |
+ public <T> void serialize(Class<T> type, T value, OutputStream out) throws IOException { | |
+ ObfuscationControl.requireClassName(type, () -> "class is serialized into session"); | |
+ try (ObjectOutput objectOut = new KryoObjectOutput(KRYO.get(), new Output(out))) { | |
+ objectOut.writeObject(value); | |
+ } | |
+ } | |
+ | |
+ @Override | |
+ @SuppressFBWarnings(value = "SECOBDES", justification = "object deserialization is intentional") | |
+ @SuppressWarnings("deprecation") | |
+ public <T> T deserialize(Class<T> type, InputStream in) throws Exception { | |
+ try (ObjectInput objectInput = new KryoObjectInput(KRYO.get(), new Input(in))) { | |
+ Object obj = objectInput.readObject(); | |
+ if (type.isInstance(obj)) { | |
+ return type.cast(obj); | |
+ } else { | |
+ throw new IllegalStateException("Expected " + type + " got " + obj.getClass()); | |
+ } | |
+ } | |
+ } | |
+ | |
+} | |
diff --git a/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/NewSessionFormatFeature.java b/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/NewSessionFormatFeature.java | |
new file mode 100644 | |
index 00000000000..cbb56d8b2f4 | |
--- /dev/null | |
+++ b/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/NewSessionFormatFeature.java | |
@@ -0,0 +1,8 @@ | |
+package com.gradle.ratpack.session; | |
+ | |
+import com.gradle.obfuscation.KeepName; | |
+import com.gradle.ratpack.feature.Feature; | |
+ | |
+@KeepName | |
+public interface NewSessionFormatFeature extends Feature { | |
+} | |
diff --git a/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/TogglingSessionSerializer.java b/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/TogglingSessionSerializer.java | |
new file mode 100644 | |
index 00000000000..54866eb44cb | |
--- /dev/null | |
+++ b/ratpack-app-lib-common/src/main/java/com/gradle/ratpack/session/TogglingSessionSerializer.java | |
@@ -0,0 +1,46 @@ | |
+package com.gradle.ratpack.session; | |
+ | |
+import ratpack.session.JavaSessionSerializer; | |
+import ratpack.session.SessionTypeFilter; | |
+ | |
+import javax.inject.Inject; | |
+import javax.inject.Singleton; | |
+import java.io.InputStream; | |
+import java.io.OutputStream; | |
+ | |
+@Singleton | |
+final class TogglingSessionSerializer implements JavaSessionSerializer { | |
+ | |
+ private final NewSessionFormatFeature feature; | |
+ private final KryoSessionSerializer oldSerializer; | |
+ private final ObfuscationAwareKryoSessionSerializer newSerializer; | |
+ | |
+ @Inject | |
+ TogglingSessionSerializer( | |
+ NewSessionFormatFeature feature, | |
+ KryoSessionSerializer oldSerializer, | |
+ ObfuscationAwareKryoSessionSerializer newSerializer | |
+ ) { | |
+ this.feature = feature; | |
+ this.oldSerializer = oldSerializer; | |
+ this.newSerializer = newSerializer; | |
+ } | |
+ | |
+ @Override | |
+ public <T> void serialize(Class<T> type, T value, OutputStream out, SessionTypeFilter typeFilter) throws Exception { | |
+ if (feature.isEnabled()) { | |
+ newSerializer.serialize(type, value, out, typeFilter); | |
+ } else { | |
+ oldSerializer.serialize(type, value, out, typeFilter); | |
+ } | |
+ } | |
+ | |
+ @Override | |
+ public <T> T deserialize(Class<T> type, InputStream in, SessionTypeFilter typeFilter) throws Exception { | |
+ if (feature.isEnabled()) { | |
+ return newSerializer.deserialize(type, in, typeFilter); | |
+ } else { | |
+ return oldSerializer.deserialize(type, in, typeFilter); | |
+ } | |
+ } | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment