mirror of
https://github.com/kestra-io/kestra.git
synced 2025-12-19 18:05:41 -05:00
feat: allows importFlows endpoint to be able to throw when having an invalid flow (#12995)
This commit is contained in:
@@ -875,7 +875,8 @@ public class FlowController {
|
||||
@ApiResponse(responseCode = "200", description = "On success")
|
||||
public HttpResponse<List<String>> importFlows(
|
||||
@Parameter(description = "The file to import, can be a ZIP archive or a multi-objects YAML file")
|
||||
@Part CompletedFileUpload fileUpload
|
||||
@Part CompletedFileUpload fileUpload,
|
||||
@Parameter(description = "If should fail on invalid flows") @QueryValue(defaultValue = "false") Boolean failOnError
|
||||
) throws IOException {
|
||||
String tenantId = tenantService.resolveTenant();
|
||||
final List<String> wrongFiles = new ArrayList<>();
|
||||
@@ -892,6 +893,9 @@ public class FlowController {
|
||||
fileUpload.discard();
|
||||
return HttpResponse.badRequest();
|
||||
}
|
||||
if (failOnError && !wrongFiles.isEmpty()) {
|
||||
throw new IllegalArgumentException("Following invalids flows were not imported: " + String.join(", ", wrongFiles));
|
||||
}
|
||||
return HttpResponse.ok(wrongFiles);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@ import io.micronaut.http.hateoas.JsonError;
|
||||
import io.micronaut.http.uri.UriBuilder;
|
||||
import io.micronaut.reactor.http.client.ReactorHttpClient;
|
||||
import jakarta.inject.Inject;
|
||||
import java.net.URI;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -48,6 +47,7 @@ import org.slf4j.event.Level;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
@@ -699,6 +699,55 @@ class FlowControllerTest {
|
||||
temp.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void importFlowsWithInvalidButAllowed() throws IOException {
|
||||
var yaml = generateFlowAsString(TEST_NAMESPACE,"a") + "---" +
|
||||
generateInvalidFlowAsString("importFlowsWithInvalidButAllowed",TEST_NAMESPACE);
|
||||
var temp = File.createTempFile("flows", ".yaml");
|
||||
Files.writeString(temp.toPath(), yaml);
|
||||
|
||||
var body = MultipartBody.builder()
|
||||
.addPart("fileUpload", "flows.yaml", temp)
|
||||
.build();
|
||||
var response = client.toBlocking().exchange(POST("/api/v1/main/flows/import", body).contentType(MediaType.MULTIPART_FORM_DATA));
|
||||
assertThat(response.getStatus().getCode()).isEqualTo(OK.getCode());
|
||||
temp.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void importFlowsWithInvalidNotAllowed() throws IOException {
|
||||
var yaml = generateFlowAsString(TEST_NAMESPACE,"a") + "---" +
|
||||
generateInvalidFlowAsString("importFlowsWithInvalidNotAllowed",TEST_NAMESPACE);
|
||||
var temp = File.createTempFile("flows", ".yaml");
|
||||
Files.writeString(temp.toPath(), yaml);
|
||||
|
||||
var body = MultipartBody.builder()
|
||||
.addPart("fileUpload", "flows.yaml", temp)
|
||||
.build();
|
||||
var exception = assertThrows(HttpClientResponseException.class, () -> {
|
||||
client.toBlocking().exchange(POST("/api/v1/main/flows/import?failOnError=true", body).contentType(MediaType.MULTIPART_FORM_DATA));
|
||||
});
|
||||
|
||||
assertThat(exception.getStatus().getCode()).isEqualTo(UNPROCESSABLE_ENTITY.getCode());
|
||||
temp.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void importFlowsWithInvalidFile() throws IOException {
|
||||
var temp = File.createTempFile("flows", ".txt");
|
||||
Files.writeString(temp.toPath(), "this is not a valid file");
|
||||
|
||||
var body = MultipartBody.builder()
|
||||
.addPart("fileUpload", "flows.txt", temp)
|
||||
.build();
|
||||
var exception = assertThrows(HttpClientResponseException.class, () -> {
|
||||
client.toBlocking().exchange(POST("/api/v1/main/flows/import?failOnError=false", body).contentType(MediaType.MULTIPART_FORM_DATA));
|
||||
});
|
||||
|
||||
assertThat(exception.getStatus().getCode()).isEqualTo(UNPROCESSABLE_ENTITY.getCode());
|
||||
temp.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void disableEnableFlowsByIds() {
|
||||
List<IdWithNamespace> ids = List.of(
|
||||
@@ -1112,6 +1161,20 @@ class FlowControllerTest {
|
||||
|
||||
}
|
||||
|
||||
private String generateInvalidFlowAsString(String id, String namespace) {
|
||||
return """
|
||||
id: %s
|
||||
# Comment i added
|
||||
namespace: %s
|
||||
tasks:
|
||||
- id: test
|
||||
type: io.kestra.plugin.core.debug.Invalid
|
||||
format: test
|
||||
disabled: false
|
||||
deleted: false
|
||||
""".formatted(id, namespace);
|
||||
}
|
||||
|
||||
private String postFlow(String friendlyId, String namespace, String format) {
|
||||
return client.toBlocking().retrieve(POST("/api/v1/main/flows", generateFlow(friendlyId, namespace, format)), String.class);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user