diff --git a/pom.xml b/pom.xml index 6d1cd4ac..009fdcdb 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ bio.overture dms - 0.15.1 + 0.16.0 dms Overture Data Management System diff --git a/src/main/bin/dms-docker b/src/main/bin/dms-docker index ad1ca3ea..93f970c4 100755 --- a/src/main/bin/dms-docker +++ b/src/main/bin/dms-docker @@ -112,6 +112,10 @@ function provisionConfig { mkdir -p $DMS_HOME fi + if [ ! -d $DMS_HOME/assets ];then + mkdir -p $DMS_HOME/assets + fi + if [ ! -f $DMS_CONFIG_FILE ];then genLatestConfig $DMS_CONFIG_FILE fi @@ -171,7 +175,7 @@ function main { docker_opts="$docker_opts -p 5005:5005" set -x fi - docker_opts="$docker_opts -e DOCKER_RUNAS=true" + docker_opts="$docker_opts -e DOCKER_RUNAS=true -e DMS_HOME_HOST_PATH=$DMS_HOME" # create dms-swarm-network if it doesn't exist, this is important for first run # since the dms uses that in its run options found_network=$(docker network ls --filter name=${NETWORK_NAME} --format="{{ .Name }}") diff --git a/src/main/java/bio/overture/dms/cli/command/DmsCommand.java b/src/main/java/bio/overture/dms/cli/command/DmsCommand.java index 265b0bc6..c563ad58 100644 --- a/src/main/java/bio/overture/dms/cli/command/DmsCommand.java +++ b/src/main/java/bio/overture/dms/cli/command/DmsCommand.java @@ -16,7 +16,6 @@ mixinStandardHelpOptions = true, versionProvider = VersionProvider.class, subcommands = { - SummaryCommand.class, ConfigCommand.class, ClusterCommand.class, BashCompletionCommand.class diff --git a/src/main/java/bio/overture/dms/cli/command/cluster/ClusterApplyCommand.java b/src/main/java/bio/overture/dms/cli/command/cluster/ClusterApplyCommand.java deleted file mode 100644 index 238ea7a3..00000000 --- a/src/main/java/bio/overture/dms/cli/command/cluster/ClusterApplyCommand.java +++ /dev/null @@ -1,49 +0,0 @@ -package bio.overture.dms.cli.command.cluster; - -import bio.overture.dms.cli.DmsConfigStore; -import bio.overture.dms.cli.terminal.Terminal; -import bio.overture.dms.cli.util.VersionProvider; -import bio.overture.dms.compose.deployment.DmsComposeManager; -import java.util.concurrent.Callable; -import lombok.NonNull; -import lombok.val; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import picocli.CommandLine.Command; - -@Component -@Command( - name = "apply", - mixinStandardHelpOptions = true, - versionProvider = VersionProvider.class, - description = "Deploy a configuration to the cluster") -public class ClusterApplyCommand implements Callable { - - private final Terminal t; - private final DmsComposeManager dmsComposeManager; - private final DmsConfigStore dmsConfigStore; - - @Autowired - public ClusterApplyCommand( - @NonNull Terminal terminal, - @NonNull DmsComposeManager dmsComposeManager, - @NonNull DmsConfigStore dmsConfigStore) { - this.dmsComposeManager = dmsComposeManager; - this.t = terminal; - this.dmsConfigStore = dmsConfigStore; - } - - @Override - public Integer call() throws Exception { - val result = dmsConfigStore.findStoredConfig(); - if (result.isPresent()) { - t.printStatusLn("Starting deployment..."); - dmsComposeManager.deploy(result.get()); - t.printStatusLn("Deployment completed successfully"); - return 0; - } - - t.printErrorLn("Could not find DMS configuration: %s", dmsConfigStore.getDmsConfigFilePath()); - return 1; - } -} diff --git a/src/main/java/bio/overture/dms/cli/command/cluster/ClusterCommand.java b/src/main/java/bio/overture/dms/cli/command/cluster/ClusterCommand.java index fb895b8c..3875422d 100644 --- a/src/main/java/bio/overture/dms/cli/command/cluster/ClusterCommand.java +++ b/src/main/java/bio/overture/dms/cli/command/cluster/ClusterCommand.java @@ -9,12 +9,8 @@ mixinStandardHelpOptions = true, versionProvider = VersionProvider.class, subcommands = { - ClusterApplyCommand.class, - ClusterDestroyCommand.class, - ClusterGetCommand.class, - ClusterRestartCommand.class, ClusterStartCommand.class, ClusterStopCommand.class, - ClusterStatusCommand.class + ClusterDestroyCommand.class, }) public class ClusterCommand {} diff --git a/src/main/java/bio/overture/dms/cli/command/cluster/ClusterDestroyCommand.java b/src/main/java/bio/overture/dms/cli/command/cluster/ClusterDestroyCommand.java index 064972b0..2ce2dea7 100644 --- a/src/main/java/bio/overture/dms/cli/command/cluster/ClusterDestroyCommand.java +++ b/src/main/java/bio/overture/dms/cli/command/cluster/ClusterDestroyCommand.java @@ -24,7 +24,7 @@ name = "destroy", mixinStandardHelpOptions = true, versionProvider = VersionProvider.class, - description = "Destroy the cluster") + description = "Destroy the cluster and ALL the data") public class ClusterDestroyCommand implements Callable { /** Dependencies */ @@ -34,14 +34,6 @@ public class ClusterDestroyCommand implements Callable { private final DmsComposeManager dmsComposeManager; private final DmsConfigStore dmsConfigStore; - /** CLI Options */ - @CommandLine.Option( - names = {"-v", "--volumes"}, - required = false, - showDefaultValue = ALWAYS, - description = "Additionally destroy volumes") - private boolean destroyVolumes = false; - @CommandLine.Option( names = {"-f", "--force"}, required = false, @@ -67,9 +59,13 @@ public Integer call() throws Exception { val result = dmsConfigStore.findStoredConfig(); if (result.isPresent()) { t.printStatusLn( - "Starting cluster destruction: force=%s destroyVolumes=%s", force, destroyVolumes); - val resolvedDestroyVolumes = resolveDestroyVolumes(); - dmsComposeManager.destroy(result.get(), resolvedDestroyVolumes); + "Starting cluster destruction: force=%s", force); + val isConfirmed = confirmVolumesDeletion(); + if (!isConfirmed) { + t.printStatusLn("Cluster destruction canceled."); + return 2; + } + dmsComposeManager.destroy(result.get(), true); t.printStatusLn("Finished cluster destruction"); return 0; } @@ -78,11 +74,11 @@ public Integer call() throws Exception { return 1; } - private boolean resolveDestroyVolumes() { - boolean askQuestion = !force && destroyVolumes; - boolean resolvedDestroyVolumes = force && destroyVolumes; + private boolean confirmVolumesDeletion() { + boolean askQuestion = !force; + boolean confirmedVolumeDestruction = force; if (askQuestion) { - resolvedDestroyVolumes = + confirmedVolumeDestruction = questionFactory .newSingleQuestion( WARNING, @@ -91,13 +87,10 @@ private boolean resolveDestroyVolumes() { true, false) .getAnswer(); - if (!resolvedDestroyVolumes) { - t.printStatus("Volumes will NOT be destroyed!"); - } } - if (resolvedDestroyVolumes) { + if (confirmedVolumeDestruction) { t.printStatus("Forcefully destroying all volumes!"); } - return resolvedDestroyVolumes; + return confirmedVolumeDestruction; } } diff --git a/src/main/java/bio/overture/dms/cli/command/cluster/ClusterStartCommand.java b/src/main/java/bio/overture/dms/cli/command/cluster/ClusterStartCommand.java index 3674cedc..cf9780b8 100644 --- a/src/main/java/bio/overture/dms/cli/command/cluster/ClusterStartCommand.java +++ b/src/main/java/bio/overture/dms/cli/command/cluster/ClusterStartCommand.java @@ -1,25 +1,49 @@ package bio.overture.dms.cli.command.cluster; +import bio.overture.dms.cli.DmsConfigStore; +import bio.overture.dms.cli.terminal.Terminal; import bio.overture.dms.cli.util.VersionProvider; +import bio.overture.dms.compose.deployment.DmsComposeManager; import java.util.concurrent.Callable; +import lombok.NonNull; +import lombok.val; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import picocli.CommandLine.Command; -import picocli.CommandLine.Option; +@Component @Command( name = "start", mixinStandardHelpOptions = true, versionProvider = VersionProvider.class, - description = "Start an existing cluster") + description = "Deploy a configuration to the cluster") public class ClusterStartCommand implements Callable { - @Option( - names = {"--skip-ego-init"}, - required = false, - description = "Skip Ego initialization") - private boolean skipEgoInit = false; + private final Terminal t; + private final DmsComposeManager dmsComposeManager; + private final DmsConfigStore dmsConfigStore; + + @Autowired + public ClusterStartCommand( + @NonNull Terminal terminal, + @NonNull DmsComposeManager dmsComposeManager, + @NonNull DmsConfigStore dmsConfigStore) { + this.dmsComposeManager = dmsComposeManager; + this.t = terminal; + this.dmsConfigStore = dmsConfigStore; + } @Override public Integer call() throws Exception { - return 0; + val result = dmsConfigStore.findStoredConfig(); + if (result.isPresent()) { + t.printStatusLn("Starting deployment..."); + dmsComposeManager.deploy(result.get()); + t.printStatusLn("Deployment completed successfully"); + return 0; + } + + t.printErrorLn("Could not find DMS configuration: %s", dmsConfigStore.getDmsConfigFilePath()); + return 1; } } diff --git a/src/main/java/bio/overture/dms/cli/command/cluster/ClusterStopCommand.java b/src/main/java/bio/overture/dms/cli/command/cluster/ClusterStopCommand.java index 4539eaa1..a35da372 100644 --- a/src/main/java/bio/overture/dms/cli/command/cluster/ClusterStopCommand.java +++ b/src/main/java/bio/overture/dms/cli/command/cluster/ClusterStopCommand.java @@ -1,18 +1,54 @@ package bio.overture.dms.cli.command.cluster; +import bio.overture.dms.cli.DmsConfigStore; +import bio.overture.dms.cli.terminal.Terminal; import bio.overture.dms.cli.util.VersionProvider; import java.util.concurrent.Callable; + +import bio.overture.dms.compose.deployment.DmsComposeManager; +import lombok.Builder; +import lombok.NonNull; +import lombok.val; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import picocli.CommandLine.Command; +@Component @Command( name = "stop", mixinStandardHelpOptions = true, versionProvider = VersionProvider.class, - description = "Stop a running cluster") + description = "Stop a running cluster, without deleting data volumes") public class ClusterStopCommand implements Callable { + /** Dependencies */ + private final Terminal t; + + private final DmsComposeManager dmsComposeManager; + private final DmsConfigStore dmsConfigStore; + + @Builder + @Autowired + public ClusterStopCommand( + @NonNull Terminal terminal, + @NonNull DmsComposeManager dmsComposeManager, + @NonNull DmsConfigStore dmsConfigStore) { + this.t = terminal; + this.dmsComposeManager = dmsComposeManager; + this.dmsConfigStore = dmsConfigStore; + } + @Override public Integer call() throws Exception { - return 0; + val result = dmsConfigStore.findStoredConfig(); + if (result.isPresent()) { + t.printStatusLn( + "Stopping cluster.."); + dmsComposeManager.destroy(result.get(), false); + t.printStatusLn("Finished stopping cluster"); + return 0; + } + t.printErrorLn("Could not find DMS configuration: %s", dmsConfigStore.getDmsConfigFilePath()); + return 1; } } diff --git a/src/main/java/bio/overture/dms/cli/command/config/ConfigBuildCommand.java b/src/main/java/bio/overture/dms/cli/command/config/ConfigBuildCommand.java index e54ec72b..1e607b53 100644 --- a/src/main/java/bio/overture/dms/cli/command/config/ConfigBuildCommand.java +++ b/src/main/java/bio/overture/dms/cli/command/config/ConfigBuildCommand.java @@ -52,7 +52,7 @@ public ConfigBuildCommand( public Integer call() throws Exception { t.printStatusLn("Starting interactive configuration"); // TODO: Fix this so that the storedDmsConfig is input into the buildDmsConfig method - dmsConfigStore.apply(storedDmsConfig -> dmsQuestionnaire.buildDmsConfig()); + dmsConfigStore.apply(dmsQuestionnaire::buildDmsConfig); t.printStatusLn("Wrote config file to %s", dmsConfigStore.getDmsConfigFilePath()); return 0; } diff --git a/src/main/java/bio/overture/dms/cli/command/config/ConfigCommand.java b/src/main/java/bio/overture/dms/cli/command/config/ConfigCommand.java index 442f4286..c8bad9b9 100644 --- a/src/main/java/bio/overture/dms/cli/command/config/ConfigCommand.java +++ b/src/main/java/bio/overture/dms/cli/command/config/ConfigCommand.java @@ -9,13 +9,7 @@ mixinStandardHelpOptions = true, versionProvider = VersionProvider.class, subcommands = { - ConfigCheckCommand.class, ConfigBuildCommand.class, ConfigGetCommand.class, - ConfigSetCommand.class, - ConfigDeleteCommand.class, - ConfigStatusCommand.class, - ConfigUpgradeCommand.class, - ConfigVersionCommand.class }) public class ConfigCommand {} diff --git a/src/main/java/bio/overture/dms/cli/question/QuestionFactory.java b/src/main/java/bio/overture/dms/cli/question/QuestionFactory.java index 0b5d5857..99fb9115 100644 --- a/src/main/java/bio/overture/dms/cli/question/QuestionFactory.java +++ b/src/main/java/bio/overture/dms/cli/question/QuestionFactory.java @@ -13,6 +13,8 @@ import static java.util.Objects.isNull; import bio.overture.dms.cli.model.enums.QuestionProfiles; +import bio.overture.dms.cli.question.validation.EmailValidator; +import bio.overture.dms.cli.question.validation.FileValidator; import bio.overture.dms.cli.question.validation.QuestionValidator; import bio.overture.dms.cli.question.validation.UrlQuestionValidator; import bio.overture.dms.cli.terminal.UrlInputReader; @@ -43,6 +45,10 @@ public class QuestionFactory { private static final UrlQuestionValidator URL_QUESTION_VALIDATOR = new UrlQuestionValidator(); + private static final EmailValidator EMAIL_VALIDATOR = new EmailValidator(); + + private static final FileValidator FILE_VALIDATOR = new FileValidator(); + /** Dependencies */ private final TextIO textIO; @@ -85,6 +91,18 @@ public SingleQuestion newUrlSingleQuestion( URL.class, question, optional, defaultValue, URL_QUESTION_VALIDATOR); } + public SingleQuestion newEmailQuestion( + @NonNull String question, boolean optional, String defaultVal) { + return newDefaultSingleQuestion( + String.class, question, optional, defaultVal, EMAIL_VALIDATOR); + } + + public SingleQuestion newFileQuestion( + @NonNull String question, boolean optional) { + return newDefaultSingleQuestion( + String.class, question, optional, null, FILE_VALIDATOR); + } + public SingleQuestion newPasswordQuestion(@NonNull String question) { return new SingleQuestion<>(question, buildPasswordInputReader()); } diff --git a/src/main/java/bio/overture/dms/cli/question/validation/EmailValidator.java b/src/main/java/bio/overture/dms/cli/question/validation/EmailValidator.java new file mode 100644 index 00000000..09cbccf8 --- /dev/null +++ b/src/main/java/bio/overture/dms/cli/question/validation/EmailValidator.java @@ -0,0 +1,18 @@ +package bio.overture.dms.cli.question.validation; + +import java.util.List; +import java.util.regex.Pattern; + +public class EmailValidator implements QuestionValidator { + + public static final Pattern VALID_EMAIL_ADDRESS_REGEX = + Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE); + + @Override + public List getErrorMessages(String val) { + if (VALID_EMAIL_ADDRESS_REGEX.matcher(val).matches()) { + return null; + } + return List.of("The provided value is not a valid email"); + } +} diff --git a/src/main/java/bio/overture/dms/cli/question/validation/FileValidator.java b/src/main/java/bio/overture/dms/cli/question/validation/FileValidator.java new file mode 100644 index 00000000..10a651d2 --- /dev/null +++ b/src/main/java/bio/overture/dms/cli/question/validation/FileValidator.java @@ -0,0 +1,20 @@ +package bio.overture.dms.cli.question.validation; + +import lombok.val; + +import java.io.File; +import java.util.List; + +public class FileValidator implements QuestionValidator { + + @Override + public List getErrorMessages(String path) { + try { + val fileExists = new File(path).exists(); + if (fileExists) return null; + return List.of("File not found"); + } catch (Exception e) { + return List.of("Couldn't check the provided file"); + } + } +} diff --git a/src/main/java/bio/overture/dms/cli/question/validation/UrlQuestionValidator.java b/src/main/java/bio/overture/dms/cli/question/validation/UrlQuestionValidator.java index 12efb967..9b5b8dbb 100644 --- a/src/main/java/bio/overture/dms/cli/question/validation/UrlQuestionValidator.java +++ b/src/main/java/bio/overture/dms/cli/question/validation/UrlQuestionValidator.java @@ -24,6 +24,6 @@ public List getErrorMessages(URL url) { errors.add( format("The url protocol '%s' is not one of ['http', 'https']", url.getProtocol())); } - return null; + return errors.size() == 0 ? null : errors; } } diff --git a/src/main/java/bio/overture/dms/cli/questionnaire/ArrangerQuestionnaire.java b/src/main/java/bio/overture/dms/cli/questionnaire/ArrangerQuestionnaire.java index 4615ce6e..88dd7228 100644 --- a/src/main/java/bio/overture/dms/cli/questionnaire/ArrangerQuestionnaire.java +++ b/src/main/java/bio/overture/dms/cli/questionnaire/ArrangerQuestionnaire.java @@ -1,18 +1,12 @@ package bio.overture.dms.cli.questionnaire; -import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.createLocalhostUrl; import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.resolveServiceConnectionInfo; import static bio.overture.dms.compose.model.ComposeServiceResources.*; -import static bio.overture.dms.core.model.enums.ClusterRunModes.LOCAL; -import static bio.overture.dms.core.model.enums.ClusterRunModes.SERVER; -import static java.lang.String.format; import bio.overture.dms.cli.question.QuestionFactory; -import bio.overture.dms.compose.deployment.DmsComposeManager; import bio.overture.dms.core.model.dmsconfig.ArrangerConfig; import bio.overture.dms.core.model.dmsconfig.GatewayConfig; import bio.overture.dms.core.model.enums.ClusterRunModes; -import java.net.URL; import lombok.NonNull; import lombok.val; import org.springframework.beans.factory.annotation.Autowired; @@ -30,19 +24,28 @@ public ArrangerQuestionnaire(@NonNull QuestionFactory questionFactory) { public ArrangerConfig buildConfig(ClusterRunModes clusterRunMode, GatewayConfig gatewayConfig) { - val info = resolveServiceConnectionInfo(clusterRunMode, - gatewayConfig, - questionFactory, - ARRANGER_SERVER.toString(), - 5050); - - val uiHostInfo = resolveServiceConnectionInfo(clusterRunMode, - gatewayConfig, questionFactory, - ARRANGER_UI.toString(), - ArrangerConfig.ArrangerUIConfig.DEFAULT_PORT); + val info = + resolveServiceConnectionInfo( + clusterRunMode, gatewayConfig, questionFactory, ARRANGER_SERVER.toString(), 5050); + + val uiHostInfo = + resolveServiceConnectionInfo( + clusterRunMode, + gatewayConfig, + questionFactory, + ARRANGER_UI.toString(), + ArrangerConfig.ArrangerUIConfig.DEFAULT_PORT); return ArrangerConfig.builder() - .api(ArrangerConfig.ArrangerApiConfig.builder().hostPort(info.port).url(info.serverUrl).build()) - .ui(ArrangerConfig.ArrangerUIConfig.builder().url(uiHostInfo.serverUrl).hostPort(uiHostInfo.port).build()) + .api( + ArrangerConfig.ArrangerApiConfig.builder() + .hostPort(info.port) + .url(info.serverUrl) + .build()) + .ui( + ArrangerConfig.ArrangerUIConfig.builder() + .url(uiHostInfo.serverUrl) + .hostPort(uiHostInfo.port) + .build()) .build(); } } diff --git a/src/main/java/bio/overture/dms/cli/questionnaire/DmsQuestionnaire.java b/src/main/java/bio/overture/dms/cli/questionnaire/DmsQuestionnaire.java index 3c099b64..86a95392 100644 --- a/src/main/java/bio/overture/dms/cli/questionnaire/DmsQuestionnaire.java +++ b/src/main/java/bio/overture/dms/cli/questionnaire/DmsQuestionnaire.java @@ -9,12 +9,8 @@ import bio.overture.dms.core.model.dmsconfig.GatewayConfig; import bio.overture.dms.core.model.dmsconfig.HealthCheckConfig; import bio.overture.dms.core.model.enums.ClusterRunModes; - -import java.io.Serializable; import java.net.URI; import java.net.URL; -import java.util.Map; - import lombok.NonNull; import lombok.SneakyThrows; import lombok.val; @@ -65,11 +61,13 @@ public DmsQuestionnaire( } @SneakyThrows - public DmsConfig buildDmsConfig() { + public DmsConfig buildDmsConfig(DmsConfig oldConfig) { val clusterRunMode = questionFactory .newOneHotQuestion( - ClusterRunModes.class, "Select the cluster mode to configure: ", false, null) + ClusterRunModes.class, "Select the cluster mode to configure: ", + false, + null) .getAnswer(); GatewayConfig gatewayConfig; @@ -79,42 +77,39 @@ public DmsConfig buildDmsConfig() { if (clusterRunMode == SERVER) { dmsGatewayUrl = questionFactory - .newUrlSingleQuestion("What is the base DMS Gateway URL (example: https://dms.cancercollaboratory.org)?", + .newUrlSingleQuestion( + "What is the base DMS Gateway URL (example: https://dms.cancercollaboratory.org)?", false, - null - ).getAnswer(); + null) + .getAnswer(); if (dmsGatewayUrl.getPort() <= 0) { - dmsGatewayUrl = new URI("https", null, dmsGatewayUrl.getHost(), - 443, null, null, null).toURL(); + dmsGatewayUrl = + new URI("https", null, dmsGatewayUrl.getHost(), 443, null, null, null).toURL(); } - sslPath = + sslPath = questionFactory - .newDefaultSingleQuestion(String.class,"What is the absolute path for the SSL certificate ?", - false, - "/etc/letsencrypt/" - ).getAnswer(); + .newDefaultSingleQuestion( + String.class, + "What is the absolute path for the SSL certificate ?", + true, + "/etc/letsencrypt/") + .getAnswer(); gatewayPort = 443; } else { gatewayPort = questionFactory .newDefaultSingleQuestion( - Integer.class, - "What port will the gateway be exposed on?", - true, - 80 - ).getAnswer(); - dmsGatewayUrl = new URI("http", null, "localhost", - gatewayPort, null, null, null).toURL(); + Integer.class, "What port will the gateway be exposed on?", true, 80) + .getAnswer(); + + dmsGatewayUrl = new URI("http", null, "localhost", gatewayPort, null, null, null).toURL(); } - gatewayConfig = GatewayConfig.builder() - .hostPort(gatewayPort) - .url(dmsGatewayUrl) - .sslDir(sslPath) - .build(); + gatewayConfig = + GatewayConfig.builder().hostPort(gatewayPort).url(dmsGatewayUrl).sslDir(sslPath).build(); printHeader("EGO"); val egoConfig = egoQuestionnaire.buildEgoConfig(clusterRunMode, gatewayConfig); @@ -127,18 +122,17 @@ public DmsConfig buildDmsConfig() { printHeader("MAESTRO"); val maestroConfig = maestroQuestionnaire.buildConfig(clusterRunMode, gatewayConfig); // there are no questions for arranger - //printHeader("ARRANGER"); + // printHeader("ARRANGER"); val arrangerConfig = arrangerQuestionnaire.buildConfig(clusterRunMode, gatewayConfig); printHeader("DMS UI"); // we pass maestro's config to read the alias name to be used // in case the user changed the default. - val dmsUIConfig = dmsUIQuestionnaire.buildConfig(maestroConfig, clusterRunMode, gatewayConfig); + val dmsUIConfig = dmsUIQuestionnaire.buildConfig(maestroConfig, clusterRunMode, gatewayConfig, egoConfig); return DmsConfig.builder() .gateway(gatewayConfig) .clusterRunMode(clusterRunMode) - .healthCheck(HealthCheckConfig.builder() - .build()) + .healthCheck(HealthCheckConfig.builder().build()) .version(buildProperties.getVersion()) .network(composeProperties.getNetwork()) .ego(egoConfig) @@ -156,6 +150,13 @@ static URL createLocalhostUrl(int port) { return new URL("http://localhost:" + port); } + public static T resolveDefault(T existingValue, T defaultVal) { + if (existingValue == null) { + return defaultVal; + } + return existingValue; + } + private void printHeader(@NonNull String title) { val line = "==============="; terminal.println(); @@ -168,11 +169,12 @@ static class ServiceUrlInfo { } @SneakyThrows - static ServiceUrlInfo resolveServiceConnectionInfo(ClusterRunModes clusterRunMode, - GatewayConfig gatewayConfig, - QuestionFactory questionFactory, - String serviceName, - int defaultApiPort) { + static ServiceUrlInfo resolveServiceConnectionInfo( + ClusterRunModes clusterRunMode, + GatewayConfig gatewayConfig, + QuestionFactory questionFactory, + String serviceName, + int defaultApiPort) { URL serverUrl; int apiPort = defaultApiPort; if (gatewayConfig.isPathBased()) { @@ -184,7 +186,10 @@ static ServiceUrlInfo resolveServiceConnectionInfo(ClusterRunModes clusterRunMod apiPort = questionFactory .newDefaultSingleQuestion( - Integer.class, "What port would you like to expose " + serviceName + " on?", true, defaultApiPort) + Integer.class, + "What port would you like to expose " + serviceName + " on?", + true, + defaultApiPort) .getAnswer(); serverUrl = createLocalhostUrl(apiPort); } diff --git a/src/main/java/bio/overture/dms/cli/questionnaire/DmsUIQuestionnaire.java b/src/main/java/bio/overture/dms/cli/questionnaire/DmsUIQuestionnaire.java index cadd99b6..b10828a5 100644 --- a/src/main/java/bio/overture/dms/cli/questionnaire/DmsUIQuestionnaire.java +++ b/src/main/java/bio/overture/dms/cli/questionnaire/DmsUIQuestionnaire.java @@ -1,31 +1,88 @@ package bio.overture.dms.cli.questionnaire; +import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.resolveServiceConnectionInfo; +import static bio.overture.dms.compose.model.ComposeServiceResources.DMS_UI; + import bio.overture.dms.cli.question.QuestionFactory; -import bio.overture.dms.core.model.dmsconfig.DmsConfig; import bio.overture.dms.core.model.dmsconfig.DmsUIConfig; +import bio.overture.dms.core.model.dmsconfig.EgoConfig; import bio.overture.dms.core.model.dmsconfig.GatewayConfig; import bio.overture.dms.core.model.dmsconfig.MaestroConfig; import bio.overture.dms.core.model.enums.ClusterRunModes; +import bio.overture.dms.swarm.properties.DockerProperties; import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; import lombok.val; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.resolveServiceConnectionInfo; -import static bio.overture.dms.compose.model.ComposeServiceResources.DMS_UI; +import java.io.File; +import java.nio.file.Paths; +import java.util.List; +import java.util.stream.Collectors; @Component +@Slf4j public class DmsUIQuestionnaire { private final QuestionFactory questionFactory; + private DockerProperties dockerProperties; @Autowired - public DmsUIQuestionnaire(@NonNull QuestionFactory questionFactory) { + public DmsUIQuestionnaire(@NonNull QuestionFactory questionFactory, DockerProperties dockerProperties) { this.questionFactory = questionFactory; + this.dockerProperties = dockerProperties; } - public DmsUIConfig buildConfig(MaestroConfig maestroConfig, ClusterRunModes runModes, GatewayConfig gatewayConfig) { - val info = resolveServiceConnectionInfo(runModes, gatewayConfig, questionFactory, DMS_UI.toString(), DmsUIConfig.DEFAULT_PORT); + public DmsUIConfig buildConfig( + MaestroConfig maestroConfig, ClusterRunModes runModes, GatewayConfig gatewayConfig, EgoConfig egoConfig) { + + String email = + questionFactory + .newEmailQuestion( + "What will the contact email be (will appear on the UI) ?", + false, + null + ).getAnswer(); + + String labName = + questionFactory + .newDefaultSingleQuestion( + String.class, + "Would you like to customise the portal title ?", + true, + "Data Management System") + .getAnswer(); + + String logoFileName = null; + String assetsDirPath = null; + + try { + val userDir = Paths.get(System.getProperty("user.home")); + val dmsDir = userDir.resolve(".dms"); + // we need to figure out the assets directory host path (if running in docker) + if (this.dockerProperties.getRunAs()) { + assetsDirPath = Paths.get(dockerProperties.getDmsHomeHostPath()).resolve("assets").toAbsolutePath().toString(); + } else { + assetsDirPath = dmsDir.resolve("assets").toAbsolutePath().toString(); + } + + // now we need to check the file we + val dmsAssetsPath = dmsDir.resolve("assets").toAbsolutePath().toString(); + val exts = List.of("png", "svg", "jpg"); + val result = exts.stream().filter((ext) -> + new File(Paths.get(dmsAssetsPath, "dms_logo.png").toString()).exists() + ).findFirst(); + if (result.isPresent()) { + logoFileName = "dms_logo." + result.get(); + } + } catch (Exception e) { + log.error("failed to resolve the assets directory"); + } + + val info = + resolveServiceConnectionInfo( + runModes, gatewayConfig, questionFactory, DMS_UI.toString(), DmsUIConfig.DEFAULT_PORT); String projectId = questionFactory .newDefaultSingleQuestion( @@ -61,6 +118,17 @@ public DmsUIConfig buildConfig(MaestroConfig maestroConfig, ClusterRunModes runM .indexAlias(elasticSearchIndexOrAlias) .build()) .url(info.serverUrl) + .labName(labName) + .logoFileName(logoFileName) + .assetsDir(assetsDirPath) + .ssoProviders(egoConfig.getApi() + .getSso() + .getConfiguredProviders() + .stream() + .map(p -> p.name().toUpperCase()) + .collect(Collectors.joining(",")) + ) + .adminEmail(email) .hostPort(info.port) .build(); } diff --git a/src/main/java/bio/overture/dms/cli/questionnaire/EgoQuestionnaire.java b/src/main/java/bio/overture/dms/cli/questionnaire/EgoQuestionnaire.java index 3ca2ab09..f8ba9ae3 100644 --- a/src/main/java/bio/overture/dms/cli/questionnaire/EgoQuestionnaire.java +++ b/src/main/java/bio/overture/dms/cli/questionnaire/EgoQuestionnaire.java @@ -1,11 +1,8 @@ package bio.overture.dms.cli.questionnaire; -import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.createLocalhostUrl; import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.resolveServiceConnectionInfo; import static bio.overture.dms.compose.model.ComposeServiceResources.EGO_API; import static bio.overture.dms.compose.model.ComposeServiceResources.EGO_UI; -import static bio.overture.dms.core.model.enums.ClusterRunModes.LOCAL; -import static bio.overture.dms.core.model.enums.ClusterRunModes.SERVER; import static bio.overture.dms.core.util.RandomGenerator.createRandomGenerator; import static java.lang.String.format; import static java.util.Objects.isNull; @@ -13,7 +10,6 @@ import bio.overture.dms.cli.question.QuestionFactory; import bio.overture.dms.core.model.dmsconfig.AppCredential; -import bio.overture.dms.core.model.dmsconfig.DmsConfig; import bio.overture.dms.core.model.dmsconfig.EgoConfig; import bio.overture.dms.core.model.dmsconfig.EgoConfig.EgoApiConfig; import bio.overture.dms.core.model.dmsconfig.EgoConfig.EgoDbConfig; @@ -25,7 +21,6 @@ import bio.overture.dms.core.model.dmsconfig.GatewayConfig; import bio.overture.dms.core.model.enums.ClusterRunModes; import bio.overture.dms.core.util.RandomGenerator; - import java.net.URL; import java.util.List; import java.util.function.BiConsumer; @@ -67,7 +62,9 @@ public EgoConfig buildEgoConfig(ClusterRunModes runModes, GatewayConfig gatewayC @SneakyThrows private EgoUiConfig processEgoUiConfig(ClusterRunModes runModes, GatewayConfig gatewayConfig) { val egoUiConfig = new EgoUiConfig(); - val info = resolveServiceConnectionInfo(runModes, gatewayConfig, questionFactory, EGO_UI.toString(), 9002); + val info = + resolveServiceConnectionInfo( + runModes, gatewayConfig, questionFactory, EGO_UI.toString(), 9002); egoUiConfig.setHostPort(info.port); egoUiConfig.setUrl(info.serverUrl); egoUiConfig.setUiAppCredential(processUiAppCreds(info.serverUrl)); @@ -75,7 +72,8 @@ private EgoUiConfig processEgoUiConfig(ClusterRunModes runModes, GatewayConfig g } @SneakyThrows - private EgoApiConfig processEgoApiConfig(ClusterRunModes clusterRunMode, GatewayConfig gatewayConfig) { + private EgoApiConfig processEgoApiConfig( + ClusterRunModes clusterRunMode, GatewayConfig gatewayConfig) { val apiBuilder = EgoApiConfig.builder(); val apiKeyDurationDays = questionFactory @@ -109,7 +107,9 @@ private EgoApiConfig processEgoApiConfig(ClusterRunModes clusterRunMode, Gateway .getAnswer(); apiBuilder.refreshTokenDurationMS(HOURS.toMillis(refreshTokenDurationHours)); - val info = resolveServiceConnectionInfo(clusterRunMode, gatewayConfig, questionFactory, EGO_API.toString(), 9000); + val info = + resolveServiceConnectionInfo( + clusterRunMode, gatewayConfig, questionFactory, EGO_API.toString(), 9000); apiBuilder.hostPort(info.port); apiBuilder.url(info.serverUrl); @@ -141,18 +141,9 @@ private EgoApiConfig processEgoApiConfig(ClusterRunModes clusterRunMode, Gateway private EgoDbConfig processEgoDbConfig() { val dbBuilder = EgoDbConfig.builder(); - - val isSetDBPassword = - questionFactory - .newDefaultSingleQuestion( - Boolean.class, "Would you like to set the database password for EGO?", false, null) - .getAnswer(); - - if (isSetDBPassword) { - val dbPassword = - questionFactory.newPasswordQuestion("What should the EGO db password be?").getAnswer(); + val dbPassword = + questionFactory.newPasswordQuestion("What should the EGO db password be ?").getAnswer(); dbBuilder.databasePassword(dbPassword); - } return dbBuilder.build(); } @@ -274,7 +265,6 @@ public enum SSOProviders { GOOGLE(SSOConfig::setGoogle), LINKEDIN(SSOConfig::setLinkedin), GITHUB(SSOConfig::setGithub), - FACEBOOK(SSOConfig::setFacebook), ORCID(SSOConfig::setOrcid); private final BiConsumer setter; diff --git a/src/main/java/bio/overture/dms/cli/questionnaire/ElasticsearchQuestionnaire.java b/src/main/java/bio/overture/dms/cli/questionnaire/ElasticsearchQuestionnaire.java index 092e04db..7664896d 100644 --- a/src/main/java/bio/overture/dms/cli/questionnaire/ElasticsearchQuestionnaire.java +++ b/src/main/java/bio/overture/dms/cli/questionnaire/ElasticsearchQuestionnaire.java @@ -1,19 +1,17 @@ package bio.overture.dms.cli.questionnaire; +import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.resolveServiceConnectionInfo; +import static bio.overture.dms.compose.model.ComposeServiceResources.ELASTICSEARCH; + import bio.overture.dms.cli.question.QuestionFactory; import bio.overture.dms.core.model.dmsconfig.ElasticsearchConfig; import bio.overture.dms.core.model.dmsconfig.GatewayConfig; -import bio.overture.dms.core.model.dmsconfig.MaestroConfig; import bio.overture.dms.core.model.enums.ClusterRunModes; import lombok.NonNull; import lombok.val; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.resolveServiceConnectionInfo; -import static bio.overture.dms.compose.model.ComposeServiceResources.ELASTICSEARCH; -import static bio.overture.dms.compose.model.ComposeServiceResources.MAESTRO; - @Component public class ElasticsearchQuestionnaire { @@ -25,30 +23,25 @@ public ElasticsearchQuestionnaire(@NonNull QuestionFactory questionFactory) { } public ElasticsearchConfig buildConfig(ClusterRunModes runModes, GatewayConfig gatewayConfig) { - String password = null; - val info = resolveServiceConnectionInfo(runModes, gatewayConfig, questionFactory, ELASTICSEARCH.toString(), ElasticsearchConfig.DEFAULT_PORT); - val enableSecurity = + String password; + val info = + resolveServiceConnectionInfo( + runModes, + gatewayConfig, + questionFactory, + ELASTICSEARCH.toString(), + ElasticsearchConfig.DEFAULT_PORT); + + password = questionFactory - .newDefaultSingleQuestion( - Boolean.class, - "Do you want to enable elasticsearch user authentication?", - true, - true) + .newPasswordQuestion("What should the superuser (elastic) password be?") .getAnswer(); - if (enableSecurity) { - password = - questionFactory - .newPasswordQuestion("What should the superuser (elastic) password be?") - .getAnswer(); - } - return ElasticsearchConfig.builder() .hostPort(info.port) .url(info.serverUrl) .security( ElasticsearchConfig.Security.builder() - .enabled(enableSecurity) .rootPassword(password) .build()) .build(); diff --git a/src/main/java/bio/overture/dms/cli/questionnaire/MaestroQuestionnaire.java b/src/main/java/bio/overture/dms/cli/questionnaire/MaestroQuestionnaire.java index f2ced8c6..16998d22 100644 --- a/src/main/java/bio/overture/dms/cli/questionnaire/MaestroQuestionnaire.java +++ b/src/main/java/bio/overture/dms/cli/questionnaire/MaestroQuestionnaire.java @@ -1,5 +1,8 @@ package bio.overture.dms.cli.questionnaire; +import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.resolveServiceConnectionInfo; +import static bio.overture.dms.compose.model.ComposeServiceResources.MAESTRO; + import bio.overture.dms.cli.question.QuestionFactory; import bio.overture.dms.core.model.dmsconfig.GatewayConfig; import bio.overture.dms.core.model.dmsconfig.MaestroConfig; @@ -9,10 +12,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.resolveServiceConnectionInfo; -import static bio.overture.dms.compose.model.ComposeServiceResources.EGO_API; -import static bio.overture.dms.compose.model.ComposeServiceResources.MAESTRO; - @Component public class MaestroQuestionnaire { @@ -25,8 +24,13 @@ public MaestroQuestionnaire(@NonNull QuestionFactory questionFactory) { public MaestroConfig buildConfig(ClusterRunModes runModes, GatewayConfig gatewayConfig) { - val info = resolveServiceConnectionInfo(runModes, gatewayConfig, questionFactory, MAESTRO.toString(), MaestroConfig.DEFAULT_PORT); - + val info = + resolveServiceConnectionInfo( + runModes, + gatewayConfig, + questionFactory, + MAESTRO.toString(), + MaestroConfig.DEFAULT_PORT); String aliasName = questionFactory diff --git a/src/main/java/bio/overture/dms/cli/questionnaire/ScoreQuestionnaire.java b/src/main/java/bio/overture/dms/cli/questionnaire/ScoreQuestionnaire.java index 54cf96ca..df48533b 100644 --- a/src/main/java/bio/overture/dms/cli/questionnaire/ScoreQuestionnaire.java +++ b/src/main/java/bio/overture/dms/cli/questionnaire/ScoreQuestionnaire.java @@ -1,6 +1,5 @@ package bio.overture.dms.cli.questionnaire; -import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.createLocalhostUrl; import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.resolveServiceConnectionInfo; import static bio.overture.dms.compose.model.ComposeServiceResources.*; import static bio.overture.dms.core.util.RandomGenerator.createRandomGenerator; @@ -12,8 +11,8 @@ import bio.overture.dms.core.model.dmsconfig.ScoreConfig.ScoreApiConfig; import bio.overture.dms.core.model.dmsconfig.ScoreConfig.ScoreS3Config; import bio.overture.dms.core.model.enums.ClusterRunModes; -import bio.overture.dms.core.util.Nullable; import bio.overture.dms.core.util.RandomGenerator; + import java.net.URL; import lombok.NonNull; import lombok.SneakyThrows; @@ -57,13 +56,13 @@ private static AppCredential processScoreAppCreds() { } @SneakyThrows - private ScoreApiConfig processScoreApiConfig(ClusterRunModes clusterRunMode, GatewayConfig gatewayConfig) { + private ScoreApiConfig processScoreApiConfig( + ClusterRunModes clusterRunMode, GatewayConfig gatewayConfig) { val apiBuilder = ScoreApiConfig.builder(); - val info = resolveServiceConnectionInfo(clusterRunMode, - gatewayConfig, - questionFactory, - SCORE_API.toString(), 9020); + val info = + resolveServiceConnectionInfo( + clusterRunMode, gatewayConfig, questionFactory, SCORE_API.toString(), 9020); apiBuilder.hostPort(info.port); apiBuilder.url(info.serverUrl); @@ -92,7 +91,8 @@ private ScoreApiConfig processScoreApiConfig(ClusterRunModes clusterRunMode, Gat } @SneakyThrows - private ScoreS3Config processScoreS3Config(ClusterRunModes runModes, GatewayConfig gatewayConfig) { + private ScoreS3Config processScoreS3Config( + ClusterRunModes runModes, GatewayConfig gatewayConfig) { val s3Builder = ScoreS3Config.builder(); val useExternalS3 = questionFactory @@ -123,10 +123,15 @@ private ScoreS3Config processScoreS3Config(ClusterRunModes runModes, GatewayConf s3Builder.s3Region(awsS3Region); s3Builder.url(awsS3Url); } else { - val externalS3Url = + URL externalS3Url = questionFactory .newUrlSingleQuestion("What is the URL of the S3 service?", false, null) .getAnswer(); + + // remove the trailing slash from the url because it breaks score + if (externalS3Url.toString().endsWith("/")) { + externalS3Url = new URL(externalS3Url.toString().substring(0, externalS3Url.toString().length() - 1)); + } s3Builder.url(externalS3Url); } @@ -173,11 +178,12 @@ private ScoreS3Config processScoreS3Config(ClusterRunModes runModes, GatewayConf s3Builder.accessKey(minioAccessKey); s3Builder.secretKey(minioSecretKey); - val info = resolveServiceConnectionInfo(runModes, gatewayConfig, questionFactory, MINIO_API.toString(), 9021); + val info = + resolveServiceConnectionInfo( + runModes, gatewayConfig, questionFactory, MINIO_API.toString(), 9021); s3Builder.hostPort(info.port); s3Builder.url(info.serverUrl); } return s3Builder.build(); } - } diff --git a/src/main/java/bio/overture/dms/cli/questionnaire/SongQuestionnaire.java b/src/main/java/bio/overture/dms/cli/questionnaire/SongQuestionnaire.java index 4c4dd37f..ebe0453b 100644 --- a/src/main/java/bio/overture/dms/cli/questionnaire/SongQuestionnaire.java +++ b/src/main/java/bio/overture/dms/cli/questionnaire/SongQuestionnaire.java @@ -1,8 +1,6 @@ package bio.overture.dms.cli.questionnaire; -import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.createLocalhostUrl; import static bio.overture.dms.cli.questionnaire.DmsQuestionnaire.resolveServiceConnectionInfo; -import static bio.overture.dms.compose.model.ComposeServiceResources.SCORE_API; import static bio.overture.dms.compose.model.ComposeServiceResources.SONG_API; import static bio.overture.dms.core.util.RandomGenerator.createRandomGenerator; @@ -14,7 +12,6 @@ import bio.overture.dms.core.model.dmsconfig.SongConfig.SongDbConfig; import bio.overture.dms.core.model.enums.ClusterRunModes; import bio.overture.dms.core.util.RandomGenerator; -import java.net.URL; import lombok.NonNull; import lombok.SneakyThrows; import lombok.val; @@ -40,7 +37,8 @@ public SongQuestionnaire(@NonNull QuestionFactory questionFactory) { this.questionFactory = questionFactory; } - public SongConfig buildSongConfig(ClusterRunModes clusterRunModes, @NonNull GatewayConfig gatewayConfig) { + public SongConfig buildSongConfig( + ClusterRunModes clusterRunModes, @NonNull GatewayConfig gatewayConfig) { val apiConfig = processSongApiConfig(clusterRunModes, gatewayConfig); val dbConfig = processSongDbConfig(); return SongConfig.builder().api(apiConfig).db(dbConfig).build(); @@ -55,12 +53,12 @@ private static AppCredential processSongAppCreds() { } @SneakyThrows - private SongApiConfig processSongApiConfig(ClusterRunModes clusterRunModes, GatewayConfig gatewayConfig) { + private SongApiConfig processSongApiConfig( + ClusterRunModes clusterRunModes, GatewayConfig gatewayConfig) { val apiBuilder = SongApiConfig.builder(); - val info = resolveServiceConnectionInfo(clusterRunModes, - gatewayConfig, - questionFactory, - SONG_API.toString(), 9010); + val info = + resolveServiceConnectionInfo( + clusterRunModes, gatewayConfig, questionFactory, SONG_API.toString(), 9010); apiBuilder.url(info.serverUrl); apiBuilder.hostPort(info.port); @@ -70,18 +68,9 @@ private SongApiConfig processSongApiConfig(ClusterRunModes clusterRunModes, Gate private SongDbConfig processSongDbConfig() { val dbBuilder = SongDbConfig.builder(); - - val isSetDBPassword = - questionFactory - .newDefaultSingleQuestion( - Boolean.class, "Would you like to set the database password for SONG?", false, null) - .getAnswer(); - - if (isSetDBPassword) { - val dbPassword = + val dbPassword = questionFactory.newPasswordQuestion("What should the SONG db password be?").getAnswer(); - dbBuilder.databasePassword(dbPassword); - } + dbBuilder.databasePassword(dbPassword); return dbBuilder.build(); } diff --git a/src/main/java/bio/overture/dms/compose/deployment/DmsComposeManager.java b/src/main/java/bio/overture/dms/compose/deployment/DmsComposeManager.java index 1e4d2eee..1e304232 100644 --- a/src/main/java/bio/overture/dms/compose/deployment/DmsComposeManager.java +++ b/src/main/java/bio/overture/dms/compose/deployment/DmsComposeManager.java @@ -16,7 +16,6 @@ import bio.overture.dms.core.model.enums.ClusterRunModes; import bio.overture.dms.swarm.properties.DockerProperties; import bio.overture.dms.swarm.service.SwarmService; - import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; @@ -79,7 +78,8 @@ public void deploy(@NonNull DmsConfig dmsConfig) { completableFutures.add(gateway); val egoFuture = - gateway.thenRunAsync(() -> egoApiDbDeployer.deploy(dmsConfig), executorService) + gateway + .thenRunAsync(() -> egoApiDbDeployer.deploy(dmsConfig), executorService) .thenRunAsync(getDeployRunnable(dmsConfig, EGO_UI, messenger), executorService); completableFutures.add(egoFuture); @@ -107,7 +107,9 @@ public void deploy(@NonNull DmsConfig dmsConfig) { completableFutures.add(scoreApiFuture); val elasticMaestroFuture = - gateway.thenRunAsync(() -> elasticsearchDeployer.deploy(dmsRunningInDocker, dmsConfig), executorService) + gateway + .thenRunAsync( + () -> elasticsearchDeployer.deploy(dmsRunningInDocker, dmsConfig), executorService) .thenRunAsync( getMaestroDeployRunnable(dmsConfig, dmsRunningInDocker, messenger), executorService); @@ -159,7 +161,9 @@ private Runnable getMaestroDeployRunnable( } } try { - ServiceDeployer.waitForOk(maestroUrl.toString(), dmsConfig.getHealthCheck().getRetries(), + ServiceDeployer.waitForOk( + maestroUrl.toString(), + dmsConfig.getHealthCheck().getRetries(), dmsConfig.getHealthCheck().getDelaySec()); } catch (Exception e) { messenger.send("❌ Health check failed for Maestro"); diff --git a/src/main/java/bio/overture/dms/compose/deployment/ServiceDeployer.java b/src/main/java/bio/overture/dms/compose/deployment/ServiceDeployer.java index 0dc4d6f2..b2061f70 100644 --- a/src/main/java/bio/overture/dms/compose/deployment/ServiceDeployer.java +++ b/src/main/java/bio/overture/dms/compose/deployment/ServiceDeployer.java @@ -37,8 +37,6 @@ public class ServiceDeployer { private final Messenger messenger; private final ServiceSpecRenderEngine serviceSpecRenderEngine; - - @Autowired public ServiceDeployer( @NonNull SwarmService swarmService, diff --git a/src/main/java/bio/overture/dms/compose/deployment/ego/EgoApiDbDeployer.java b/src/main/java/bio/overture/dms/compose/deployment/ego/EgoApiDbDeployer.java index 92e8d7c8..6cc8b62b 100644 --- a/src/main/java/bio/overture/dms/compose/deployment/ego/EgoApiDbDeployer.java +++ b/src/main/java/bio/overture/dms/compose/deployment/ego/EgoApiDbDeployer.java @@ -7,7 +7,6 @@ import bio.overture.dms.compose.deployment.ServiceDeployer; import bio.overture.dms.core.Messenger; import bio.overture.dms.core.model.dmsconfig.DmsConfig; -import bio.overture.dms.core.model.dmsconfig.EgoConfig; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import lombok.val; diff --git a/src/main/java/bio/overture/dms/compose/deployment/ego/EgoDMSProvisioner.java b/src/main/java/bio/overture/dms/compose/deployment/ego/EgoDMSProvisioner.java index 2ba180c6..da256048 100644 --- a/src/main/java/bio/overture/dms/compose/deployment/ego/EgoDMSProvisioner.java +++ b/src/main/java/bio/overture/dms/compose/deployment/ego/EgoDMSProvisioner.java @@ -1,5 +1,7 @@ package bio.overture.dms.compose.deployment.ego; +import static bio.overture.dms.ego.model.PermissionMasks.WRITE; + import bio.overture.dms.compose.deployment.SimpleProvisionService; import bio.overture.dms.core.model.dmsconfig.AppCredential; import bio.overture.dms.ego.client.EgoService; @@ -7,8 +9,6 @@ import lombok.NonNull; import lombok.RequiredArgsConstructor; -import static bio.overture.dms.ego.model.PermissionMasks.WRITE; - /** Provisions necessary DMS groups, application and permissions in EGO in an idempotent manner */ @Builder @RequiredArgsConstructor diff --git a/src/main/java/bio/overture/dms/compose/deployment/ego/EgoHelper.java b/src/main/java/bio/overture/dms/compose/deployment/ego/EgoHelper.java index 427e00f7..749d1fa3 100644 --- a/src/main/java/bio/overture/dms/compose/deployment/ego/EgoHelper.java +++ b/src/main/java/bio/overture/dms/compose/deployment/ego/EgoHelper.java @@ -1,9 +1,6 @@ package bio.overture.dms.compose.deployment.ego; import static bio.overture.dms.compose.model.ComposeServiceResources.EGO_API; -import static bio.overture.dms.core.model.enums.ClusterRunModes.LOCAL; -import static bio.overture.dms.core.model.enums.ClusterRunModes.SERVER; -import static bio.overture.dms.core.util.Exceptions.buildIllegalStateException; import static bio.overture.dms.ego.client.EgoService.createEgoService; import bio.overture.dms.core.model.dmsconfig.EgoConfig; @@ -77,7 +74,7 @@ public void waitForEgoApiHealthy(ClusterRunModes clusterRunMode, EgoConfig egoCo .build(); EgoClient egoClient = - egoClientFactory2.buildNoAuthEgoClient(getLocalEgoApiUrl(egoConfig.getApi()).toString()); + egoClientFactory2.buildNoAuthEgoClient(getLocalEgoApiUrl(egoConfig.getApi()).toString()); // Attempt to get the public key several times Failsafe.with(RETRY_POLICY).get(egoClient::getPublicKey); diff --git a/src/main/java/bio/overture/dms/compose/deployment/elasticsearch/ElasticsearchDeployer.java b/src/main/java/bio/overture/dms/compose/deployment/elasticsearch/ElasticsearchDeployer.java index 7a913068..02976c96 100644 --- a/src/main/java/bio/overture/dms/compose/deployment/elasticsearch/ElasticsearchDeployer.java +++ b/src/main/java/bio/overture/dms/compose/deployment/elasticsearch/ElasticsearchDeployer.java @@ -2,21 +2,18 @@ import static bio.overture.dms.compose.model.ComposeServiceResources.*; -import bio.overture.dms.compose.deployment.DmsComposeManager; import bio.overture.dms.compose.deployment.ServiceDeployer; import bio.overture.dms.core.Messenger; import bio.overture.dms.core.model.dmsconfig.DmsConfig; import bio.overture.dms.core.model.dmsconfig.ElasticsearchConfig; +import java.net.URI; +import java.net.URL; import lombok.NonNull; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import lombok.val; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.net.URI; -import java.net.URL; - @Slf4j @Component public class ElasticsearchDeployer { @@ -38,10 +35,11 @@ public void deploy(boolean runInDocker, @NonNull DmsConfig dmsConfig) { serviceDeployer.deploy(dmsConfig, ELASTICSEARCH, true); messenger.send("⏳ Waiting for '%s' service to be healthy..", ELASTICSEARCH.toString()); - URL baseUrl = dmsConfig.getElasticsearch().getUrl(); if (runInDocker) { - baseUrl = new URI("http://" + ELASTICSEARCH.toString() + ":" + ElasticsearchConfig.DEFAULT_PORT).toURL(); + baseUrl = + new URI("http://" + ELASTICSEARCH.toString() + ":" + ElasticsearchConfig.DEFAULT_PORT) + .toURL(); } try { ServiceDeployer.waitForOk( diff --git a/src/main/java/bio/overture/dms/compose/deployment/score/EgoScoreProvisioner.java b/src/main/java/bio/overture/dms/compose/deployment/score/EgoScoreProvisioner.java index 4248e55f..75d6e3be 100644 --- a/src/main/java/bio/overture/dms/compose/deployment/score/EgoScoreProvisioner.java +++ b/src/main/java/bio/overture/dms/compose/deployment/score/EgoScoreProvisioner.java @@ -17,6 +17,5 @@ public class EgoScoreProvisioner implements Runnable { @NonNull private final AppCredential scoreAppCredential; @Override - public void run() { - } + public void run() {} } diff --git a/src/main/java/bio/overture/dms/compose/deployment/score/ScoreApiDeployer.java b/src/main/java/bio/overture/dms/compose/deployment/score/ScoreApiDeployer.java index 372f4a23..33b5361c 100644 --- a/src/main/java/bio/overture/dms/compose/deployment/score/ScoreApiDeployer.java +++ b/src/main/java/bio/overture/dms/compose/deployment/score/ScoreApiDeployer.java @@ -1,13 +1,7 @@ package bio.overture.dms.compose.deployment.score; -import static bio.overture.dms.compose.deployment.SimpleProvisionService.createSimpleProvisionService; import static bio.overture.dms.compose.deployment.score.s3.S3ServiceFactory.buildS3Service; import static bio.overture.dms.compose.model.ComposeServiceResources.*; -import static bio.overture.dms.compose.model.Constants.DMS_ADMIN_GROUP_NAME; -import static bio.overture.dms.compose.model.Constants.SCORE_POLICY_NAME; -import static bio.overture.dms.core.model.enums.ClusterRunModes.LOCAL; -import static bio.overture.dms.core.model.enums.ClusterRunModes.SERVER; -import static java.lang.String.format; import static software.amazon.awssdk.regions.Region.US_EAST_1; import bio.overture.dms.compose.deployment.ServiceDeployer; @@ -15,9 +9,7 @@ import bio.overture.dms.compose.model.S3ObjectUploadRequest; import bio.overture.dms.core.Messenger; import bio.overture.dms.core.model.dmsconfig.DmsConfig; -import bio.overture.dms.core.model.dmsconfig.EgoConfig; import bio.overture.dms.core.model.dmsconfig.ScoreConfig; -import bio.overture.dms.core.model.dmsconfig.ScoreConfig.ScoreApiConfig; import bio.overture.dms.core.model.dmsconfig.ScoreConfig.ScoreS3Config; import bio.overture.dms.core.model.enums.ClusterRunModes; import bio.overture.dms.swarm.properties.DockerProperties; diff --git a/src/main/java/bio/overture/dms/compose/deployment/song/EgoSongProvisioner.java b/src/main/java/bio/overture/dms/compose/deployment/song/EgoSongProvisioner.java index 630635ef..6ee05c31 100644 --- a/src/main/java/bio/overture/dms/compose/deployment/song/EgoSongProvisioner.java +++ b/src/main/java/bio/overture/dms/compose/deployment/song/EgoSongProvisioner.java @@ -1,7 +1,5 @@ package bio.overture.dms.compose.deployment.song; -import static bio.overture.dms.ego.model.PermissionMasks.WRITE; - import bio.overture.dms.compose.deployment.SimpleProvisionService; import bio.overture.dms.core.model.dmsconfig.AppCredential; import bio.overture.dms.ego.client.EgoService; @@ -22,7 +20,5 @@ public class EgoSongProvisioner implements Runnable { @NonNull private final EgoService egoService; @Override - public void run() { - } - + public void run() {} } diff --git a/src/main/java/bio/overture/dms/compose/deployment/song/SongApiDeployer.java b/src/main/java/bio/overture/dms/compose/deployment/song/SongApiDeployer.java index a4433463..8eef9bbf 100644 --- a/src/main/java/bio/overture/dms/compose/deployment/song/SongApiDeployer.java +++ b/src/main/java/bio/overture/dms/compose/deployment/song/SongApiDeployer.java @@ -1,19 +1,13 @@ package bio.overture.dms.compose.deployment.song; -import static bio.overture.dms.compose.deployment.SimpleProvisionService.createSimpleProvisionService; import static bio.overture.dms.compose.model.ComposeServiceResources.SONG_API; -import static bio.overture.dms.compose.model.Constants.DMS_ADMIN_GROUP_NAME; -import static bio.overture.dms.compose.model.Constants.SCORE_POLICY_NAME; import bio.overture.dms.compose.deployment.ServiceDeployer; import bio.overture.dms.compose.deployment.ego.EgoHelper; import bio.overture.dms.core.Messenger; import bio.overture.dms.core.model.dmsconfig.DmsConfig; -import bio.overture.dms.core.model.dmsconfig.EgoConfig; -import bio.overture.dms.core.model.dmsconfig.SongConfig.SongApiConfig; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; -import lombok.val; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -21,8 +15,6 @@ @Component public class SongApiDeployer { - - /** Dependencies */ private final ServiceDeployer serviceDeployer; diff --git a/src/main/java/bio/overture/dms/core/model/dmsconfig/DmsConfig.java b/src/main/java/bio/overture/dms/core/model/dmsconfig/DmsConfig.java index 5ff1652b..d178a0b6 100644 --- a/src/main/java/bio/overture/dms/core/model/dmsconfig/DmsConfig.java +++ b/src/main/java/bio/overture/dms/core/model/dmsconfig/DmsConfig.java @@ -5,7 +5,6 @@ import bio.overture.dms.core.model.enums.ClusterRunModes; import com.fasterxml.jackson.annotation.JsonInclude; -import java.net.URL; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.NoArgsConstructor; diff --git a/src/main/java/bio/overture/dms/core/model/dmsconfig/DmsUIConfig.java b/src/main/java/bio/overture/dms/core/model/dmsconfig/DmsUIConfig.java index c1ebd569..2ba3949b 100644 --- a/src/main/java/bio/overture/dms/core/model/dmsconfig/DmsUIConfig.java +++ b/src/main/java/bio/overture/dms/core/model/dmsconfig/DmsUIConfig.java @@ -3,11 +3,11 @@ import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; import com.fasterxml.jackson.annotation.JsonInclude; +import java.net.URL; +import javax.validation.constraints.Email; import javax.validation.constraints.Min; import lombok.*; -import java.net.URL; - @Data @Builder @NoArgsConstructor @@ -21,6 +21,20 @@ public class DmsUIConfig { @NonNull URL url; + @NonNull + @Email + private String adminEmail; + + private String ssoProviders; + + @NonNull + @Builder.Default + private String labName = "Data Management System"; + + private String logoFileName; + + private String assetsDir; + private ArrangerProjectConfig projectConfig; public static final int DEFAULT_PORT = 8000; diff --git a/src/main/java/bio/overture/dms/core/model/dmsconfig/EgoConfig.java b/src/main/java/bio/overture/dms/core/model/dmsconfig/EgoConfig.java index caf1c1be..e97eed2b 100644 --- a/src/main/java/bio/overture/dms/core/model/dmsconfig/EgoConfig.java +++ b/src/main/java/bio/overture/dms/core/model/dmsconfig/EgoConfig.java @@ -3,18 +3,19 @@ import static bio.overture.dms.core.util.Strings.isDefined; import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; +import bio.overture.dms.cli.questionnaire.EgoQuestionnaire; import bio.overture.dms.core.util.Nullable; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import java.net.URL; +import java.util.ArrayList; +import java.util.List; import javax.validation.constraints.Min; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; + +import lombok.*; @Data @Builder @@ -108,6 +109,16 @@ public static class SSOConfig { @Nullable private SSOClientConfig facebook; @Nullable private SSOClientConfig orcid; + + @JsonIgnore + public List getConfiguredProviders() { + val array = new ArrayList(); + if (google != null) array.add(EgoQuestionnaire.SSOProviders.GOOGLE); + if (github != null) array.add(EgoQuestionnaire.SSOProviders.GITHUB); + if (linkedin != null) array.add(EgoQuestionnaire.SSOProviders.LINKEDIN); + if (orcid != null) array.add(EgoQuestionnaire.SSOProviders.ORCID); + return array; + } } @Data diff --git a/src/main/java/bio/overture/dms/core/model/dmsconfig/ElasticsearchConfig.java b/src/main/java/bio/overture/dms/core/model/dmsconfig/ElasticsearchConfig.java index cef26735..f1aa1bb1 100644 --- a/src/main/java/bio/overture/dms/core/model/dmsconfig/ElasticsearchConfig.java +++ b/src/main/java/bio/overture/dms/core/model/dmsconfig/ElasticsearchConfig.java @@ -3,9 +3,8 @@ import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.*; - import java.net.URL; +import lombok.*; @Data @Builder @@ -19,6 +18,7 @@ public class ElasticsearchConfig { @NonNull private Security security; URL url; + @Data @Builder @NoArgsConstructor diff --git a/src/main/java/bio/overture/dms/core/model/dmsconfig/GatewayConfig.java b/src/main/java/bio/overture/dms/core/model/dmsconfig/GatewayConfig.java index 7a7603fd..4e4e1407 100644 --- a/src/main/java/bio/overture/dms/core/model/dmsconfig/GatewayConfig.java +++ b/src/main/java/bio/overture/dms/core/model/dmsconfig/GatewayConfig.java @@ -1,17 +1,16 @@ package bio.overture.dms.core.model.dmsconfig; +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; + import com.fasterxml.jackson.annotation.JsonInclude; +import java.net.URL; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import java.net.URL; - -import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; - @Data @Builder @NoArgsConstructor @@ -19,9 +18,11 @@ @JsonInclude(NON_EMPTY) public class GatewayConfig { @Builder.Default private boolean pathBased = true; + @Min(value = 2000) @Builder.Default private int hostPort = 80; + @NotNull private URL url; private String sslDir = "/etc/ssl/dms"; } diff --git a/src/main/java/bio/overture/dms/core/model/dmsconfig/HealthCheckConfig.java b/src/main/java/bio/overture/dms/core/model/dmsconfig/HealthCheckConfig.java index 14c1024b..4c6575ed 100644 --- a/src/main/java/bio/overture/dms/core/model/dmsconfig/HealthCheckConfig.java +++ b/src/main/java/bio/overture/dms/core/model/dmsconfig/HealthCheckConfig.java @@ -1,13 +1,13 @@ package bio.overture.dms.core.model.dmsconfig; +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; + import com.fasterxml.jackson.annotation.JsonInclude; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; - @Data @Builder @NoArgsConstructor diff --git a/src/main/java/bio/overture/dms/core/model/dmsconfig/MaestroConfig.java b/src/main/java/bio/overture/dms/core/model/dmsconfig/MaestroConfig.java index 7d4adc8a..ac9088f2 100644 --- a/src/main/java/bio/overture/dms/core/model/dmsconfig/MaestroConfig.java +++ b/src/main/java/bio/overture/dms/core/model/dmsconfig/MaestroConfig.java @@ -3,9 +3,8 @@ import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.*; - import java.net.URL; +import lombok.*; @Data @Builder diff --git a/src/main/java/bio/overture/dms/swarm/properties/DockerProperties.java b/src/main/java/bio/overture/dms/swarm/properties/DockerProperties.java index 23b88237..5b6cae5f 100644 --- a/src/main/java/bio/overture/dms/swarm/properties/DockerProperties.java +++ b/src/main/java/bio/overture/dms/swarm/properties/DockerProperties.java @@ -15,4 +15,5 @@ public class DockerProperties { @NotBlank private String host; @NotNull private Boolean runAs; + @NotNull private String dmsHomeHostPath; } diff --git a/src/main/java/bio/overture/dms/swarm/service/SwarmService.java b/src/main/java/bio/overture/dms/swarm/service/SwarmService.java index a0053be6..5616ae84 100644 --- a/src/main/java/bio/overture/dms/swarm/service/SwarmService.java +++ b/src/main/java/bio/overture/dms/swarm/service/SwarmService.java @@ -159,7 +159,9 @@ private void concurrentlyDeletedServicesAndWait( val containerIds = e.getValue(); return executors.submit( () -> { + deleteServiceAndWait(serviceName, containerIds, numRetries, poll); + }); }) .collect(toUnmodifiableList()); @@ -177,8 +179,11 @@ private void deleteServiceAndWait( // and so we create a unique monitor per thread. For more info, refer to // Guarded Blocks // https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html - val lock = new Object(); - waitForContainerDeletion(lock, containerIds, numRetries, poll); + // ego-ui takes a long time to stop the container (the service stops quickly) + if (!serviceName.equalsIgnoreCase("ego-ui")) { + val lock = new Object(); + waitForContainerDeletion(lock, containerIds, numRetries, poll); + } } private void deleteContainersByVolumes(Collection volumeNames) { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a09f3ba3..64ccac79 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -30,3 +30,10 @@ docker: run-as: false # If blank, will use the system default docker daemon. Useful for using a remote docker daemon. host: "" + + # this is needed to enable host mounts to be able to mount things + # like the custom logo for example in dms ui. + # since running in docker will hide the original host path we need to know + # it somehow, this is provided in dms-docker script as an env var. + # when running without docker, we get the home path from the system properties. + dmsHomeHostPath: /home/ubuntu/.dms \ No newline at end of file diff --git a/src/main/resources/templates/servicespec/arranger-ui.yaml.vm b/src/main/resources/templates/servicespec/arranger-ui.yaml.vm index 16c5330c..1201a456 100644 --- a/src/main/resources/templates/servicespec/arranger-ui.yaml.vm +++ b/src/main/resources/templates/servicespec/arranger-ui.yaml.vm @@ -5,7 +5,7 @@ Name: arranger-ui TaskTemplate: ContainerSpec: - Image: "overture/arranger-ui:2.11.1-8577ed4" + Image: "overture/arranger-ui:2.11.2" Env: - PORT=8080 # no slash at beginning is intended otherwise arranger won't work correctly diff --git a/src/main/resources/templates/servicespec/dms-ui.yaml.vm b/src/main/resources/templates/servicespec/dms-ui.yaml.vm index 18464ff7..a03d75e4 100644 --- a/src/main/resources/templates/servicespec/dms-ui.yaml.vm +++ b/src/main/resources/templates/servicespec/dms-ui.yaml.vm @@ -5,7 +5,7 @@ Name: dms-ui TaskTemplate: ContainerSpec: - Image: "overture/dms-ui:0.7.0" + Image: "overture/dms-ui:0.8.0" Env: - NEXT_PUBLIC_EGO_API_ROOT=$dmsConfig.ego.api.url - NEXT_PUBLIC_EGO_CLIENT_ID=dms @@ -14,7 +14,17 @@ TaskTemplate: - NEXT_PUBLIC_ARRANGER_GRAPHQL_FIELD=$dmsConfig.dmsUI.projectConfig.name - NEXT_PUBLIC_ARRANGER_INDEX=$dmsConfig.dmsUI.projectConfig.indexAlias - NEXT_PUBLIC_ARRANGER_API_URL=$dmsConfig.arranger.api.url - Mounts: null + - NEXT_PUBLIC_ADMIN_EMAIL=$dmsConfig.dmsUI.adminEmail + - NEXT_PUBLIC_LAB_NAME=$dmsConfig.dmsUI.labName + - NEXT_PUBLIC_SSO_PROVIDERS=$dmsConfig.dmsUI.ssoProviders +#if($dmsConfig.dmsUI.logoFileName) + - NEXT_PUBLIC_LOGO_FILENAME=$dmsConfig.dmsUI.logoFileName + Mounts: + - Type: bind + Source: $dmsConfig.dmsUI.assetsDir + Target: /usr/src/public/static/dms_user_assets + ReadOnly: true +#end Duration: null StopGracePeriod: 120000000000 DNSConfig: null diff --git a/src/main/resources/templates/servicespec/ego-api.yaml.vm b/src/main/resources/templates/servicespec/ego-api.yaml.vm index a568ba0f..57fc8e0a 100644 --- a/src/main/resources/templates/servicespec/ego-api.yaml.vm +++ b/src/main/resources/templates/servicespec/ego-api.yaml.vm @@ -5,7 +5,7 @@ Name: ego-api TaskTemplate: ContainerSpec: - Image: "overture/ego:369abd0d" + Image: "overture/ego:4.2.0" Env: - SERVER_PORT=8080 - SPRING_FLYWAY_ENABLED=true diff --git a/src/main/resources/templates/servicespec/ego-ui.yaml.vm b/src/main/resources/templates/servicespec/ego-ui.yaml.vm index dc9d0d22..0a4ae296 100644 --- a/src/main/resources/templates/servicespec/ego-ui.yaml.vm +++ b/src/main/resources/templates/servicespec/ego-ui.yaml.vm @@ -5,11 +5,11 @@ Name: ego-ui TaskTemplate: ContainerSpec: - Image: "overture/ego-ui:eabe9b0" + Image: "overture/ego-ui:4.1.0" Env: - REACT_APP_API=$dmsConfig.ego.api.url - PUBLIC_URL=$dmsConfig.ego.ui.url - - REACT_APP_PUBLIC_URL=/ego-ui + - REACT_APP_PUBLIC_PATH=/ego-ui - REACT_APP_EGO_CLIENT_ID=${composeServiceResources.EGO_UI.toString()} Mounts: null Duration: null @@ -20,7 +20,11 @@ TaskTemplate: Hosts: null Hostname: null Secrets: null - HealthCheck: null + HealthCheck: + Test: ["CMD", "wget", "-O-", "http://localhost:8080/"] + Interval: 20000000000 + Timeout: 10000000000 + Retries: 5 StopSignal: "SIGINT" Privileges: null Configs: null diff --git a/src/main/resources/templates/servicespec/score-api.yaml.vm b/src/main/resources/templates/servicespec/score-api.yaml.vm index c01eec83..dee10e15 100644 --- a/src/main/resources/templates/servicespec/score-api.yaml.vm +++ b/src/main/resources/templates/servicespec/score-api.yaml.vm @@ -5,7 +5,7 @@ Name: score-api TaskTemplate: ContainerSpec: - Image: "overture/score-server:23c9d1a" + Image: "overture/score-server:5.3.0" Env: - SERVER_PORT=8080 - SPRING_PROFILES_ACTIVE=amazon,collaboratory,prod,secure,jwt diff --git a/src/test/java/bio/overture/dms/DeployTest.java b/src/test/java/bio/overture/dms/DeployTest.java index 4d327293..a60423ab 100644 --- a/src/test/java/bio/overture/dms/DeployTest.java +++ b/src/test/java/bio/overture/dms/DeployTest.java @@ -1,6 +1,6 @@ package bio.overture.dms; -import bio.overture.dms.cli.command.cluster.ClusterApplyCommand; +import bio.overture.dms.cli.command.cluster.ClusterStartCommand; import bio.overture.dms.cli.command.cluster.ClusterDestroyCommand; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -16,13 +16,13 @@ @Disabled("Should only be used for local testing") public class DeployTest { - @Autowired private ClusterApplyCommand clusterApplyCommand; + @Autowired private ClusterStartCommand clusterStartCommand; @Autowired private ClusterDestroyCommand clusterDestroyCommand; @Test @SneakyThrows public void testDeploy() { - clusterApplyCommand.call(); + clusterStartCommand.call(); log.info("sdf"); } @@ -30,7 +30,6 @@ public void testDeploy() { @SneakyThrows public void testDestroy() { clusterDestroyCommand.setForce(true); - clusterDestroyCommand.setDestroyVolumes(false); clusterDestroyCommand.call(); log.info("sdf"); }