[KEYCLOAK-19380] - Import not running once schema is inited and requiring full server setup
This commit is contained in:
parent
69a146db7e
commit
6e8cd3262d
5 changed files with 50 additions and 47 deletions
|
@ -19,11 +19,16 @@ package org.keycloak.cli;
|
||||||
|
|
||||||
import static org.keycloak.cli.Picocli.error;
|
import static org.keycloak.cli.Picocli.error;
|
||||||
import static org.keycloak.cli.Picocli.println;
|
import static org.keycloak.cli.Picocli.println;
|
||||||
|
import static org.keycloak.exportimport.ExportImportConfig.ACTION_EXPORT;
|
||||||
|
import static org.keycloak.exportimport.ExportImportConfig.ACTION_IMPORT;
|
||||||
|
import static org.keycloak.exportimport.Strategy.IGNORE_EXISTING;
|
||||||
|
import static org.keycloak.exportimport.Strategy.OVERWRITE_EXISTING;
|
||||||
|
|
||||||
import io.quarkus.bootstrap.runner.RunnerClassLoader;
|
import io.quarkus.bootstrap.runner.RunnerClassLoader;
|
||||||
import org.keycloak.configuration.KeycloakConfigSourceProvider;
|
import org.keycloak.configuration.KeycloakConfigSourceProvider;
|
||||||
|
|
||||||
import io.quarkus.bootstrap.runner.QuarkusEntryPoint;
|
import io.quarkus.bootstrap.runner.QuarkusEntryPoint;
|
||||||
|
|
||||||
import org.keycloak.util.Environment;
|
import org.keycloak.util.Environment;
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
import picocli.CommandLine.Command;
|
import picocli.CommandLine.Command;
|
||||||
|
@ -31,11 +36,7 @@ import picocli.CommandLine.Model.CommandSpec;
|
||||||
import picocli.CommandLine.Option;
|
import picocli.CommandLine.Option;
|
||||||
import picocli.CommandLine.Spec;
|
import picocli.CommandLine.Spec;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
@Command(name = "keycloak",
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Command(name = "keycloak",
|
|
||||||
usageHelpWidth = 150,
|
usageHelpWidth = 150,
|
||||||
header = "Keycloak - Open Source Identity and Access Management\n\nFind more information at: https://www.keycloak.org/%n",
|
header = "Keycloak - Open Source Identity and Access Management\n\nFind more information at: https://www.keycloak.org/%n",
|
||||||
description = "Use this command-line tool to manage your Keycloak cluster%n", footerHeading = "%nUse \"${COMMAND-NAME} <command> --help\" for more information about a command.%nUse \"${COMMAND-NAME} options\" for a list of all command-line options.",
|
description = "Use this command-line tool to manage your Keycloak cluster%n", footerHeading = "%nUse \"${COMMAND-NAME} <command> --help\" for more information about a command.%nUse \"${COMMAND-NAME} options\" for a list of all command-line options.",
|
||||||
|
@ -109,8 +110,7 @@ public class MainCommand {
|
||||||
optionListHeading = "%nOptions%n",
|
optionListHeading = "%nOptions%n",
|
||||||
parameterListHeading = "Available Commands%n")
|
parameterListHeading = "Available Commands%n")
|
||||||
public void startDev(@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) {
|
public void startDev(@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) {
|
||||||
System.setProperty("kc.profile", "dev");
|
setProfile("dev");
|
||||||
System.setProperty("quarkus.profile", "dev");
|
|
||||||
KeycloakMain.start(spec.commandLine());
|
KeycloakMain.start(spec.commandLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,28 +126,13 @@ public class MainCommand {
|
||||||
@Option(names = "--users", arity = "1", description = "Set how users should be exported. Possible values are: skip, realm_file, same_file, different_files.", paramLabel = "<strategy>", defaultValue = "different_files") String users,
|
@Option(names = "--users", arity = "1", description = "Set how users should be exported. Possible values are: skip, realm_file, same_file, different_files.", paramLabel = "<strategy>", defaultValue = "different_files") String users,
|
||||||
@Option(names = "--users-per-file", arity = "1", description = "Set the number of users per file. It’s used only if --users=different_files.", paramLabel = "<number>", defaultValue = "50") Integer usersPerFile,
|
@Option(names = "--users-per-file", arity = "1", description = "Set the number of users per file. It’s used only if --users=different_files.", paramLabel = "<number>", defaultValue = "50") Integer usersPerFile,
|
||||||
@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) {
|
@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) {
|
||||||
System.setProperty("keycloak.migration.action", "export");
|
|
||||||
|
|
||||||
if (toDir != null) {
|
|
||||||
System.setProperty("keycloak.migration.provider", "dir");
|
|
||||||
System.setProperty("keycloak.migration.dir", toDir);
|
|
||||||
} else if (toFile != null) {
|
|
||||||
System.setProperty("keycloak.migration.provider", "singleFile");
|
|
||||||
System.setProperty("keycloak.migration.file", toFile);
|
|
||||||
} else {
|
|
||||||
error(spec.commandLine(), "Must specify either --dir or --file options.");
|
|
||||||
}
|
|
||||||
|
|
||||||
System.setProperty("keycloak.migration.usersExportStrategy", users.toUpperCase());
|
System.setProperty("keycloak.migration.usersExportStrategy", users.toUpperCase());
|
||||||
|
|
||||||
if (usersPerFile != null) {
|
if (usersPerFile != null) {
|
||||||
System.setProperty("keycloak.migration.usersPerFile", usersPerFile.toString());
|
System.setProperty("keycloak.migration.usersPerFile", usersPerFile.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (realm != null) {
|
runImportExport(ACTION_EXPORT, toDir, toFile, realm, verbose);
|
||||||
System.setProperty("keycloak.migration.realmName", realm);
|
|
||||||
}
|
|
||||||
KeycloakMain.start(spec.commandLine());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(name = "import",
|
@Command(name = "import",
|
||||||
|
@ -161,24 +146,9 @@ public class MainCommand {
|
||||||
@Option(names = "--realm", arity = "1", description = "Set the name of the realm to import", paramLabel = "<realm>") String realm,
|
@Option(names = "--realm", arity = "1", description = "Set the name of the realm to import", paramLabel = "<realm>") String realm,
|
||||||
@Option(names = "--override", arity = "1", description = "Set if existing data should be skipped or overridden.", paramLabel = "false", defaultValue = "true") boolean override,
|
@Option(names = "--override", arity = "1", description = "Set if existing data should be skipped or overridden.", paramLabel = "false", defaultValue = "true") boolean override,
|
||||||
@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) {
|
@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) {
|
||||||
System.setProperty("keycloak.migration.action", "import");
|
System.setProperty("keycloak.migration.strategy", override ? OVERWRITE_EXISTING.name() : IGNORE_EXISTING.name());
|
||||||
if (toDir != null) {
|
|
||||||
System.setProperty("keycloak.migration.provider", "dir");
|
|
||||||
System.setProperty("keycloak.migration.dir", toDir);
|
|
||||||
} else if (toFile != null) {
|
|
||||||
System.setProperty("keycloak.migration.provider", "singleFile");
|
|
||||||
System.setProperty("keycloak.migration.file", toFile);
|
|
||||||
} else {
|
|
||||||
error(spec.commandLine(), "Must specify either --dir or --file options.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (realm != null) {
|
runImportExport(ACTION_IMPORT, toDir, toFile, realm, verbose);
|
||||||
System.setProperty("keycloak.migration.realmName", realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
System.setProperty("keycloak.migration.strategy", override ? "OVERWRITE_EXISTING" : "IGNORE_EXISTING");
|
|
||||||
|
|
||||||
KeycloakMain.start(spec.commandLine());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(name = "start",
|
@Command(name = "start",
|
||||||
|
@ -212,4 +182,25 @@ public class MainCommand {
|
||||||
System.setProperty("kc.show.config", filter);
|
System.setProperty("kc.show.config", filter);
|
||||||
KeycloakMain.start(spec.commandLine());
|
KeycloakMain.start(spec.commandLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void runImportExport(String action, String toDir, String toFile, String realm, Boolean verbose) {
|
||||||
|
System.setProperty("keycloak.migration.action", action);
|
||||||
|
|
||||||
|
if (toDir != null) {
|
||||||
|
System.setProperty("keycloak.migration.provider", "dir");
|
||||||
|
System.setProperty("keycloak.migration.dir", toDir);
|
||||||
|
} else if (toFile != null) {
|
||||||
|
System.setProperty("keycloak.migration.provider", "singleFile");
|
||||||
|
System.setProperty("keycloak.migration.file", toFile);
|
||||||
|
} else {
|
||||||
|
error(spec.commandLine(), "Must specify either --dir or --file options.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (realm != null) {
|
||||||
|
System.setProperty("keycloak.migration.realmName", realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
setProfile(Environment.IMPORT_EXPORT_MODE);
|
||||||
|
start(null, verbose);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,8 @@ public final class PropertyMappers {
|
||||||
Boolean enabled = Boolean.valueOf(value);
|
Boolean enabled = Boolean.valueOf(value);
|
||||||
ConfigValue proxy = context.proceed(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + "proxy");
|
ConfigValue proxy = context.proceed(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + "proxy");
|
||||||
|
|
||||||
if (Environment.isDevMode() || (proxy != null && "edge".equalsIgnoreCase(proxy.getValue()))) {
|
if (Environment.isDevMode() || Environment.isImportExportMode()
|
||||||
|
|| (proxy != null && "edge".equalsIgnoreCase(proxy.getValue()))) {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ import org.keycloak.services.ServicesLogger;
|
||||||
import org.keycloak.services.managers.ApplianceBootstrap;
|
import org.keycloak.services.managers.ApplianceBootstrap;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.transaction.JtaTransactionManagerLookup;
|
import org.keycloak.transaction.JtaTransactionManagerLookup;
|
||||||
|
import org.keycloak.util.Environment;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,20 +145,20 @@ public final class QuarkusJpaConnectionProviderFactory implements JpaConnectionP
|
||||||
emf = instance.get();
|
emf = instance.get();
|
||||||
|
|
||||||
KeycloakSession session = factory.create();
|
KeycloakSession session = factory.create();
|
||||||
boolean initSchema;
|
boolean schemaChanged;
|
||||||
|
|
||||||
try (Connection connection = getConnection()) {
|
try (Connection connection = getConnection()) {
|
||||||
createOperationalInfo(connection);
|
createOperationalInfo(connection);
|
||||||
addSpecificNamedQueries(session, connection);
|
addSpecificNamedQueries(session, connection);
|
||||||
initSchema = createOrUpdateSchema(getSchema(), connection, session);
|
schemaChanged = createOrUpdateSchema(getSchema(), connection, session);
|
||||||
} catch (SQLException cause) {
|
} catch (SQLException cause) {
|
||||||
throw new RuntimeException("Failed to update database.", cause);
|
throw new RuntimeException("Failed to update database.", cause);
|
||||||
} finally {
|
} finally {
|
||||||
session.close();
|
session.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initSchema || ExportImportConfig.ACTION_EXPORT.equals(ExportImportConfig.getAction())) {
|
if (schemaChanged || Environment.isImportExportMode()) {
|
||||||
runJobInTransaction(factory, this::initSchemaOrExport);
|
runJobInTransaction(factory, this::initSchema);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +202,7 @@ public final class QuarkusJpaConnectionProviderFactory implements JpaConnectionP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initSchemaOrExport(KeycloakSession session) {
|
private void initSchema(KeycloakSession session) {
|
||||||
ExportImportManager exportImportManager = new ExportImportManager(session);
|
ExportImportManager exportImportManager = new ExportImportManager(session);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -26,6 +26,8 @@ import org.keycloak.configuration.Configuration;
|
||||||
|
|
||||||
public final class Environment {
|
public final class Environment {
|
||||||
|
|
||||||
|
public static final String IMPORT_EXPORT_MODE = "import_export";
|
||||||
|
|
||||||
public static Boolean isRebuild() {
|
public static Boolean isRebuild() {
|
||||||
return Boolean.valueOf(System.getProperty("quarkus.launch.rebuild"));
|
return Boolean.valueOf(System.getProperty("quarkus.launch.rebuild"));
|
||||||
}
|
}
|
||||||
|
@ -90,6 +92,10 @@ public final class Environment {
|
||||||
return ProfileManager.getLaunchMode() == LaunchMode.DEVELOPMENT;
|
return ProfileManager.getLaunchMode() == LaunchMode.DEVELOPMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isImportExportMode() {
|
||||||
|
return IMPORT_EXPORT_MODE.equalsIgnoreCase(getProfile());
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isWindows() {
|
public static boolean isWindows() {
|
||||||
return SystemUtils.IS_OS_WINDOWS;
|
return SystemUtils.IS_OS_WINDOWS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,10 @@ spi.theme.folder.dir=${kc.home.dir:}/themes
|
||||||
%dev.spi.theme.cache-templates=false
|
%dev.spi.theme.cache-templates=false
|
||||||
%dev.spi.theme.static-max-age=-1
|
%dev.spi.theme.static-max-age=-1
|
||||||
|
|
||||||
|
# The default configuration when running in import or export mode
|
||||||
|
%import_export.http.enabled=true
|
||||||
|
%import_export.cluster=local
|
||||||
|
|
||||||
# Logging configuration. INFO is the default level for most of the categories
|
# Logging configuration. INFO is the default level for most of the categories
|
||||||
#quarkus.log.level = DEBUG
|
#quarkus.log.level = DEBUG
|
||||||
quarkus.log.category."org.jboss.resteasy.resteasy_jaxrs.i18n".level=WARN
|
quarkus.log.category."org.jboss.resteasy.resteasy_jaxrs.i18n".level=WARN
|
||||||
|
|
Loading…
Reference in a new issue