Load all ProtoSchemas from the classpath

Closes #34971

Signed-off-by: Pedro Ruivo <pruivo@redhat.com>
This commit is contained in:
Pedro Ruivo 2025-03-27 14:41:01 +00:00 committed by GitHub
parent 065d5c4289
commit 6aa3f9d5a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 39 additions and 6 deletions

View File

@ -17,8 +17,12 @@
package org.keycloak.marshalling;
import java.util.List;
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
import org.infinispan.commons.util.ServiceFinder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.protostream.SerializationContextInitializer;
/**
* Ids of the protostream type.
@ -45,6 +49,19 @@ public final class Marshalling {
public static final String PROTO_SCHEMA_PACKAGE = "keycloak";
private static List<SerializationContextInitializer> SCHEMAS;
public static List<SerializationContextInitializer> getSchemas() {
if (SCHEMAS == null) {
setSchemas(ServiceFinder.load(SerializationContextInitializer.class).stream().toList());
}
return SCHEMAS;
}
public static void setSchemas(List<SerializationContextInitializer> schemas) {
SCHEMAS = List.copyOf(schemas);
}
private Marshalling() {
}
@ -166,12 +183,11 @@ public final class Marshalling {
public static final int RELOAD_CERTIFICATE_FUNCTION = 65615;
public static void configure(GlobalConfigurationBuilder builder) {
builder.serialization()
.addContextInitializer(KeycloakModelSchema.INSTANCE);
getSchemas().forEach(builder.serialization()::addContextInitializer);
}
public static void configure(ConfigurationBuilder builder) {
builder.addContextInitializer(KeycloakModelSchema.INSTANCE);
getSchemas().forEach(builder::addContextInitializer);
}
public static String protoEntity(Class<?> clazz) {

View File

@ -57,6 +57,7 @@ import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
import org.hibernate.jpa.boot.internal.PersistenceXmlParser;
import org.infinispan.protostream.SerializationContextInitializer;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationTransformation;
@ -147,6 +148,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.jar.JarEntry;
@ -684,6 +686,15 @@ class KeycloakProcessor {
hotFiles.produce(new HotDeploymentWatchedFileBuildItem("META-INF/keycloak.conf"));
}
@Record(ExecutionTime.STATIC_INIT)
@BuildStep
void configureProtoStreamSchemas(KeycloakRecorder recorder) {
var schemas = ServiceLoader.load(SerializationContextInitializer.class).stream()
.map(ServiceLoader.Provider::get)
.toList();
recorder.configureProtoStreamSchemas(schemas);
}
private Map<Spi, Map<Class<? extends Provider>, Map<String, ProviderFactory>>> loadFactories(
Map<String, ProviderFactory> preConfiguredProviders) {
Config.init(new MicroProfileConfigProvider());
@ -844,7 +855,7 @@ class KeycloakProcessor {
metadata.setCode(StreamUtil.readString(in, StandardCharsets.UTF_8));
}
metadata.setId(new StringBuilder("script").append("-").append(fileName).toString());
metadata.setId("script-" + fileName);
String name = metadata.getName();

View File

@ -30,6 +30,7 @@ import liquibase.Scope;
import liquibase.servicelocator.ServiceLocator;
import org.hibernate.cfg.AvailableSettings;
import org.infinispan.commons.util.FileLookupFactory;
import org.infinispan.protostream.SerializationContextInitializer;
import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.common.Profile;
@ -37,6 +38,7 @@ import org.keycloak.common.crypto.CryptoIntegration;
import org.keycloak.common.crypto.CryptoProvider;
import org.keycloak.common.crypto.FipsMode;
import org.keycloak.config.TruststoreOptions;
import org.keycloak.marshalling.Marshalling;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.Spi;
@ -209,4 +211,8 @@ public class KeycloakRecorder {
throw new RuntimeException("Unexpected error when configuring the crypto provider: " + cryptoProvider, cause);
}
}
public void configureProtoStreamSchemas(List<SerializationContextInitializer> schemas) {
Marshalling.setSchemas(schemas);
}
}

View File

@ -21,7 +21,7 @@ import org.infinispan.transaction.TransactionMode;
import org.junit.rules.ExternalResource;
import org.keycloak.Config;
import org.keycloak.connections.infinispan.InfinispanUtil;
import org.keycloak.marshalling.KeycloakModelSchema;
import org.keycloak.marshalling.Marshalling;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.ACTION_TOKEN_CACHE;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME;
@ -75,7 +75,7 @@ public class HotRodServerRule extends ExternalResource {
// Create a Hot Rod client
org.infinispan.client.hotrod.configuration.ConfigurationBuilder remoteBuilder = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder();
remoteBuilder.addContextInitializers(KeycloakModelSchema.INSTANCE);
Marshalling.configure(remoteBuilder);
org.infinispan.client.hotrod.configuration.Configuration cfg = remoteBuilder
.addServers(hotRodServer.getHost() + ":" + hotRodServer.getPort() + ";"
+ hotRodServer2.getHost() + ":" + hotRodServer2.getPort()).build();