parent
4817e152e3
commit
dd3d7be2b4
24 changed files with 206 additions and 196 deletions
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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">
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -15,4 +15,4 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
org.keycloak.models.map.storage.jpa.client.JpaClientMapStorageProviderFactory
|
||||
org.keycloak.models.map.storage.jpa.JpaMapStorageProviderFactory
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}"
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -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}"
|
||||
}
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in a new issue