Register custom functions FunctionContributor
Closes #16336 --- Quarkus3 branch sync no. 6 (17.2.2023) Resolved conflicts: keycloak/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/JpaMapStorage.java - Modified keycloak/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/JpaMapStorageCockroachdb.java - Modified keycloak/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/JpaMapStorageProviderFactory.java - Modified --- Quarkus3 branch sync no. 3 (27.1.2023) Resolved conflicts: keycloak/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/JpaMapStorage.java - Modified keycloak/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/JpaMapStorageCockroachdb.java - Modified
This commit is contained in:
parent
33e2bcd94f
commit
60e6fb9dae
8 changed files with 93 additions and 46 deletions
|
@ -410,7 +410,7 @@ public class JpaMapStorageProviderFactory implements
|
||||||
properties.put("hibernate.format_sql", config.getBoolean("formatSql", true));
|
properties.put("hibernate.format_sql", config.getBoolean("formatSql", true));
|
||||||
properties.put("hibernate.dialect", config.get("driverDialect"));
|
properties.put("hibernate.dialect", config.get("driverDialect"));
|
||||||
// metadata contributor to register the json type
|
// metadata contributor to register the json type
|
||||||
properties.put("hibernate.metadata_builder_contributor", "org.keycloak.models.map.storage.jpa.hibernate.jsonb.JsonbMetadataBuilderContributor");
|
properties.put("hibernate.metadata_builder_contributor", "org.keycloak.models.map.storage.jpa.hibernate.contributor.JsonbMetadataBuilderContributor");
|
||||||
properties.put("jakarta.persistence.validation.mode", ValidationMode.NONE.name());
|
properties.put("jakarta.persistence.validation.mode", ValidationMode.NONE.name());
|
||||||
Long lockTimeout = config.getLong("lockTimeout", DEFAULT_LOCK_TIMEOUT);
|
Long lockTimeout = config.getLong("lockTimeout", DEFAULT_LOCK_TIMEOUT);
|
||||||
if (lockTimeout >= 0) {
|
if (lockTimeout >= 0) {
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.hibernate.contributor;
|
||||||
|
|
||||||
|
import org.hibernate.boot.model.FunctionContributions;
|
||||||
|
import org.hibernate.boot.model.FunctionContributor;
|
||||||
|
import org.hibernate.dialect.CockroachDialect;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.dialect.PostgreSQLDialect;
|
||||||
|
import org.hibernate.type.BasicType;
|
||||||
|
import org.hibernate.type.BasicTypeReference;
|
||||||
|
import org.hibernate.type.SqlTypes;
|
||||||
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.JsonbType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link FunctionContributor} to register custom functions.
|
||||||
|
*/
|
||||||
|
public class JpaMapFunctionContributor implements FunctionContributor {
|
||||||
|
|
||||||
|
private final Logger LOG = Logger.getLogger(JpaMapFunctionContributor.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contributeFunctions(FunctionContributions fc) {
|
||||||
|
|
||||||
|
fc.getFunctionRegistry().registerPattern("->>", "?1->>?2", getBasicType(fc, StandardBasicTypes.STRING));
|
||||||
|
fc.getFunctionRegistry().registerPattern("->", "?1->?2", getJsonbBasicType(fc));
|
||||||
|
fc.getFunctionRegistry().registerPattern("@>", "?1@>?2::jsonb", getBasicType(fc, StandardBasicTypes.BOOLEAN));
|
||||||
|
|
||||||
|
contributeDbSpecificFunctions(fc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BasicType getJsonbBasicType(FunctionContributions fc) {
|
||||||
|
return fc.getTypeConfiguration().getBasicTypeRegistry().resolve(JsonbType.class, SqlTypes.JSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BasicType getBasicType(FunctionContributions fc, BasicTypeReference<?> btr) {
|
||||||
|
return fc.getTypeConfiguration().getBasicTypeRegistry().resolve(btr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since Hibernate 6.2.0 dialect should be accessible via FunctionContributions.getDialect(): https://github.com/hibernate/hibernate-orm/pull/5964/
|
||||||
|
private Dialect getDialect(FunctionContributions fc) {
|
||||||
|
return fc.getTypeConfiguration().getMetadataBuildingContext().getMetadataCollector().getDatabase().getDialect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void contributeDbSpecificFunctions(FunctionContributions fc) {
|
||||||
|
Dialect dialect = getDialect(fc);
|
||||||
|
if (dialect instanceof PostgreSQLDialect) {
|
||||||
|
fc.getFunctionRegistry().registerPattern("kc_hash", "sha256(?1::bytea)", getBasicType(fc, StandardBasicTypes.BINARY));
|
||||||
|
} else if (dialect instanceof CockroachDialect) {
|
||||||
|
fc.getFunctionRegistry().registerPattern("kc_hash", "sha256(?1)", getBasicType(fc, StandardBasicTypes.STRING));
|
||||||
|
} else {
|
||||||
|
LOG.warnf("Dialect %s not recognized.", dialect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,26 +14,19 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.keycloak.models.map.storage.jpa.hibernate.jsonb;
|
package org.keycloak.models.map.storage.jpa.hibernate.contributor;
|
||||||
|
|
||||||
import org.hibernate.boot.MetadataBuilder;
|
import org.hibernate.boot.MetadataBuilder;
|
||||||
import org.hibernate.boot.spi.MetadataBuilderContributor;
|
import org.hibernate.boot.spi.MetadataBuilderContributor;
|
||||||
import org.hibernate.query.sqm.function.FunctionKind;
|
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.JsonbType;
|
||||||
import org.hibernate.query.sqm.function.PatternBasedSqmFunctionDescriptor;
|
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
|
||||||
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link MetadataBuilderContributor} to register JSONB types/functions.
|
* A {@link MetadataBuilderContributor} to register JSONB type.
|
||||||
*/
|
*/
|
||||||
public class JsonbMetadataBuilderContributor implements MetadataBuilderContributor {
|
public class JsonbMetadataBuilderContributor implements MetadataBuilderContributor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contribute(MetadataBuilder metadataBuilder) {
|
public void contribute(MetadataBuilder metadataBuilder) {
|
||||||
metadataBuilder.applyBasicType(JsonbType.INSTANCE);
|
metadataBuilder.applyBasicType(JsonbType.INSTANCE);
|
||||||
metadataBuilder.applySqlFunction("->>", new PatternBasedSqmFunctionDescriptor(
|
|
||||||
new PatternRenderer("?1->>?2"), StandardArgumentsValidators.exactly(2), null, null, "->>",
|
|
||||||
FunctionKind.NORMAL, null
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,32 +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.hibernate.dialect;
|
|
||||||
|
|
||||||
import org.hibernate.dialect.PostgreSQL95Dialect;
|
|
||||||
//import org.hibernate.dialect.function.SQLFunctionTemplate;
|
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
|
||||||
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.JsonbType;
|
|
||||||
|
|
||||||
public class JsonbPostgreSQL95Dialect extends PostgreSQL95Dialect {
|
|
||||||
public JsonbPostgreSQL95Dialect() {
|
|
||||||
super();
|
|
||||||
// registerFunction("->", new SQLFunctionTemplate(JsonbType.INSTANCE, "?1->?2"));
|
|
||||||
// registerFunction("->>", new SQLFunctionTemplate(StandardBasicTypes.STRING, "?1->>?2"));
|
|
||||||
// registerFunction("@>", new SQLFunctionTemplate(StandardBasicTypes.BOOLEAN, "?1@>?2::jsonb"));
|
|
||||||
// registerFunction("kc_hash", new SQLFunctionTemplate(StandardBasicTypes.BINARY, "sha256(?1::bytea)"));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#
|
||||||
|
# Copyright 2023 Red Hat, Inc. and/or its affiliates
|
||||||
|
# and other contributors as indicated by the @author tags.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
org.keycloak.models.map.storage.jpa.hibernate.contributor.JpaMapFunctionContributor
|
|
@ -174,7 +174,6 @@
|
||||||
"user": "${keycloak.map.storage.connectionsJpa.user:}",
|
"user": "${keycloak.map.storage.connectionsJpa.user:}",
|
||||||
"password": "${keycloak.map.storage.connectionsJpa.password:}",
|
"password": "${keycloak.map.storage.connectionsJpa.password:}",
|
||||||
"driver": "org.postgresql.Driver",
|
"driver": "org.postgresql.Driver",
|
||||||
"driverDialect": "org.keycloak.models.map.storage.jpa.hibernate.dialect.JsonbPostgreSQL95Dialect",
|
|
||||||
"showSql": "${keycloak.map.storage.connectionsJpa,showSql:false}"
|
"showSql": "${keycloak.map.storage.connectionsJpa,showSql:false}"
|
||||||
},
|
},
|
||||||
"file": {
|
"file": {
|
||||||
|
|
|
@ -100,7 +100,6 @@ public class JpaMapStorage extends KeycloakModelParameters {
|
||||||
.config("user", POSTGRES_DB_USER)
|
.config("user", POSTGRES_DB_USER)
|
||||||
.config("password", POSTGRES_DB_PASSWORD)
|
.config("password", POSTGRES_DB_PASSWORD)
|
||||||
.config("driver", "org.postgresql.Driver")
|
.config("driver", "org.postgresql.Driver")
|
||||||
.config("driverDialect", "org.keycloak.models.map.storage.jpa.hibernate.dialect.JsonbPostgreSQL95Dialect")
|
|
||||||
.config("lockTimeout", "${" + LOCK_TIMEOUT_SYSTEM_PROPERTY + ":}");
|
.config("lockTimeout", "${" + LOCK_TIMEOUT_SYSTEM_PROPERTY + ":}");
|
||||||
|
|
||||||
cf.spi(AuthenticationSessionSpi.PROVIDER_ID).provider(MapRootAuthenticationSessionProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID)
|
cf.spi(AuthenticationSessionSpi.PROVIDER_ID).provider(MapRootAuthenticationSessionProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
|
|
@ -98,7 +98,6 @@ public class JpaMapStorageCockroachdb extends KeycloakModelParameters {
|
||||||
.config("user", COCKROACHDB_DB_USER)
|
.config("user", COCKROACHDB_DB_USER)
|
||||||
.config("password", COCKROACHDB_DB_PASSWORD)
|
.config("password", COCKROACHDB_DB_PASSWORD)
|
||||||
.config("driver", "org.postgresql.Driver")
|
.config("driver", "org.postgresql.Driver")
|
||||||
.config("driverDialect", "org.keycloak.models.map.storage.jpa.hibernate.dialect.JsonbPostgreSQL95Dialect")
|
|
||||||
.config("lockTimeout", "${" + LOCK_TIMEOUT_SYSTEM_PROPERTY + ":}");
|
.config("lockTimeout", "${" + LOCK_TIMEOUT_SYSTEM_PROPERTY + ":}");
|
||||||
|
|
||||||
cf.spi(AuthenticationSessionSpi.PROVIDER_ID).provider(MapRootAuthenticationSessionProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID)
|
cf.spi(AuthenticationSessionSpi.PROVIDER_ID).provider(MapRootAuthenticationSessionProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
|
Loading…
Reference in a new issue