Make JpaClientMapStorage generic

Closes #9244
This commit is contained in:
vramik 2021-12-15 22:19:57 +01:00 committed by Hynek Mlnařík
parent 4817e152e3
commit dd3d7be2b4
24 changed files with 206 additions and 196 deletions

View file

@ -0,0 +1,21 @@
/*
* 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.storage.jpa;
public interface Constants {
public static final Integer SUPPORTED_VERSION_CLIENT = 1;
}

View file

@ -0,0 +1,63 @@
/*
* 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.storage.jpa;
import javax.persistence.EntityManager;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.map.common.AbstractEntity;
import org.keycloak.models.map.storage.MapKeycloakTransaction;
import org.keycloak.models.map.storage.MapStorage;
import org.keycloak.models.map.storage.MapStorageProvider;
import org.keycloak.models.map.storage.MapStorageProviderFactory.Flag;
public class JpaMapStorageProvider implements MapStorageProvider {
private final String SESSION_TX_PREFIX = "jpa-map-tx-";
private final JpaMapStorageProviderFactory factory;
private final KeycloakSession session;
private final EntityManager em;
public JpaMapStorageProvider(JpaMapStorageProviderFactory factory, KeycloakSession session, EntityManager em) {
this.factory = factory;
this.session = session;
this.em = em;
}
@Override
public void close() {
em.close();
}
@Override
@SuppressWarnings("unchecked")
public <V extends AbstractEntity, M> MapStorage<V, M> getStorage(Class<M> modelType, Flag... flags) {
factory.validateAndUpdateSchema(session, modelType);
return new MapStorage<V, M>() {
@Override
public MapKeycloakTransaction<V, M> createTransaction(KeycloakSession session) {
MapKeycloakTransaction<V, M> sessionTx = session.getAttribute(SESSION_TX_PREFIX + modelType.hashCode(), MapKeycloakTransaction.class);
if (sessionTx == null) {
sessionTx = factory.createTransaction(modelType, em);
session.setAttribute(SESSION_TX_PREFIX + modelType.hashCode(), sessionTx);
}
return sessionTx;
}
};
}
}

View file

@ -14,20 +14,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.models.map.storage.jpa.client;
package org.keycloak.models.map.storage.jpa;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.sql.DataSource;
import org.hibernate.cfg.AvailableSettings;
import org.jboss.logging.Logger;
@ -41,40 +42,49 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.map.storage.jpa.client.entity.JpaClientEntity;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.dblock.DBLockManager;
import org.keycloak.models.dblock.DBLockProvider;
import org.keycloak.models.map.client.MapProtocolMapperEntity;
import org.keycloak.models.map.client.MapProtocolMapperEntityImpl;
import org.keycloak.models.map.common.DeepCloner;
import org.keycloak.models.map.storage.MapKeycloakTransaction;
import org.keycloak.models.map.storage.MapStorageProvider;
import org.keycloak.models.map.storage.MapStorageProviderFactory;
import org.keycloak.models.map.storage.jpa.client.JpaClientMapKeycloakTransaction;
import org.keycloak.models.map.storage.jpa.updater.MapJpaUpdaterProvider;
import static org.keycloak.models.map.storage.jpa.updater.MapJpaUpdaterProvider.Status.VALID;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.provider.EnvironmentDependentProviderFactory;
public class JpaClientMapStorageProviderFactory implements
public class JpaMapStorageProviderFactory implements
AmphibianProviderFactory<MapStorageProvider>,
MapStorageProviderFactory,
EnvironmentDependentProviderFactory {
final static DeepCloner CLONER = new DeepCloner.Builder()
.constructor(JpaClientEntity.class, JpaClientEntity::new)
.constructor(MapProtocolMapperEntity.class, MapProtocolMapperEntityImpl::new)
.build();
public static final String PROVIDER_ID = "jpa-client-map-storage";
public static final String PROVIDER_ID = "jpa-map-storage";
private volatile EntityManagerFactory emf;
private static final Logger logger = Logger.getLogger(JpaClientMapStorageProviderFactory.class);
private Config.Scope config;
private static final Logger logger = Logger.getLogger(JpaMapStorageProviderFactory.class);
public final static DeepCloner CLONER = new DeepCloner.Builder()
//client
.constructor(JpaClientEntity.class, JpaClientEntity::new)
.constructor(MapProtocolMapperEntity.class, MapProtocolMapperEntityImpl::new)
.build();
private static final Map<Class<?>, Function<EntityManager, MapKeycloakTransaction>> MODEL_TO_TX = new HashMap<>();
static {
MODEL_TO_TX.put(ClientModel.class, JpaClientMapKeycloakTransaction::new);
}
public MapKeycloakTransaction createTransaction(Class<?> modelType, EntityManager em) {
return MODEL_TO_TX.get(modelType).apply(em);
}
@Override
public MapStorageProvider create(KeycloakSession session) {
lazyInit(session);
return new JpaClientMapStorageProvider(emf.createEntityManager());
lazyInit();
return new JpaMapStorageProvider(this, session, emf.createEntityManager());
}
@Override
@ -93,7 +103,7 @@ public class JpaClientMapStorageProviderFactory implements
@Override
public String getHelpText() {
return "JPA Client Map Storage";
return "JPA Map Storage";
}
@Override
@ -108,15 +118,15 @@ public class JpaClientMapStorageProviderFactory implements
}
}
private void lazyInit(KeycloakSession session) {
private void lazyInit() {
if (emf == null) {
synchronized (this) {
if (emf == null) {
logger.debugf("Initializing JPA connections%s", StackUtil.getShortStackTrace());
logger.debugf("Initializing JPA connections %s", StackUtil.getShortStackTrace());
Map<String, Object> properties = new HashMap<>();
String unitName = "keycloak-client-store";
String unitName = config.get("persistenceUnitName", "keycloak-jpa-default");
String dataSource = config.get("dataSource");
if (dataSource != null) {
@ -155,66 +165,37 @@ public class JpaClientMapStorageProviderFactory implements
logger.warn("Concurrent requests may not be reliable with transaction level lower than TRANSACTION_REPEATABLE_READ.");
}
Connection connection = getConnection();
try {
printOperationalInfo(connection);
customChanges(connection, schema, session, session.getProvider(MapJpaUpdaterProvider.class));
logger.trace("Creating EntityManagerFactory");
Collection<ClassLoader> classLoaders = new ArrayList<>();
if (properties.containsKey(AvailableSettings.CLASSLOADERS)) {
classLoaders.addAll((Collection<ClassLoader>) properties.get(AvailableSettings.CLASSLOADERS));
}
classLoaders.add(getClass().getClassLoader());
properties.put(AvailableSettings.CLASSLOADERS, classLoaders);
this.emf = JpaUtils.createEntityManagerFactory(session, unitName, properties, false);
logger.trace("EntityManagerFactory created");
} finally {
// Close after creating EntityManagerFactory to prevent in-mem databases from closing
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
logger.warn("Can't close connection", e);
}
}
}
logger.trace("Creating EntityManagerFactory");
this.emf = Persistence.createEntityManagerFactory(unitName, properties);
logger.trace("EntityManagerFactory created");
}
}
}
}
private void customChanges(Connection connection, String schema, KeycloakSession session, MapJpaUpdaterProvider updater) {
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession lockSession) -> {
DBLockManager dbLockManager = new DBLockManager(lockSession);
DBLockProvider dbLock2 = dbLockManager.getDBLock();
dbLock2.waitForLock(DBLockProvider.Namespace.DATABASE);
try {
updater.update(ClientModel.class, connection, schema);
} finally {
dbLock2.releaseLock();
}
});
}
public void validateAndUpdateSchema(KeycloakSession session, Class<?> modelType) {
Connection connection = getConnection();
private void printOperationalInfo(Connection connection) {
try {
HashMap<String, String> operationalInfo = new LinkedHashMap<>();
DatabaseMetaData md = connection.getMetaData();
operationalInfo.put("databaseUrl", md.getURL());
operationalInfo.put("databaseUser", md.getUserName());
operationalInfo.put("databaseProduct", md.getDatabaseProductName() + " " + md.getDatabaseProductVersion());
operationalInfo.put("databaseDriver", md.getDriverName() + " " + md.getDriverVersion());
if (logger.isDebugEnabled()) printOperationalInfo(connection);
logger.infof("Database info: %s", operationalInfo.toString());
} catch (SQLException e) {
logger.warn("Unable to prepare operational info due database exception: " + e.getMessage());
MapJpaUpdaterProvider updater = session.getProvider(MapJpaUpdaterProvider.class);
MapJpaUpdaterProvider.Status status = updater.validate(modelType, connection, config.get("schema"));
if (! status.equals(VALID)) {
update(modelType, connection, session);
}
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
logger.warn("Can't close connection", e);
}
}
}
}
private Connection getConnection() {
try {
String dataSourceLookup = config.get("dataSource");
@ -232,4 +213,32 @@ public class JpaClientMapStorageProviderFactory implements
throw new RuntimeException("Failed to connect to database", e);
}
}
private void printOperationalInfo(Connection connection) {
try {
HashMap<String, String> operationalInfo = new LinkedHashMap<>();
DatabaseMetaData md = connection.getMetaData();
operationalInfo.put("databaseUrl", md.getURL());
operationalInfo.put("databaseUser", md.getUserName());
operationalInfo.put("databaseProduct", md.getDatabaseProductName() + " " + md.getDatabaseProductVersion());
operationalInfo.put("databaseDriver", md.getDriverName() + " " + md.getDriverVersion());
logger.debugf("Database info: %s", operationalInfo.toString());
} catch (SQLException e) {
logger.warn("Unable to prepare operational info due database exception: " + e.getMessage());
}
}
private void update(Class<?> modelType, Connection connection, KeycloakSession session) {
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession lockSession) -> {
// TODO locking tables based on modelType: https://github.com/keycloak/keycloak/issues/9388
DBLockProvider dbLock = session.getProvider(DBLockProvider.class);
dbLock.waitForLock(DBLockProvider.Namespace.DATABASE);
try {
session.getProvider(MapJpaUpdaterProvider.class).update(modelType, connection, config.get("schema"));
} finally {
dbLock.releaseLock();
}
});
}
}

View file

@ -34,10 +34,10 @@ import org.keycloak.models.map.client.MapClientEntityDelegate;
import org.keycloak.models.map.common.StringKeyConvertor.UUIDKey;
import org.keycloak.models.map.storage.jpa.client.delegate.JpaClientDelegateProvider;
import org.keycloak.models.map.storage.jpa.client.entity.JpaClientEntity;
import static org.keycloak.models.map.storage.jpa.client.JpaClientMapStorage.SUPPORTED_VERSION;
import static org.keycloak.models.map.storage.jpa.client.JpaClientMapStorageProviderFactory.CLONER;
import static org.keycloak.models.map.storage.jpa.JpaMapStorageProviderFactory.CLONER;
import org.keycloak.models.map.storage.MapKeycloakTransaction;
import org.keycloak.models.map.storage.QueryParameters;
import static org.keycloak.models.map.storage.jpa.Constants.SUPPORTED_VERSION_CLIENT;
import static org.keycloak.utils.StreamsUtil.closing;
public class JpaClientMapKeycloakTransaction extends JpaKeycloakTransaction implements MapKeycloakTransaction<MapClientEntity, ClientModel> {
@ -52,7 +52,7 @@ public class JpaClientMapKeycloakTransaction extends JpaKeycloakTransaction impl
if (mapEntity.getId() == null) {
jpaEntity.setId(UUIDKey.INSTANCE.yieldNewUniqueKey().toString());
}
jpaEntity.setEntityVersion(SUPPORTED_VERSION);
jpaEntity.setEntityVersion(SUPPORTED_VERSION_CLIENT);
em.persist(jpaEntity);
return jpaEntity;
}

View file

@ -1,40 +0,0 @@
/*
* 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.storage.jpa.client;
import javax.persistence.EntityManager;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.map.client.MapClientEntity;
import org.keycloak.models.map.storage.MapKeycloakTransaction;
import org.keycloak.models.map.storage.MapStorage;
public class JpaClientMapStorage implements MapStorage<MapClientEntity, ClientModel> {
public static final Integer SUPPORTED_VERSION = 1;
private final EntityManager em;
public JpaClientMapStorage(EntityManager em) {
this.em = em;
}
@Override
public MapKeycloakTransaction<MapClientEntity, ClientModel> createTransaction(KeycloakSession session) {
return new JpaClientMapKeycloakTransaction(em);
}
}

View file

@ -1,43 +0,0 @@
/*
* 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.storage.jpa.client;
import javax.persistence.EntityManager;
import org.keycloak.models.ClientModel;
import org.keycloak.models.map.client.MapClientEntity;
import org.keycloak.models.map.storage.MapStorage;
import org.keycloak.models.map.storage.MapStorageProvider;
import org.keycloak.models.map.storage.MapStorageProviderFactory.Flag;
public class JpaClientMapStorageProvider implements MapStorageProvider {
private final EntityManager em;
public JpaClientMapStorageProvider(EntityManager em) {
this.em = em;
}
@Override
public void close() {
em.close();
}
@Override
public MapStorage<MapClientEntity, ClientModel> getStorage(Class modelType, Flag... flags) {
return new JpaClientMapStorage(em);
}
}

View file

@ -41,9 +41,8 @@ import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;
import org.keycloak.models.map.client.MapClientEntity.AbstractClientEntity;
import org.keycloak.models.map.client.MapProtocolMapperEntity;
import static org.keycloak.models.map.storage.jpa.client.JpaClientMapStorage.SUPPORTED_VERSION;
import org.keycloak.models.map.common.DeepCloner;
import static org.keycloak.models.map.storage.jpa.Constants.SUPPORTED_VERSION_CLIENT;
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.JsonbType;
@Entity
@ -118,8 +117,8 @@ public class JpaClientEntity extends AbstractClientEntity implements Serializabl
*/
private void checkEntityVersionForUpdate() {
Integer ev = getEntityVersion();
if (ev != null && ev < SUPPORTED_VERSION) {
setEntityVersion(SUPPORTED_VERSION);
if (ev != null && ev < SUPPORTED_VERSION_CLIENT) {
setEntityVersion(SUPPORTED_VERSION_CLIENT);
}
}

View file

@ -22,15 +22,15 @@ import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import org.keycloak.models.map.storage.jpa.client.JpaClientMapStorage;
import org.keycloak.models.map.storage.jpa.client.entity.JpaClientMetadata;
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.migration.JpaClientMigration;
import static org.keycloak.models.map.storage.jpa.Constants.SUPPORTED_VERSION_CLIENT;
public class JpaEntityMigration {
static final Map<Class<?>, BiFunction<ObjectNode, Integer, ObjectNode>> MIGRATIONS = new HashMap<>();
static {
MIGRATIONS.put(JpaClientMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, JpaClientMapStorage.SUPPORTED_VERSION, tree, JpaClientMigration.MIGRATORS));
MIGRATIONS.put(JpaClientMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, SUPPORTED_VERSION_CLIENT, tree, JpaClientMigration.MIGRATORS));
}
private static ObjectNode migrateTreeTo(int entityVersion, Integer supportedVersion, ObjectNode node, List<Function<ObjectNode, ObjectNode>> migrators) {

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.keycloak.models.map.storage.jpa.liquibase;
package org.keycloak.models.map.storage.jpa.liquibase.connection;
import java.sql.Connection;
import java.util.concurrent.atomic.AtomicBoolean;

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.keycloak.models.map.storage.jpa.liquibase;
package org.keycloak.models.map.storage.jpa.liquibase.connection;
import org.keycloak.Config;
import org.keycloak.models.KeycloakSession;

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.keycloak.models.map.storage.jpa.liquibase;
package org.keycloak.models.map.storage.jpa.liquibase.connection;
import java.sql.Connection;

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.keycloak.models.map.storage.jpa.liquibase;
package org.keycloak.models.map.storage.jpa.liquibase.connection;
import org.keycloak.provider.ProviderFactory;

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.keycloak.models.map.storage.jpa.liquibase;
package org.keycloak.models.map.storage.jpa.liquibase.connection;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;

View file

@ -15,8 +15,9 @@
* limitations under the License.
*/
package org.keycloak.models.map.storage.jpa.liquibase;
package org.keycloak.models.map.storage.jpa.liquibase.updater;
import org.keycloak.models.map.storage.jpa.liquibase.connection.MapLiquibaseConnectionProvider;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.keycloak.models.map.storage.jpa.liquibase;
package org.keycloak.models.map.storage.jpa.liquibase.updater;
import org.keycloak.Config;
import org.keycloak.models.KeycloakSession;

View file

@ -22,7 +22,7 @@ limitations under the License.
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<!-- format of id of changeSet: clients-${JpaClientMapStorage.SUPPORTED_VERSION} -->
<!-- format of id of changeSet: clients-${org.keycloak.models.map.storage.jpa.Constants.SUPPORTED_VERSION_CLIENT} -->
<changeSet author="keycloak" id="clients-1">
<createTable tableName="client">

View file

@ -18,6 +18,6 @@ limitations under the License.
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<!-- format of id of changelog file names: jpa-clients-changelog-${JpaClientMapStorage.SUPPORTED_VERSION}.xml -->
<include file="META-INF/jpa-clients-changelog-1.xml"/>
<!-- format of id of changelog file names: jpa-clients-changelog-${org.keycloak.models.map.storage.jpa.Constants.SUPPORTED_VERSION_CLIENT}.xml -->
<include file="META-INF/clients/jpa-clients-changelog-1.xml"/>
</databaseChangeLog>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="keycloak-client-store">
<persistence-unit name="keycloak-jpa-default">
<class>org.keycloak.models.map.storage.jpa.client.entity.JpaClientEntity</class>
<class>org.keycloak.models.map.storage.jpa.client.entity.JpaClientAttributeEntity</class>
</persistence-unit>

View file

@ -15,4 +15,4 @@
# limitations under the License.
#
org.keycloak.models.map.storage.jpa.client.JpaClientMapStorageProviderFactory
org.keycloak.models.map.storage.jpa.JpaMapStorageProviderFactory

View file

@ -15,4 +15,4 @@
# limitations under the License.
#
org.keycloak.models.map.storage.jpa.liquibase.DefaultLiquibaseConnectionProviderFactory
org.keycloak.models.map.storage.jpa.liquibase.connection.DefaultLiquibaseConnectionProviderFactory

View file

@ -15,4 +15,4 @@
# limitations under the License.
#
org.keycloak.models.map.storage.jpa.liquibase.MapJpaLiquibaseUpdaterProviderFactory
org.keycloak.models.map.storage.jpa.liquibase.updater.MapJpaLiquibaseUpdaterProviderFactory

View file

@ -16,4 +16,4 @@
#
org.keycloak.models.map.storage.jpa.updater.MapJpaUpdaterSpi
org.keycloak.models.map.storage.jpa.liquibase.MapLiquibaseConnectionSpi
org.keycloak.models.map.storage.jpa.liquibase.connection.MapLiquibaseConnectionSpi

View file

@ -69,15 +69,7 @@
"provider": "${keycloak.client.provider:jpa}",
"map": {
"storage": {
"provider": "${keycloak.client.map.storage.provider:concurrenthashmap}",
"jpa-client-map-storage": {
"url": "${keycloak.client.map.storage.connectionsJpa.url:}",
"driver": "org.postgresql.Driver",
"driverDialect": "org.keycloak.models.map.jpa.hibernate.dialect.JsonbPostgreSQL95Dialect",
"user": "${keycloak.client.map.storage.connectionsJpa.user:}",
"password": "${keycloak.client.map.storage.connectionsJpa.password:}",
"showSql": "${keycloak.client.map.storage.connectionsJpa,showSql:false}"
}
"provider": "${keycloak.client.map.storage.provider:concurrenthashmap}"
}
}
},
@ -147,6 +139,14 @@
"dir": "${project.build.directory:target}",
"keyType.realms": "string",
"keyType.authz-resource-servers": "string"
},
"jpa-map-storage": {
"url": "${keycloak.map.storage.connectionsJpa.url:}",
"user": "${keycloak.map.storage.connectionsJpa.user:}",
"password": "${keycloak.map.storage.connectionsJpa.password:}",
"driver": "org.postgresql.Driver",
"driverDialect": "org.keycloak.models.map.storage.jpa.hibernate.dialect.JsonbPostgreSQL95Dialect",
"showSql": "${keycloak.map.storage.connectionsJpa,showSql:false}"
}
},

View file

@ -38,15 +38,7 @@
"provider": "${keycloak.client.provider:jpa}",
"map": {
"storage": {
"provider": "${keycloak.client.map.storage.provider:concurrenthashmap}",
"jpa-client-map-storage": {
"url": "${keycloak.client.map.storage.connectionsJpa.url:}",
"driver": "org.postgresql.Driver",
"driverDialect": "org.keycloak.models.map.jpa.hibernate.dialect.JsonbPostgreSQL95Dialect",
"user": "${keycloak.client.map.storage.connectionsJpa.user:}",
"password": "${keycloak.client.map.storage.connectionsJpa.password:}",
"showSql": "${keycloak.client.map.storage.connectionsJpa,showSql:false}"
}
"provider": "${keycloak.client.map.storage.provider:concurrenthashmap}"
}
}
},
@ -99,6 +91,14 @@
"dir": "${project.build.directory:target/map}",
"keyType.realms": "string",
"keyType.authz-resource-servers": "string"
},
"jpa-map-storage": {
"url": "${keycloak.map.storage.connectionsJpa.url:}",
"user": "${keycloak.map.storage.connectionsJpa.user:}",
"password": "${keycloak.map.storage.connectionsJpa.password:}",
"driver": "org.postgresql.Driver",
"driverDialect": "org.keycloak.models.map.storage.jpa.hibernate.dialect.JsonbPostgreSQL95Dialect",
"showSql": "${keycloak.map.storage.connectionsJpa,showSql:false}"
}
},