diff --git a/src/main/java/cz/trask/migration/AbstractProcess.java b/src/main/java/cz/trask/migration/AbstractProcess.java index 7ea4960..5c46547 100644 --- a/src/main/java/cz/trask/migration/AbstractProcess.java +++ b/src/main/java/cz/trask/migration/AbstractProcess.java @@ -1,16 +1,22 @@ package cz.trask.migration; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.net.URLEncoder; import java.security.KeyStore; +import java.text.Normalizer; +import java.util.ArrayList; import java.util.Base64; import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import javax.net.ssl.HttpsURLConnection; @@ -26,15 +32,18 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; import cz.trask.migration.config.ConfigManager; +import cz.trask.migration.model.APIInfo; import cz.trask.migration.model.APIList; import cz.trask.migration.model.ApplicationConfig; import cz.trask.migration.model.ApplicationConfig.Wso2Endpoints; 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 io.apicurio.registry.rest.client.RegistryClient; import io.apicurio.registry.rest.client.RegistryClientFactory; import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; +import io.apicurio.registry.rest.v2.beans.ArtifactReference; import io.apicurio.registry.rest.v2.beans.EditableMetaData; import io.apicurio.registry.rest.v2.beans.Rule; import io.apicurio.registry.types.RuleType; @@ -479,10 +488,10 @@ public abstract class AbstractProcess { return resp; } - protected void setArtifactMetaData(ArtifactMetaData meta, Map props) { + protected void setArtifactMetaData(ArtifactMetaData meta, String name, String description, Map props) { EditableMetaData metaData = new EditableMetaData(); - metaData.setName(meta.getName()); - metaData.setDescription(meta.getDescription()); + metaData.setName(name); + metaData.setDescription(description); if (props != null) metaData.setProperties(props); @@ -516,4 +525,61 @@ public abstract class AbstractProcess { "Basic ".concat(Base64.getEncoder().encodeToString(username.concat(":").concat(password).getBytes()))); return httpHeaders; } + + protected void addEndpointsToProps(Map props, Map apiMap) { + if (apiMap == null || !apiMap.containsKey("endpointURLs")) + return; + @SuppressWarnings("unchecked") + List> envs = (List>) apiMap.get("endpointURLs"); + for (Map env : envs) { + @SuppressWarnings("unchecked") + Map urls = (Map) env.get("URLs"); + if (urls == null) + continue; + urls.forEach((k, v) -> { + if (v != null) + props.put(k + " Endpoint", v); + }); + } + } + + protected void addTagsToProps(Map props, List tags) { + if (tags != null && !tags.isEmpty()) { + props.put("tags", String.join(", ", tags)); + } + } + + protected List createReferencesFromZip(List zipEntries, APIInfo api) + throws IOException { + + List references = new ArrayList<>(); + for (ZipEntryData entry : zipEntries) { + String artifactId = convertToAscii(api.getName() + "/" + api.getVersion() + "/" + entry.getName()); + + log.debug("Creating artifact reference for entry: {} with artifactId: {}", entry.getName(), artifactId); + + try (ByteArrayInputStream is = new ByteArrayInputStream(entry.getContent())) { + ArtifactMetaData meta = client.createArtifactWithVersion(entry.getType().toString(), artifactId, api.getVersion(), is); + Map props = new LinkedHashMap<>(); + props.put(PARAM_SOURCE_APIM, VERSION_32); + setArtifactMetaData(meta, entry.getName(), null, props); + } + + ArtifactReference ref = new ArtifactReference(); + ref.setName(entry.getName()); + ref.setGroupId(entry.getType().toString()); + ref.setArtifactId(artifactId); + ref.setVersion(api.getVersion()); + references.add(ref); + } + return references; + } + + private String convertToAscii(String input) { + if (input == null) { + return null; + } + String normalized = Normalizer.normalize(input, Normalizer.Form.NFD); + return normalized.replaceAll("[^\\x00-\\x7F]", "").replace(" ", "_"); + } } diff --git a/src/main/java/cz/trask/migration/impl/v32/Wso2v32ToApicurio.java b/src/main/java/cz/trask/migration/impl/v32/Wso2v32ToApicurio.java index 46a3cfb..db166a4 100644 --- a/src/main/java/cz/trask/migration/impl/v32/Wso2v32ToApicurio.java +++ b/src/main/java/cz/trask/migration/impl/v32/Wso2v32ToApicurio.java @@ -170,7 +170,7 @@ public class Wso2v32ToApicurio extends AbstractProcess { api.getName(), fullDesc, null, null, null, new ByteArrayInputStream(swaggerObj.toString().getBytes()), references); - setArtifactMetaData(meta, props); + setArtifactMetaData(meta, api.getName(), fullDesc,props); // Create the three required rules createRule(meta, "NONE", RuleType.COMPATIBILITY); createRule(meta, "NONE", RuleType.VALIDITY); @@ -193,7 +193,7 @@ public class Wso2v32ToApicurio extends AbstractProcess { ArtifactMetaData meta = client.updateArtifact(group, mainArtifactId, api.getVersion(), api.getName(), fullDesc, new ByteArrayInputStream(swaggerObj.toString().getBytes()), references); - setArtifactMetaData(meta, props); + setArtifactMetaData(meta, api.getName(), fullDesc, props); } else { // Version already exists – no action needed log.warn("API {} with version {} already exists. Skipping import.", api.getContext(), @@ -263,54 +263,6 @@ public class Wso2v32ToApicurio extends AbstractProcess { } } - private void addEndpointsToProps(Map props, Map apiMap) { - if (apiMap == null || !apiMap.containsKey("endpointURLs")) - return; - @SuppressWarnings("unchecked") - List> envs = (List>) apiMap.get("endpointURLs"); - for (Map env : envs) { - @SuppressWarnings("unchecked") - Map urls = (Map) env.get("URLs"); - if (urls == null) - continue; - urls.forEach((k, v) -> { - if (v != null) - props.put(k + " Endpoint", v); - }); - } - } - - private void addTagsToProps(Map props, List tags) { - if (tags != null && !tags.isEmpty()) { - props.put("tags", String.join(", ", tags)); - } - } - - private List createReferencesFromZip(List zipEntries, APIInfo api) - throws IOException { - - List references = new ArrayList<>(); - for (ZipEntryData entry : zipEntries) { - String artifactId = api.getName() + "/" + api.getVersion() + "/" + entry.getName(); - - try (ByteArrayInputStream is = new ByteArrayInputStream(entry.getContent())) { - ArtifactMetaData meta = client.createArtifactWithVersion(entry.getType().toString(), artifactId, - api.getVersion(), is); - Map props = new LinkedHashMap<>(); - props.put(PARAM_SOURCE_APIM, VERSION_32); - setArtifactMetaData(meta, props); - } - - ArtifactReference ref = new ArtifactReference(); - ref.setName(entry.getName()); - ref.setGroupId(entry.getType().toString()); - ref.setArtifactId(artifactId); - ref.setVersion(api.getVersion()); - references.add(ref); - } - return references; - } - private void addSubscriptionsToReferences(List references, Subscriptions subs, APIInfo api) throws Exception { if (subs == null || subs.getList() == null || subs.getList().isEmpty()) @@ -325,7 +277,7 @@ public class Wso2v32ToApicurio extends AbstractProcess { api.getVersion(), is); Map props = new LinkedHashMap<>(); props.put(PARAM_SOURCE_APIM, VERSION_32); - setArtifactMetaData(meta, props); + setArtifactMetaData(meta, artifactId, null, props); } ArtifactReference ref = new ArtifactReference(); diff --git a/src/main/java/cz/trask/migration/impl/v32/Wso2v32ToApicurioFromDir.java b/src/main/java/cz/trask/migration/impl/v32/Wso2v32ToApicurioFromDir.java index dc14d66..3b5b709 100644 --- a/src/main/java/cz/trask/migration/impl/v32/Wso2v32ToApicurioFromDir.java +++ b/src/main/java/cz/trask/migration/impl/v32/Wso2v32ToApicurioFromDir.java @@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.text.Normalizer; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -13,7 +14,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import cz.trask.migration.AbstractProcess; @@ -21,9 +21,6 @@ import cz.trask.migration.model.APIInfo; import cz.trask.migration.model.FileType; import cz.trask.migration.model.ZipEntryData; import cz.trask.migration.model.v32.ApiDefinition32; -import cz.trask.migration.model.v32.Subscriptions; -import cz.trask.migration.model.v32.Subscriptions.ApplicationInfo; -import cz.trask.migration.model.v32.Subscriptions.Subscription; import io.apicurio.registry.rest.client.exception.VersionAlreadyExistsException; import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; import io.apicurio.registry.rest.v2.beans.ArtifactReference; @@ -135,7 +132,6 @@ public class Wso2v32ToApicurioFromDir extends AbstractProcess { + devPortUrl; ObjectNode swaggerObj = mapperYaml.valueToTree(swaggerMap); - updateSwagger(swaggerObj, apiDef, fullDesc); String group = config.getApicurio().getDefaultApiGroup(); String mainArtifactId = api.getName() + api.getContext(); @@ -160,7 +156,7 @@ public class Wso2v32ToApicurioFromDir extends AbstractProcess { api.getName(), fullDesc, null, null, null, new ByteArrayInputStream(swaggerObj.toString().getBytes()), references); - setArtifactMetaData(meta, props); + setArtifactMetaData(meta, api.getName(), fullDesc, props); // Create the three required rules createRule(meta, "NONE", RuleType.COMPATIBILITY); createRule(meta, "NONE", RuleType.VALIDITY); @@ -185,7 +181,7 @@ public class Wso2v32ToApicurioFromDir extends AbstractProcess { api.getVersion(), api.getName(), fullDesc, new ByteArrayInputStream(swaggerObj.toString().getBytes()), references); - setArtifactMetaData(meta, props); + setArtifactMetaData(meta, api.getName(), fullDesc,props); } else { // Version already exists – no action needed log.warn("API {} with version {} already exists. Skipping import.", @@ -206,86 +202,4 @@ public class Wso2v32ToApicurioFromDir extends AbstractProcess { } } - /* --------------------------------------------------------------------- */ - /* Helper methods */ - /* --------------------------------------------------------------------- */ - - private void updateSwagger(ObjectNode swagger, ApiDefinition32 apiDef, String description) { - // Update "info.description" - ObjectNode info = (ObjectNode) swagger.get("info"); - if (info != null) { - info.put("description", description); - } - - // Build "servers" array - ArrayNode servers = mapper.createArrayNode(); - - Map endpoints = apiDef.getEndpointConfig(); - if (endpoints != null) { - - Map prodEps = (Map) endpoints.get("production_endpoints"); - Map sandEps = (Map) endpoints.get("sandbox_endpoints"); - - - ObjectNode server = mapper.createObjectNode(); - if (k.equals("https") || k.equals("wss")) { - server.put("url", v); - } - server.put("description", "Gateway: " + env.getOrDefault("environmentName", "")); - servers.add(server); - } - } - - // Replace "servers" node - swagger.set("servers",servers); - - } - - private void addEndpointsToProps(Map props, Map apiMap) { - if (apiMap == null || !apiMap.containsKey("endpointURLs")) - return; - @SuppressWarnings("unchecked") - List> envs = (List>) apiMap.get("endpointURLs"); - for (Map env : envs) { - @SuppressWarnings("unchecked") - Map urls = (Map) env.get("URLs"); - if (urls == null) - continue; - urls.forEach((k, v) -> { - if (v != null) - props.put(k + " Endpoint", v); - }); - } - } - - private void addTagsToProps(Map props, List tags) { - if (tags != null && !tags.isEmpty()) { - props.put("tags", String.join(", ", tags)); - } - } - - private List createReferencesFromZip(List zipEntries, APIInfo api) - throws IOException { - - List references = new ArrayList<>(); - for (ZipEntryData entry : zipEntries) { - String artifactId = api.getName() + "/" + api.getVersion() + "/" + entry.getName(); - - try (ByteArrayInputStream is = new ByteArrayInputStream(entry.getContent())) { - ArtifactMetaData meta = client.createArtifactWithVersion(entry.getType().toString(), artifactId, - api.getVersion(), is); - Map props = new LinkedHashMap<>(); - props.put(PARAM_SOURCE_APIM, VERSION_32); - setArtifactMetaData(meta, props); - } - - ArtifactReference ref = new ArtifactReference(); - ref.setName(entry.getName()); - ref.setGroupId(entry.getType().toString()); - ref.setArtifactId(artifactId); - ref.setVersion(api.getVersion()); - references.add(ref); - } - return references; - } } diff --git a/src/main/java/cz/trask/migration/impl/v32/ZipUtils.java b/src/main/java/cz/trask/migration/impl/v32/ZipUtils.java index 476e64f..af32e77 100644 --- a/src/main/java/cz/trask/migration/impl/v32/ZipUtils.java +++ b/src/main/java/cz/trask/migration/impl/v32/ZipUtils.java @@ -55,9 +55,10 @@ public class ZipUtils { return FileType.POLICY_FAULT; } else if (lowerFileName.endsWith("/meta-information/endpoint_certificates.yaml")) { return FileType.CERTIFICATE; + } else if (lowerFileName.contains("/docs/filecontents/")) { + return FileType.DOCUMENTATION_FILE; } else if (lowerFileName.contains("/docs/")) { return FileType.DOCUMENTATION; - } return FileType.UNKNOWN; } diff --git a/src/main/java/cz/trask/migration/model/FileType.java b/src/main/java/cz/trask/migration/model/FileType.java index 2ba9ea3..123d103 100644 --- a/src/main/java/cz/trask/migration/model/FileType.java +++ b/src/main/java/cz/trask/migration/model/FileType.java @@ -1,5 +1,5 @@ package cz.trask.migration.model; public enum FileType { - APIDEF, OPENAPI, WSDL, POLICY_IN, POLICY_OUT, POLICY_FAULT, CERTIFICATE, SUBSCRIPTIONS, DOCUMENTATION, UNKNOWN + APIDEF, OPENAPI, WSDL, POLICY_IN, POLICY_OUT, POLICY_FAULT, CERTIFICATE, SUBSCRIPTIONS, DOCUMENTATION, DOCUMENTATION_FILE, UNKNOWN }