diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 12fbe1e..06e485e 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -16,4 +16,4 @@ # under the License. wrapperVersion=3.3.2 distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/4.0.0-rc-5/apache-maven-4.0.0-rc-5-bin.zip diff --git a/pom.xml b/pom.xml index 9044549..0fc1972 100644 --- a/pom.xml +++ b/pom.xml @@ -75,15 +75,20 @@ - + - com.kjetland - mbknor-jackson-jsonschema_2.12 - 1.0.39 + com.github.victools + jsonschema-generator + 5.0.0 + + + com.github.victools + jsonschema-module-jackson + 5.0.0 io.jsonwebtoken - jjwt-jackson + jjwt-gson 0.13.0 runtime @@ -105,10 +110,7 @@ springdoc-openapi-starter-webmvc-ui 3.0.3 - - org.springframework.boot - spring-boot-jackson2 - + org.projectlombok lombok @@ -186,6 +188,16 @@ + + org.apache.maven.plugins + maven-surefire-plugin + + -javaagent:${settings.localRepository}/net/bytebuddy/byte-buddy-agent/${byte-buddy.version}/byte-buddy-agent-${byte-buddy.version}.jar + + subclass + + + diff --git a/src/main/java/it/cnr/isti/workflow/manager/app/ObjectMapperHolder.java b/src/main/java/it/cnr/isti/workflow/manager/app/ObjectMapperHolder.java index c612363..0039ad0 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/app/ObjectMapperHolder.java +++ b/src/main/java/it/cnr/isti/workflow/manager/app/ObjectMapperHolder.java @@ -2,7 +2,7 @@ package it.cnr.isti.workflow.manager.app; import org.springframework.stereotype.Component; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; @Component public class ObjectMapperHolder { diff --git a/src/main/java/it/cnr/isti/workflow/manager/assistant/BlockCatalogService.java b/src/main/java/it/cnr/isti/workflow/manager/assistant/BlockCatalogService.java index 15d1687..0d2e4b2 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/assistant/BlockCatalogService.java +++ b/src/main/java/it/cnr/isti/workflow/manager/assistant/BlockCatalogService.java @@ -8,8 +8,8 @@ import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; import it.cnr.isti.workflow.manager.blocks.Block; import it.cnr.isti.workflow.manager.blocks.configurations.BlockConfiguration; @@ -131,7 +131,7 @@ public class BlockCatalogService { } Set requiredFields = extractRequiredFields(schema.path("required")); - return iterable(schema.path("properties").fields()).stream() + return schema.path("properties").properties().stream() .filter(entry -> !"type".equals(entry.getKey())) .map(entry -> new AssistantPromptFieldDescriptor( entry.getKey(), diff --git a/src/main/java/it/cnr/isti/workflow/manager/assistant/FlowAssistantService.java b/src/main/java/it/cnr/isti/workflow/manager/assistant/FlowAssistantService.java index 0c1cac6..55bb699 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/assistant/FlowAssistantService.java +++ b/src/main/java/it/cnr/isti/workflow/manager/assistant/FlowAssistantService.java @@ -15,8 +15,8 @@ import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ObjectNode; import it.cnr.isti.workflow.manager.app.ObjectMapperHolder; import it.cnr.isti.workflow.manager.assistant.FlowAssistantPromptService.OperationMode; diff --git a/src/main/java/it/cnr/isti/workflow/manager/blocks/Block.java b/src/main/java/it/cnr/isti/workflow/manager/blocks/Block.java index ca6284d..7325665 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/blocks/Block.java +++ b/src/main/java/it/cnr/isti/workflow/manager/blocks/Block.java @@ -3,6 +3,8 @@ package it.cnr.isti.workflow.manager.blocks; import java.util.List; import java.util.UUID; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; @@ -20,13 +22,14 @@ import lombok.NonNull; import lombok.Singular; import lombok.ToString; -@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED, onConstructor_ = @JsonCreator) @Getter @ToString @JsonIgnoreProperties(ignoreUnknown = true) +@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) public class Block implements FlowNode { - final String id = UUID.randomUUID().toString(); + String id = UUID.randomUUID().toString(); Position position; diff --git a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/BlockConfiguration.java b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/BlockConfiguration.java index 6236c45..99e8bb8 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/BlockConfiguration.java +++ b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/BlockConfiguration.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver; +import tools.jackson.databind.annotation.JsonTypeIdResolver; import it.cnr.isti.workflow.manager.blocks.types.BlockType; import it.cnr.isti.workflow.manager.configurations.annotations.UiOrder; diff --git a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/ChatInteractionBlockConfiguration.java b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/ChatInteractionBlockConfiguration.java index 23a1046..74f5443 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/ChatInteractionBlockConfiguration.java +++ b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/ChatInteractionBlockConfiguration.java @@ -52,7 +52,7 @@ public class ChatInteractionBlockConfiguration extends BlockConfiguration inputs, - Boolean exposeHistory) { + @JsonProperty(value = "exposeHistory", required = false) Boolean exposeHistory) { super(name); this.llmDescriptor = llmDescriptor; this.goalDescription = goalDescription; diff --git a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/DynamicBlockConfigurationTypeResolver.java b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/DynamicBlockConfigurationTypeResolver.java index b5c4b00..aeb7172 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/DynamicBlockConfigurationTypeResolver.java +++ b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/DynamicBlockConfigurationTypeResolver.java @@ -1,9 +1,10 @@ package it.cnr.isti.workflow.manager.blocks.configurations; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.DatabindContext; +import tools.jackson.databind.jsontype.impl.TypeIdResolverBase; +import tools.jackson.databind.JavaType; +import tools.jackson.databind.DatabindContext; +import tools.jackson.core.JacksonException; import io.github.classgraph.ClassGraph; import io.github.classgraph.ScanResult; @@ -36,21 +37,33 @@ public class DynamicBlockConfigurationTypeResolver extends TypeIdResolverBase { } @Override - public String idFromValue(Object value) { + public String idFromValue(DatabindContext context, Object value) throws JacksonException { return classToId.get(value.getClass()); } @Override - public String idFromValueAndType(Object value, Class suggestedType) { + public String idFromValueAndType(DatabindContext context, Object value, Class suggestedType) throws JacksonException { return classToId.get(suggestedType); } @Override - public JavaType typeFromId(DatabindContext context, String id) { + public JavaType typeFromId(DatabindContext context, String id) throws JacksonException { if (CHAT_INTERACTION_LEGACY_CONFIGURATION_ID.equals(id)) { id = CHAT_INTERACTION_CONFIGURATION_ID; } Class clazz = idToClass.get(id); + if (clazz == null && id != null) { + String normalized = id; + int suffixSeparator = normalized.indexOf("__"); + if (suffixSeparator > 0) { + normalized = normalized.substring(0, suffixSeparator); + } + int lastDot = normalized.lastIndexOf('.'); + if (lastDot >= 0 && lastDot < normalized.length() - 1) { + normalized = normalized.substring(lastDot + 1); + } + clazz = idToClass.get(normalized); + } if (clazz == null) { throw new IllegalArgumentException("Unknown BlockConfiguration type id: " + id); } diff --git a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/HumanInteractiveBlockConfiguration.java b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/HumanInteractiveBlockConfiguration.java index 86d563b..2eab81b 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/HumanInteractiveBlockConfiguration.java +++ b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/HumanInteractiveBlockConfiguration.java @@ -28,7 +28,8 @@ public class HumanInteractiveBlockConfiguration extends BlockConfiguration entry : iterable(definitions.fields())) { + for (Entry entry : definitions.properties()) { definitionsByName .computeIfAbsent(entry.getKey(), ignored -> new DefinitionStats()) .register(entry.getValue()); @@ -96,8 +96,8 @@ public class JsonSchemaCatalogBundler { objectNode.put("$ref", rewritten); } } - for (JsonNode child : iterable(objectNode.elements())) { - rewriteSharedRefs(child, sharedNames); + for (Map.Entry child : objectNode.properties()) { + rewriteSharedRefs(child.getValue(), sharedNames); } return; } diff --git a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/JsonSchemaProducer.java b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/JsonSchemaProducer.java index 2ad4ba6..d17d432 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/JsonSchemaProducer.java +++ b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/JsonSchemaProducer.java @@ -17,15 +17,21 @@ import java.util.Map.Entry; import java.util.Queue; import java.util.Set; import java.util.Deque; +import java.util.Arrays; import org.springframework.stereotype.Component; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.kjetland.jackson.jsonSchema.JsonSchemaConfig; -import com.kjetland.jackson.jsonSchema.JsonSchemaGenerator; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; +import com.github.victools.jsonschema.generator.Option; +import com.github.victools.jsonschema.generator.OptionPreset; +import com.github.victools.jsonschema.generator.SchemaGenerator; +import com.github.victools.jsonschema.generator.SchemaGeneratorConfig; +import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder; +import com.github.victools.jsonschema.generator.SchemaVersion; +import com.github.victools.jsonschema.module.jackson.JacksonModule; +import com.github.victools.jsonschema.module.jackson.JacksonOption; import it.cnr.isti.workflow.manager.configurations.annotations.FieldRetriever; import it.cnr.isti.workflow.manager.configurations.annotations.LongText; @@ -41,22 +47,32 @@ import it.cnr.isti.workflow.manager.configurations.annotations.UiOrder; import it.cnr.isti.workflow.manager.configurations.annotations.UiOptionsFromNode; import it.cnr.isti.workflow.manager.configurations.annotations.UiUniqueItemsBy; import jakarta.validation.constraints.Size; +import com.fasterxml.jackson.annotation.JsonProperty; +import it.cnr.isti.workflow.manager.containers.configurations.ContainerConfiguration; @Component public class JsonSchemaProducer { - private final JsonSchemaGenerator schemaGenerator; + private final SchemaGenerator schemaGenerator; - public JsonSchemaProducer(ObjectMapper objectMapper) { - this.schemaGenerator = new JsonSchemaGenerator(objectMapper, JsonSchemaConfig.vanillaJsonSchemaDraft4()); + public JsonSchemaProducer() { + SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder( + SchemaVersion.DRAFT_7, OptionPreset.PLAIN_JSON) + .with(Option.DEFINITIONS_FOR_ALL_OBJECTS) + .with(new JacksonModule(JacksonOption.IGNORE_TYPE_INFO_TRANSFORM)); + this.schemaGenerator = new SchemaGenerator(configBuilder.build()); } public JsonNode generateSchemaNode(Class type) { - JsonNode schema = schemaGenerator.generateJsonSchema(type); + JsonNode schema = schemaGenerator.generateSchema(type); if (!(schema instanceof ObjectNode root)) { return schema; } + ensureDiscriminatorProperties(root, type); + applyRequiredMetadata(root, collectRequiredPropertyNames(type)); + applyEnumMetadata(root, collectEnumValues(type)); + Map, Map> retrieverMap = collectRetrieverMetadata(type); Map, Map> dynamicSchemaMap = collectDynamicSchemaMetadata(type); Map, Map> longTextMap = collectLongTextMetadata(type); @@ -102,12 +118,15 @@ public class JsonSchemaProducer { metadataClasses.addAll(sizeMap.keySet()); metadataClasses.addAll(schemaAllowedValuesMap.keySet()); metadataClasses.addAll(configurableAsInputMap.keySet()); - for (Entry entry : iterable(definitions.fields())) { + for (Entry entry : definitions.properties()) { if (!(entry.getValue() instanceof ObjectNode classSchema)) { continue; } Class matchedClass = findMatchingClass(entry.getKey(), metadataClasses); if (matchedClass != null) { + ensureDiscriminatorProperties(classSchema, matchedClass); + applyRequiredMetadata(classSchema, collectRequiredPropertyNames(matchedClass)); + applyEnumMetadata(classSchema, collectEnumValues(matchedClass)); applyRetrieverMetadata(classSchema, matchedClass, getMergedMetadata(retrieverMap, matchedClass)); applyDynamicSchemaMetadata(classSchema, getMergedMetadata(dynamicSchemaMap, matchedClass)); applyLongTextMetadata(classSchema, getMergedMetadata(longTextMap, matchedClass)); @@ -129,6 +148,150 @@ public class JsonSchemaProducer { return root; } + private void ensureDiscriminatorProperties(ObjectNode classSchema, Class ownerClass) { + JsonNode propsNode = classSchema.get("properties"); + if (!(propsNode instanceof ObjectNode properties)) { + return; + } + + if (BlockConfiguration.class.isAssignableFrom(ownerClass)) { + ensureStringProperty(properties, "type"); + } + if (ContainerConfiguration.class.isAssignableFrom(ownerClass)) { + ensureStringProperty(properties, "containerType"); + ensureStringProperty(properties, "type"); + } + } + + private void ensureStringProperty(ObjectNode properties, String propertyName) { + JsonNode existing = properties.get(propertyName); + if (existing instanceof ObjectNode) { + return; + } + ObjectNode property = properties.putObject(propertyName); + property.put("type", "string"); + } + + private Set collectRequiredPropertyNames(Class rootClass) { + Set required = new LinkedHashSet<>(); + Deque> hierarchy = new ArrayDeque<>(); + Class current = rootClass; + while (current != null && current != Object.class) { + hierarchy.addFirst(current); + current = current.getSuperclass(); + } + + for (Class clazz : hierarchy) { + for (Field field : clazz.getDeclaredFields()) { + JsonProperty jsonProperty = field.getAnnotation(JsonProperty.class); + if (jsonProperty != null && jsonProperty.required()) { + required.add(field.getName()); + } + } + if (clazz.isRecord()) { + for (RecordComponent component : clazz.getRecordComponents()) { + JsonProperty jsonProperty = component.getAnnotation(JsonProperty.class); + if (jsonProperty != null && jsonProperty.required()) { + required.add(component.getName()); + } + } + } + } + return required; + } + + private void applyRequiredMetadata(ObjectNode classSchema, Set requiredNames) { + if (requiredNames == null || requiredNames.isEmpty()) { + return; + } + + JsonNode propsNode = classSchema.get("properties"); + if (!(propsNode instanceof ObjectNode properties)) { + return; + } + + ArrayNode requiredArray; + JsonNode existingRequired = classSchema.get("required"); + if (existingRequired instanceof ArrayNode existingArray) { + requiredArray = existingArray; + } else { + requiredArray = classSchema.putArray("required"); + } + + Set currentRequired = new LinkedHashSet<>(); + for (JsonNode node : requiredArray) { + if (node.isTextual()) { + currentRequired.add(node.asText()); + } + } + + for (String requiredName : requiredNames) { + if (properties.has(requiredName) && currentRequired.add(requiredName)) { + requiredArray.add(requiredName); + } + } + } + + private Map> collectEnumValues(Class rootClass) { + Map> enumValues = new LinkedHashMap<>(); + Deque> hierarchy = new ArrayDeque<>(); + Class current = rootClass; + while (current != null && current != Object.class) { + hierarchy.addFirst(current); + current = current.getSuperclass(); + } + + for (Class clazz : hierarchy) { + for (Field field : clazz.getDeclaredFields()) { + if (field.getType().isEnum()) { + enumValues.put(field.getName(), enumConstantNames(field.getType())); + } + } + if (clazz.isRecord()) { + for (RecordComponent component : clazz.getRecordComponents()) { + if (component.getType().isEnum()) { + enumValues.put(component.getName(), enumConstantNames(component.getType())); + } + } + } + } + return enumValues; + } + + private List enumConstantNames(Class enumType) { + return Arrays.stream(enumType.getEnumConstants()) + .map(value -> ((Enum) value).name()) + .toList(); + } + + private void applyEnumMetadata(ObjectNode classSchema, Map> enumValues) { + if (enumValues == null || enumValues.isEmpty()) { + return; + } + + JsonNode propsNode = classSchema.get("properties"); + if (!(propsNode instanceof ObjectNode properties)) { + return; + } + + for (Entry> entry : enumValues.entrySet()) { + JsonNode propNode = properties.get(entry.getKey()); + if (!(propNode instanceof ObjectNode propertySchema)) { + continue; + } + + JsonNode existingEnum = propertySchema.get("enum"); + if (existingEnum instanceof ArrayNode existingArray && !existingArray.isEmpty()) { + continue; + } + + ArrayNode enumArray = propertySchema.putArray("enum"); + for (String value : entry.getValue()) { + enumArray.add(value); + } + } + } + private Map getMergedMetadata(Map, Map> metadataMap, Class type) { if (type == null || metadataMap == null || metadataMap.isEmpty()) { return Map.of(); @@ -918,7 +1081,7 @@ public class JsonSchemaProducer { } List propertyNames = new ArrayList<>(); - for (String propertyName : iterable(properties.fieldNames())) { + for (String propertyName : properties.propertyNames()) { propertyNames.add(propertyName); } if (propertyNames.isEmpty()) { @@ -1115,7 +1278,9 @@ public class JsonSchemaProducer { for (Class candidate : candidates) { if (candidate.getSimpleName().equals(schemaKey) || candidate.getName().equals(schemaKey) - || schemaKey.endsWith("." + candidate.getSimpleName())) { + || schemaKey.endsWith("." + candidate.getSimpleName()) + || schemaKey.startsWith(candidate.getSimpleName() + "__") + || schemaKey.startsWith(candidate.getName() + "__")) { return candidate; } } diff --git a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/LLMBlockConfiguration.java b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/LLMBlockConfiguration.java index 233626a..d3c848c 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/LLMBlockConfiguration.java +++ b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/LLMBlockConfiguration.java @@ -46,7 +46,9 @@ public class LLMBlockConfiguration extends BlockConfiguration { List skills = List.of(); @Builder - public LLMBlockConfiguration(@NonNull String name, @NonNull LLMDescriptor llmDescriptor, String prompt, + public LLMBlockConfiguration(@NonNull String name, + @JsonProperty(value = "llmDescriptor", required = false) LLMDescriptor llmDescriptor, + String prompt, List skills) { super(name); this.llmDescriptor = llmDescriptor; diff --git a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/MCPAgentBlockConfiguration.java b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/MCPAgentBlockConfiguration.java index f922407..d217b15 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/MCPAgentBlockConfiguration.java +++ b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/MCPAgentBlockConfiguration.java @@ -5,7 +5,7 @@ import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; import it.cnr.isti.workflow.manager.configurations.annotations.FieldRetriever; import it.cnr.isti.workflow.manager.configurations.annotations.LongText; diff --git a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/MCPAgentChatBlockConfiguration.java b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/MCPAgentChatBlockConfiguration.java index c4163a1..afdf179 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/MCPAgentChatBlockConfiguration.java +++ b/src/main/java/it/cnr/isti/workflow/manager/blocks/configurations/MCPAgentChatBlockConfiguration.java @@ -5,7 +5,7 @@ import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; import it.cnr.isti.workflow.manager.blocks.types.MCPAgentChatBlockType; import it.cnr.isti.workflow.manager.configurations.annotations.ConfigurableAsInput; diff --git a/src/main/java/it/cnr/isti/workflow/manager/containers/Container.java b/src/main/java/it/cnr/isti/workflow/manager/containers/Container.java index 453b8c5..5f6f62c 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/containers/Container.java +++ b/src/main/java/it/cnr/isti/workflow/manager/containers/Container.java @@ -6,6 +6,7 @@ import java.util.UUID; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonAlias; import it.cnr.isti.workflow.manager.blocks.Position; import it.cnr.isti.workflow.manager.containers.configurations.ContainerConfiguration; @@ -27,7 +28,7 @@ import lombok.ToString; @JsonIgnoreProperties(ignoreUnknown = true) public class Container implements FlowNode { - final String id = UUID.randomUUID().toString(); + String id = UUID.randomUUID().toString(); Position position; @@ -57,14 +58,16 @@ public class Container implements FlowNode { @Builder public Container(@NonNull ContainerConfiguration specificConfiguration, @Singular List inputs, - @Singular List outputs, @NonNull T type, Position position) { + @Singular List outputs, T type, + @JsonProperty("typeName") @JsonAlias("type") String resolvedTypeName, + Position position) { this.specificConfiguration = specificConfiguration; this.name = specificConfiguration.getName(); this.inputs = inputs; this.outputs = outputs; - this.typeName = type.getName(); + this.typeName = type != null ? type.getName() : resolvedTypeName; this.position = position; - this.type = type; + this.type = type != null ? type : (T) ContainerTypes.get(this.typeName); } @Override diff --git a/src/main/java/it/cnr/isti/workflow/manager/containers/configurations/ContainerConfiguration.java b/src/main/java/it/cnr/isti/workflow/manager/containers/configurations/ContainerConfiguration.java index febcf1c..589abf3 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/containers/configurations/ContainerConfiguration.java +++ b/src/main/java/it/cnr/isti/workflow/manager/containers/configurations/ContainerConfiguration.java @@ -3,7 +3,7 @@ package it.cnr.isti.workflow.manager.containers.configurations; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver; +import tools.jackson.databind.annotation.JsonTypeIdResolver; import it.cnr.isti.workflow.manager.configurations.annotations.FieldRetriever; import it.cnr.isti.workflow.manager.configurations.annotations.Structural; diff --git a/src/main/java/it/cnr/isti/workflow/manager/containers/configurations/DynamicContainerConfigurationTypeResolver.java b/src/main/java/it/cnr/isti/workflow/manager/containers/configurations/DynamicContainerConfigurationTypeResolver.java index 1a7b023..5f4a094 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/containers/configurations/DynamicContainerConfigurationTypeResolver.java +++ b/src/main/java/it/cnr/isti/workflow/manager/containers/configurations/DynamicContainerConfigurationTypeResolver.java @@ -1,9 +1,10 @@ package it.cnr.isti.workflow.manager.containers.configurations; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.databind.DatabindContext; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase; +import tools.jackson.databind.DatabindContext; +import tools.jackson.databind.JavaType; +import tools.jackson.databind.jsontype.impl.TypeIdResolverBase; +import tools.jackson.core.JacksonException; import io.github.classgraph.ClassGraph; import io.github.classgraph.ScanResult; @@ -32,18 +33,30 @@ public class DynamicContainerConfigurationTypeResolver extends TypeIdResolverBas } @Override - public String idFromValue(Object value) { + public String idFromValue(DatabindContext context, Object value) throws JacksonException { return classToId.get(value.getClass()); } @Override - public String idFromValueAndType(Object value, Class suggestedType) { + public String idFromValueAndType(DatabindContext context, Object value, Class suggestedType) throws JacksonException { return classToId.get(suggestedType); } @Override - public JavaType typeFromId(DatabindContext context, String id) { + public JavaType typeFromId(DatabindContext context, String id) throws JacksonException { Class clazz = idToClass.get(id); + if (clazz == null && id != null) { + String normalized = id; + int suffixSeparator = normalized.indexOf("__"); + if (suffixSeparator > 0) { + normalized = normalized.substring(0, suffixSeparator); + } + int lastDot = normalized.lastIndexOf('.'); + if (lastDot >= 0 && lastDot < normalized.length() - 1) { + normalized = normalized.substring(lastDot + 1); + } + clazz = idToClass.get(normalized); + } if (clazz == null) { throw new IllegalArgumentException("Unknown ContainerConfiguration type id: " + id); } diff --git a/src/main/java/it/cnr/isti/workflow/manager/controllers/BlocksController.java b/src/main/java/it/cnr/isti/workflow/manager/controllers/BlocksController.java index b2293d8..c3e25f5 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/controllers/BlocksController.java +++ b/src/main/java/it/cnr/isti/workflow/manager/controllers/BlocksController.java @@ -26,8 +26,8 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import org.springframework.web.server.ResponseStatusException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.core.JsonProcessingException; +import tools.jackson.databind.JsonNode; +import tools.jackson.core.JacksonException; @RestController @RequestMapping("/blocks") @@ -243,7 +243,7 @@ public class BlocksController { String blockAsJson = null; try { blockAsJson = ObjectMapperHolder.mapper.writeValueAsString(block); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { logger.error("Failed to serialize block to JSON", e); } logger.debug("Block created: {}", blockAsJson); diff --git a/src/main/java/it/cnr/isti/workflow/manager/controllers/ContainersController.java b/src/main/java/it/cnr/isti/workflow/manager/controllers/ContainersController.java index 79078e9..f124e21 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/controllers/ContainersController.java +++ b/src/main/java/it/cnr/isti/workflow/manager/controllers/ContainersController.java @@ -26,7 +26,7 @@ import it.cnr.isti.workflow.manager.blocks.configurations.JsonSchemaCatalogBundl import it.cnr.isti.workflow.manager.flows.model.FlowData; import it.cnr.isti.workflow.manager.flows.validation.ValidationError; import it.cnr.isti.workflow.manager.ios.IODescriptor; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; @RestController @RequestMapping("/containers") diff --git a/src/main/java/it/cnr/isti/workflow/manager/controllers/MCPServersController.java b/src/main/java/it/cnr/isti/workflow/manager/controllers/MCPServersController.java index 4d055e6..5f5bf66 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/controllers/MCPServersController.java +++ b/src/main/java/it/cnr/isti/workflow/manager/controllers/MCPServersController.java @@ -5,10 +5,10 @@ import java.util.List; import io.swagger.v3.oas.annotations.Operation; import org.springframework.http.HttpStatus; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/src/main/java/it/cnr/isti/workflow/manager/executions/executors/blocks/ConditionalExecutor.java b/src/main/java/it/cnr/isti/workflow/manager/executions/executors/blocks/ConditionalExecutor.java index 468fe22..882dc0b 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/executions/executors/blocks/ConditionalExecutor.java +++ b/src/main/java/it/cnr/isti/workflow/manager/executions/executors/blocks/ConditionalExecutor.java @@ -14,8 +14,8 @@ import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.ObjectMapper; import it.cnr.isti.workflow.manager.blocks.Block; import it.cnr.isti.workflow.manager.blocks.configurations.ConditionalBlockConfiguration; diff --git a/src/main/java/it/cnr/isti/workflow/manager/executions/executors/blocks/SwitchExecutor.java b/src/main/java/it/cnr/isti/workflow/manager/executions/executors/blocks/SwitchExecutor.java index fe5c475..6ea39f8 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/executions/executors/blocks/SwitchExecutor.java +++ b/src/main/java/it/cnr/isti/workflow/manager/executions/executors/blocks/SwitchExecutor.java @@ -15,8 +15,8 @@ import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.ObjectMapper; import it.cnr.isti.workflow.manager.blocks.Block; import it.cnr.isti.workflow.manager.blocks.configurations.SwitchBlockConfiguration; diff --git a/src/main/java/it/cnr/isti/workflow/manager/executions/executors/containers/LoopContainerExecutor.java b/src/main/java/it/cnr/isti/workflow/manager/executions/executors/containers/LoopContainerExecutor.java index b29cb07..191b978 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/executions/executors/containers/LoopContainerExecutor.java +++ b/src/main/java/it/cnr/isti/workflow/manager/executions/executors/containers/LoopContainerExecutor.java @@ -15,8 +15,8 @@ import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.ObjectMapper; import it.cnr.isti.workflow.manager.containers.Container; import it.cnr.isti.workflow.manager.containers.configurations.LoopContainerConfiguration; diff --git a/src/main/java/it/cnr/isti/workflow/manager/executions/persistence/ExecutionSnapshotConverter.java b/src/main/java/it/cnr/isti/workflow/manager/executions/persistence/ExecutionSnapshotConverter.java index 4278a2f..eee3b8f 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/executions/persistence/ExecutionSnapshotConverter.java +++ b/src/main/java/it/cnr/isti/workflow/manager/executions/persistence/ExecutionSnapshotConverter.java @@ -1,7 +1,9 @@ package it.cnr.isti.workflow.manager.executions.persistence; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import it.cnr.isti.workflow.manager.app.ObjectMapperHolder; import jakarta.persistence.AttributeConverter; @@ -10,7 +12,9 @@ import jakarta.persistence.Converter; @Converter(autoApply = false) public class ExecutionSnapshotConverter implements AttributeConverter { - private static final ObjectMapper FALLBACK_MAPPER = new ObjectMapper(); + private static final ObjectMapper FALLBACK_MAPPER = JsonMapper.builder() + .changeDefaultVisibility(vc -> vc.withFieldVisibility(JsonAutoDetect.Visibility.ANY)) + .build(); @Override public String convertToDatabaseColumn(ExecutionSnapshot snapshot) { @@ -19,7 +23,7 @@ public class ExecutionSnapshotConverter implements AttributeConverter { - private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final ObjectMapper objectMapper = JsonMapper.builder() + .changeDefaultVisibility(vc -> vc.withFieldVisibility(JsonAutoDetect.Visibility.ANY)) + .build(); @Override public String convertToDatabaseColumn(FlowData flowData) { @@ -18,7 +22,7 @@ public class FlowConverter implements AttributeConverter { } try { return objectMapper.writeValueAsString(flowData); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new IllegalArgumentException("Errore nella serializzazione di FlowData in JSON", e); } } diff --git a/src/main/java/it/cnr/isti/workflow/manager/flows/validation/ValidationErrorCodec.java b/src/main/java/it/cnr/isti/workflow/manager/flows/validation/ValidationErrorCodec.java index 819464d..105a096 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/flows/validation/ValidationErrorCodec.java +++ b/src/main/java/it/cnr/isti/workflow/manager/flows/validation/ValidationErrorCodec.java @@ -2,7 +2,7 @@ package it.cnr.isti.workflow.manager.flows.validation; import java.util.List; -import com.fasterxml.jackson.core.JsonProcessingException; +import tools.jackson.core.JacksonException; import it.cnr.isti.workflow.manager.app.ObjectMapperHolder; @@ -14,7 +14,7 @@ public final class ValidationErrorCodec { public static String encode(List errors) { try { return ObjectMapperHolder.mapper.writeValueAsString(errors); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new IllegalStateException("Unable to encode validation errors", e); } } diff --git a/src/main/java/it/cnr/isti/workflow/manager/llms/providers/ollama/InternalOllamaLLMProvider.java b/src/main/java/it/cnr/isti/workflow/manager/llms/providers/ollama/InternalOllamaLLMProvider.java index 64f08f4..ec94317 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/llms/providers/ollama/InternalOllamaLLMProvider.java +++ b/src/main/java/it/cnr/isti/workflow/manager/llms/providers/ollama/InternalOllamaLLMProvider.java @@ -11,7 +11,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import it.cnr.isti.workflow.manager.llms.ChatMessage; import it.cnr.isti.workflow.manager.llms.providers.LLMProvider; diff --git a/src/main/java/it/cnr/isti/workflow/manager/mcp/MCPAgentService.java b/src/main/java/it/cnr/isti/workflow/manager/mcp/MCPAgentService.java index 42fdeae..696aea0 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/mcp/MCPAgentService.java +++ b/src/main/java/it/cnr/isti/workflow/manager/mcp/MCPAgentService.java @@ -16,7 +16,7 @@ import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.util.StringUtils; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import reactor.core.publisher.Mono; diff --git a/src/main/java/it/cnr/isti/workflow/manager/mcp/MCPServersProvider.java b/src/main/java/it/cnr/isti/workflow/manager/mcp/MCPServersProvider.java index 3d2135d..5f614b2 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/mcp/MCPServersProvider.java +++ b/src/main/java/it/cnr/isti/workflow/manager/mcp/MCPServersProvider.java @@ -12,8 +12,8 @@ import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; @Component public class MCPServersProvider { diff --git a/src/main/java/it/cnr/isti/workflow/manager/skills/SkillsCatalogService.java b/src/main/java/it/cnr/isti/workflow/manager/skills/SkillsCatalogService.java index f4926ff..f9d2a24 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/skills/SkillsCatalogService.java +++ b/src/main/java/it/cnr/isti/workflow/manager/skills/SkillsCatalogService.java @@ -17,7 +17,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; @Component public class SkillsCatalogService { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 31fef99..aa65057 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,9 +1,5 @@ spring.application.name=workflow-manager -# Use Jackson 2 as the preferred JSON mapper for HTTP message conversion -# (project uses com.fasterxml.jackson annotations, Jackson 3 is incompatible) -spring.http.converters.preferred-json-mapper=jackson2 - #postgresql details spring.datasource.url=${DB_URL:jdbc:postgresql://localhost:5432/mydb} spring.datasource.username=${DB_USER:lucio} @@ -53,3 +49,7 @@ app.turnstile.secret=${TURNSTILE_SECRET:} app.turnstile.verify-url=${TURNSTILE_VERIFY_URL:https://challenges.cloudflare.com/turnstile/v0/siteverify} logging.level.it.cnr.isti.workflow.manager=DEBUG logging.level.root=ERROR + +# Jackson 3 changed default field visibility from ANY (Jackson 2) to PUBLIC_ONLY. +# Restore to ANY to match Jackson 2 behavior for package-private fields in domain model. +spring.jackson.visibility.field=any diff --git a/src/test/java/it/cnr/isti/workflow/manager/controllers/BlocksControllerTest.java b/src/test/java/it/cnr/isti/workflow/manager/controllers/BlocksControllerTest.java index cfb294f..df02046 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/controllers/BlocksControllerTest.java +++ b/src/test/java/it/cnr/isti/workflow/manager/controllers/BlocksControllerTest.java @@ -16,7 +16,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.TestPropertySource; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; import it.cnr.isti.workflow.manager.auth.repo.LoginEntity; import it.cnr.isti.workflow.manager.blocks.Block; @@ -549,9 +549,8 @@ public class BlocksControllerTest { JsonNode inputs = schema.path("properties").path("inputs"); assertEquals("name", inputs.path("x-ui-unique-by").asText()); JsonNode definitions = schema.has("definitions") ? schema.path("definitions") : schema.path("$defs"); - JsonNode inputDefinition = definitions.fields().next().getValue(); - for (java.util.Iterator> it = definitions.fields(); it.hasNext();) { - java.util.Map.Entry entry = it.next(); + JsonNode inputDefinition = definitions.properties().iterator().next().getValue(); + for (java.util.Map.Entry entry : definitions.properties()) { if (entry.getKey().contains("ChatInteractionInput")) { inputDefinition = entry.getValue(); break; @@ -922,9 +921,7 @@ public class BlocksControllerTest { } private List propertyNames(JsonNode objectNode) { - List names = new java.util.ArrayList<>(); - objectNode.fieldNames().forEachRemaining(names::add); - return names; + return objectNode.properties().stream().map(java.util.Map.Entry::getKey).collect(java.util.stream.Collectors.toList()); } private List arrayValues(JsonNode arrayNode) { diff --git a/src/test/java/it/cnr/isti/workflow/manager/controllers/ContainersControllerTest.java b/src/test/java/it/cnr/isti/workflow/manager/controllers/ContainersControllerTest.java index 64f7c95..2c3e3b4 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/controllers/ContainersControllerTest.java +++ b/src/test/java/it/cnr/isti/workflow/manager/controllers/ContainersControllerTest.java @@ -13,7 +13,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.TestPropertySource; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; import it.cnr.isti.workflow.manager.app.ObjectMapperHolder; import it.cnr.isti.workflow.manager.blocks.Block; @@ -527,9 +527,7 @@ public class ContainersControllerTest { } private List propertyNames(JsonNode objectNode) { - List names = new java.util.ArrayList<>(); - objectNode.fieldNames().forEachRemaining(names::add); - return names; + return objectNode.properties().stream().map(java.util.Map.Entry::getKey).collect(java.util.stream.Collectors.toList()); } private List arrayValues(JsonNode arrayNode) { diff --git a/src/test/java/it/cnr/isti/workflow/manager/controllers/ExecutionControllerTest.java b/src/test/java/it/cnr/isti/workflow/manager/controllers/ExecutionControllerTest.java index a0f9bba..470980e 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/controllers/ExecutionControllerTest.java +++ b/src/test/java/it/cnr/isti/workflow/manager/controllers/ExecutionControllerTest.java @@ -15,8 +15,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.test.context.TestPropertySource; import org.springframework.web.server.ResponseStatusException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; import it.cnr.isti.workflow.manager.app.ObjectMapperHolder; import it.cnr.isti.workflow.manager.auth.repo.LoginEntity; @@ -179,7 +179,7 @@ public class ExecutionControllerTest { try { logger.info("Execution object: {}", ObjectMapperHolder.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(executionObject)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new RuntimeException(e); } } @@ -408,7 +408,7 @@ public class ExecutionControllerTest { } @Test - public void executionPayloadDoesNotSerializeEvents() throws JsonProcessingException { + public void executionPayloadDoesNotSerializeEvents() throws JacksonException { LLMDescriptor llmDescriptor = LLMDescriptor.builder() .provider("testProvider") .model("testModel") diff --git a/src/test/java/it/cnr/isti/workflow/manager/controllers/FlowControllerTest.java b/src/test/java/it/cnr/isti/workflow/manager/controllers/FlowControllerTest.java index 5dc44ec..93f7863 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/controllers/FlowControllerTest.java +++ b/src/test/java/it/cnr/isti/workflow/manager/controllers/FlowControllerTest.java @@ -19,9 +19,9 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; import org.springframework.web.server.ResponseStatusException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; import it.cnr.isti.workflow.manager.app.ObjectMapperHolder; import it.cnr.isti.workflow.manager.auth.config.JwtUtil; @@ -125,7 +125,7 @@ public class FlowControllerTest { try { System.out.println(ObjectMapperHolder.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(retrieved)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new RuntimeException(e); } @@ -688,7 +688,7 @@ public class FlowControllerTest { } @Test - public void createFlowRejectsBlockTamperedOutsideFactory() throws JsonProcessingException { + public void createFlowRejectsBlockTamperedOutsideFactory() throws JacksonException { LLMDescriptor llmDescriptor = LLMDescriptor.builder() .provider("testProvider") .model("testModel") diff --git a/src/test/java/it/cnr/isti/workflow/manager/controllers/RetrieverControllerTest.java b/src/test/java/it/cnr/isti/workflow/manager/controllers/RetrieverControllerTest.java index d14ec34..5a04684 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/controllers/RetrieverControllerTest.java +++ b/src/test/java/it/cnr/isti/workflow/manager/controllers/RetrieverControllerTest.java @@ -75,7 +75,7 @@ public class RetrieverControllerTest { @Test public void customMcpServerSchemaExposesFreeConfiguration() { - com.fasterxml.jackson.databind.JsonNode schema = mcpServersController.getConfigurationSchema("CUSTOM", null); + tools.jackson.databind.JsonNode schema = mcpServersController.getConfigurationSchema("CUSTOM", null); assertEquals("object", schema.path("type").asText()); assertTrue(schema.path("additionalProperties").asBoolean()); diff --git a/src/test/java/it/cnr/isti/workflow/manager/executions/ExecutionTest.java b/src/test/java/it/cnr/isti/workflow/manager/executions/ExecutionTest.java index c0275e1..df2294e 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/executions/ExecutionTest.java +++ b/src/test/java/it/cnr/isti/workflow/manager/executions/ExecutionTest.java @@ -21,8 +21,8 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.util.ResourceUtils; import org.springframework.web.server.ResponseStatusException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.ObjectMapper; import it.cnr.isti.workflow.manager.app.ObjectMapperHolder; import it.cnr.isti.workflow.manager.blocks.configurations.BlockConfiguration; diff --git a/src/test/java/it/cnr/isti/workflow/manager/executions/ExecutionWithContainer.java b/src/test/java/it/cnr/isti/workflow/manager/executions/ExecutionWithContainer.java index 8f04141..f960212 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/executions/ExecutionWithContainer.java +++ b/src/test/java/it/cnr/isti/workflow/manager/executions/ExecutionWithContainer.java @@ -16,7 +16,7 @@ import org.springframework.context.annotation.Import; import org.springframework.test.context.TestPropertySource; import org.testcontainers.containers.GenericContainer; -import com.fasterxml.jackson.core.JsonProcessingException; +import tools.jackson.core.JacksonException; import it.cnr.isti.workflow.manager.app.ObjectMapperHolder; import it.cnr.isti.workflow.manager.configuration.TestContainersConfiguration; @@ -153,7 +153,7 @@ public class ExecutionWithContainer { try { logger.info("Execution object: {}", ObjectMapperHolder.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(execObject)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new RuntimeException(e); } @@ -168,7 +168,7 @@ public class ExecutionWithContainer { assertEquals(ExecutionStatus.CREATED, execObject.getContext().getStatus()); try { logger.info("Execution object in CREATED State: {}", ObjectMapperHolder.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(execObject)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new RuntimeException(e); } for (Step s : execObject.getContext().getSteps().values()) { @@ -181,7 +181,7 @@ public class ExecutionWithContainer { try { logger.info("Execution object in READY State: {}", ObjectMapperHolder.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(execObject)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new RuntimeException(e); } @@ -201,7 +201,7 @@ public class ExecutionWithContainer { try { logger.info("Execution object in WAITING State: {}", ObjectMapperHolder.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(execObject)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new RuntimeException(e); } diff --git a/src/test/java/it/cnr/isti/workflow/manager/flows/FlowTest.java b/src/test/java/it/cnr/isti/workflow/manager/flows/FlowTest.java index 080ca46..0fcd270 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/flows/FlowTest.java +++ b/src/test/java/it/cnr/isti/workflow/manager/flows/FlowTest.java @@ -5,7 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.TestPropertySource; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import it.cnr.isti.workflow.manager.app.ObjectMapperHolder; import it.cnr.isti.workflow.manager.flows.model.Flow; import it.cnr.isti.workflow.manager.flows.model.FlowCreateRequest; diff --git a/src/test/java/it/cnr/isti/workflow/manager/mcp/MCPAgentServiceTest.java b/src/test/java/it/cnr/isti/workflow/manager/mcp/MCPAgentServiceTest.java index 9e0519e..3898f5f 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/mcp/MCPAgentServiceTest.java +++ b/src/test/java/it/cnr/isti/workflow/manager/mcp/MCPAgentServiceTest.java @@ -14,7 +14,7 @@ import org.junit.jupiter.api.io.TempDir; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.web.reactive.function.client.WebClient; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import it.cnr.isti.workflow.manager.blocks.configurations.MCPAgentBlockConfiguration; diff --git a/src/test/java/it/cnr/isti/workflow/manager/mcp/MCPServersProviderTest.java b/src/test/java/it/cnr/isti/workflow/manager/mcp/MCPServersProviderTest.java index 3c4a0eb..78ac14c 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/mcp/MCPServersProviderTest.java +++ b/src/test/java/it/cnr/isti/workflow/manager/mcp/MCPServersProviderTest.java @@ -12,7 +12,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.springframework.core.io.DefaultResourceLoader; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; public class MCPServersProviderTest { diff --git a/src/test/java/it/cnr/isti/workflow/manager/ollama/OllamaService.java b/src/test/java/it/cnr/isti/workflow/manager/ollama/OllamaService.java index 910e23c..4147220 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/ollama/OllamaService.java +++ b/src/test/java/it/cnr/isti/workflow/manager/ollama/OllamaService.java @@ -6,7 +6,7 @@ import org.springframework.http.MediaType; import org.springframework.web.reactive.function.client.WebClient; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import it.cnr.isti.workflow.manager.app.ObjectMapperHolder; import reactor.core.publisher.Mono;