From fa1200473b576c04ff4f0d4315451bd6a3fae64c Mon Sep 17 00:00:00 2001 From: Radek Davidek Date: Wed, 22 Oct 2025 17:23:55 +0200 Subject: [PATCH] rewritten parsing of operations, added sequences to policies --- Calculator-1.0.0.zip | Bin 0 -> 4206 bytes pom.xml | 6 +- src/main/java/cz/trask/migration/ApiSync.java | 1 - .../impl/v45/ExportToWso2FromV32.java | 88 ++++++++++----- .../migration/mapper/ApiDefinitionMapper.java | 105 ++++++++++-------- 5 files changed, 118 insertions(+), 82 deletions(-) create mode 100644 Calculator-1.0.0.zip diff --git a/Calculator-1.0.0.zip b/Calculator-1.0.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..bb923e56a003039d740d9ad18034c73e30b69420 GIT binary patch literal 4206 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 N%axprY=imi?H{E=fB*mh literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index 0a84bd0..b395a1a 100644 --- a/pom.xml +++ b/pom.xml @@ -45,9 +45,9 @@ provided - org.wso2.carbon.apimgt - org.wso2.carbon.apimgt.impl - 9.31.86 + io.swagger + swagger-parser + 1.0.75 diff --git a/src/main/java/cz/trask/migration/ApiSync.java b/src/main/java/cz/trask/migration/ApiSync.java index af3ac8f..7562233 100644 --- a/src/main/java/cz/trask/migration/ApiSync.java +++ b/src/main/java/cz/trask/migration/ApiSync.java @@ -29,7 +29,6 @@ public class ApiSync { log.info("Export command selected."); ExportToWso2FromV32 exp = new ExportToWso2FromV32(); exp.process(); - log.error("Export command not implemented yet."); } else { log.error("Unknown command: " + sp.getCommand()); printHelp(); diff --git a/src/main/java/cz/trask/migration/impl/v45/ExportToWso2FromV32.java b/src/main/java/cz/trask/migration/impl/v45/ExportToWso2FromV32.java index dce7c21..313939d 100644 --- a/src/main/java/cz/trask/migration/impl/v45/ExportToWso2FromV32.java +++ b/src/main/java/cz/trask/migration/impl/v45/ExportToWso2FromV32.java @@ -9,13 +9,13 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.wso2.carbon.apimgt.api.APIDefinition; -import org.wso2.carbon.apimgt.impl.definitions.OASParserUtil; import cz.trask.migration.AbstractProcess; import cz.trask.migration.mapper.ApiDefinitionMapper; @@ -114,6 +114,13 @@ public class ExportToWso2FromV32 extends AbstractProcess { byte[] data = prepareApiZipFile32to45(client, ver, ref); String fileName = api.getName() + "-" + ver.getVersion() + ".zip"; + FileOutputStream fos = new FileOutputStream(fileName); + fos.write(data); + fos.flush(); + fos.close(); + + // System.exit(0); + if (data != null && data.length > 0 && fileName != null && !fileName.isEmpty()) { int responseCode = publishApiToWso2(fileName, data, tokenResponse); if (responseCode == 200 || responseCode == 201) { @@ -161,8 +168,8 @@ public class ExportToWso2FromV32 extends AbstractProcess { return responseCode; } - public static byte[] prepareApiZipFile32to45(RegistryClient client, SearchedVersion ver, - List ref) throws Exception { + public byte[] prepareApiZipFile32to45(RegistryClient client, SearchedVersion ver, List ref) + throws Exception { String baseDir = ver.getName() + "-" + ver.getVersion() + "/"; @@ -170,7 +177,6 @@ public class ExportToWso2FromV32 extends AbstractProcess { ZipOutputStream zos = new ZipOutputStream(baos)) { ApiDefinition32 apiDef = null; - APIDefinition openApiParser = null; String contentStr = null; for (ArtifactReference r : ref) { @@ -178,43 +184,65 @@ public class ExportToWso2FromV32 extends AbstractProcess { ArtifactMetaData amd = client.getArtifactMetaData(r.getGroupId(), r.getArtifactId()); - String subDir = ""; - - if (FileType.OPENAPI.toString().equals(amd.getGroupId())) { - subDir = "Definitions/"; - } else if (FileType.POLICY_IN.toString().equals(amd.getGroupId())) { - subDir = "Policies/"; - } - - String fileName = baseDir + subDir + r.getName(); - log.info(" - Adding file: {}", fileName); - byte[] content = client.getContentByGlobalId(amd.getGlobalId()).readAllBytes(); - if (FileType.APIDEF.toString().equals(amd.getGroupId())) { - apiDef = mapperYaml.readValue(content, ApiDefinition32.class); + String subDir = ""; + boolean appendFile = true; + String specialName = null; + + if (FileType.POLICY_IN.toString().equals(amd.getGroupId())) { + subDir = "Policies/"; + specialName = r.getName().replace(".xml", "_v1_common.j2"); + content = convertSequenceToPolicy(content); + } else if (FileType.POLICY_OUT.toString().equals(amd.getGroupId())) { + subDir = "Policies/"; + specialName = r.getName().replace(".xml", "_v1_common.j2"); + content = convertSequenceToPolicy(content); + } else if (FileType.POLICY_FAULT.toString().equals(amd.getGroupId())) { + subDir = "Policies/"; + specialName = r.getName().replace(".xml", "_v1_common.j2"); + content = convertSequenceToPolicy(content); } else if (FileType.OPENAPI.toString().equals(amd.getGroupId())) { + subDir = "Definitions/"; contentStr = new String(content); - if (contentStr != null) - openApiParser = OASParserUtil.getOASParser(contentStr); + } else if (FileType.CERTIFICATE.toString().equals(amd.getGroupId())) { + subDir = "Meta-information/"; + } else if (FileType.APIDEF.toString().equals(amd.getGroupId())) { + apiDef = mapperYaml.readValue(content, ApiDefinition32.class); + appendFile = false; } - if (apiDef != null && openApiParser != null) { - ApiDefinition45 apiDef45 = ApiDefinitionMapper.map(apiDef, openApiParser, contentStr); - content = mapperYaml.writeValueAsBytes(apiDef45); - FileOutputStream fos = new FileOutputStream("api.yaml"); - fos.write(content); - fos.flush(); - fos.close(); - System.exit(0); - } + String fileName = baseDir + subDir + (specialName != null ? specialName : r.getName()); + log.info(" - Adding file: {}", fileName); - zos.putNextEntry(new ZipEntry(fileName)); + if (appendFile) { + zos.putNextEntry(new ZipEntry(fileName)); + zos.write(content); + zos.closeEntry(); + } + } + if (apiDef != null && contentStr != null) { + ApiDefinition45 apiDef45 = ApiDefinitionMapper.map(apiDef, contentStr); + byte[] content = mapperYaml.writeValueAsBytes(apiDef45); + zos.putNextEntry(new ZipEntry(baseDir.concat("api.yaml"))); zos.write(content); zos.closeEntry(); } + zos.finish(); return baos.toByteArray(); } } + + private byte[] convertSequenceToPolicy(byte[] content) throws Exception { + if (content != null && content.length > 0) { + Pattern pattern = Pattern.compile("]*>(.*?)", Pattern.DOTALL); + Matcher matcher = pattern.matcher(new String(content)); + + // Replace the entire sequence block with its inner content + String result = matcher.replaceAll("$1").trim(); + return result.getBytes(); + } + return null; + } } diff --git a/src/main/java/cz/trask/migration/mapper/ApiDefinitionMapper.java b/src/main/java/cz/trask/migration/mapper/ApiDefinitionMapper.java index a080a07..2b3a32b 100644 --- a/src/main/java/cz/trask/migration/mapper/ApiDefinitionMapper.java +++ b/src/main/java/cz/trask/migration/mapper/ApiDefinitionMapper.java @@ -3,27 +3,25 @@ package cz.trask.migration.mapper; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.stream.Collectors; -import org.wso2.carbon.apimgt.api.APIDefinition; -import org.wso2.carbon.apimgt.api.model.Scope; -import org.wso2.carbon.apimgt.api.model.URITemplate; - import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; import cz.trask.migration.AbstractProcess; import cz.trask.migration.model.ApiDefinition32; import cz.trask.migration.model.ApiDefinition45; import cz.trask.migration.model.ApiDefinition45.ApiPolicies; +import cz.trask.migration.model.ApiDefinition45.Operation; +import cz.trask.migration.model.ApiDefinition45.OperationPolicies; import cz.trask.migration.util.CredentialsDecoder; public class ApiDefinitionMapper { - public static ApiDefinition45 map(ApiDefinition32 oldApi, APIDefinition openApiParser, String swagger) - throws Exception { + public static ApiDefinition45 map(ApiDefinition32 oldApi, String swagger) throws Exception { if (oldApi == null) return null; @@ -107,6 +105,7 @@ public class ApiDefinitionMapper { // ---------- API policies ---------- data.setApiPolicies(mapApiPolicies(oldApi)); + // data.setApiPolicies(mapApiPolicies(null)); // ---------- key managers ---------- data.setKeyManagers(oldApi.getKeyManagers()); @@ -134,8 +133,7 @@ public class ApiDefinitionMapper { data.setSubscriptionAvailableTenants(Collections.emptyList()); // ---------- operations ---------- - Set uriTemplates = openApiParser.getURITemplates(swagger); - data.setOperations(mapOperations(uriTemplates)); + data.setOperations(mapOperations(swagger)); // ---------- additional metadata ---------- data.setCreatedTime(oldApi.getCreatedTime()); @@ -151,18 +149,18 @@ public class ApiDefinitionMapper { private static ApiPolicies mapApiPolicies(ApiDefinition32 oldApi) { ApiDefinition45.ApiPolicies apiPolicies = new ApiDefinition45.ApiPolicies(); // ---------- request policies ---------- - if (oldApi.getInSequence() != null && !oldApi.getInSequence().isEmpty()) { + if (oldApi != null && oldApi.getInSequence() != null && !oldApi.getInSequence().isEmpty()) { ApiDefinition45.Policy requestPolicy = new ApiDefinition45.Policy(); requestPolicy.setPolicyName(oldApi.getInSequence()); - requestPolicy.setPolicyType("common"); - requestPolicy.setPolicyVersion("v1"); + requestPolicy.setPolicyType(""); + requestPolicy.setPolicyVersion(""); requestPolicy.setPolicyId(""); requestPolicy.setParameters(Collections.emptyMap()); apiPolicies.setRequest(List.of(requestPolicy)); } else apiPolicies.setRequest(Collections.emptyList()); // ---------- response policies ---------- - if (oldApi.getOutSequence() != null && !oldApi.getOutSequence().isEmpty()) { + if (oldApi != null && oldApi.getOutSequence() != null && !oldApi.getOutSequence().isEmpty()) { ApiDefinition45.Policy requestPolicy = new ApiDefinition45.Policy(); requestPolicy.setPolicyName(oldApi.getOutSequence()); requestPolicy.setPolicyType("common"); @@ -173,7 +171,7 @@ public class ApiDefinitionMapper { } else apiPolicies.setResponse(Collections.emptyList()); // ---------- fault policies ---------- - if (oldApi.getFaultSequence() != null && !oldApi.getFaultSequence().isEmpty()) { + if (oldApi != null && oldApi.getFaultSequence() != null && !oldApi.getFaultSequence().isEmpty()) { ApiDefinition45.Policy requestPolicy = new ApiDefinition45.Policy(); requestPolicy.setPolicyName(oldApi.getFaultSequence()); requestPolicy.setPolicyType("common"); @@ -236,7 +234,8 @@ public class ApiDefinitionMapper { newSec.setType(oldSec.getType()); newSec.setTokenUrl(oldSec.getTokenUrl()); newSec.setClientId(oldSec.getClientId()); - newSec.setClientSecret(CredentialsDecoder.decodeCredentials(oldSec.getClientSecret(), AbstractProcess.PRIVATE_KEY_APIM_32)); + newSec.setClientSecret( + CredentialsDecoder.decodeCredentials(oldSec.getClientSecret(), AbstractProcess.PRIVATE_KEY_APIM_32)); newSec.setUsername(oldSec.getUsername()); newSec.setPassword(oldSec.getPassword()); newSec.setGrantType(oldSec.getGrantType()); @@ -249,8 +248,9 @@ public class ApiDefinitionMapper { // ---------- parse customParameters JSON string ---------- if (oldSec.getCustomParameters() != null && !oldSec.getCustomParameters().isEmpty()) { try { - Map map = AbstractProcess.mapperYaml.readValue(oldSec.getCustomParameters(), new TypeReference<>() { - }); + Map map = AbstractProcess.mapperYaml.readValue(oldSec.getCustomParameters(), + new TypeReference<>() { + }); newSec.setCustomParameters(map); } catch (Exception e) { newSec.setCustomParameters(Collections.emptyMap()); @@ -265,37 +265,46 @@ public class ApiDefinitionMapper { return newSec; } - private static List mapOperations(Set uriTemplates) { - if (uriTemplates == null || uriTemplates.isEmpty()) - return Collections.emptyList(); - - List operations = new ArrayList<>(); - - for (URITemplate uriTemplate : uriTemplates) { - - ApiDefinition45.Operation op = new ApiDefinition45.Operation(); - op.setId(""); - op.setAuthType(uriTemplate.getAuthType()); - op.setThrottlingPolicy(uriTemplate.getThrottlingTier()); - op.setVerb(uriTemplate.getHTTPVerb()); - op.setTarget(uriTemplate.getUriTemplate()); - op.setScopes(new ArrayList<>()); - for (Scope scope : uriTemplate.getScopes()) { - if (scope != null && scope.getKey() != null && !scope.getKey().isEmpty()) { - op.getScopes().add(scope.getName()); - } - } - - op.setUsedProductIds(new ArrayList<>()); - - ApiDefinition45.OperationPolicies opPolicies = new ApiDefinition45.OperationPolicies(); - opPolicies.setRequest(Collections.emptyList()); - opPolicies.setResponse(Collections.emptyList()); - opPolicies.setFault(Collections.emptyList()); - op.setOperationPolicies(opPolicies); - - operations.add(op); + public static List mapOperations(String swaggerYamlString) throws Exception { + JsonNode root = AbstractProcess.mapperYaml.readTree(swaggerYamlString); + JsonNode pathsNode = root.get("paths"); + if (pathsNode == null || !pathsNode.isObject()) { + throw new IllegalArgumentException("Swagger YAML neobsahuje sekci 'paths'."); } - return operations; + + List operationsList = new ArrayList<>(); + + Iterator> pathIter = pathsNode.fields(); + while (pathIter.hasNext()) { + Map.Entry pathEntry = pathIter.next(); + String path = pathEntry.getKey(); + JsonNode methodsNode = pathEntry.getValue(); + + Iterator> methodIter = methodsNode.fields(); + while (methodIter.hasNext()) { + Map.Entry methodEntry = methodIter.next(); + String verb = methodEntry.getKey().toUpperCase(); + JsonNode methodDef = methodEntry.getValue(); + + Operation op = new Operation(); + op.setId(""); + op.setTarget(path); + op.setVerb(verb); + op.setAuthType(methodDef.path("x-auth-type").asText("")); + op.setThrottlingPolicy(methodDef.path("x-throttling-tier").asText("")); + op.setScopes(new ArrayList<>()); + op.setUsedProductIds(new ArrayList<>()); + + OperationPolicies policies = new OperationPolicies(); + policies.setRequest(new ArrayList<>()); + policies.setResponse(new ArrayList<>()); + policies.setFault(new ArrayList<>()); + op.setOperationPolicies(policies); + + operationsList.add(op); + } + } + + return operationsList; } }