Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

public class ClassLoaderOptions {

public static final String QUARKUS_REMOVED_ARTIFACTS_PROPERTY = "quarkus.class-loading.removed-artifacts";

public static final Option<String> IGNORE_ARTIFACTS = new OptionBuilder<>("class-loader-ignore-artifacts", String.class)
.category(OptionCategory.GENERAL)
.hidden()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.keycloak.config.database;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
Expand Down Expand Up @@ -51,6 +52,12 @@ public static boolean isLiquibaseDatabaseSupported(String databaseType, String d
return false;
}

public static Optional<Vendor> getVendorByDbKind(String dbKind) {
return Arrays.stream(Vendor.values())
.filter(v -> v.isOfKind(dbKind))
.findAny();
}

public static Optional<String> getDatabaseKind(String alias) {
Vendor vendor = DATABASES.get(alias);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.keycloak.quarkus.runtime.cli.command;

import static org.keycloak.config.ClassLoaderOptions.QUARKUS_REMOVED_ARTIFACTS_PROPERTY;
import static org.keycloak.quarkus.runtime.Environment.getHomePath;
import static org.keycloak.quarkus.runtime.Environment.isDevMode;
import static org.keycloak.quarkus.runtime.cli.Picocli.println;
Expand All @@ -39,6 +40,7 @@
import picocli.CommandLine.Command;

import java.util.List;
import java.util.Optional;

@Command(name = Build.NAME,
header = "Creates a new and optimized server image.",
Expand Down Expand Up @@ -94,13 +96,10 @@ public void run() {
}

private static void configureBuildClassLoader() {
ConfigValue ignoredArtifacts = Configuration.getCurrentBuiltTimeProperty(
MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + ClassLoaderOptions.IGNORE_ARTIFACTS.getKey());

if (ignoredArtifacts != null && StringUtil.isNotBlank(ignoredArtifacts.getValue())) {
// ignored artifacts must be set prior to starting re-augmentation
System.setProperty("quarkus.class-loading.removed-artifacts", ignoredArtifacts.getValue());
}
// ignored artifacts must be set prior to starting re-augmentation
Optional.ofNullable(Configuration.getCurrentBuiltTimeProperty(QUARKUS_REMOVED_ARTIFACTS_PROPERTY))
.map(ConfigValue::getValue)
.ifPresent(s -> System.setProperty(QUARKUS_REMOVED_ARTIFACTS_PROPERTY, s));
Comment on lines 100 to 102

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to the changes in this PR (#24812), the transformation of values in property mappers is not executed when we want to obtain the option by its name. As that is the default behavior ATM, we can leverage the final property the option is mapped to and ensure the transformation is done.

}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@
package org.keycloak.quarkus.runtime.configuration;

import org.keycloak.common.Profile;
import org.keycloak.config.database.Database;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.keycloak.quarkus.runtime.Environment.getCurrentOrCreateFeatureProfile;

Expand All @@ -29,9 +33,12 @@
public class IgnoredArtifacts {

public static Set<String> getDefaultIgnoredArtifacts() {
return new Builder()
.append(fips())
.build();
return Stream.of(
fips(),
jdbcDrivers()
)
.flatMap(Collection::stream)
.collect(Collectors.toUnmodifiableSet());
}

// FIPS
Expand All @@ -56,23 +63,71 @@ private static Set<String> fips() {
return isFipsEnabled ? FIPS_ENABLED : FIPS_DISABLED;
}

/**
* Builder for artifacts aggregation
*/
private static final class Builder {
private final Set<String> finalIgnoredArtifacts;
// JDBC Drivers
public static final Set<String> JDBC_H2 = Set.of(
"io.quarkus:quarkus-jdbc-h2",
"io.quarkus:quarkus-jdbc-h2-deployment",
"com.h2database:h2"
);

public static final Set<String> JDBC_POSTGRES = Set.of(
"io.quarkus:quarkus-jdbc-postgresql",
"io.quarkus:quarkus-jdbc-postgresql-deployment",
"org.postgresql:postgresql"
);

public static final Set<String> JDBC_MARIADB = Set.of(
"io.quarkus:quarkus-jdbc-mariadb",
"io.quarkus:quarkus-jdbc-mariadb-deployment",
"org.mariadb.jdbc:mariadb-java-client"
);

public static final Set<String> JDBC_MYSQL = Set.of(
"io.quarkus:quarkus-jdbc-mysql",
"io.quarkus:quarkus-jdbc-mysql-deployment",
"mysql:mysql-connector-java"
);

public static final Set<String> JDBC_MSSQL = Set.of(
"io.quarkus:quarkus-jdbc-mssql",
"io.quarkus:quarkus-jdbc-mssql-deployment",
"com.microsoft.sqlserver:mssql-jdbc"
);

public static final Set<String> JDBC_ORACLE = Set.of(
"io.quarkus:quarkus-jdbc-oracle",
"io.quarkus:quarkus-jdbc-oracle-deployment",
"com.oracle.database.jdbc:ojdbc11",
"com.oracle.database.nls:orai18n"
);

public static final Set<String> JDBC_DRIVERS = Stream.of(
JDBC_H2,
JDBC_POSTGRES,
JDBC_MARIADB,
JDBC_MYSQL,
JDBC_MSSQL,
JDBC_ORACLE
)
.flatMap(Collection::stream)
.collect(Collectors.toUnmodifiableSet());

public Builder() {
this.finalIgnoredArtifacts = new HashSet<>();
}
private static Set<String> jdbcDrivers() {
final Database.Vendor vendor = Configuration.getOptionalValue("quarkus.datasource.db-kind")
.flatMap(Database::getVendorByDbKind)
.orElse(Database.Vendor.H2);

public Builder append(Set<String> ignoredArtifacts) {
finalIgnoredArtifacts.addAll(ignoredArtifacts);
return this;
}
final Set<String> jdbcArtifacts = switch (vendor) {
case H2 -> JDBC_H2;
case MYSQL -> JDBC_MYSQL;
case MARIADB -> JDBC_MARIADB;
case POSTGRES -> JDBC_POSTGRES;
case MSSQL -> JDBC_MSSQL;
case ORACLE -> JDBC_ORACLE;
};

public Set<String> build() {
return finalIgnoredArtifacts;
}
final Set<String> allJdbcDrivers = new HashSet<>(JDBC_DRIVERS);
allJdbcDrivers.removeAll(jdbcArtifacts);
return allJdbcDrivers;
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
package org.keycloak.quarkus.runtime.configuration.mappers;

import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;

import io.smallrye.config.ConfigSourceInterceptorContext;
import java.util.Optional;

import org.keycloak.config.ClassLoaderOptions;
import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts;

import java.util.Optional;

import static org.keycloak.config.ClassLoaderOptions.QUARKUS_REMOVED_ARTIFACTS_PROPERTY;
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;

final class ClassLoaderPropertyMappers {

private ClassLoaderPropertyMappers(){}

public static PropertyMapper[] getMappers() {
return new PropertyMapper[] {
fromOption(ClassLoaderOptions.IGNORE_ARTIFACTS)
.to("quarkus.class-loading.removed-artifacts")
.to(QUARKUS_REMOVED_ARTIFACTS_PROPERTY)
.transformer(ClassLoaderPropertyMappers::resolveIgnoredArtifacts)
.build()
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,27 @@

package org.keycloak.quarkus.runtime.configuration.test;

import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.keycloak.common.Profile;
import org.keycloak.common.profile.PropertiesProfileConfigResolver;
import org.keycloak.config.DatabaseOptions;
import org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts;
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;

import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts.JDBC_H2;
import static org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts.JDBC_MARIADB;
import static org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts.JDBC_MSSQL;
import static org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts.JDBC_MYSQL;
import static org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts.JDBC_ORACLE;
import static org.keycloak.quarkus.runtime.configuration.IgnoredArtifacts.JDBC_POSTGRES;

public class IgnoredArtifactsTest {

Expand All @@ -49,4 +61,52 @@ public void fipsEnabled() {
var ignoredArtifacts = IgnoredArtifacts.getDefaultIgnoredArtifacts();
assertThat(ignoredArtifacts.containsAll(IgnoredArtifacts.FIPS_ENABLED), is(true));
}

@Test
public void jdbcH2() {
assertJdbc("h2", JDBC_H2);
}

@Test
public void jdbcMssql() {
assertJdbc("mssql", JDBC_MSSQL);
}

@Test
public void jdbcMariadb() {
assertJdbc("mariadb", JDBC_MARIADB);
}

@Test
public void jdbcMysql() {
assertJdbc("mysql", JDBC_MYSQL);
}

@Test
public void jdbcOracle() {
assertJdbc("oracle", JDBC_ORACLE);
}

@Test
public void jdbcPostgres() {
assertJdbc("postgres", JDBC_POSTGRES);
}

private void assertJdbc(String vendor, Set<String> notIgnored) {
System.setProperty(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + DatabaseOptions.DB.getKey(), vendor);
try {
final var resultArtifacts = IgnoredArtifacts.getDefaultIgnoredArtifacts();
assertThat(String.format("Ignored artifacts does not comply with the specified artifacts for '%s' JDBC driver", vendor),
resultArtifacts,
not(CoreMatchers.hasItems(notIgnored.toArray(new String[0]))));

final var includedArtifacts = new HashSet<>(IgnoredArtifacts.JDBC_DRIVERS);
includedArtifacts.removeAll(notIgnored);
assertThat("Ignored artifacts does not contain items for the other JDBC drivers",
resultArtifacts,
CoreMatchers.hasItems(includedArtifacts.toArray(new String[0])));
} finally {
System.setProperty(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + DatabaseOptions.DB.getKey(), "");
}
}
}