diff --git a/cli/src/main/java/io/kestra/cli/commands/sys/ReindexCommand.java b/cli/src/main/java/io/kestra/cli/commands/sys/ReindexCommand.java new file mode 100644 index 00000000000..02639b31e70 --- /dev/null +++ b/cli/src/main/java/io/kestra/cli/commands/sys/ReindexCommand.java @@ -0,0 +1,52 @@ +package io.kestra.cli.commands.sys; + +import io.kestra.cli.AbstractCommand; +import io.kestra.cli.App; +import io.kestra.core.models.flows.FlowWithSource; +import io.kestra.core.repositories.FlowRepositoryInterface; +import io.kestra.core.services.TaskDefaultService; +import io.micronaut.configuration.picocli.PicocliRunner; +import io.micronaut.context.ApplicationContext; +import jakarta.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import picocli.CommandLine; + +import java.util.List; + +@CommandLine.Command( + name = "reindex", + description = "reindex all records of a type: read them from the database then update them", + mixinStandardHelpOptions = true, + subcommands = { + RestoreQueueCommand.class, + FlowListenersRestoreCommand.class + } +) +@Slf4j +public class ReindexCommand extends AbstractCommand { + @Inject + private ApplicationContext applicationContext; + + @CommandLine.Option(names = {"-t", "--type"}, description = "The type of the records to reindex, only 'flow' is supported for now.") + private String type; + + @Override + public Integer call() throws Exception { + super.call(); + + if ("flow".equals(type)) { + FlowRepositoryInterface flowRepository = applicationContext.getBean(FlowRepositoryInterface.class); + TaskDefaultService taskDefaultService = applicationContext.getBean(TaskDefaultService.class); + + List flows = flowRepository.findWithSource(null, null, null); + flows.forEach(flow -> flowRepository.update(flow.toFlow(), flow.toFlow(), flow.getSource(), taskDefaultService.injectDefaults(flow.toFlow()))); + + stdOut("Successfully reindex " + flows.size() + " flow(s)."); + } + else { + throw new IllegalArgumentException("Reindexing type '" + type + "' is not supported"); + } + + return 0; + } +} diff --git a/cli/src/main/java/io/kestra/cli/commands/sys/SysCommand.java b/cli/src/main/java/io/kestra/cli/commands/sys/SysCommand.java index 92e977fd6a4..ee92c2ddb64 100644 --- a/cli/src/main/java/io/kestra/cli/commands/sys/SysCommand.java +++ b/cli/src/main/java/io/kestra/cli/commands/sys/SysCommand.java @@ -12,7 +12,8 @@ mixinStandardHelpOptions = true, subcommands = { RestoreQueueCommand.class, - FlowListenersRestoreCommand.class + FlowListenersRestoreCommand.class, + ReindexCommand.class } ) @Slf4j diff --git a/cli/src/test/java/io/kestra/cli/commands/sys/ReindexCommandTest.java b/cli/src/test/java/io/kestra/cli/commands/sys/ReindexCommandTest.java new file mode 100644 index 00000000000..fa3f8a1093d --- /dev/null +++ b/cli/src/test/java/io/kestra/cli/commands/sys/ReindexCommandTest.java @@ -0,0 +1,51 @@ +package io.kestra.cli.commands.sys; + +import io.kestra.cli.commands.flows.namespaces.FlowNamespaceUpdateCommand; +import io.micronaut.configuration.picocli.PicocliRunner; +import io.micronaut.context.ApplicationContext; +import io.micronaut.context.env.Environment; +import io.micronaut.runtime.server.EmbeddedServer; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.net.URL; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.StringContains.containsString; + +class ReindexCommandTest { + @Test + void reindexFlow() { + URL directory = ReindexCommandTest.class.getClassLoader().getResource("flows"); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + System.setOut(new PrintStream(out)); + + try (ApplicationContext ctx = ApplicationContext.run(Environment.CLI, Environment.TEST)) { + EmbeddedServer embeddedServer = ctx.getBean(EmbeddedServer.class); + embeddedServer.start(); + + // we use the update command to add flows to extract + String[] updateArgs = { + "--server", + embeddedServer.getURL().toString(), + "--user", + "myuser:pass:word", + "io.kestra.cli", + directory.getPath(), + }; + PicocliRunner.call(FlowNamespaceUpdateCommand.class, ctx, updateArgs); + assertThat(out.toString(), containsString("3 flow(s)")); + + // then we reindex them + String[] reindexArgs = { + "--type", + "flow", + }; + Integer call = PicocliRunner.call(ReindexCommand.class, ctx, reindexArgs); + assertThat(call, is(0)); + assertThat(out.toString(), containsString("Successfully reindex 3 flow(s).")); + } + } +} \ No newline at end of file