rewritten parsing of operations, added sequences to policies

This commit is contained in:
Radek Davidek 2025-10-22 17:23:55 +02:00
parent 8d7bc54713
commit fa1200473b
5 changed files with 118 additions and 82 deletions

BIN
Calculator-1.0.0.zip Normal file

Binary file not shown.

View File

@ -45,9 +45,9 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.apimgt</groupId>
<artifactId>org.wso2.carbon.apimgt.impl</artifactId>
<version>9.31.86</version>
<groupId>io.swagger</groupId>
<artifactId>swagger-parser</artifactId>
<version>1.0.75</version>
</dependency>
</dependencies>

View File

@ -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();

View File

@ -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<ArtifactReference> ref) throws Exception {
public byte[] prepareApiZipFile32to45(RegistryClient client, SearchedVersion ver, List<ArtifactReference> 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);
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("<sequence[^>]*>(.*?)</sequence>", 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;
}
}

View File

@ -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<URITemplate> 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,7 +248,8 @@ public class ApiDefinitionMapper {
// ---------- parse customParameters JSON string ----------
if (oldSec.getCustomParameters() != null && !oldSec.getCustomParameters().isEmpty()) {
try {
Map<String, Object> map = AbstractProcess.mapperYaml.readValue(oldSec.getCustomParameters(), new TypeReference<>() {
Map<String, Object> map = AbstractProcess.mapperYaml.readValue(oldSec.getCustomParameters(),
new TypeReference<>() {
});
newSec.setCustomParameters(map);
} catch (Exception e) {
@ -265,37 +265,46 @@ public class ApiDefinitionMapper {
return newSec;
}
private static List<ApiDefinition45.Operation> mapOperations(Set<URITemplate> uriTemplates) {
if (uriTemplates == null || uriTemplates.isEmpty())
return Collections.emptyList();
public static List<Operation> 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'.");
}
List<ApiDefinition45.Operation> operations = new ArrayList<>();
List<Operation> operationsList = new ArrayList<>();
for (URITemplate uriTemplate : uriTemplates) {
Iterator<Map.Entry<String, JsonNode>> pathIter = pathsNode.fields();
while (pathIter.hasNext()) {
Map.Entry<String, JsonNode> pathEntry = pathIter.next();
String path = pathEntry.getKey();
JsonNode methodsNode = pathEntry.getValue();
ApiDefinition45.Operation op = new ApiDefinition45.Operation();
Iterator<Map.Entry<String, JsonNode>> methodIter = methodsNode.fields();
while (methodIter.hasNext()) {
Map.Entry<String, JsonNode> methodEntry = methodIter.next();
String verb = methodEntry.getKey().toUpperCase();
JsonNode methodDef = methodEntry.getValue();
Operation op = new Operation();
op.setId("");
op.setAuthType(uriTemplate.getAuthType());
op.setThrottlingPolicy(uriTemplate.getThrottlingTier());
op.setVerb(uriTemplate.getHTTPVerb());
op.setTarget(uriTemplate.getUriTemplate());
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<>());
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);
OperationPolicies policies = new OperationPolicies();
policies.setRequest(new ArrayList<>());
policies.setResponse(new ArrayList<>());
policies.setFault(new ArrayList<>());
op.setOperationPolicies(policies);
operations.add(op);
operationsList.add(op);
}
return operations;
}
return operationsList;
}
}