mirror of
https://github.com/keycloak/keycloak.git
synced 2025-12-17 20:44:50 -06:00
Add TiDB as supported db
Closes #41455 Signed-off-by: Dennis Kniep <kniepdennis@gmail.com> Signed-off-by: Alexander Schwartz <aschwart@redhat.com> Co-authored-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -693,7 +693,7 @@ jobs:
|
||||
timeout-minutes: 75
|
||||
strategy:
|
||||
matrix:
|
||||
db: [postgres, mysql, oracle, mssql, mariadb]
|
||||
db: [postgres, mysql, oracle, mssql, mariadb, tidb]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
@@ -53,6 +53,23 @@ Stop MySQl:
|
||||
|
||||
docker rm -f mariadb
|
||||
|
||||
TiDB
|
||||
-----
|
||||
|
||||
The simplest way to test with TiDB is to use the official [TiDB docker image](https://hub.docker.com/r/pingcap/tidb).
|
||||
|
||||
Start TiDB:
|
||||
|
||||
docker run --name tidb -p 4000:4000 -d pingcap/tidb:v8.5.2
|
||||
|
||||
Run tests:
|
||||
|
||||
mvn install -Dkeycloak.connectionsJpa.url=jdbc:mysql://`docker inspect --format '{{ .NetworkSettings.IPAddress }}' tidb`:4000/test -Dkeycloak.connectionsJpa.driver=com.mysql.jdbc.Driver -Dkeycloak.connectionsJpa.user=root -Dkeycloak.connectionsJpa.password=
|
||||
|
||||
Stop TiDB:
|
||||
|
||||
docker rm -f tidb
|
||||
|
||||
Using built-in profiles to run database tests using docker containers
|
||||
-------
|
||||
|
||||
|
||||
@@ -55,6 +55,17 @@
|
||||
</createIndex>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="keycloak" id="client-attributes-string-accomodation-fixed-pre-drop-index">
|
||||
<preConditions onSqlOutput="TEST" onFail="MARK_RAN">
|
||||
<and>
|
||||
<not>
|
||||
<changeSetExecuted id="client-attributes-string-accomodation-fixed" author="keycloak" changeLogFile="META-INF/jpa-changelog-20.0.0.xml"/>
|
||||
</not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<dropIndex tableName="CLIENT_ATTRIBUTES" indexName="IDX_CLIENT_ATT_BY_NAME_VALUE" />
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="keycloak" id="client-attributes-string-accomodation-fixed">
|
||||
<addColumn tableName="CLIENT_ATTRIBUTES">
|
||||
<column name="VALUE_NEW" type="NCLOB" />
|
||||
@@ -68,4 +79,19 @@
|
||||
<renameColumn tableName="CLIENT_ATTRIBUTES" oldColumnName="VALUE_NEW" newColumnName="VALUE" columnDataType="NCLOB"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="keycloak" id="client-attributes-string-accomodation-fixed-post-create-index">
|
||||
<preConditions onSqlOutput="TEST" onFail="MARK_RAN">
|
||||
<and>
|
||||
<not>
|
||||
<changeSetExecuted id="client-attributes-string-accomodation-fixed" author="keycloak" changeLogFile="META-INF/jpa-changelog-20.0.0.xml"/>
|
||||
</not>
|
||||
</and>
|
||||
</preConditions>
|
||||
|
||||
<createIndex tableName="CLIENT_ATTRIBUTES" indexName="IDX_CLIENT_ATT_BY_NAME_VALUE">
|
||||
<column name="NAME" type="VARCHAR(255)"/>
|
||||
<column name="VALUE(255)" valueComputed="VALUE(255)" />
|
||||
</createIndex>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
2
pom.xml
2
pom.xml
@@ -151,6 +151,8 @@
|
||||
<twitter4j.version>4.1.2</twitter4j.version>
|
||||
|
||||
<!-- Databases - also published to db.adoc as "Tested Version" -->
|
||||
<tidb.version>v8.5.2</tidb.version>
|
||||
<tidb.container>mirror.gcr.io/pingcap/tidb:${tidb.version}</tidb.container>
|
||||
<mysql.version>8.4</mysql.version>
|
||||
<mysql.container>mirror.gcr.io/mysql:${mysql.version}</mysql.container>
|
||||
<mysql-jdbc.version>8.3.0</mysql-jdbc.version>
|
||||
|
||||
@@ -190,6 +190,7 @@
|
||||
<kc.db.mysql.container.image>${mysql.container}</kc.db.mysql.container.image>
|
||||
<kc.infinispan.container.image>quay.io/infinispan/server:${infinispan.version}</kc.infinispan.container.image>
|
||||
<kc.db.mssql.container.image>${mssql.container}</kc.db.mssql.container.image>
|
||||
<kc.db.tidb.container.image>${tidb.container}</kc.db.tidb.container.image>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@@ -102,6 +102,10 @@
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>mssqlserver</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>tidb</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- JDBC Drivers -->
|
||||
<dependency>
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.testcontainers.containers.MSSQLServerContainer;
|
||||
import org.testcontainers.containers.MariaDBContainer;
|
||||
import org.testcontainers.containers.MySQLContainer;
|
||||
import org.testcontainers.containers.PostgreSQLContainer;
|
||||
import org.testcontainers.images.PullPolicy;
|
||||
import org.testcontainers.tidb.TiDBContainer;
|
||||
import org.testcontainers.utility.DockerImageName;
|
||||
|
||||
public class DatabaseContainer {
|
||||
@@ -95,6 +95,7 @@ public class DatabaseContainer {
|
||||
String MARIADB_IMAGE = System.getProperty("kc.db.mariadb.container.image");
|
||||
String MYSQL_IMAGE = System.getProperty("kc.db.mysql.container.image");
|
||||
String MSSQL_IMAGE = System.getProperty("kc.db.mssql.container.image");
|
||||
String TIDB_IMAGE = System.getProperty("kc.db.tidb.container.image");
|
||||
|
||||
switch (alias) {
|
||||
case "postgres":
|
||||
@@ -109,6 +110,9 @@ public class DatabaseContainer {
|
||||
case "mssql":
|
||||
DockerImageName MSSQL = DockerImageName.parse(MSSQL_IMAGE).asCompatibleSubstituteFor("sqlserver");
|
||||
return configureJdbcContainer(new MSSQLServerContainer<>(MSSQL));
|
||||
case "tidb":
|
||||
DockerImageName TIDB = DockerImageName.parse(TIDB_IMAGE).asCompatibleSubstituteFor("pingcap/tidb");
|
||||
return configureJdbcContainer(new TiDBContainer(TIDB));
|
||||
default:
|
||||
throw new RuntimeException("Unsupported database: " + alias);
|
||||
}
|
||||
|
||||
@@ -385,6 +385,7 @@ Valid values:
|
||||
| mysql | MySQL test container |
|
||||
| oracle | Oracle test container |
|
||||
| postgres | PostgreSQL test container |
|
||||
| tidb | TiDb test container |
|
||||
|
||||
Configuration:
|
||||
|
||||
|
||||
@@ -75,6 +75,12 @@
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak.testframework</groupId>
|
||||
<artifactId>keycloak-test-framework-db-tidb</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak.testframework</groupId>
|
||||
<artifactId>keycloak-test-framework-db-oracle</artifactId>
|
||||
|
||||
@@ -3,3 +3,4 @@ postgres.container=${postgresql.container}
|
||||
mariadb.container=${mariadb.container}
|
||||
mssql.container=${mssql.container}
|
||||
oracle.container=${oracledb.container}
|
||||
tidb.container=${tidb.container}
|
||||
45
test-framework/db-tidb/pom.xml
Executable file
45
test-framework/db-tidb/pom.xml
Executable file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
~ Copyright 2016 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-test-framework-parent</artifactId>
|
||||
<groupId>org.keycloak.testframework</groupId>
|
||||
<version>999.0.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-test-framework-db-tidb</artifactId>
|
||||
<name>Keycloak Test Framework - TiDB support</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>TiDB support for Keycloak Test Framework</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak.testframework</groupId>
|
||||
<artifactId>keycloak-test-framework-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>tidb</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.keycloak.testframework.database;
|
||||
|
||||
public class TiDBDatabaseSupplier extends AbstractDatabaseSupplier {
|
||||
|
||||
@Override
|
||||
public String getAlias() {
|
||||
return "tidb";
|
||||
}
|
||||
|
||||
@Override
|
||||
TestDatabase getTestDatabase() {
|
||||
return new TiDBTestDatabase();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.keycloak.testframework.database;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.testcontainers.containers.JdbcDatabaseContainer;
|
||||
import org.testcontainers.tidb.TiDBContainer;
|
||||
import org.testcontainers.utility.DockerImageName;
|
||||
|
||||
class TiDBTestDatabase extends AbstractContainerTestDatabase {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(TiDBTestDatabase.class);
|
||||
|
||||
public static final String NAME = "tidb";
|
||||
|
||||
@Override
|
||||
public JdbcDatabaseContainer<?> createContainer() {
|
||||
return new TiDBContainer(DockerImageName.parse(DatabaseProperties.getContainerImageName(NAME)).asCompatibleSubstituteFor("pingcap/tidb")){
|
||||
@Override
|
||||
public TiDBContainer withDatabaseName(String databaseName) {
|
||||
if(StringUtils.equals(this.getDatabaseName(), databaseName)) {
|
||||
return this;
|
||||
}
|
||||
throw new UnsupportedOperationException("The TiDB docker image does not currently support this");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TiDBContainer withUsername(String username) {
|
||||
if(StringUtils.equals(this.getUsername(), username)) {
|
||||
return this;
|
||||
}
|
||||
throw new UnsupportedOperationException("The TiDB docker image does not currently support this");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TiDBContainer withPassword(String password) {
|
||||
if(StringUtils.equals(this.getPassword(), password)) {
|
||||
return this;
|
||||
}
|
||||
throw new UnsupportedOperationException("The TiDB docker image does not currently support this");
|
||||
}
|
||||
}.withExposedPorts(4000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatabaseVendor() {
|
||||
return "mysql";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
return LOGGER;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDatabase() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return "root";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.keycloak.testframework.database;
|
||||
|
||||
import org.keycloak.testframework.TestFrameworkExtension;
|
||||
import org.keycloak.testframework.injection.Supplier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TiDBTestFrameworkExtension implements TestFrameworkExtension {
|
||||
|
||||
@Override
|
||||
public List<Supplier<?, ?>> suppliers() {
|
||||
return List.of(new TiDBDatabaseSupplier());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.keycloak.testframework.database.TiDBTestFrameworkExtension
|
||||
@@ -64,6 +64,10 @@
|
||||
<groupId>org.keycloak.testframework</groupId>
|
||||
<artifactId>keycloak-test-framework-db-mysql</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak.testframework</groupId>
|
||||
<artifactId>keycloak-test-framework-db-tidb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak.testframework</groupId>
|
||||
<artifactId>keycloak-test-framework-db-oracle</artifactId>
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
<module>db-mysql</module>
|
||||
<module>db-oracle</module>
|
||||
<module>db-postgres</module>
|
||||
<module>db-tidb</module>
|
||||
<module>email-server</module>
|
||||
<module>examples</module>
|
||||
<module>oauth</module>
|
||||
|
||||
@@ -76,6 +76,10 @@
|
||||
<groupId>org.keycloak.testframework</groupId>
|
||||
<artifactId>keycloak-test-framework-db-postgres</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak.testframework</groupId>
|
||||
<artifactId>keycloak-test-framework-db-tidb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak.testframework</groupId>
|
||||
<artifactId>keycloak-test-framework-email-server</artifactId>
|
||||
|
||||
@@ -19,7 +19,8 @@ import org.keycloak.testframework.realm.RoleConfigBuilder;
|
||||
|
||||
@KeycloakIntegrationTest(config = CaseSensitiveSchemaTest.KeycloakConfig.class)
|
||||
// MSSQL does not support setting the default schema per session
|
||||
@DisabledForDatabases("mssql")
|
||||
// TiDb does not support setting the default schema per session.
|
||||
@DisabledForDatabases({"mssql", "tidb"})
|
||||
public class CaseSensitiveSchemaTest {
|
||||
@InjectTestDatabase(lifecycle = LifeCycle.CLASS, config = DatabaseConfigurator.class)
|
||||
TestDatabase db;
|
||||
|
||||
@@ -12,8 +12,9 @@ import org.keycloak.testframework.server.KeycloakServerConfigBuilder;
|
||||
|
||||
@KeycloakIntegrationTest(config = PreserveSchemaCaseLiquibaseTest.KeycloakConfig.class)
|
||||
// MSSQL does not support setting the default schema per session.
|
||||
// TiDb does not support setting the default schema per session.
|
||||
// Oracle image does not support configuring user/databases with '-'
|
||||
@DisabledForDatabases({ "mssql", "oracle" })
|
||||
@DisabledForDatabases({ "mssql", "oracle", "tidb" })
|
||||
public class PreserveSchemaCaseLiquibaseTest extends CaseSensitiveSchemaTest {
|
||||
|
||||
@InjectTestDatabase(lifecycle = LifeCycle.CLASS, config = DatabaseConfigurator.class)
|
||||
|
||||
@@ -416,6 +416,29 @@
|
||||
<docker.database.wait-for-log-regex>(?si)Ready for start up.*ready [^\n]{0,30}connections</docker.database.wait-for-log-regex>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>db-tidb</id>
|
||||
<properties>
|
||||
<keycloak.storage.connections.vendor>mysql</keycloak.storage.connections.vendor>
|
||||
<keycloak.connectionsJpa.driver>com.mysql.jdbc.Driver</keycloak.connectionsJpa.driver>
|
||||
<keycloak.connectionsJpa.database>test</keycloak.connectionsJpa.database>
|
||||
<keycloak.connectionsJpa.user>root</keycloak.connectionsJpa.user>
|
||||
<keycloak.connectionsJpa.password></keycloak.connectionsJpa.password>
|
||||
<keycloak.connectionsJpa.url>jdbc:mysql://${auth.server.db.host}:${docker.database.port}/${keycloak.connectionsJpa.database}</keycloak.connectionsJpa.url>
|
||||
|
||||
<!-- JDBC properties point to "default" JDBC driver for the particular DB -->
|
||||
<!-- For EAP testing, it is recommended to override those with system properties pointing to GAV of more appropriate JDBC driver -->
|
||||
<!-- for the particular EAP version -->
|
||||
<jdbc.mvn.groupId>com.mysql</jdbc.mvn.groupId>
|
||||
<jdbc.mvn.artifactId>mysql-connector-j</jdbc.mvn.artifactId>
|
||||
<jdbc.mvn.version>${mysql-jdbc.version}</jdbc.mvn.version>
|
||||
<docker.database.image>${tidb.container}</docker.database.image>
|
||||
<docker.database.port>4000</docker.database.port>
|
||||
<docker.database.skip>false</docker.database.skip>
|
||||
<docker.database.cmd>start</docker.database.cmd>
|
||||
<docker.database.wait-for-log-regex>server is running MySQL protocol</docker.database.wait-for-log-regex>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>db-postgres</id>
|
||||
<properties>
|
||||
|
||||
@@ -59,8 +59,6 @@
|
||||
</requireProperty>
|
||||
<requireProperty>
|
||||
<property>keycloak.connectionsJpa.password</property>
|
||||
<regex>^(?!\s*$).+</regex>
|
||||
<regexMessage>"keycloak.connectionsJpa.password" property cannot be empty string!</regexMessage>
|
||||
</requireProperty>
|
||||
<requireProperty>
|
||||
<property>keycloak.connectionsJpa.url</property>
|
||||
|
||||
Reference in New Issue
Block a user