Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
tchiotludo committed Feb 2, 2023
1 parent 1a1831d commit 9607ff6
Show file tree
Hide file tree
Showing 24 changed files with 220 additions and 317 deletions.
2 changes: 1 addition & 1 deletion cli/src/main/java/io/kestra/cli/AbstractApiCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import java.util.Map;

public abstract class AbstractApiCommand extends AbstractCommand {
@CommandLine.Option(names = {"--server"}, description = "Server Kestra", defaultValue = "http://localhost:8080")
@CommandLine.Option(names = {"--server"}, description = " Kestra server url", defaultValue = "http://localhost:8080")
protected URL server;

@CommandLine.Option(names = {"--headers"}, description = "Headers to add to the request")
Expand Down
94 changes: 79 additions & 15 deletions cli/src/main/java/io/kestra/cli/AbstractValidateCommand.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
package io.kestra.cli;

import io.kestra.cli.commands.flows.FlowValidateCommand;
import io.kestra.core.models.validations.ModelValidator;
import io.kestra.core.models.validations.ValidateConstraintViolation;
import io.kestra.core.serializers.YamlFlowParser;
import io.micronaut.core.type.Argument;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.MediaType;
import io.micronaut.http.MutableHttpRequest;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import io.micronaut.http.client.netty.DefaultHttpClient;
import picocli.CommandLine;

import javax.validation.ConstraintViolationException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.validation.ConstraintViolationException;

import static io.kestra.core.utils.Rethrow.throwConsumer;
import static io.kestra.core.utils.Rethrow.throwFunction;

public class AbstractValidateCommand extends AbstractApiCommand {
@CommandLine.Option(names = {"--local"}, description = "If validation should be done by the client", defaultValue = "false")
public abstract class AbstractValidateCommand extends AbstractApiCommand {
@CommandLine.Option(names = {"--local"}, description = "If validation should be done locally or using a remote server", defaultValue = "false")
protected boolean local;

@CommandLine.Parameters(index = "0", description = "the directory containing flows to check")
public Path directory;
@CommandLine.Parameters(index = "0", description = "the directory containing files to check")
protected Path directory;

public static void handleException(ConstraintViolationException e, String resource) {
stdErr("\t@|fg(red) Unable to parse {0} due to the following error(s):|@", resource);
Expand Down Expand Up @@ -46,20 +58,72 @@ public static void handleValidateConstraintViolation(ValidateConstraintViolation
"\t- @|bold,yellow {0}|@",
validateConstraintViolation.getConstraints()
);

}

public static String buildYamlBody(Path directory) throws IOException {
return String.join("\n---\n", Files.walk(directory)
return Files.walk(directory)
.filter(Files::isRegularFile)
.filter(YamlFlowParser::isValidExtension)
.map(path -> {
try {
return Files.readString(path, Charset.defaultCharset());
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList()));
.map(throwFunction(path -> Files.readString(path, Charset.defaultCharset())))
.collect(Collectors.joining("\n---\n"));
}

// bug in micronaut, we can't inject YamlFlowParser & ModelValidator, so we inject from implementation
public Integer call(
Class<?> cls,
YamlFlowParser yamlFlowParser,
ModelValidator modelValidator,
Function<Object, String> identity
) throws Exception {
super.call();

AtomicInteger returnCode = new AtomicInteger(0);
String clsName = cls.getSimpleName().toLowerCase();

if(this.local) {
Files.walk(directory)
.filter(Files::isRegularFile)
.filter(YamlFlowParser::isValidExtension)
.forEach(path -> {
try {
Object parse = yamlFlowParser.parse(path.toFile(), cls);
modelValidator.validate(parse);
stdOut("@|green \u2713|@ - " + identity.apply(parse));
} catch (ConstraintViolationException e) {
stdErr("@|red \u2718|@ - " + path);
FlowValidateCommand.handleException(e, clsName);
returnCode.set(1);
}
});
} else {
String body = FlowValidateCommand.buildYamlBody(directory);

try(DefaultHttpClient client = client()) {
MutableHttpRequest<String> request = HttpRequest
.POST("/api/v1/flows/validate", body).contentType(MediaType.APPLICATION_YAML);

List<ValidateConstraintViolation> validations = client.toBlocking().retrieve(
this.requestOptions(request),
Argument.listOf(ValidateConstraintViolation.class)
);

validations
.forEach(throwConsumer(validation -> {
if (validation.getConstraints() == null) {
stdOut("@|green \u2713|@ - " + validation.getIdentity());
} else {
stdErr("@|red \u2718|@ - " + validation.getIdentity(directory));
FlowValidateCommand.handleValidateConstraintViolation(validation, clsName);
returnCode.set(1);
}
}));
} catch (HttpClientResponseException e){
FlowValidateCommand.handleHttpException(e, clsName);

return 1;
}
}

return returnCode.get();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ public abstract class AbstractServiceNamespaceUpdateCommand extends AbstractApiC
@CommandLine.Parameters(index = "0", description = "the namespace of flow to update")
public String namespace;

@CommandLine.Parameters(index = "1", description = "the directory containing flows to from current namespace")
@CommandLine.Parameters(index = "1", description = "the directory containing files for current namespace")
public Path directory;

@CommandLine.Option(names = {"--no-delete"}, description = "if flow not contained in the directory should not be delete")
@CommandLine.Option(names = {"--no-delete"}, description = "if missing should not be deleted")
public boolean noDelete = false ;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
description = "handle flows",
mixinStandardHelpOptions = true,
subcommands = {
ValidateCommand.class,
FlowValidateCommand.class,
FlowTestCommand.class,
FlowNamespaceCommand.class,
FlowDotCommand.class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public Integer call() throws Exception {
super.call();

YamlFlowParser parser = applicationContext.getBean(YamlFlowParser.class);
Flow flow = parser.parse(file.toFile());
Flow flow = parser.parse(file.toFile(), Flow.class);

GraphCluster graph = GraphService.of(flow, null);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.kestra.cli.commands.flows;

import io.kestra.cli.AbstractValidateCommand;
import io.kestra.core.models.flows.Flow;
import io.kestra.core.models.validations.ModelValidator;
import io.kestra.core.serializers.YamlFlowParser;
import jakarta.inject.Inject;
import picocli.CommandLine;

@CommandLine.Command(
name = "validate",
description = "validate a flow"
)
public class FlowValidateCommand extends AbstractValidateCommand {
@Inject
private YamlFlowParser yamlFlowParser;

@Inject
private ModelValidator modelValidator;

@Override
public Integer call() throws Exception {
return this.call(
Flow.class,
yamlFlowParser,
modelValidator,
(Object object) -> {
Flow flow = (Flow) object;
return flow.getNamespace() + " / " + flow.getId();
}
);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.kestra.cli.commands.flows.namespaces;

import io.kestra.cli.commands.AbstractServiceNamespaceUpdateCommand;
import io.kestra.cli.commands.flows.ValidateCommand;
import io.kestra.cli.commands.flows.FlowValidateCommand;
import io.kestra.core.models.flows.FlowWithSource;
import io.kestra.core.serializers.YamlFlowParser;
import io.micronaut.core.type.Argument;
Expand Down Expand Up @@ -67,11 +67,11 @@ public Integer call() throws Exception {
stdOut(updated.size() + " flow(s) for namespace '" + namespace + "' successfully updated !");
updated.forEach(flow -> stdOut("- " + flow.getNamespace() + "." + flow.getId()));
} catch (HttpClientResponseException e){
ValidateCommand.handleHttpException(e, "flow");
FlowValidateCommand.handleHttpException(e, "flow");
return 1;
}
} catch (ConstraintViolationException e) {
ValidateCommand.handleException(e, "flow");
FlowValidateCommand.handleException(e, "flow");

return 1;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
mixinStandardHelpOptions = true,
subcommands = {
TemplateNamespaceCommand.class,
ValidateCommand.class
TemplateValidateCommand.class
}
)
@Slf4j
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.kestra.cli.commands.templates;

import io.kestra.cli.AbstractValidateCommand;
import io.kestra.core.models.templates.Template;
import io.kestra.core.models.validations.ModelValidator;
import io.kestra.core.serializers.YamlFlowParser;
import jakarta.inject.Inject;
import picocli.CommandLine;

@CommandLine.Command(
name = "validate",
description = "validate a template"
)
public class TemplateValidateCommand extends AbstractValidateCommand {
@Inject
private YamlFlowParser yamlFlowParser;

@Inject
private ModelValidator modelValidator;

@Override
public Integer call() throws Exception {
return this.call(
Template.class,
yamlFlowParser,
modelValidator,
(Object object) -> {
Template template = (Template) object;
return template.getNamespace() + " / " + template.getId();
}
);
}
}
Loading

0 comments on commit 9607ff6

Please sign in to comment.