mirror of
https://github.com/keycloak/keycloak.git
synced 2025-12-16 12:05:49 -06:00
Clear classes loaded on the server side for run-on-server when a new execution happens (#44909)
Closes #44908 Signed-off-by: stianst <stianst@gmail.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
@@ -13,11 +14,11 @@ import org.keycloak.util.JsonSerialization;
|
||||
public class RunOnServerRealmResourceProvider implements RealmResourceProvider {
|
||||
|
||||
private final KeycloakSession session;
|
||||
private final ClassLoader classLoader;
|
||||
private final RunOnServerRealmResourceProviderFactory factory;
|
||||
|
||||
public RunOnServerRealmResourceProvider(KeycloakSession session, ClassLoader classLoader) {
|
||||
public RunOnServerRealmResourceProvider(KeycloakSession session, RunOnServerRealmResourceProviderFactory factory) {
|
||||
this.session = session;
|
||||
this.classLoader = classLoader;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -33,8 +34,9 @@ public class RunOnServerRealmResourceProvider implements RealmResourceProvider {
|
||||
@Path("/")
|
||||
@Consumes(MediaType.TEXT_PLAIN + ";charset=utf-8")
|
||||
@Produces(MediaType.TEXT_PLAIN + ";charset=utf-8")
|
||||
public String runOnServer(String runOnServer) {
|
||||
public String runOnServer(String runOnServer, @QueryParam("executionId") String executionId) {
|
||||
try {
|
||||
ClassLoader classLoader = factory.getTestClassLoader(executionId);
|
||||
Object o = SerializationUtil.decode(runOnServer, classLoader);
|
||||
if (o instanceof FetchOnServer f) {
|
||||
Object result = f.run(session);
|
||||
|
||||
@@ -11,11 +11,12 @@ public class RunOnServerRealmResourceProviderFactory implements RealmResourcePro
|
||||
|
||||
private static final String ID = "testing-run-on-server";
|
||||
|
||||
private String executionId;
|
||||
private ClassLoader testClassLoader;
|
||||
|
||||
@Override
|
||||
public RealmResourceProvider create(KeycloakSession session) {
|
||||
return new RunOnServerRealmResourceProvider(session, testClassLoader);
|
||||
return new RunOnServerRealmResourceProvider(session, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -31,6 +32,18 @@ public class RunOnServerRealmResourceProviderFactory implements RealmResourcePro
|
||||
return ID;
|
||||
}
|
||||
|
||||
public ClassLoader getTestClassLoader(String executionId) {
|
||||
if (!executionId.equals(this.executionId)) {
|
||||
try {
|
||||
testClassLoader = new TestClassLoader();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
this.executionId = executionId;
|
||||
}
|
||||
return testClassLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(org.keycloak.Config.Scope config) {
|
||||
try {
|
||||
|
||||
@@ -23,10 +23,12 @@ public class RunOnServerClient {
|
||||
private static final String RUN_ON_SERVER_ENDPOINT = "/testing-run-on-server";
|
||||
private final HttpClient httpClient;
|
||||
private final String url;
|
||||
private final int executionId;
|
||||
|
||||
public RunOnServerClient(HttpClient httpClient, String realmUrl) {
|
||||
public RunOnServerClient(HttpClient httpClient, String realmUrl, int executionId) {
|
||||
this.httpClient = httpClient;
|
||||
this.url = realmUrl + RUN_ON_SERVER_ENDPOINT;
|
||||
this.executionId = executionId;
|
||||
}
|
||||
|
||||
public <T> T fetch(FetchOnServerWrapper<T> wrapper) throws RunOnServerException {
|
||||
@@ -74,7 +76,7 @@ public class RunOnServerClient {
|
||||
|
||||
public String runOnServer(String encoded) throws RunOnServerException {
|
||||
try {
|
||||
HttpPost request = new HttpPost(url);
|
||||
HttpPost request = new HttpPost(url + "?executionId=" + executionId);
|
||||
request.setHeader("Content-type", "text/plain;charset=utf-8");
|
||||
request.setEntity(new StringEntity(encoded));
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.keycloak.testframework.injection.Supplier;
|
||||
import org.keycloak.testframework.injection.SupplierOrder;
|
||||
import org.keycloak.testframework.realm.ManagedRealm;
|
||||
import org.keycloak.testframework.remote.RemoteProviders;
|
||||
import org.keycloak.testframework.server.KeycloakServer;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
|
||||
@@ -17,6 +18,8 @@ public class RunOnServerSupplier implements Supplier<RunOnServerClient, InjectRu
|
||||
|
||||
@Override
|
||||
public RunOnServerClient getValue(InstanceContext<RunOnServerClient, InjectRunOnServer> instanceContext) {
|
||||
KeycloakServer server = instanceContext.getDependency(KeycloakServer.class);
|
||||
|
||||
HttpClient httpClient = instanceContext.getDependency(HttpClient.class);
|
||||
ManagedRealm realm = instanceContext.getDependency(ManagedRealm.class, instanceContext.getAnnotation().realmRef());
|
||||
instanceContext.getDependency(RemoteProviders.class);
|
||||
@@ -25,7 +28,7 @@ public class RunOnServerSupplier implements Supplier<RunOnServerClient, InjectRu
|
||||
String[] permittedPackages = instanceContext.getAnnotation().permittedPackages();
|
||||
testClassServer.addPermittedPackages(new HashSet<>(Arrays.asList(permittedPackages)));
|
||||
|
||||
return new RunOnServerClient(httpClient, realm.getBaseUrl());
|
||||
return new RunOnServerClient(httpClient, realm.getBaseUrl(), server.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user