Repository: kestra-io/kestra
Issue: Flow schema validation issue with multiple conditions
Labels: bug

### Expected Behavior

_No response_

### Actual Behaviour

When using multiple conditions, the flow schema validator shows some warning but the flow works without issue.

![Capture d’écran du 2023-02-09 17-21-35](https://user-images.githubusercontent.com/1819009/217872637-b4b53cd9-f0da-4a65-b41c-bf1926678242.png)


### Steps To Reproduce

You can use the example multiple condition flow, it triggers the issue:

```yaml
id: trigger-multiplecondition-listener
namespace: io.kestra.tests

tasks:
  - id: onlyListener
    type: io.kestra.core.tasks.debugs.Return
    format: "let's go "

triggers:
  - id: multipleListenFlow
    type: io.kestra.core.models.triggers.types.Flow
    conditions:
      - id: multiple
        type: io.kestra.core.models.conditions.types.MultipleCondition
        window: P1D
        windowAdvance: P0D
        conditions:
          flow-a:
            type: io.kestra.core.models.conditions.types.ExecutionFlowCondition
            namespace: io.kestra.tests
            flowId: trigger-multiplecondition-flow-a
          flow-b:
            type: io.kestra.core.models.conditions.types.ExecutionFlowCondition
            namespace: io.kestra.tests
            flowId: trigger-multiplecondition-flow-b
```

### Environment Information

- Kestra Version: 0.6.1-SNAPSHOT
- Operating System (OS / Docker / Kubernetes): Linux
- Java Version (If not docker): 17


### Example flow

_No response_

Issue comments:

Pull request review comments:

Patch that resolved the issue:
diff --git a/core/src/main/java/io/kestra/core/docs/JsonSchemaGenerator.java b/core/src/main/java/io/kestra/core/docs/JsonSchemaGenerator.java
index ac3225c056..bfeaed4dfc 100644
--- a/core/src/main/java/io/kestra/core/docs/JsonSchemaGenerator.java
+++ b/core/src/main/java/io/kestra/core/docs/JsonSchemaGenerator.java
@@ -10,6 +10,7 @@
 import com.github.victools.jsonschema.generator.impl.DefinitionKey;
 import com.github.victools.jsonschema.generator.naming.DefaultSchemaDefinitionNamingStrategy;
 import com.github.victools.jsonschema.module.jackson.JacksonModule;
+import com.github.victools.jsonschema.module.jackson.JacksonOption;
 import com.github.victools.jsonschema.module.javax.validation.JavaxValidationModule;
 import com.github.victools.jsonschema.module.javax.validation.JavaxValidationOption;
 import com.github.victools.jsonschema.module.swagger2.Swagger2Module;
@@ -60,9 +61,7 @@ public <T> Map<String, Object> schemas(Class<? extends T> cls) {
             Map<String, Object> map = JacksonMapper.toMap(objectNode);
 
             // hack
-            if (cls == Task.class) {
-                fixTask(map);
-            } else if (cls == Flow.class) {
+            if (cls == Flow.class) {
                 fixFlow(map);
             }
 
@@ -103,14 +102,6 @@ private void mutateDescription(ObjectNode collectedTypeAttributes) {
         }
     }
 
-    @SuppressWarnings("unchecked")
-    private static void fixTask(Map<String, Object> map) {
-        var definitions = (Map<String, Map<String, Object>>) map.get("definitions");
-        var task = (Map<String, Object>) definitions.get("io.kestra.core.models.tasks.Task-2");
-        var allOf = (List<Object>) task.get("allOf");
-        allOf.remove(1);
-    }
-
     @SuppressWarnings("unchecked")
     private static void fixFlow(Map<String, Object> map) {
         var definitions = (Map<String, Map<String, Object>>) map.get("definitions");
@@ -155,7 +146,7 @@ public <T> Map<String, Object> outputs(Class<T> base, Class<? extends T> cls) {
     protected <T> void build(SchemaGeneratorConfigBuilder builder, Class<? extends T> cls) {
 
         builder
-            .with(new JacksonModule())
+            .with(new JacksonModule(JacksonOption.IGNORE_TYPE_INFO_TRANSFORM))
             .with(new JavaxValidationModule(
                 JavaxValidationOption.NOT_NULLABLE_FIELD_IS_REQUIRED,
                 JavaxValidationOption.INCLUDE_PATTERN_EXPRESSIONS
@@ -164,7 +155,8 @@ protected <T> void build(SchemaGeneratorConfigBuilder builder, Class<? extends T
             .with(Option.DEFINITIONS_FOR_ALL_OBJECTS)
             .with(Option.DEFINITION_FOR_MAIN_SCHEMA)
             .with(Option.PLAIN_DEFINITION_KEYS)
-            .with(Option.ALLOF_CLEANUP_AT_THE_END);
+            .with(Option.ALLOF_CLEANUP_AT_THE_END)
+            .with(Option.MAP_VALUES_AS_ADDITIONAL_PROPERTIES);
 
         // default value
         builder.forFields().withDefaultResolver(this::defaults);
diff --git a/core/src/main/java/io/kestra/core/models/triggers/types/Flow.java b/core/src/main/java/io/kestra/core/models/triggers/types/Flow.java
index 4641b7d1d1..ec0c443af2 100644
--- a/core/src/main/java/io/kestra/core/models/triggers/types/Flow.java
+++ b/core/src/main/java/io/kestra/core/models/triggers/types/Flow.java
@@ -1,5 +1,6 @@
 package io.kestra.core.models.triggers.types;
 
+import io.kestra.core.models.annotations.PluginProperty;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.*;
 import lombok.experimental.SuperBuilder;
@@ -73,6 +74,7 @@ public class Flow extends AbstractTrigger implements TriggerOutput<Flow.Output>
             "So you will need to go to Logs tabs on the ui to understand the error\n" +
             ":::"
     )
+    @PluginProperty
     private Map<String, Object> inputs;
 
     public Optional<Execution> evaluate(RunContext runContext, io.kestra.core.models.flows.Flow flow, Execution current) {
diff --git a/core/src/main/java/io/kestra/core/models/triggers/types/Schedule.java b/core/src/main/java/io/kestra/core/models/triggers/types/Schedule.java
index 4091f4bbf2..1fc1015e76 100644
--- a/core/src/main/java/io/kestra/core/models/triggers/types/Schedule.java
+++ b/core/src/main/java/io/kestra/core/models/triggers/types/Schedule.java
@@ -125,12 +125,13 @@ public class Schedule extends AbstractTrigger implements PollingTriggerInterface
             "* `@midnight`\n" +
             "* `@hourly`"
     )
+    @PluginProperty
     private String cron;
 
     @Schema(
         title = "The time zone id to use for evaluate cron. Default value is the server default zone id."
     )
-    @PluginProperty(dynamic = false)
+    @PluginProperty
     @Builder.Default
     private String timezone = ZoneId.systemDefault().toString();
 
@@ -140,6 +141,7 @@ public class Schedule extends AbstractTrigger implements PollingTriggerInterface
             "\n" +
             "Backfill will do all schedules between define date & current date and will start after the normal schedule."
     )
+    @PluginProperty
     private ScheduleBackfill backfill;
 
     @Builder.Default
@@ -149,6 +151,7 @@ public class Schedule extends AbstractTrigger implements PollingTriggerInterface
     @Schema(
         title = "List of schedule Conditions in order to limit schedule date."
     )
+    @PluginProperty
     private List<ScheduleCondition> scheduleConditions;
 
     @Schema(
@@ -161,6 +164,7 @@ public class Schedule extends AbstractTrigger implements PollingTriggerInterface
         title = "The maximum late delay accepted",
         description = "If the schedule didn't start after this delay, the execution will be skip."
     )
+    @PluginProperty
     private Duration lateMaximumDelay;
 
     @Getter(AccessLevel.NONE)
diff --git a/core/src/main/java/io/kestra/core/models/triggers/types/Webhook.java b/core/src/main/java/io/kestra/core/models/triggers/types/Webhook.java
index 7993d45f89..a7971c7a9e 100644
--- a/core/src/main/java/io/kestra/core/models/triggers/types/Webhook.java
+++ b/core/src/main/java/io/kestra/core/models/triggers/types/Webhook.java
@@ -2,6 +2,7 @@
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import io.kestra.core.models.annotations.PluginProperty;
 import io.micronaut.http.HttpRequest;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.*;
@@ -69,8 +70,10 @@ public class Webhook extends AbstractTrigger implements TriggerOutput<Webhook.Ou
             "\n" +
             "::: warning\n" +
             "Take care when using manual key, the key is the only security to protect your webhook and must be considered as a secret !\n" +
-            ":::\n"
+            ":::\n",
+        defaultValue = "<generated-hash>"
     )
+    @PluginProperty
     private final String key = IdUtils.create();
 
     public Optional<Execution> evaluate(HttpRequest<String> request, io.kestra.core.models.flows.Flow flow) {
diff --git a/core/src/main/java/io/kestra/core/plugins/PluginScanner.java b/core/src/main/java/io/kestra/core/plugins/PluginScanner.java
index 90085f8495..189557cc3a 100644
--- a/core/src/main/java/io/kestra/core/plugins/PluginScanner.java
+++ b/core/src/main/java/io/kestra/core/plugins/PluginScanner.java
@@ -8,6 +8,7 @@
 import io.micronaut.core.beans.BeanIntrospectionReference;
 import io.micronaut.core.io.service.SoftServiceLoader;
 import io.micronaut.http.annotation.Controller;
+import io.swagger.v3.oas.annotations.Hidden;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.io.IOUtils;
 
@@ -113,6 +114,10 @@ private RegisteredPlugin scanClassLoader(final ClassLoader classLoader, External
                 continue;
             }
 
+            if(beanType.isAnnotationPresent(Hidden.class)) {
+                continue;
+            }
+
             if (Task.class.isAssignableFrom(beanType)) {
                 tasks.add(beanType);
             }
diff --git a/core/src/main/java/io/kestra/core/tasks/flows/Template.java b/core/src/main/java/io/kestra/core/tasks/flows/Template.java
index 32e06077b8..3efcde2b07 100644
--- a/core/src/main/java/io/kestra/core/tasks/flows/Template.java
+++ b/core/src/main/java/io/kestra/core/tasks/flows/Template.java
@@ -22,6 +22,7 @@
 import io.micronaut.context.ApplicationContext;
 import io.micronaut.context.event.StartupEvent;
 import io.micronaut.runtime.event.annotation.EventListener;
+import io.swagger.v3.oas.annotations.Hidden;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.*;
 import lombok.experimental.SuperBuilder;
@@ -198,6 +199,7 @@ protected io.kestra.core.models.templates.Template findTemplate(ApplicationConte
     @Getter
     @NoArgsConstructor
     @AllArgsConstructor
+    @Hidden
     public static class ExecutorTemplate extends Template {
         private io.kestra.core.models.templates.Template template;
 


Test patch:
diff --git a/core/src/test/java/io/kestra/core/docs/JsonSchemaGeneratorTest.java b/core/src/test/java/io/kestra/core/docs/JsonSchemaGeneratorTest.java
index d90d5143d5..12fb69f16a 100644
--- a/core/src/test/java/io/kestra/core/docs/JsonSchemaGeneratorTest.java
+++ b/core/src/test/java/io/kestra/core/docs/JsonSchemaGeneratorTest.java
@@ -69,12 +69,11 @@ void flow() throws URISyntaxException {
             Map<String, Object> generate = jsonSchemaGenerator.schemas(Flow.class);
 
             var definitions = (Map<String, Map<String, Object>>) generate.get("definitions");
-
             var flow = definitions.get("io.kestra.core.models.flows.Flow");
             assertThat((List<String>) flow.get("required"), not(contains("deleted")));
             assertThat((List<String>) flow.get("required"), hasItems("id", "namespace", "tasks"));
 
-            var bash = definitions.get("io.kestra.core.tasks.scripts.Bash-1");
+            var bash = definitions.get("io.kestra.core.tasks.scripts.Bash");
             assertThat((List<String>) bash.get("required"), not(contains("exitOnFailed")));
             assertThat((String) ((Map<String, Map<String, Object>>) bash.get("properties")).get("exitOnFailed").get("markdownDescription"), containsString("Default value is : `true`"));
             assertThat(((String) ((Map<String, Map<String, Object>>) bash.get("properties")).get("exitOnFailed").get("markdownDescription")).startsWith("This tells bash that"), is(true));
@@ -82,9 +81,7 @@ void flow() throws URISyntaxException {
             assertThat((String) bash.get("markdownDescription"), containsString("Bash with some inputs files"));
             assertThat((String) bash.get("markdownDescription"), containsString("outputFiles.first"));
 
-            var bashType = definitions.get("io.kestra.core.tasks.scripts.Bash-2");
-
-            var python = definitions.get("io.kestra.core.tasks.scripts.Python-1");
+            var python = definitions.get("io.kestra.core.tasks.scripts.Python");
             assertThat((List<String>) python.get("required"), not(contains("exitOnFailed")));
         });
     }
@@ -98,10 +95,10 @@ void task() throws URISyntaxException {
             Map<String, Object> generate = jsonSchemaGenerator.schemas(Task.class);
 
             var definitions = (Map<String, Map<String, Object>>) generate.get("definitions");
-            var task = (Map<String, Object>) definitions.get("io.kestra.core.models.tasks.Task-2");
-            var allOf = (List<Object>) task.get("allOf");
+            var task = (Map<String, Object>) definitions.get("io.kestra.core.models.tasks.Task");
+            var anyOf = (List<Object>) task.get("anyOf");
 
-            assertThat(allOf.size(), is(1));
+            assertThat(anyOf.size(), greaterThanOrEqualTo(31)); //31 in local but 56 in CI
         });
     }
 
@@ -115,7 +112,7 @@ void bash() throws URISyntaxException {
 
             var definitions = (Map<String, Map<String, Object>>) generate.get("definitions");
 
-            var bash = definitions.get("io.kestra.core.tasks.scripts.Bash-1");
+            var bash = definitions.get("io.kestra.core.tasks.scripts.Bash");
             assertThat((List<String>) bash.get("required"), not(contains("exitOnFailed")));
             assertThat((List<String>) bash.get("required"), not(contains("interpreter")));
         });
@@ -124,7 +121,6 @@ void bash() throws URISyntaxException {
     @Test
     void testEnum() {
         Map<String, Object> generate = jsonSchemaGenerator.properties(Task.class, TaskWithEnum.class);
-        System.out.println(generate);
         assertThat(generate, is(not(nullValue())));
         assertThat(((Map<String, Map<String, Object>>) generate.get("properties")).size(), is(3));
     }
diff --git a/webserver/src/test/java/io/kestra/webserver/controllers/PluginControllerTest.java b/webserver/src/test/java/io/kestra/webserver/controllers/PluginControllerTest.java
index 4fe12c16a9..1133c4a8b7 100644
--- a/webserver/src/test/java/io/kestra/webserver/controllers/PluginControllerTest.java
+++ b/webserver/src/test/java/io/kestra/webserver/controllers/PluginControllerTest.java
@@ -132,7 +132,7 @@ void task() throws URISyntaxException {
                 Argument.mapOf(String.class, Object.class)
             );
 
-            assertThat(doc.get("$ref"), is("#/definitions/io.kestra.core.models.tasks.Task-2"));
+            assertThat(doc.get("$ref"), is("#/definitions/io.kestra.core.models.tasks.Task"));
         });
     }
 }