KEYCLOAK-19030 Implement HotRodConnectionProvider
This commit is contained in:
parent
36f7139bdd
commit
af97849feb
24 changed files with 846 additions and 18 deletions
4
dependencies/server-all/pom.xml
vendored
4
dependencies/server-all/pom.xml
vendored
|
@ -48,6 +48,10 @@
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-model-infinispan</artifactId>
|
<artifactId>keycloak-model-infinispan</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-model-map-hot-rod</artifactId>
|
||||||
|
</dependency>
|
||||||
<!-- identity providers -->
|
<!-- identity providers -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.twitter4j</groupId>
|
<groupId>org.twitter4j</groupId>
|
||||||
|
|
|
@ -200,6 +200,16 @@
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-model-map-hot-rod</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>*</groupId>
|
||||||
|
<artifactId>*</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-saml-core</artifactId>
|
<artifactId>keycloak-saml-core</artifactId>
|
||||||
|
|
52
model/hot-rod/pom.xml
Normal file
52
model/hot-rod/pom.xml
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>keycloak-model-pom</artifactId>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<version>16.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>keycloak-model-map-hot-rod</artifactId>
|
||||||
|
<name>Keycloak Model Hot Rod</name>
|
||||||
|
<description/>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-model-map</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-client-hotrod</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-query-dsl</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-remote-query-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-server-router</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-server-rest</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-server-runtime</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan.protostream</groupId>
|
||||||
|
<artifactId>protostream-processor</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.keycloak.models.map.common;
|
||||||
|
|
||||||
|
import org.infinispan.manager.DefaultCacheManager;
|
||||||
|
import org.infinispan.rest.RestServer;
|
||||||
|
import org.infinispan.rest.configuration.RestServerConfigurationBuilder;
|
||||||
|
import org.infinispan.server.configuration.endpoint.SinglePortServerConfigurationBuilder;
|
||||||
|
import org.infinispan.server.hotrod.HotRodServer;
|
||||||
|
import org.infinispan.server.hotrod.configuration.HotRodServerConfigurationBuilder;
|
||||||
|
import org.infinispan.server.router.RoutingTable;
|
||||||
|
import org.infinispan.server.router.configuration.SinglePortRouterConfiguration;
|
||||||
|
import org.infinispan.server.router.router.impl.singleport.SinglePortEndpointRouter;
|
||||||
|
import org.infinispan.server.router.routes.Route;
|
||||||
|
import org.infinispan.server.router.routes.RouteDestination;
|
||||||
|
import org.infinispan.server.router.routes.RouteSource;
|
||||||
|
import org.infinispan.server.router.routes.hotrod.HotRodServerRouteDestination;
|
||||||
|
import org.infinispan.server.router.routes.rest.RestServerRouteDestination;
|
||||||
|
import org.infinispan.server.router.routes.singleport.SinglePortRouteSource;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||||
|
*/
|
||||||
|
public class HotRodUtils {
|
||||||
|
/**
|
||||||
|
* Not suitable for a production usage. Only for development and test purposes.
|
||||||
|
* Also do not use in clustered environment.
|
||||||
|
* @param hotRodServer HotRodServer
|
||||||
|
* @param hotRodCacheManager DefaultCacheManager
|
||||||
|
* @param embeddedPort int
|
||||||
|
*/
|
||||||
|
public static void createHotRodMapStoreServer(HotRodServer hotRodServer, DefaultCacheManager hotRodCacheManager, int embeddedPort) {
|
||||||
|
HotRodServerConfigurationBuilder hotRodServerConfigurationBuilder = new HotRodServerConfigurationBuilder();
|
||||||
|
hotRodServerConfigurationBuilder.startTransport(false);
|
||||||
|
hotRodServerConfigurationBuilder.port(embeddedPort);
|
||||||
|
hotRodServer.start(hotRodServerConfigurationBuilder.build(), hotRodCacheManager);
|
||||||
|
|
||||||
|
RestServerConfigurationBuilder restServerConfigurationBuilder = new RestServerConfigurationBuilder();
|
||||||
|
restServerConfigurationBuilder.startTransport(false);
|
||||||
|
restServerConfigurationBuilder.port(embeddedPort);
|
||||||
|
RestServer restServer = new RestServer();
|
||||||
|
restServer.start(restServerConfigurationBuilder.build(), hotRodCacheManager);
|
||||||
|
|
||||||
|
SinglePortRouteSource routeSource = new SinglePortRouteSource();
|
||||||
|
Set<Route<? extends RouteSource, ? extends RouteDestination>> routes = new HashSet<>();
|
||||||
|
routes.add(new Route<>(routeSource, new HotRodServerRouteDestination("hotrod", hotRodServer)));
|
||||||
|
routes.add(new Route<>(routeSource, new RestServerRouteDestination("rest", restServer)));
|
||||||
|
|
||||||
|
SinglePortRouterConfiguration singlePortRouter = new SinglePortServerConfigurationBuilder().port(embeddedPort).build();
|
||||||
|
SinglePortEndpointRouter endpointServer = new SinglePortEndpointRouter(singlePortRouter);
|
||||||
|
endpointServer.start(new RoutingTable(routes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not suitable for a production usage. Only for development and test purposes.
|
||||||
|
* Also do not use in clustered environment.
|
||||||
|
* @param embeddedPort int
|
||||||
|
*/
|
||||||
|
public static void createHotRodMapStoreServer(int embeddedPort) {
|
||||||
|
DefaultCacheManager hotRodCacheManager = null;
|
||||||
|
try {
|
||||||
|
hotRodCacheManager = new DefaultCacheManager("config/infinispan.xml");
|
||||||
|
} catch (IOException e) {
|
||||||
|
new RuntimeException("Cannot initialize cache manager!", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
HotRodUtils.createHotRodMapStoreServer(new HotRodServer(), hotRodCacheManager, embeddedPort);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.common;
|
||||||
|
|
||||||
|
import org.infinispan.protostream.GeneratedSchema;
|
||||||
|
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;
|
||||||
|
//import org.keycloak.models.map.client.HotRodAttributeEntity;
|
||||||
|
//import org.keycloak.models.map.client.HotRodClientEntity;
|
||||||
|
//import org.keycloak.models.map.client.HotRodPair;
|
||||||
|
//import org.keycloak.models.map.client.HotRodProtocolMapperEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||||
|
*/
|
||||||
|
@AutoProtoSchemaBuilder(
|
||||||
|
includeClasses = {
|
||||||
|
//HotRodAttributeEntity.class,
|
||||||
|
//HotRodClientEntity.class,
|
||||||
|
//HotRodProtocolMapperEntity.class,
|
||||||
|
//HotRodPair.class
|
||||||
|
},
|
||||||
|
schemaFileName = "KeycloakHotRodMapStorage.proto",
|
||||||
|
schemaFilePath = "proto/",
|
||||||
|
schemaPackageName = "org.keycloak.models.map.storage.hotrod")
|
||||||
|
public interface ProtoSchemaInitializer extends GeneratedSchema {
|
||||||
|
ProtoSchemaInitializer INSTANCE = new ProtoSchemaInitializerImpl();
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.keycloak.models.map.connections;
|
||||||
|
|
||||||
|
import org.infinispan.client.hotrod.RemoteCache;
|
||||||
|
import org.infinispan.client.hotrod.RemoteCacheManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||||
|
*/
|
||||||
|
public class DefaultHotRodConnectionProvider implements HotRodConnectionProvider {
|
||||||
|
|
||||||
|
private RemoteCacheManager remoteCacheManager;
|
||||||
|
|
||||||
|
public DefaultHotRodConnectionProvider(RemoteCacheManager remoteCacheManager) {
|
||||||
|
this.remoteCacheManager = remoteCacheManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <K, V> RemoteCache<K, V> getRemoteCache(String name) {
|
||||||
|
return remoteCacheManager.getCache(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.keycloak.models.map.connections;
|
||||||
|
|
||||||
|
import org.infinispan.client.hotrod.RemoteCache;
|
||||||
|
import org.infinispan.client.hotrod.RemoteCacheManager;
|
||||||
|
import org.infinispan.client.hotrod.configuration.ClientIntelligence;
|
||||||
|
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
|
||||||
|
import org.infinispan.commons.marshall.ProtoStreamMarshaller;
|
||||||
|
import org.infinispan.protostream.GeneratedSchema;
|
||||||
|
import org.infinispan.query.remote.client.ProtobufMetadataManagerConstants;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
//import org.keycloak.models.map.common.HotRodEntityDescriptor;
|
||||||
|
import org.keycloak.models.map.common.HotRodUtils;
|
||||||
|
import org.keycloak.models.map.common.ProtoSchemaInitializer;
|
||||||
|
//import org.keycloak.models.map.storage.hotRod.HotRodMapStorageProviderFactory;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||||
|
*/
|
||||||
|
public class DefaultHotRodConnectionProviderFactory implements HotRodConnectionProviderFactory {
|
||||||
|
|
||||||
|
public static final String PROVIDER_ID = "default";
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(DefaultHotRodConnectionProviderFactory.class);
|
||||||
|
|
||||||
|
private org.keycloak.Config.Scope config;
|
||||||
|
|
||||||
|
private RemoteCacheManager remoteCacheManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HotRodConnectionProvider create(KeycloakSession session) {
|
||||||
|
if (remoteCacheManager == null) {
|
||||||
|
lazyInit();
|
||||||
|
}
|
||||||
|
return new DefaultHotRodConnectionProvider(remoteCacheManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postInit(KeycloakSessionFactory factory) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return PROVIDER_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(org.keycloak.Config.Scope config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lazyInit() {
|
||||||
|
if (config.getBoolean("embedded", false)) {
|
||||||
|
HotRodUtils.createHotRodMapStoreServer(config.getInt("embeddedPort", 11444));
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationBuilder remoteBuilder = new ConfigurationBuilder();
|
||||||
|
remoteBuilder.addServer()
|
||||||
|
.host(config.get("host", "localhost"))
|
||||||
|
.port(config.getInt("port", 11444))
|
||||||
|
.clientIntelligence(ClientIntelligence.HASH_DISTRIBUTION_AWARE)
|
||||||
|
.marshaller(new ProtoStreamMarshaller());
|
||||||
|
|
||||||
|
if (config.getBoolean("enableSecurity", true)) {
|
||||||
|
remoteBuilder.security()
|
||||||
|
.authentication()
|
||||||
|
.saslMechanism("SCRAM-SHA-512")
|
||||||
|
.username(config.get("username", "admin"))
|
||||||
|
.password(config.get("password", "admin"))
|
||||||
|
.realm(config.get("realm", "default"));
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean configureRemoteCaches = config.getBoolean("configureRemoteCaches", false);
|
||||||
|
if (configureRemoteCaches) {
|
||||||
|
configureRemoteCaches(remoteBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteBuilder.addContextInitializer(ProtoSchemaInitializer.INSTANCE);
|
||||||
|
remoteCacheManager = new RemoteCacheManager(remoteBuilder.build());
|
||||||
|
|
||||||
|
if (configureRemoteCaches) {
|
||||||
|
// access the caches to force their creation
|
||||||
|
/*HotRodMapStorageProviderFactory.ENTITY_DESCRIPTOR_MAP.values().stream()
|
||||||
|
.map(HotRodEntityDescriptor::getCacheName)
|
||||||
|
.forEach(remoteCacheManager::getCache);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
registerSchemata(ProtoSchemaInitializer.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerSchemata(GeneratedSchema initializer) {
|
||||||
|
final RemoteCache<String, String> protoMetadataCache = remoteCacheManager.getCache(ProtobufMetadataManagerConstants.PROTOBUF_METADATA_CACHE_NAME);
|
||||||
|
|
||||||
|
protoMetadataCache.put(initializer.getProtoFileName(), initializer.getProtoFile());
|
||||||
|
|
||||||
|
String errors = protoMetadataCache.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX);
|
||||||
|
if (errors != null) {
|
||||||
|
throw new IllegalStateException("Some Protobuf schema files contain errors: " + errors + "\nSchema :\n" + initializer.getProtoFileName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureRemoteCaches(ConfigurationBuilder builder) {
|
||||||
|
URI uri;
|
||||||
|
try {
|
||||||
|
uri = DefaultHotRodConnectionProviderFactory.class.getClassLoader().getResource("config/cacheConfig.xml").toURI();
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
throw new RuntimeException("Cannot read the cache configuration!", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*HotRodMapStorageProviderFactory.ENTITY_DESCRIPTOR_MAP.values().stream()
|
||||||
|
.map(HotRodEntityDescriptor::getCacheName)
|
||||||
|
.forEach(name -> builder.remoteCache(name).configurationURI(uri));*/
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.connections;
|
||||||
|
|
||||||
|
import org.infinispan.client.hotrod.RemoteCache;
|
||||||
|
import org.keycloak.provider.Provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||||
|
*/
|
||||||
|
public interface HotRodConnectionProvider extends Provider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a remote Infinispan cache specified by the given name.
|
||||||
|
* @param name String Name of the remote cache.
|
||||||
|
* @param <K> key
|
||||||
|
* @param <V> value
|
||||||
|
* @return A remote Infinispan cache specified by name.
|
||||||
|
*/
|
||||||
|
<K, V> RemoteCache<K, V> getRemoteCache(String name);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.connections;
|
||||||
|
|
||||||
|
import org.keycloak.provider.ProviderFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||||
|
*/
|
||||||
|
public interface HotRodConnectionProviderFactory extends ProviderFactory<HotRodConnectionProvider> {
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.connections;
|
||||||
|
|
||||||
|
import org.keycloak.provider.Provider;
|
||||||
|
import org.keycloak.provider.ProviderFactory;
|
||||||
|
import org.keycloak.provider.Spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||||
|
*/
|
||||||
|
public class HotRodConnectionSpi implements Spi {
|
||||||
|
|
||||||
|
public static final String NAME = "connectionsHotRod";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInternal() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Provider> getProviderClass() {
|
||||||
|
return HotRodConnectionProvider.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||||
|
return HotRodConnectionProviderFactory.class;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#
|
||||||
|
# Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
# and other contributors as indicated by the @author tags.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
org.keycloak.models.map.connections.DefaultHotRodConnectionProviderFactory
|
|
@ -0,0 +1,18 @@
|
||||||
|
#
|
||||||
|
# Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
# and other contributors as indicated by the @author tags.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
org.keycloak.models.map.connections.HotRodConnectionSpi
|
10
model/hot-rod/src/main/resources/config/cacheConfig.xml
Normal file
10
model/hot-rod/src/main/resources/config/cacheConfig.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<!-- Used for configuration of remote caches on the Infinispan server if the configureRemoteCaches option is set to true
|
||||||
|
in DefaultHotRodConnectionProviderFactory configuration. -->
|
||||||
|
<infinispan>
|
||||||
|
<cache-container>
|
||||||
|
<!-- Specify all remote caches that should be created on the Infinispan server. -->
|
||||||
|
<distributed-cache name="clients" mode="SYNC">
|
||||||
|
<encoding media-type="application/x-protostream"/>
|
||||||
|
</distributed-cache>
|
||||||
|
</cache-container>
|
||||||
|
</infinispan>
|
12
model/hot-rod/src/main/resources/config/infinispan.xml
Normal file
12
model/hot-rod/src/main/resources/config/infinispan.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<!-- Configuration is used to start embedded Infinispan server in DefaultHotRodConnectionProviderFactory if
|
||||||
|
the embedded property is set tu true.-->
|
||||||
|
<infinispan>
|
||||||
|
<cache-container>
|
||||||
|
<transport stack="udp"/>
|
||||||
|
|
||||||
|
<!-- Specify all remote caches that should be created on the embedded Infinispan server. -->
|
||||||
|
<distributed-cache name="clients" mode="SYNC">
|
||||||
|
<encoding media-type="application/x-protostream"/>
|
||||||
|
</distributed-cache>
|
||||||
|
</cache-container>
|
||||||
|
</infinispan>
|
|
@ -75,10 +75,5 @@
|
||||||
<artifactId>microprofile-metrics-api</artifactId>
|
<artifactId>microprofile-metrics-api</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.infinispan</groupId>
|
|
||||||
<artifactId>infinispan-server-hotrod</artifactId>
|
|
||||||
<version>${infinispan.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -35,5 +35,6 @@
|
||||||
<module>infinispan</module>
|
<module>infinispan</module>
|
||||||
<module>map</module>
|
<module>map</module>
|
||||||
<module>build-processor</module>
|
<module>build-processor</module>
|
||||||
|
<module>hot-rod</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
||||||
|
|
53
pom.xml
53
pom.xml
|
@ -78,6 +78,7 @@
|
||||||
<hibernate.core.version>5.3.20.Final</hibernate.core.version>
|
<hibernate.core.version>5.3.20.Final</hibernate.core.version>
|
||||||
<hibernate.c3p0.version>5.3.20.Final</hibernate.c3p0.version>
|
<hibernate.c3p0.version>5.3.20.Final</hibernate.c3p0.version>
|
||||||
<infinispan.version>11.0.9.Final</infinispan.version>
|
<infinispan.version>11.0.9.Final</infinispan.version>
|
||||||
|
<infinispan.protostream.processor.version>4.3.4.Final</infinispan.protostream.processor.version>
|
||||||
<jackson.version>2.12.1</jackson.version>
|
<jackson.version>2.12.1</jackson.version>
|
||||||
<jackson.databind.version>${jackson.version}</jackson.databind.version>
|
<jackson.databind.version>${jackson.version}</jackson.databind.version>
|
||||||
<jackson.annotations.version>${jackson.databind.version}</jackson.annotations.version>
|
<jackson.annotations.version>${jackson.databind.version}</jackson.annotations.version>
|
||||||
|
@ -908,6 +909,53 @@
|
||||||
<artifactId>infinispan-jboss-marshalling</artifactId>
|
<artifactId>infinispan-jboss-marshalling</artifactId>
|
||||||
<version>${infinispan.version}</version>
|
<version>${infinispan.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-server-core</artifactId>
|
||||||
|
<version>${infinispan.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-server-router</artifactId>
|
||||||
|
<version>${infinispan.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-server-runtime</artifactId>
|
||||||
|
<version>${infinispan.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>*</groupId>
|
||||||
|
<artifactId>*</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-server-rest</artifactId>
|
||||||
|
<version>${infinispan.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-client-hotrod</artifactId>
|
||||||
|
<version>${infinispan.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-query-dsl</artifactId>
|
||||||
|
<version>${infinispan.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-remote-query-client</artifactId>
|
||||||
|
<version>${infinispan.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan.protostream</groupId>
|
||||||
|
<artifactId>protostream-processor</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<version>${infinispan.protostream.processor.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jboss.marshalling</groupId>
|
<groupId>org.jboss.marshalling</groupId>
|
||||||
<artifactId>jboss-marshalling</artifactId>
|
<artifactId>jboss-marshalling</artifactId>
|
||||||
|
@ -1243,6 +1291,11 @@
|
||||||
<artifactId>keycloak-model-infinispan</artifactId>
|
<artifactId>keycloak-model-infinispan</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-model-map-hot-rod</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>launcher</artifactId>
|
<artifactId>launcher</artifactId>
|
||||||
|
|
|
@ -48,42 +48,90 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"realm": {
|
"realm": {
|
||||||
"provider": "${keycloak.realm.provider:jpa}"
|
"provider": "${keycloak.realm.provider:jpa}",
|
||||||
|
"map": {
|
||||||
|
"storage": {
|
||||||
|
"provider": "${keycloak.realm.map.storage.provider:concurrenthashmap}"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"user": {
|
"user": {
|
||||||
"provider": "${keycloak.user.provider:jpa}"
|
"provider": "${keycloak.user.provider:jpa}",
|
||||||
|
"map": {
|
||||||
|
"storage": {
|
||||||
|
"provider": "${keycloak.user.map.storage.provider:concurrenthashmap}"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"client": {
|
"client": {
|
||||||
"provider": "${keycloak.client.provider:jpa}"
|
"provider": "${keycloak.client.provider:jpa}",
|
||||||
|
"map": {
|
||||||
|
"storage": {
|
||||||
|
"provider": "${keycloak.client.map.storage.provider:concurrenthashmap}"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"clientScope": {
|
"clientScope": {
|
||||||
"provider": "${keycloak.clientScope.provider:jpa}"
|
"provider": "${keycloak.clientScope.provider:jpa}",
|
||||||
|
"map": {
|
||||||
|
"storage": {
|
||||||
|
"provider": "${keycloak.clientScope.map.storage.provider:concurrenthashmap}"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"group": {
|
"group": {
|
||||||
"provider": "${keycloak.group.provider:jpa}"
|
"provider": "${keycloak.group.provider:jpa}",
|
||||||
|
"map": {
|
||||||
|
"storage": {
|
||||||
|
"provider": "${keycloak.group.map.storage.provider:concurrenthashmap}"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"role": {
|
"role": {
|
||||||
"provider": "${keycloak.role.provider:jpa}"
|
"provider": "${keycloak.role.provider:jpa}",
|
||||||
|
"map": {
|
||||||
|
"storage": {
|
||||||
|
"provider": "${keycloak.role.map.storage.provider:concurrenthashmap}"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"authenticationSessions": {
|
"authenticationSessions": {
|
||||||
"provider": "${keycloak.authSession.provider:infinispan}",
|
"provider": "${keycloak.authSession.provider:infinispan}",
|
||||||
|
"map": {
|
||||||
|
"storage": {
|
||||||
|
"provider": "${keycloak.authSession.map.storage.provider:concurrenthashmap}"
|
||||||
|
}
|
||||||
|
},
|
||||||
"infinispan": {
|
"infinispan": {
|
||||||
"authSessionsLimit": "${keycloak.authSessions.limit:300}"
|
"authSessionsLimit": "${keycloak.authSessions.limit:300}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"userSessions": {
|
"userSessions": {
|
||||||
"provider": "${keycloak.userSession.provider:infinispan}"
|
"provider": "${keycloak.userSession.provider:infinispan}",
|
||||||
|
"map": {
|
||||||
|
"storage-user-sessions": {
|
||||||
|
"provider": "${keycloak.userSession.map.storage.provider:concurrenthashmap}"
|
||||||
|
},
|
||||||
|
"storage-client-sessions": {
|
||||||
|
"provider": "${keycloak.userSession.map.storage.provider:concurrenthashmap}"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"loginFailure": {
|
"loginFailure": {
|
||||||
"provider": "${keycloak.loginFailure.provider:infinispan}"
|
"provider": "${keycloak.loginFailure.provider:infinispan}",
|
||||||
|
"map": {
|
||||||
|
"storage": {
|
||||||
|
"provider": "${keycloak.loginFailure.map.storage.provider:concurrenthashmap}"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"mapStorage": {
|
"mapStorage": {
|
||||||
|
@ -104,7 +152,12 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"authorizationPersister": {
|
"authorizationPersister": {
|
||||||
"provider": "${keycloak.authorization.provider:jpa}"
|
"provider": "${keycloak.authorization.provider:jpa}",
|
||||||
|
"map": {
|
||||||
|
"storage": {
|
||||||
|
"provider": "${keycloak.authorization.map.storage.provider:concurrenthashmap}"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"userCache": {
|
"userCache": {
|
||||||
|
@ -192,6 +245,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"connectionsHotRod": {
|
||||||
|
"default": {
|
||||||
|
"embedded": "${keycloak.connectionsHotRod.embedded:true}",
|
||||||
|
"embeddedPort": "${keycloak.connectionsHotRod.embeddedPort:11444}",
|
||||||
|
"enableSecurity": "${keycloak.connectionsHotRod.enableSecurity:false}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"truststore": {
|
"truststore": {
|
||||||
"file": {
|
"file": {
|
||||||
"file": "${keycloak.truststore.file:target/dependency/keystore/keycloak.truststore}",
|
"file": "${keycloak.truststore.file:target/dependency/keystore/keycloak.truststore}",
|
||||||
|
|
|
@ -75,7 +75,6 @@
|
||||||
<version>${jdbc.mvn.version}</version>
|
<version>${jdbc.mvn.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-model-jpa</artifactId>
|
<artifactId>keycloak-model-jpa</artifactId>
|
||||||
|
@ -93,6 +92,14 @@
|
||||||
<artifactId>integration-arquillian-testsuite-providers</artifactId>
|
<artifactId>integration-arquillian-testsuite-providers</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-model-map-hot-rod</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-server-core</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -266,6 +273,14 @@
|
||||||
<keycloak.model.parameters>Jpa,Map,ConcurrentHashMapStorage</keycloak.model.parameters>
|
<keycloak.model.parameters>Jpa,Map,ConcurrentHashMapStorage</keycloak.model.parameters>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>hot-rod</id>
|
||||||
|
<properties>
|
||||||
|
<keycloak.profile.feature.map_storage>enabled</keycloak.profile.feature.map_storage>
|
||||||
|
<keycloak.model.parameters>Jpa,Map,HotRodMapStorage</keycloak.model.parameters>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -133,7 +133,7 @@ public class Config implements ConfigProvider {
|
||||||
@Override
|
@Override
|
||||||
public Scope scope(String... scope) {
|
public Scope scope(String... scope) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(prefix).append(".");
|
sb.append(prefix);
|
||||||
for (String s : scope) {
|
for (String s : scope) {
|
||||||
sb.append(s);
|
sb.append(s);
|
||||||
sb.append(".");
|
sb.append(".");
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.infinispan.server.hotrod.configuration.HotRodServerConfiguration;
|
||||||
import org.infinispan.server.hotrod.configuration.HotRodServerConfigurationBuilder;
|
import org.infinispan.server.hotrod.configuration.HotRodServerConfigurationBuilder;
|
||||||
import org.junit.rules.ExternalResource;
|
import org.junit.rules.ExternalResource;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
|
import org.keycloak.models.map.common.HotRodUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -39,7 +40,9 @@ public class HotRodServerRule extends ExternalResource {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void after() {
|
protected void after() {
|
||||||
remoteCacheManager.stop();
|
if (remoteCacheManager != null) {
|
||||||
|
remoteCacheManager.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createEmbeddedHotRodServer(Config.Scope config) {
|
public void createEmbeddedHotRodServer(Config.Scope config) {
|
||||||
|
@ -76,6 +79,29 @@ public class HotRodServerRule extends ExternalResource {
|
||||||
LOGIN_FAILURE_CACHE_NAME, WORK_CACHE_NAME, ACTION_TOKEN_CACHE);
|
LOGIN_FAILURE_CACHE_NAME, WORK_CACHE_NAME, ACTION_TOKEN_CACHE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void createHotRodMapStoreServer() {
|
||||||
|
hotRodCacheManager = configureHotRodCacheManager("hotrod/infinispan.xml");
|
||||||
|
hotRodServer = new HotRodServer();
|
||||||
|
|
||||||
|
HotRodUtils.createHotRodMapStoreServer(hotRodServer, hotRodCacheManager, 11444);
|
||||||
|
|
||||||
|
org.infinispan.client.hotrod.configuration.ConfigurationBuilder remoteBuilder = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder();
|
||||||
|
org.infinispan.client.hotrod.configuration.Configuration cfg = remoteBuilder
|
||||||
|
.addServers(hotRodServer.getHost() + ":" + hotRodServer.getPort()).build();
|
||||||
|
remoteCacheManager = new RemoteCacheManager(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DefaultCacheManager configureHotRodCacheManager(String configPath) {
|
||||||
|
DefaultCacheManager manager = null;
|
||||||
|
try {
|
||||||
|
manager = new DefaultCacheManager(configPath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
|
||||||
private void getCaches(String... cache) {
|
private void getCaches(String... cache) {
|
||||||
for (String c: cache) {
|
for (String c: cache) {
|
||||||
hotRodCacheManager.getCache(c, true);
|
hotRodCacheManager.getCache(c, true);
|
||||||
|
|
9
testsuite/model/src/main/resources/hotrod/infinispan.xml
Normal file
9
testsuite/model/src/main/resources/hotrod/infinispan.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<infinispan>
|
||||||
|
<cache-container>
|
||||||
|
<transport stack="udp"/>
|
||||||
|
|
||||||
|
<distributed-cache name="clients" mode="SYNC">
|
||||||
|
<encoding media-type="application/x-protostream"/>
|
||||||
|
</distributed-cache>
|
||||||
|
</cache-container>
|
||||||
|
</infinispan>
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.keycloak.testsuite.model.parameters;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import org.junit.runner.Description;
|
||||||
|
import org.junit.runners.model.Statement;
|
||||||
|
import org.keycloak.authorization.store.StoreFactorySpi;
|
||||||
|
import org.keycloak.models.DeploymentStateSpi;
|
||||||
|
import org.keycloak.models.UserLoginFailureSpi;
|
||||||
|
import org.keycloak.models.UserSessionSpi;
|
||||||
|
import org.keycloak.models.dblock.NoLockingDBLockProviderFactory;
|
||||||
|
import org.keycloak.models.map.authSession.MapRootAuthenticationSessionProviderFactory;
|
||||||
|
import org.keycloak.models.map.authorization.MapAuthorizationStoreFactory;
|
||||||
|
import org.keycloak.models.map.client.MapClientProviderFactory;
|
||||||
|
import org.keycloak.models.map.clientscope.MapClientScopeProviderFactory;
|
||||||
|
import org.keycloak.models.map.connections.DefaultHotRodConnectionProviderFactory;
|
||||||
|
import org.keycloak.models.map.connections.HotRodConnectionProviderFactory;
|
||||||
|
import org.keycloak.models.map.connections.HotRodConnectionSpi;
|
||||||
|
import org.keycloak.models.map.deploymentState.MapDeploymentStateProviderFactory;
|
||||||
|
import org.keycloak.models.map.group.MapGroupProviderFactory;
|
||||||
|
import org.keycloak.models.map.loginFailure.MapUserLoginFailureProviderFactory;
|
||||||
|
import org.keycloak.models.map.realm.MapRealmProviderFactory;
|
||||||
|
import org.keycloak.models.map.role.MapRoleProviderFactory;
|
||||||
|
import org.keycloak.models.map.storage.MapStorageSpi;
|
||||||
|
import org.keycloak.models.map.storage.chm.ConcurrentHashMapStorageProviderFactory;
|
||||||
|
//import org.keycloak.models.map.storage.hotRod.HotRodMapStorageProviderFactory;
|
||||||
|
import org.keycloak.models.map.user.MapUserProviderFactory;
|
||||||
|
import org.keycloak.models.map.userSession.MapUserSessionProviderFactory;
|
||||||
|
import org.keycloak.provider.ProviderFactory;
|
||||||
|
import org.keycloak.provider.Spi;
|
||||||
|
import org.keycloak.sessions.AuthenticationSessionSpi;
|
||||||
|
import org.keycloak.testsuite.model.Config;
|
||||||
|
import org.keycloak.testsuite.model.HotRodServerRule;
|
||||||
|
import org.keycloak.testsuite.model.KeycloakModelParameters;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author hmlnarik
|
||||||
|
*/
|
||||||
|
public class HotRodMapStorage extends KeycloakModelParameters {
|
||||||
|
|
||||||
|
static final Set<Class<? extends Spi>> ALLOWED_SPIS = ImmutableSet.<Class<? extends Spi>>builder()
|
||||||
|
.add(HotRodConnectionSpi.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
static final Set<Class<? extends ProviderFactory>> ALLOWED_FACTORIES = ImmutableSet.<Class<? extends ProviderFactory>>builder()
|
||||||
|
//.add(HotRodMapStorageProviderFactory.class)
|
||||||
|
.add(HotRodConnectionProviderFactory.class)
|
||||||
|
.add(ConcurrentHashMapStorageProviderFactory.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
private static final String STORAGE_CONFIG = "storage.provider";
|
||||||
|
|
||||||
|
private HotRodServerRule hotRodServerRule = new HotRodServerRule();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateConfig(Config cf) {
|
||||||
|
cf.spi(AuthenticationSessionSpi.PROVIDER_ID).provider(MapRootAuthenticationSessionProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
//.spi("client").provider(MapClientProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.spi("client").provider(MapClientProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.spi("clientScope").provider(MapClientScopeProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.spi("group").provider(MapGroupProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.spi("realm").provider(MapRealmProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.spi("role").provider(MapRoleProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.spi(DeploymentStateSpi.NAME).provider(MapDeploymentStateProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.spi(StoreFactorySpi.NAME).provider(MapAuthorizationStoreFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.spi("user").provider(MapUserProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.spi(UserSessionSpi.NAME).provider(MapUserSessionProviderFactory.PROVIDER_ID).config("storage-user-sessions.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.config("storage-client-sessions.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.spi(UserLoginFailureSpi.NAME).provider(MapUserLoginFailureProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.spi("dblock").provider(NoLockingDBLockProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID);
|
||||||
|
|
||||||
|
cf.spi(MapStorageSpi.NAME)
|
||||||
|
.provider(ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
.config("dir", "${project.build.directory:target}");
|
||||||
|
|
||||||
|
cf.spi(HotRodConnectionSpi.NAME).provider(DefaultHotRodConnectionProviderFactory.PROVIDER_ID)
|
||||||
|
.config("enableSecurity", "false")
|
||||||
|
.config("configureRemoteCaches", "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeSuite(Config cf) {
|
||||||
|
hotRodServerRule.createHotRodMapStoreServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Statement classRule(Statement base, Description description) {
|
||||||
|
return hotRodServerRule.apply(base, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HotRodMapStorage() {
|
||||||
|
super(ALLOWED_SPIS, ALLOWED_FACTORIES);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -124,6 +124,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"connectionsHotRod": {
|
||||||
|
"default": {
|
||||||
|
"embedded": "${keycloak.connectionsHotRod.embedded:true}",
|
||||||
|
"embeddedPort": "${keycloak.connectionsHotRod.embeddedPort:11444}",
|
||||||
|
"enableSecurity": "${keycloak.connectionsHotRod.enableSecurity:false}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"scripting": {
|
"scripting": {
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue