From 5507cb938ea681eb7fcad16b276041eb03648b62 Mon Sep 17 00:00:00 2001 From: Radek Davidek Date: Thu, 16 Oct 2025 13:06:41 +0200 Subject: [PATCH] api def parser --- pom.xml | 10 ++ .../migration/impl/v32/ImportToApicurio.java | 21 ++- .../migration/model/v32/ApiDefinition.java | 168 ++++++++++++++++++ 3 files changed, 193 insertions(+), 6 deletions(-) create mode 100644 src/main/java/cz/trask/migration/model/v32/ApiDefinition.java diff --git a/pom.xml b/pom.xml index d298a44..d27ee8f 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,16 @@ snakeyaml 2.4 + + com.fasterxml.jackson.core + jackson-databind + 2.19.2 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.19.2 + org.apache.commons commons-lang3 diff --git a/src/main/java/cz/trask/migration/impl/v32/ImportToApicurio.java b/src/main/java/cz/trask/migration/impl/v32/ImportToApicurio.java index bb77b4d..b7ffb75 100644 --- a/src/main/java/cz/trask/migration/impl/v32/ImportToApicurio.java +++ b/src/main/java/cz/trask/migration/impl/v32/ImportToApicurio.java @@ -14,7 +14,10 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.yaml.snakeyaml.Yaml; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; @@ -27,6 +30,7 @@ import cz.trask.migration.model.HttpResponse; import cz.trask.migration.model.RegisterResponse; import cz.trask.migration.model.TokenResponse; import cz.trask.migration.model.ZipEntryData; +import cz.trask.migration.model.v32.ApiDefinition; import io.apicurio.registry.rest.client.RegistryClient; import io.apicurio.registry.rest.client.RegistryClientFactory; import io.apicurio.registry.rest.client.exception.VersionAlreadyExistsException; @@ -197,7 +201,7 @@ public class ImportToApicurio extends AbstractProcess { api.getName(), fullDesc, null, null, null, new ByteArrayInputStream(swaggerObj.toString().getBytes()), references); - setMetaAndRules(meta, props, tagsList); + setArtifactMetaData(meta, props, tagsList); // Create the three required rules createRule(meta, "NONE", RuleType.COMPATIBILITY); createRule(meta, "NONE", RuleType.VALIDITY); @@ -219,7 +223,7 @@ public class ImportToApicurio extends AbstractProcess { ArtifactMetaData meta = client.updateArtifact(group, mainArtifactId, api.getVersion(), api.getName(), fullDesc, new ByteArrayInputStream(swaggerObj.toString().getBytes()), references); - setMetaAndRules(meta, props, tagsList); + setArtifactMetaData(meta, props, tagsList); } else { // Version already exists – no action needed log.warn("API {} with version {} already exists. Skipping import.", api.getContext(), @@ -321,6 +325,9 @@ public class ImportToApicurio extends AbstractProcess { List references = new ArrayList<>(); for (ZipEntryData entry : zipEntries) { String artifactId = api.getName() + "/" + api.getVersion() + "/" + entry.getName(); + + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + ApiDefinition apiDef = mapper.readValue(entry.getContent(), ApiDefinition.class); // Create the artifact (versioned) try (ByteArrayInputStream is = new ByteArrayInputStream(entry.getContent())) { @@ -328,7 +335,7 @@ public class ImportToApicurio extends AbstractProcess { api.getVersion(), is); Map props = new LinkedHashMap<>(); props.put(PARAM_SOURCE_APIM, VERSION_32); - setMetaAndRules(meta, props, Collections.emptyList()); + setArtifactMetaData(meta, props, Collections.emptyList()); } ArtifactReference ref = new ArtifactReference(); @@ -341,12 +348,14 @@ public class ImportToApicurio extends AbstractProcess { return references; } - private void setMetaAndRules(ArtifactMetaData meta, Map props, List tags) { + private void setArtifactMetaData(ArtifactMetaData meta, Map props, List tags) { EditableMetaData metaData = new EditableMetaData(); metaData.setName(meta.getName()); metaData.setDescription(meta.getDescription()); - metaData.setProperties(props); - metaData.setLabels(tags); + if (props != null) + metaData.setProperties(props); + if (tags != null) + metaData.setLabels(tags); client.updateArtifactMetaData(meta.getGroupId(), meta.getId(), metaData); } diff --git a/src/main/java/cz/trask/migration/model/v32/ApiDefinition.java b/src/main/java/cz/trask/migration/model/v32/ApiDefinition.java new file mode 100644 index 0000000..3dbbf14 --- /dev/null +++ b/src/main/java/cz/trask/migration/model/v32/ApiDefinition.java @@ -0,0 +1,168 @@ +package cz.trask.migration.model.v32; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +public class ApiDefinition { + + public static class CorsConfiguration { + @JsonProperty("corsConfigurationEnabled") + public boolean corsConfigurationEnabled; + + @JsonProperty("accessControlAllowOrigins") + public List accessControlAllowOrigins; + + @JsonProperty("accessControlAllowCredentials") + public boolean accessControlAllowCredentials; + + @JsonProperty("accessControlAllowHeaders") + public List accessControlAllowHeaders; + + @JsonProperty("accessControlAllowMethods") + public List accessControlAllowMethods; + } + + public static class Tier { + public String name; + public String displayName; + public String description; + public long requestsPerMin; + public long requestCount; + public int unitTime; + public String timeUnit; + public String tierPlan; + public boolean stopOnQuotaReached; + } + + public static class EndpointSecurity { + public static class SecurityConfig { + public String password; + public String tokenUrl; + public String clientId; + public String clientSecret; + public String customParameters; + public String type; + public String grantType; + public boolean enabled; + public String username; + } + + public SecurityConfig production; + public SecurityConfig sandbox; + } + + public static class Id { + public String providerName; + public String apiName; + public String version; + public long id; + } + + public static class ApiTierPolicy { + public String name; + public String displayName; + public String description; + public long requestsPerMin; + public long requestCount; + public int unitTime; + public String timeUnit; + public String tierPlan; + public boolean stopOnQuotaReached; + } + + public static class EndpointConfig { + public String endpoint_type; + public Endpoint sandbox_endpoints; + public Endpoint production_endpoints; + public EndpointSecurity endpoint_security; + + public static class Endpoint { + public String url; + } + + public static class EndpointSecurity { + public SecurityConfig production; + public SecurityConfig sandbox; + + public static class SecurityConfig { + public String password; + public String tokenUrl; + public String clientId; + public String clientSecret; + public String customParameters; + public String type; + public String grantType; + public boolean enabled; + public String username; + } + } + } + + // --- Hlavní pole --- + public Id id; + public String uuid; + public String type; + public String context; + public String contextTemplate; + public List tags; + public List documents; + public String lastUpdated; + public List availableTiers; + public List availableSubscriptionLevelPolicies; + public List uriTemplates; + public boolean apiHeaderChanged; + public boolean apiResourcePatternsChanged; + public String status; + public String visibility; + public List gatewayLabels; + public boolean endpointSecured; + public boolean endpointAuthDigest; + public String transports; + public String inSequence; + public boolean advertiseOnly; + public String subscriptionAvailability; + public CorsConfiguration corsConfiguration; + @JsonDeserialize(using = EndpointConfigDeserializer.class) + public EndpointConfig endpointConfig; + public String responseCache; + public int cacheTimeout; + public String implementation; + public String authorizationHeader; + public List scopes; + public boolean isDefaultVersion; + public boolean isPublishedDefaultVersion; + public List keyManagers; + public List environments; + public String createdTime; + public Map additionalProperties; + public Map monetizationProperties; + public boolean isMonetizationEnabled; + public List environmentList; + public String apiSecurity; + public List endpoints; + public boolean enableSchemaValidation; + public List apiCategories; + public boolean enableStore; + public String accessControl; + public double rating; + public boolean isLatest; + + public static class EndpointConfigDeserializer extends JsonDeserializer { + + @Override + public EndpointConfig deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + String json = p.getValueAsString(); // YAML string + ObjectMapper mapper = new ObjectMapper(); // běžný JSON mapper + return mapper.readValue(json, EndpointConfig.class); + } + } + +}