KEYCLOAK-1542 - code formatting cleanup
This commit is contained in:
parent
85816be967
commit
1c142cb170
4 changed files with 420 additions and 403 deletions
|
@ -1,19 +1,5 @@
|
||||||
package org.keycloak.connections.jpa;
|
package org.keycloak.connections.jpa;
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DatabaseMetaData;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.naming.InitialContext;
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
import javax.persistence.Persistence;
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
import org.hibernate.ejb.AvailableSettings;
|
import org.hibernate.ejb.AvailableSettings;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
|
@ -22,215 +8,232 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.provider.ProviderOperationalInfo;
|
import org.keycloak.provider.ProviderOperationalInfo;
|
||||||
|
|
||||||
|
import javax.naming.InitialContext;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.Persistence;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
public class DefaultJpaConnectionProviderFactory implements JpaConnectionProviderFactory {
|
public class DefaultJpaConnectionProviderFactory implements JpaConnectionProviderFactory {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(DefaultJpaConnectionProviderFactory.class);
|
private static final Logger logger = Logger.getLogger(DefaultJpaConnectionProviderFactory.class);
|
||||||
|
|
||||||
private volatile EntityManagerFactory emf;
|
private volatile EntityManagerFactory emf;
|
||||||
|
|
||||||
private Config.Scope config;
|
private Config.Scope config;
|
||||||
|
|
||||||
|
private DatabaseInfo databaseInfo;
|
||||||
|
|
||||||
private DatabaseInfo databaseInfo;
|
@Override
|
||||||
|
public JpaConnectionProvider create(KeycloakSession session) {
|
||||||
|
lazyInit(session);
|
||||||
|
|
||||||
@Override
|
EntityManager em = emf.createEntityManager();
|
||||||
public JpaConnectionProvider create(KeycloakSession session) {
|
em = PersistenceExceptionConverter.create(em);
|
||||||
lazyInit(session);
|
session.getTransaction().enlist(new JpaKeycloakTransaction(em));
|
||||||
|
return new DefaultJpaConnectionProvider(em);
|
||||||
|
}
|
||||||
|
|
||||||
EntityManager em = emf.createEntityManager();
|
@Override
|
||||||
em = PersistenceExceptionConverter.create(em);
|
public void close() {
|
||||||
session.getTransaction().enlist(new JpaKeycloakTransaction(em));
|
if (emf != null) {
|
||||||
return new DefaultJpaConnectionProvider(em);
|
emf.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public String getId() {
|
||||||
if (emf != null) {
|
return "default";
|
||||||
emf.close();
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public void init(Config.Scope config) {
|
||||||
return "default";
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Config.Scope config) {
|
public void postInit(KeycloakSessionFactory factory) {
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public void postInit(KeycloakSessionFactory factory) {
|
|
||||||
|
|
||||||
}
|
private void lazyInit(KeycloakSession session) {
|
||||||
|
if (emf == null) {
|
||||||
|
synchronized (this) {
|
||||||
|
if (emf == null) {
|
||||||
|
logger.debug("Initializing JPA connections");
|
||||||
|
|
||||||
private void lazyInit(KeycloakSession session) {
|
Connection connection = null;
|
||||||
if (emf == null) {
|
|
||||||
synchronized (this) {
|
|
||||||
if (emf == null) {
|
|
||||||
logger.debug("Initializing JPA connections");
|
|
||||||
|
|
||||||
Connection connection = null;
|
String databaseSchema = config.get("databaseSchema");
|
||||||
|
|
||||||
String databaseSchema = config.get("databaseSchema");
|
Map<String, Object> properties = new HashMap<String, Object>();
|
||||||
|
|
||||||
Map<String, Object> properties = new HashMap<String, Object>();
|
String unitName = "keycloak-default";
|
||||||
|
|
||||||
String unitName = "keycloak-default";
|
String dataSource = config.get("dataSource");
|
||||||
|
if (dataSource != null) {
|
||||||
|
if (config.getBoolean("jta", false)) {
|
||||||
|
properties.put(AvailableSettings.JTA_DATASOURCE, dataSource);
|
||||||
|
} else {
|
||||||
|
properties.put(AvailableSettings.NON_JTA_DATASOURCE, dataSource);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
properties.put(AvailableSettings.JDBC_URL, config.get("url"));
|
||||||
|
properties.put(AvailableSettings.JDBC_DRIVER, config.get("driver"));
|
||||||
|
|
||||||
String dataSource = config.get("dataSource");
|
String user = config.get("user");
|
||||||
if (dataSource != null) {
|
if (user != null) {
|
||||||
if (config.getBoolean("jta", false)) {
|
properties.put(AvailableSettings.JDBC_USER, user);
|
||||||
properties.put(AvailableSettings.JTA_DATASOURCE, dataSource);
|
}
|
||||||
} else {
|
String password = config.get("password");
|
||||||
properties.put(AvailableSettings.NON_JTA_DATASOURCE, dataSource);
|
if (password != null) {
|
||||||
}
|
properties.put(AvailableSettings.JDBC_PASSWORD, password);
|
||||||
} else {
|
}
|
||||||
properties.put(AvailableSettings.JDBC_URL, config.get("url"));
|
}
|
||||||
properties.put(AvailableSettings.JDBC_DRIVER, config.get("driver"));
|
|
||||||
|
|
||||||
String user = config.get("user");
|
String driverDialect = config.get("driverDialect");
|
||||||
if (user != null) {
|
if (driverDialect != null && driverDialect.length() > 0) {
|
||||||
properties.put(AvailableSettings.JDBC_USER, user);
|
properties.put("hibernate.dialect", driverDialect);
|
||||||
}
|
}
|
||||||
String password = config.get("password");
|
|
||||||
if (password != null) {
|
|
||||||
properties.put(AvailableSettings.JDBC_PASSWORD, password);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String driverDialect = config.get("driverDialect");
|
String schema = config.get("schema");
|
||||||
if (driverDialect != null && driverDialect.length() > 0) {
|
if (schema != null) {
|
||||||
properties.put("hibernate.dialect", driverDialect);
|
properties.put("hibernate.default_schema", schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
String schema = config.get("schema");
|
if (databaseSchema != null) {
|
||||||
if (schema != null) {
|
if (databaseSchema.equals("development-update")) {
|
||||||
properties.put("hibernate.default_schema", schema);
|
properties.put("hibernate.hbm2ddl.auto", "update");
|
||||||
}
|
databaseSchema = null;
|
||||||
|
} else if (databaseSchema.equals("development-validate")) {
|
||||||
|
properties.put("hibernate.hbm2ddl.auto", "validate");
|
||||||
|
databaseSchema = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (databaseSchema != null) {
|
properties.put("hibernate.show_sql", config.getBoolean("showSql", false));
|
||||||
if (databaseSchema.equals("development-update")) {
|
properties.put("hibernate.format_sql", config.getBoolean("formatSql", true));
|
||||||
properties.put("hibernate.hbm2ddl.auto", "update");
|
|
||||||
databaseSchema = null;
|
|
||||||
} else if (databaseSchema.equals("development-validate")) {
|
|
||||||
properties.put("hibernate.hbm2ddl.auto", "validate");
|
|
||||||
databaseSchema = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
properties.put("hibernate.show_sql", config.getBoolean("showSql", false));
|
connection = getConnection();
|
||||||
properties.put("hibernate.format_sql", config.getBoolean("formatSql", true));
|
try{
|
||||||
|
prepareDatabaseInfo(connection);
|
||||||
|
|
||||||
|
if (databaseSchema != null) {
|
||||||
|
logger.trace("Updating database");
|
||||||
|
|
||||||
|
JpaUpdaterProvider updater = session.getProvider(JpaUpdaterProvider.class);
|
||||||
|
if (updater == null) {
|
||||||
|
throw new RuntimeException("Can't update database: JPA updater provider not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (databaseSchema.equals("update")) {
|
||||||
|
String currentVersion = null;
|
||||||
|
try {
|
||||||
|
ResultSet resultSet = connection.createStatement().executeQuery(updater.getCurrentVersionSql(schema));
|
||||||
|
if (resultSet.next()) {
|
||||||
|
currentVersion = resultSet.getString(1);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentVersion == null || !JpaUpdaterProvider.LAST_VERSION.equals(currentVersion)) {
|
||||||
|
updater.update(session, connection, schema);
|
||||||
|
} else {
|
||||||
|
logger.debug("Database is up to date");
|
||||||
|
}
|
||||||
|
} else if (databaseSchema.equals("validate")) {
|
||||||
|
updater.validate(connection, schema);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Invalid value for databaseSchema: " + databaseSchema);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.trace("Database update completed");
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.trace("Creating EntityManagerFactory");
|
||||||
|
emf = Persistence.createEntityManagerFactory(unitName, properties);
|
||||||
|
logger.trace("EntityManagerFactory created");
|
||||||
|
|
||||||
connection = getConnection();
|
} finally {
|
||||||
prepareDatabaseInfo(connection);
|
// Close after creating EntityManagerFactory to prevent in-mem databases from closing
|
||||||
|
if (connection != null) {
|
||||||
|
try {
|
||||||
|
connection.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logger.warn(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void prepareDatabaseInfo(Connection connection) {
|
||||||
|
try {
|
||||||
|
databaseInfo = new DatabaseInfo();
|
||||||
|
DatabaseMetaData md = connection.getMetaData();
|
||||||
|
databaseInfo.databaseDriver = md.getDriverName() + " " + md.getDriverVersion();
|
||||||
|
databaseInfo.databaseProduct = md.getDatabaseProductName() + " " + md.getDatabaseProductVersion();
|
||||||
|
databaseInfo.databaseUser = md.getUserName();
|
||||||
|
databaseInfo.jdbcUrl = md.getURL();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logger.warn("Unable to get database info due " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (databaseSchema != null) {
|
private Connection getConnection() {
|
||||||
logger.trace("Updating database");
|
try {
|
||||||
|
String dataSourceLookup = config.get("dataSource");
|
||||||
|
if (dataSourceLookup != null) {
|
||||||
|
DataSource dataSource = (DataSource) new InitialContext().lookup(dataSourceLookup);
|
||||||
|
return dataSource.getConnection();
|
||||||
|
} else {
|
||||||
|
Class.forName(config.get("driver"));
|
||||||
|
return DriverManager.getConnection(config.get("url"), config.get("user"), config.get("password"));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to connect to database", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DatabaseInfo getOperationalInfo() {
|
||||||
|
return databaseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
JpaUpdaterProvider updater = session.getProvider(JpaUpdaterProvider.class);
|
public static class DatabaseInfo implements ProviderOperationalInfo {
|
||||||
if (updater == null) {
|
protected String jdbcUrl;
|
||||||
throw new RuntimeException("Can't update database: JPA updater provider not found");
|
protected String databaseUser;
|
||||||
}
|
protected String databaseProduct;
|
||||||
|
protected String databaseDriver;
|
||||||
|
|
||||||
if (databaseSchema.equals("update")) {
|
public String getJdbcUrl() {
|
||||||
String currentVersion = null;
|
return jdbcUrl;
|
||||||
try {
|
}
|
||||||
ResultSet resultSet = connection.createStatement().executeQuery(updater.getCurrentVersionSql(schema));
|
|
||||||
if (resultSet.next()) {
|
|
||||||
currentVersion = resultSet.getString(1);
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentVersion == null || !JpaUpdaterProvider.LAST_VERSION.equals(currentVersion)) {
|
public String getDatabaseDriver() {
|
||||||
updater.update(session, connection, schema);
|
return databaseDriver;
|
||||||
} else {
|
}
|
||||||
logger.debug("Database is up to date");
|
|
||||||
}
|
|
||||||
} else if (databaseSchema.equals("validate")) {
|
|
||||||
updater.validate(connection, schema);
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Invalid value for databaseSchema: " + databaseSchema);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.trace("Database update completed");
|
public String getDatabaseUser() {
|
||||||
}
|
return databaseUser;
|
||||||
|
}
|
||||||
|
|
||||||
logger.trace("Creating EntityManagerFactory");
|
public String getDatabaseProduct() {
|
||||||
emf = Persistence.createEntityManagerFactory(unitName, properties);
|
return databaseProduct;
|
||||||
logger.trace("EntityManagerFactory created");
|
}
|
||||||
|
}
|
||||||
// Close after creating EntityManagerFactory to prevent in-mem databases from closing
|
|
||||||
if (connection != null) {
|
|
||||||
try {
|
|
||||||
connection.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logger.warn(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void prepareDatabaseInfo(Connection connection) {
|
|
||||||
try {
|
|
||||||
databaseInfo = new DatabaseInfo();
|
|
||||||
DatabaseMetaData md = connection.getMetaData();
|
|
||||||
databaseInfo.databaseDriver = md.getDriverName() + " " + md.getDriverVersion();
|
|
||||||
databaseInfo.databaseProduct = md.getDatabaseProductName() + " " + md.getDatabaseProductVersion();
|
|
||||||
databaseInfo.databaseUser = md.getUserName();
|
|
||||||
databaseInfo.jdbcUrl = md.getURL();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logger.warn("Unable to get database info due " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Connection getConnection() {
|
|
||||||
try {
|
|
||||||
String dataSourceLookup = config.get("dataSource");
|
|
||||||
if (dataSourceLookup != null) {
|
|
||||||
DataSource dataSource = (DataSource) new InitialContext().lookup(dataSourceLookup);
|
|
||||||
return dataSource.getConnection();
|
|
||||||
} else {
|
|
||||||
Class.forName(config.get("driver"));
|
|
||||||
return DriverManager.getConnection(config.get("url"), config.get("user"), config.get("password"));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Failed to connect to database", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DatabaseInfo getOperationalInfo() {
|
|
||||||
return databaseInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DatabaseInfo implements ProviderOperationalInfo {
|
|
||||||
protected String jdbcUrl;
|
|
||||||
protected String databaseUser;
|
|
||||||
protected String databaseProduct;
|
|
||||||
protected String databaseDriver;
|
|
||||||
|
|
||||||
public String getJdbcUrl() {
|
|
||||||
return jdbcUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDatabaseDriver() {
|
|
||||||
return databaseDriver;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDatabaseUser() {
|
|
||||||
return databaseUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDatabaseProduct() {
|
|
||||||
return databaseProduct;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package org.keycloak.connections.mongo;
|
package org.keycloak.connections.mongo;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import com.mongodb.DB;
|
||||||
import java.net.UnknownHostException;
|
import com.mongodb.MongoClient;
|
||||||
import java.util.Collections;
|
import com.mongodb.MongoClientOptions;
|
||||||
|
import com.mongodb.MongoCredential;
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
import com.mongodb.ServerAddress;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
|
@ -16,217 +16,234 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.provider.ProviderOperationalInfo;
|
import org.keycloak.provider.ProviderOperationalInfo;
|
||||||
|
|
||||||
import com.mongodb.DB;
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
import com.mongodb.MongoClient;
|
|
||||||
import com.mongodb.MongoClientOptions;
|
import java.lang.reflect.Method;
|
||||||
import com.mongodb.MongoCredential;
|
import java.net.UnknownHostException;
|
||||||
import com.mongodb.ServerAddress;
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
public class DefaultMongoConnectionFactoryProvider implements MongoConnectionProviderFactory {
|
public class DefaultMongoConnectionFactoryProvider implements MongoConnectionProviderFactory {
|
||||||
|
|
||||||
// TODO Make configurable
|
// TODO Make configurable
|
||||||
private String[] entities = new String[] { "org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity", "org.keycloak.models.mongo.keycloak.entities.MongoUserEntity", "org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity",
|
private String[] entities = new String[]{
|
||||||
"org.keycloak.models.entities.IdentityProviderEntity", "org.keycloak.models.entities.ClientIdentityProviderMappingEntity", "org.keycloak.models.entities.RequiredCredentialEntity", "org.keycloak.models.entities.CredentialEntity",
|
"org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity",
|
||||||
"org.keycloak.models.entities.FederatedIdentityEntity", "org.keycloak.models.mongo.keycloak.entities.MongoClientEntity", "org.keycloak.models.sessions.mongo.entities.MongoUsernameLoginFailureEntity",
|
"org.keycloak.models.mongo.keycloak.entities.MongoUserEntity",
|
||||||
"org.keycloak.models.sessions.mongo.entities.MongoUserSessionEntity", "org.keycloak.models.sessions.mongo.entities.MongoClientSessionEntity", "org.keycloak.models.entities.UserFederationProviderEntity",
|
"org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity",
|
||||||
"org.keycloak.models.entities.UserFederationMapperEntity", "org.keycloak.models.entities.ProtocolMapperEntity", "org.keycloak.models.entities.IdentityProviderMapperEntity",
|
"org.keycloak.models.entities.IdentityProviderEntity",
|
||||||
"org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity", "org.keycloak.models.mongo.keycloak.entities.MongoMigrationModelEntity", "org.keycloak.models.entities.AuthenticationExecutionEntity",
|
"org.keycloak.models.entities.ClientIdentityProviderMappingEntity",
|
||||||
"org.keycloak.models.entities.AuthenticationFlowEntity", "org.keycloak.models.entities.AuthenticatorConfigEntity", "org.keycloak.models.entities.RequiredActionProviderEntity", };
|
"org.keycloak.models.entities.RequiredCredentialEntity",
|
||||||
|
"org.keycloak.models.entities.CredentialEntity",
|
||||||
|
"org.keycloak.models.entities.FederatedIdentityEntity",
|
||||||
|
"org.keycloak.models.mongo.keycloak.entities.MongoClientEntity",
|
||||||
|
"org.keycloak.models.sessions.mongo.entities.MongoUsernameLoginFailureEntity",
|
||||||
|
"org.keycloak.models.sessions.mongo.entities.MongoUserSessionEntity",
|
||||||
|
"org.keycloak.models.sessions.mongo.entities.MongoClientSessionEntity",
|
||||||
|
"org.keycloak.models.entities.UserFederationProviderEntity",
|
||||||
|
"org.keycloak.models.entities.UserFederationMapperEntity",
|
||||||
|
"org.keycloak.models.entities.ProtocolMapperEntity",
|
||||||
|
"org.keycloak.models.entities.IdentityProviderMapperEntity",
|
||||||
|
"org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity",
|
||||||
|
"org.keycloak.models.mongo.keycloak.entities.MongoMigrationModelEntity",
|
||||||
|
"org.keycloak.models.entities.AuthenticationExecutionEntity",
|
||||||
|
"org.keycloak.models.entities.AuthenticationFlowEntity",
|
||||||
|
"org.keycloak.models.entities.AuthenticatorConfigEntity",
|
||||||
|
"org.keycloak.models.entities.RequiredActionProviderEntity",
|
||||||
|
};
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(DefaultMongoConnectionFactoryProvider.class);
|
private static final Logger logger = Logger.getLogger(DefaultMongoConnectionFactoryProvider.class);
|
||||||
|
|
||||||
private volatile MongoClient client;
|
private volatile MongoClient client;
|
||||||
|
|
||||||
private MongoStore mongoStore;
|
private MongoStore mongoStore;
|
||||||
private DB db;
|
private DB db;
|
||||||
protected Config.Scope config;
|
protected Config.Scope config;
|
||||||
|
|
||||||
|
private MongoDbInfo mongoDbInfo;
|
||||||
|
|
||||||
private MongoDbInfo mongoDbInfo;
|
@Override
|
||||||
|
public MongoConnectionProvider create(KeycloakSession session) {
|
||||||
|
lazyInit(session);
|
||||||
|
|
||||||
@Override
|
TransactionMongoStoreInvocationContext invocationContext = new TransactionMongoStoreInvocationContext(mongoStore);
|
||||||
public MongoConnectionProvider create(KeycloakSession session) {
|
session.getTransaction().enlist(new MongoKeycloakTransaction(invocationContext));
|
||||||
lazyInit(session);
|
return new DefaultMongoConnectionProvider(db, mongoStore, invocationContext);
|
||||||
|
}
|
||||||
|
|
||||||
TransactionMongoStoreInvocationContext invocationContext = new TransactionMongoStoreInvocationContext(mongoStore);
|
@Override
|
||||||
session.getTransaction().enlist(new MongoKeycloakTransaction(invocationContext));
|
public void init(Config.Scope config) {
|
||||||
return new DefaultMongoConnectionProvider(db, mongoStore, invocationContext);
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Config.Scope config) {
|
public void postInit(KeycloakSessionFactory factory) {
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public void postInit(KeycloakSessionFactory factory) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void lazyInit(KeycloakSession session) {
|
private void lazyInit(KeycloakSession session) {
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
try {
|
try {
|
||||||
this.client = createMongoClient();
|
this.client = createMongoClient();
|
||||||
|
|
||||||
String dbName = config.get("db", "keycloak");
|
String dbName = config.get("db", "keycloak");
|
||||||
this.db = client.getDB(dbName);
|
this.db = client.getDB(dbName);
|
||||||
|
|
||||||
String databaseSchema = config.get("databaseSchema");
|
String databaseSchema = config.get("databaseSchema");
|
||||||
if (databaseSchema != null) {
|
if (databaseSchema != null) {
|
||||||
if (databaseSchema.equals("update")) {
|
if (databaseSchema.equals("update")) {
|
||||||
MongoUpdaterProvider mongoUpdater = session.getProvider(MongoUpdaterProvider.class);
|
MongoUpdaterProvider mongoUpdater = session.getProvider(MongoUpdaterProvider.class);
|
||||||
|
|
||||||
if (mongoUpdater == null) {
|
if (mongoUpdater == null) {
|
||||||
throw new RuntimeException("Can't update database: Mongo updater provider not found");
|
throw new RuntimeException("Can't update database: Mongo updater provider not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
mongoUpdater.update(session, db);
|
mongoUpdater.update(session, db);
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Invalid value for databaseSchema: " + databaseSchema);
|
throw new RuntimeException("Invalid value for databaseSchema: " + databaseSchema);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mongoStore = new MongoStoreImpl(db, getManagedEntities());
|
this.mongoStore = new MongoStoreImpl(db, getManagedEntities());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Class[] getManagedEntities() throws ClassNotFoundException {
|
private Class[] getManagedEntities() throws ClassNotFoundException {
|
||||||
Class[] entityClasses = new Class[entities.length];
|
Class[] entityClasses = new Class[entities.length];
|
||||||
for (int i = 0; i < entities.length; i++) {
|
for (int i = 0; i < entities.length; i++) {
|
||||||
entityClasses[i] = Thread.currentThread().getContextClassLoader().loadClass(entities[i]);
|
entityClasses[i] = Thread.currentThread().getContextClassLoader().loadClass(entities[i]);
|
||||||
}
|
}
|
||||||
return entityClasses;
|
return entityClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "default";
|
return "default";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override this method if you want more possibility to configure Mongo client. It can be also used to inject mongo
|
* Override this method if you want more possibility to configure Mongo client. It can be also used to inject mongo client
|
||||||
* client from different source.
|
* from different source.
|
||||||
*
|
*
|
||||||
* This method can assume that "config" is already set and can use it.
|
* This method can assume that "config" is already set and can use it.
|
||||||
*
|
*
|
||||||
* @return mongoClient instance, which will be shared for whole Keycloak
|
* @return mongoClient instance, which will be shared for whole Keycloak
|
||||||
*
|
*
|
||||||
* @throws UnknownHostException
|
* @throws UnknownHostException
|
||||||
*/
|
*/
|
||||||
protected MongoClient createMongoClient() throws UnknownHostException {
|
protected MongoClient createMongoClient() throws UnknownHostException {
|
||||||
String host = config.get("host", ServerAddress.defaultHost());
|
String host = config.get("host", ServerAddress.defaultHost());
|
||||||
int port = config.getInt("port", ServerAddress.defaultPort());
|
int port = config.getInt("port", ServerAddress.defaultPort());
|
||||||
String dbName = config.get("db", "keycloak");
|
String dbName = config.get("db", "keycloak");
|
||||||
|
|
||||||
String user = config.get("user");
|
String user = config.get("user");
|
||||||
String password = config.get("password");
|
String password = config.get("password");
|
||||||
|
|
||||||
MongoClientOptions clientOptions = getClientOptions();
|
MongoClientOptions clientOptions = getClientOptions();
|
||||||
|
|
||||||
MongoClient client;
|
MongoClient client;
|
||||||
if (user != null && password != null) {
|
if (user != null && password != null) {
|
||||||
MongoCredential credential = MongoCredential.createMongoCRCredential(user, dbName, password.toCharArray());
|
MongoCredential credential = MongoCredential.createMongoCRCredential(user, dbName, password.toCharArray());
|
||||||
client = new MongoClient(new ServerAddress(host, port), Collections.singletonList(credential), clientOptions);
|
client = new MongoClient(new ServerAddress(host, port), Collections.singletonList(credential), clientOptions);
|
||||||
} else {
|
} else {
|
||||||
client = new MongoClient(new ServerAddress(host, port), clientOptions);
|
client = new MongoClient(new ServerAddress(host, port), clientOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mongoDbInfo = new MongoDbInfo();
|
||||||
|
mongoDbInfo.driverVersion = client.getVersion();
|
||||||
|
mongoDbInfo.address = client.getAddress().toString();
|
||||||
|
mongoDbInfo.database = dbName;
|
||||||
|
mongoDbInfo.user = user;
|
||||||
|
|
||||||
|
logger.debugv("Initialized mongo model. host: %s, port: %d, db: %s", host, port, dbName);
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
mongoDbInfo = new MongoDbInfo();
|
protected MongoClientOptions getClientOptions() {
|
||||||
mongoDbInfo.driverVersion = client.getVersion();
|
MongoClientOptions.Builder builder = MongoClientOptions.builder();
|
||||||
mongoDbInfo.address = client.getAddress().toString();
|
checkIntOption("connectionsPerHost", builder);
|
||||||
mongoDbInfo.database = dbName;
|
checkIntOption("threadsAllowedToBlockForConnectionMultiplier", builder);
|
||||||
mongoDbInfo.user = user;
|
checkIntOption("maxWaitTime", builder);
|
||||||
|
checkIntOption("connectTimeout", builder);
|
||||||
|
checkIntOption("socketTimeout", builder);
|
||||||
|
checkBooleanOption("socketKeepAlive", builder);
|
||||||
|
checkBooleanOption("autoConnectRetry", builder);
|
||||||
|
if (config.getLong("maxAutoConnectRetryTime") != null) {
|
||||||
|
builder.maxAutoConnectRetryTime(config.getLong("maxAutoConnectRetryTime"));
|
||||||
|
}
|
||||||
|
if(config.getBoolean("ssl", false)) {
|
||||||
|
builder.socketFactory(SSLSocketFactory.getDefault());
|
||||||
|
}
|
||||||
|
|
||||||
logger.debugv("Initialized mongo model. host: %s, port: %d, db: %s", host, port, dbName);
|
return builder.build();
|
||||||
return client;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected MongoClientOptions getClientOptions() {
|
protected void checkBooleanOption(String optionName, MongoClientOptions.Builder builder) {
|
||||||
MongoClientOptions.Builder builder = MongoClientOptions.builder();
|
Boolean val = config.getBoolean(optionName);
|
||||||
checkIntOption("connectionsPerHost", builder);
|
if (val != null) {
|
||||||
checkIntOption("threadsAllowedToBlockForConnectionMultiplier", builder);
|
try {
|
||||||
checkIntOption("maxWaitTime", builder);
|
Method m = MongoClientOptions.Builder.class.getMethod(optionName, boolean.class);
|
||||||
checkIntOption("connectTimeout", builder);
|
m.invoke(builder, val);
|
||||||
checkIntOption("socketTimeout", builder);
|
} catch (Exception e) {
|
||||||
checkBooleanOption("socketKeepAlive", builder);
|
throw new IllegalStateException("Problem configuring boolean option " + optionName + " for mongo client. Ensure you used correct value true or false and if this option is supported by mongo driver", e);
|
||||||
checkBooleanOption("autoConnectRetry", builder);
|
}
|
||||||
if (config.getLong("maxAutoConnectRetryTime") != null) {
|
}
|
||||||
builder.maxAutoConnectRetryTime(config.getLong("maxAutoConnectRetryTime"));
|
}
|
||||||
}
|
|
||||||
if (config.getBoolean("ssl", false)) {
|
|
||||||
builder.socketFactory(SSLSocketFactory.getDefault());
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.build();
|
protected void checkIntOption(String optionName, MongoClientOptions.Builder builder) {
|
||||||
}
|
Integer val = config.getInt(optionName);
|
||||||
|
if (val != null) {
|
||||||
|
try {
|
||||||
|
Method m = MongoClientOptions.Builder.class.getMethod(optionName, int.class);
|
||||||
|
m.invoke(builder, val);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalStateException("Problem configuring int option " + optionName + " for mongo client. Ensure you used correct value (number) and if this option is supported by mongo driver", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProviderOperationalInfo getOperationalInfo() {
|
||||||
|
return mongoDbInfo;
|
||||||
|
}
|
||||||
|
|
||||||
protected void checkBooleanOption(String optionName, MongoClientOptions.Builder builder) {
|
public static class MongoDbInfo implements ProviderOperationalInfo {
|
||||||
Boolean val = config.getBoolean(optionName);
|
|
||||||
if (val != null) {
|
|
||||||
try {
|
|
||||||
Method m = MongoClientOptions.Builder.class.getMethod(optionName, boolean.class);
|
|
||||||
m.invoke(builder, val);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new IllegalStateException("Problem configuring boolean option " + optionName + " for mongo client. Ensure you used correct value true or false and if this option is supported by mongo driver", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void checkIntOption(String optionName, MongoClientOptions.Builder builder) {
|
public String address;
|
||||||
Integer val = config.getInt(optionName);
|
public String database;
|
||||||
if (val != null) {
|
public String driverVersion;
|
||||||
try {
|
public String user;
|
||||||
Method m = MongoClientOptions.Builder.class.getMethod(optionName, int.class);
|
|
||||||
m.invoke(builder, val);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new IllegalStateException("Problem configuring int option " + optionName + " for mongo client. Ensure you used correct value (number) and if this option is supported by mongo driver", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public String getAddress() {
|
||||||
public ProviderOperationalInfo getOperationalInfo() {
|
return address;
|
||||||
return mongoDbInfo;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static class MongoDbInfo implements ProviderOperationalInfo {
|
public String getDatabase() {
|
||||||
|
return database;
|
||||||
|
}
|
||||||
|
|
||||||
public String address;
|
public String getDriverVersion() {
|
||||||
public String database;
|
return driverVersion;
|
||||||
public String driverVersion;
|
}
|
||||||
public String user;
|
|
||||||
|
|
||||||
public String getAddress() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDatabase() {
|
|
||||||
return database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDriverVersion() {
|
|
||||||
return driverVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUser() {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public String getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,5 @@
|
||||||
package org.keycloak.services.resources.admin;
|
package org.keycloak.services.resources.admin;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.ServiceLoader;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
|
||||||
import javax.ws.rs.core.Context;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.Version;
|
import org.keycloak.Version;
|
||||||
import org.keycloak.broker.provider.IdentityProvider;
|
import org.keycloak.broker.provider.IdentityProvider;
|
||||||
|
@ -43,6 +29,19 @@ import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||||
import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation;
|
import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation;
|
||||||
import org.keycloak.social.SocialIdentityProvider;
|
import org.keycloak.social.SocialIdentityProvider;
|
||||||
|
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
|
@ -219,7 +218,6 @@ public class ServerInfoAdminResource {
|
||||||
public static class MemoryInfo implements Serializable {
|
public static class MemoryInfo implements Serializable {
|
||||||
|
|
||||||
protected long total;
|
protected long total;
|
||||||
|
|
||||||
protected long used;
|
protected long used;
|
||||||
|
|
||||||
public MemoryInfo(){
|
public MemoryInfo(){
|
||||||
|
|
|
@ -21,22 +21,6 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.testsuite.admin;
|
package org.keycloak.testsuite.admin;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.ws.rs.client.Client;
|
|
||||||
import javax.ws.rs.client.ClientBuilder;
|
|
||||||
import javax.ws.rs.client.ClientRequestContext;
|
|
||||||
import javax.ws.rs.client.ClientRequestFilter;
|
|
||||||
import javax.ws.rs.client.Entity;
|
|
||||||
import javax.ws.rs.client.WebTarget;
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -57,8 +41,23 @@ import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.resources.admin.AdminRoot;
|
import org.keycloak.services.resources.admin.AdminRoot;
|
||||||
import org.keycloak.testsuite.KeycloakServer;
|
|
||||||
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
|
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
|
||||||
|
import org.keycloak.testsuite.KeycloakServer;
|
||||||
|
|
||||||
|
import javax.ws.rs.client.Client;
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
import javax.ws.rs.client.ClientRequestContext;
|
||||||
|
import javax.ws.rs.client.ClientRequestFilter;
|
||||||
|
import javax.ws.rs.client.Entity;
|
||||||
|
import javax.ws.rs.client.WebTarget;
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests Undertow Adapter
|
* Tests Undertow Adapter
|
||||||
|
|
Loading…
Reference in a new issue