apicurio-migration-tool/src/main/java/cz/trask/migration/mapper/ApiDefinitionMapper32to45.java
2026-03-03 16:48:54 +01:00

479 lines
19 KiB
Java

package cz.trask.migration.mapper;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.JsonNode;
import cz.trask.migration.AbstractProcess;
import cz.trask.migration.model.v32.ApiDefinition32;
import cz.trask.migration.model.v45.ApiDefinition45;
import cz.trask.migration.model.v45.ApiDefinition45.ApiPolicies;
import cz.trask.migration.model.v45.ApiDefinition45.Operation;
import cz.trask.migration.model.v45.ApiDefinition45.OperationPolicies;
import cz.trask.migration.util.CredentialsDecoder;
public class ApiDefinitionMapper32to45 {
private static final String CONTEXT_VERSION_TEMPLATE = "/{version}";
public static ApiDefinition45 map(ApiDefinition32 oldApi, String swagger, boolean hasWsdl) throws Exception {
if (oldApi == null)
return null;
ApiDefinition45 newApi = new ApiDefinition45();
newApi.setType("api");
newApi.setVersion("v4.5.0");
ApiDefinition45.DataSection data = new ApiDefinition45.DataSection();
Map<String, Object> swaggerData = AbstractProcess.mapperYaml.readValue(swagger, Map.class);
// ---------- základní metadata ----------
data.setId(oldApi.getUuid());
data.setName(oldApi.getId() != null ? oldApi.getId().getApiName() : null);
data.setDescription(swaggerData.get("info") != null
? ((Map<String, Object>) swaggerData.get("info")).get("description") != null
? ((Map<String, Object>) swaggerData.get("info")).get("description").toString()
: ""
: "");
data.setVersion(oldApi.getId() != null ? oldApi.getId().getVersion() : null);
data.setProvider(oldApi.getId() != null ? oldApi.getId().getProviderName() : null);
// data.setContext(swaggerData.get("basePath") != null ?
// swaggerData.get("basePath").toString() : "");
data.setContext(getContext(oldApi.getContext(), oldApi.getContextTemplate(), oldApi.getId().getVersion()));
data.setLifeCycleStatus(oldApi.getStatus());
data.setDefaultVersion(oldApi.isDefaultVersion());
data.setRevision(false);
data.setEnableSchemaValidation(oldApi.isEnableSchemaValidation());
data.setAuthorizationHeader(oldApi.getAuthorizationHeader());
data.setTransport(
oldApi.getTransports() != null ? List.of(oldApi.getTransports().split(",")) : Collections.emptyList());
data.setTags(oldApi.getTags());
data.setVisibility(oldApi.getVisibility().toUpperCase());
// data.setVisibleRoles(oldApi.getVisibleRoles()!=null ?
// List.of(oldApi.getVisibleRoles().split(",")) : Collections.emptyList());
data.setVisibleRoles(List.of("Internal/publisher"));
data.setVisibleTenants(Collections.emptyList());
data.setAccessControl("NONE");
// data.setAccessControlRoles(Collections.emptyList());
data.setOrganizationPolicies(Collections.emptyList());
data.setType(getApiType(oldApi.getType(), hasWsdl));
data.setAudiences(Arrays.asList("all"));
List<String> policies = new ArrayList<>();
for (ApiDefinition32.Tier tier : oldApi.getAvailableTiers()) {
if (tier.getName() != null && !tier.getName().isEmpty()) {
policies.add(tier.getName());
}
}
data.setPolicies(policies);
if (oldApi.getApiSecurity() != null && !oldApi.getApiSecurity().isEmpty()) {
data.setSecurityScheme(
Arrays.stream(oldApi.getApiSecurity().split(",")).map(String::trim).collect(Collectors.toList()));
} else {
data.setSecurityScheme(Collections.emptyList());
}
data.setApiKeyHeader("ApiKey");
data.setOrganizationId("carbon.super");
data.setAsyncTransportProtocols(Collections.emptyList());
data.setCategories(Collections.emptyList());
data.setSubtypeConfiguration(new ApiDefinition45.SubtypeConfiguration());
data.getSubtypeConfiguration().setSubtype("DEFAULT");
data.setScopes(new ArrayList<>());
data.setWebsubSubscriptionConfiguration(new ApiDefinition45.WebsubSubscriptionConfiguration());
data.getWebsubSubscriptionConfiguration().setEnable(false);
data.getWebsubSubscriptionConfiguration().setSecret("");
data.getWebsubSubscriptionConfiguration().setSigningAlgorithm("SHA1");
data.getWebsubSubscriptionConfiguration().setSignatureHeader("x-hub-signature");
// ---------- cache ----------
data.setResponseCachingEnabled(
oldApi.getResponseCache() != null && !"disabled".equalsIgnoreCase(oldApi.getResponseCache()));
data.setCacheTimeout(oldApi.getCacheTimeout());
// ---------- CORS ----------
data.setCorsConfiguration(mapCors(oldApi.getCorsConfiguration()));
// ---------- endpoint ----------
data.setEndpointConfig(mapEndpointConfig(oldApi.getEndpointConfig()));
data.setEndpointImplementationType(oldApi.getImplementation());
// ---------- API policies ----------
data.setApiPolicies(mapApiPolicies(oldApi));
// data.setApiPolicies(mapApiPolicies(null));
// ---------- key managers ----------
data.setKeyManagers(oldApi.getKeyManagers());
// ---------- advertise info ----------
ApiDefinition45.AdvertiseInfo ai = new ApiDefinition45.AdvertiseInfo();
ai.setAdvertised(oldApi.isAdvertiseOnly());
ai.setApiOwner(oldApi.getId() != null ? oldApi.getId().getProviderName() : null);
ai.setVendor("WSO2");
data.setAdvertiseInfo(ai);
data.setVisibleOrganizations(Arrays.asList("none"));
// ---------- gateway ----------
data.setGatewayVendor("wso2");
data.setGatewayType("wso2/synapse");
// ---------- business & monetization ----------
data.setBusinessInformation(new HashMap<>());
data.getBusinessInformation().put("businessOwner", oldApi.getBusinessOwner());
data.getBusinessInformation().put("businessOwnerEmail", oldApi.getBusinessOwnerEmail());
data.getBusinessInformation().put("technicalOwner", oldApi.getTechnicalOwner());
data.getBusinessInformation().put("technicalOwnerEmail", oldApi.getTechnicalOwnerEmail());
// ---------- additional properties ----------
data.setAdditionalProperties(mapAdditionalProperties(oldApi.getAdditionalProperties()));
data.setAdditionalPropertiesMap(mapAdditionalPropertiesMap(oldApi.getAdditionalProperties()));
// ---------- subscription ----------
if (oldApi.getSubscriptionAvailability() != null)
data.setSubscriptionAvailability(oldApi.getSubscriptionAvailability().toUpperCase());
data.setSubscriptionAvailableTenants(Collections.emptyList());
// ---------- operations ----------
data.setOperations(mapOperations(swagger));
// ---------- additional metadata ----------
data.setCreatedTime(oldApi.getCreatedTime());
data.setLastUpdatedTime(oldApi.getLastUpdated());
// ---------- mediace ----------
data.setMediationPolicies(oldApi.getDocuments());
newApi.setData(data);
return newApi;
}
private static String getApiType(String type, boolean hasWsdl) {
if (type != null && type.equalsIgnoreCase("SOAP"))
if (hasWsdl)
return "SOAP";
else
return "HTTP";
if (type != null && !type.equalsIgnoreCase("null"))
return type;
return "HTTP";
}
private static String getContext(String context, String contextTemplate, String version) {
if (contextTemplate != null && !contextTemplate.isEmpty()) {
return contextTemplate.replace(CONTEXT_VERSION_TEMPLATE, "");
}
if (context != null && !context.isEmpty()) {
return context.replace(version, "");
}
return context;
}
private static Map mapEndpointConfig(Map endpointConfig) {
if (endpointConfig == null || endpointConfig.isEmpty())
return new HashMap();
if (endpointConfig.get("production_endpoints") != null
&& (endpointConfig.get("production_endpoints") instanceof Map)) {
Map<String, Object> endpointProd = (Map<String, Object>) endpointConfig.get("production_endpoints");
if (endpointProd != null && endpointProd.containsKey("config")) {
Object value = endpointProd.get("config");
if (value == null) {
endpointProd.remove("config");
}
}
if (endpointProd != null && endpointProd.containsKey("url") && endpointProd.get("url") != null) {
String url = endpointProd.get("url").toString().trim().replaceAll("\\p{Cf}", "");
try {
URL u = new URL(url);
} catch (Exception e) {
url = url.replaceAll("\\{\\{.*?\\}\\}", "");
if (!url.startsWith("http"))
url = "http://" + url;
}
endpointProd.put("url", url);
}
}
if (endpointConfig.get("sandbox_endpoints") != null
&& (endpointConfig.get("sandbox_endpoints") instanceof Map)) {
Map<String, Object> endpointSand = (Map<String, Object>) endpointConfig.get("sandbox_endpoints");
if (endpointSand != null && endpointSand.containsKey("config")) {
Object value = endpointSand.get("config");
if (value == null) {
endpointSand.remove("config");
}
}
if (endpointSand != null && endpointSand.containsKey("url") && endpointSand.get("url") != null) {
String url = endpointSand.get("url").toString().trim().replaceAll("\\p{Cf}", "");
try {
URL u = new URL(url);
} catch (Exception e) {
url = url.replaceAll("\\{\\{.*?\\}\\}", "");
if (!url.startsWith("http"))
url = "http://" + url;
}
endpointSand.put("url", url);
}
}
if (endpointConfig.get("endpoint_security") != null
&& (endpointConfig.get("endpoint_security") instanceof Map)) {
Map<String, Object> endpointSecurity = (Map<String, Object>) endpointConfig.get("endpoint_security");
Map<String, Object> sandbox = endpointSecurity.get("sandbox") != null
&& endpointSecurity.get("sandbox") instanceof Map
? (Map<String, Object>) endpointSecurity.get("sandbox")
: null;
Map<String, Object> production = endpointSecurity.get("production") != null
&& endpointSecurity.get("production") instanceof Map
? (Map<String, Object>) endpointSecurity.get("production")
: null;
if (sandbox != null && sandbox.containsKey("clientSecret") && sandbox.get("clientSecret") != null) {
String encodedSecret = sandbox.get("clientSecret").toString();
sandbox.put("clientSecret", CredentialsDecoder.decodeCredentials(encodedSecret));
}
if (production != null && production.containsKey("clientSecret")
&& production.get("clientSecret") != null) {
String encodedSecret = production.get("clientSecret").toString();
production.put("clientSecret", CredentialsDecoder.decodeCredentials(encodedSecret));
}
if (sandbox != null && sandbox.containsKey("customParameters")) {
try {
String customParamsStr = sandbox.get("customParameters").toString();
Map<String, Object> customParams = AbstractProcess.mapperYaml.readValue(customParamsStr, Map.class);
sandbox.put("customParameters", customParams != null ? customParams : Collections.emptyMap());
} catch (Exception e) {
sandbox.put("customParameters", Collections.emptyMap());
}
}
if (production != null && production.containsKey("customParameters")) {
try {
String customParamsStr = production.get("customParameters").toString();
Map<String, Object> customParams = AbstractProcess.mapperYaml.readValue(customParamsStr, Map.class);
production.put("customParameters", customParams != null ? customParams : Collections.emptyMap());
} catch (Exception e) {
production.put("customParameters", Collections.emptyMap());
}
}
}
return endpointConfig;
}
private static List<Object> mapAdditionalProperties(Map<String, Object> additionalProperties) {
if (additionalProperties != null && !additionalProperties.isEmpty()) {
List<Object> list = new ArrayList<>();
for (Map.Entry<String, Object> entry : additionalProperties.entrySet()) {
Map<String, Object> map = new HashMap<>();
map.put("name", entry.getKey());
map.put("value", entry.getValue());
map.put("display", "false");
list.add(map);
}
return list;
}
return null;
}
private static Map<String, Object> mapAdditionalPropertiesMap(Map<String, Object> additionalProperties) {
if (additionalProperties != null && !additionalProperties.isEmpty()) {
Map<String, Object> res = new HashMap<>();
for (Map.Entry<String, Object> entry : additionalProperties.entrySet()) {
Map<String, Object> map = new HashMap<>();
map.put("name", entry.getKey());
map.put("value", entry.getValue());
map.put("display", "false");
res.put(entry.getKey(), map);
}
return res;
}
return null;
}
private static ApiPolicies mapApiPolicies(ApiDefinition32 oldApi) {
ApiDefinition45.ApiPolicies apiPolicies = new ApiDefinition45.ApiPolicies();
// ---------- request policies ----------
if (oldApi != null && oldApi.getInSequence() != null && !oldApi.getInSequence().isEmpty()) {
ApiDefinition45.Policy requestPolicy = new ApiDefinition45.Policy();
requestPolicy.setPolicyName(oldApi.getInSequence());
requestPolicy.setPolicyType("api");
requestPolicy.setPolicyVersion("v1");
requestPolicy.setPolicyId("");
requestPolicy.setParameters(Collections.emptyMap());
apiPolicies.setRequest(List.of(requestPolicy));
} else
apiPolicies.setRequest(Collections.emptyList());
// ---------- response policies ----------
if (oldApi != null && oldApi.getOutSequence() != null && !oldApi.getOutSequence().isEmpty()) {
ApiDefinition45.Policy requestPolicy = new ApiDefinition45.Policy();
requestPolicy.setPolicyName(oldApi.getOutSequence());
requestPolicy.setPolicyType("api");
requestPolicy.setPolicyVersion("v1");
requestPolicy.setPolicyId("");
requestPolicy.setParameters(Collections.emptyMap());
apiPolicies.setResponse(List.of(requestPolicy));
} else
apiPolicies.setResponse(Collections.emptyList());
// ---------- fault policies ----------
if (oldApi != null && oldApi.getFaultSequence() != null && !oldApi.getFaultSequence().isEmpty()) {
ApiDefinition45.Policy requestPolicy = new ApiDefinition45.Policy();
requestPolicy.setPolicyName(oldApi.getFaultSequence());
requestPolicy.setPolicyType("api");
requestPolicy.setPolicyVersion("v1");
requestPolicy.setPolicyId("");
requestPolicy.setParameters(Collections.emptyMap());
apiPolicies.setFault(List.of(requestPolicy));
} else
apiPolicies.setFault(Collections.emptyList());
return apiPolicies;
}
private static ApiDefinition45.CorsConfiguration mapCors(ApiDefinition32.CorsConfiguration oldCors) {
if (oldCors == null)
return null;
ApiDefinition45.CorsConfiguration cors = new ApiDefinition45.CorsConfiguration();
cors.setCorsConfigurationEnabled(oldCors.isCorsConfigurationEnabled());
cors.setAccessControlAllowOrigins(oldCors.getAccessControlAllowOrigins());
cors.setAccessControlAllowHeaders(oldCors.getAccessControlAllowHeaders());
cors.setAccessControlAllowMethods(oldCors.getAccessControlAllowMethods());
cors.setAccessControlAllowCredentials(oldCors.isAccessControlAllowCredentials());
return cors;
}
// private static ApiDefinition45.EndpointConfig
// mapEndpointConfig(ApiDefinition32.EndpointConfig oldEndpoint) {
// if (oldEndpoint == null)
// return null;
//
// ApiDefinition45.EndpointConfig newEndpoint = new
// ApiDefinition45.EndpointConfig();
// newEndpoint.setEndpoint_type(oldEndpoint.getEndpointType());
//
// if (oldEndpoint.getSandboxEndpoints() != null) {
// ApiDefinition45.EndpointGroup sandbox = new ApiDefinition45.EndpointGroup();
// sandbox.setUrl(oldEndpoint.getSandboxEndpoints().getUrl());
// newEndpoint.setSandbox_endpoints(sandbox);
// }
//
// if (oldEndpoint.getProductionEndpoints() != null) {
// ApiDefinition45.EndpointGroup production = new
// ApiDefinition45.EndpointGroup();
// production.setUrl(oldEndpoint.getProductionEndpoints().getUrl());
// newEndpoint.setProduction_endpoints(production);
// }
//
// if (oldEndpoint.getEndpointSecurity() != null) {
// ApiDefinition45.EndpointSecurity security = new
// ApiDefinition45.EndpointSecurity();
// security.setSandbox(mapSecurityEnv(oldEndpoint.getEndpointSecurity().getSandbox()));
// security.setProduction(mapSecurityEnv(oldEndpoint.getEndpointSecurity().getProduction()));
// newEndpoint.setEndpoint_security(security);
// }
//
// return newEndpoint;
// }
//
// private static ApiDefinition45.SecurityEnv
// mapSecurityEnv(ApiDefinition32.SecurityEnvironment oldSec) {
// if (oldSec == null)
// return null;
//
// ApiDefinition45.SecurityEnv newSec = new ApiDefinition45.SecurityEnv();
// newSec.setType(oldSec.getType());
// newSec.setTokenUrl(oldSec.getTokenUrl());
// newSec.setClientId(oldSec.getClientId());
// newSec.setClientSecret(
// CredentialsDecoder.decodeCredentials(oldSec.getClientSecret(),
// AbstractProcess.PRIVATE_KEY_APIM_32));
// newSec.setUsername(oldSec.getUsername());
// newSec.setPassword(oldSec.getPassword());
// newSec.setGrantType(oldSec.getGrantType());
// newSec.setEnabled(oldSec.isEnabled());
// newSec.setConnectionTimeoutDuration(0);
// newSec.setSocketTimeoutDuration(0);
// newSec.setConnectionRequestTimeoutDuration(0);
// newSec.setProxyConfigs(new ApiDefinition45.ProxyConfigs());
//
// // ---------- parse customParameters JSON string ----------
// if (oldSec.getCustomParameters() != null &&
// !oldSec.getCustomParameters().isEmpty()) {
// try {
// Map<String, Object> map =
// AbstractProcess.mapperYaml.readValue(oldSec.getCustomParameters(),
// new TypeReference<>() {
// });
// newSec.setCustomParameters(map);
// } catch (Exception e) {
// newSec.setCustomParameters(Collections.emptyMap());
// }
// } else {
// newSec.setCustomParameters(Collections.emptyMap());
// }
//
// // ---------- parse additionalProperties JSON string ----------
// newSec.setAdditionalProperties(Collections.emptyMap());
//
// return newSec;
// }
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<Operation> operationsList = new ArrayList<>();
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();
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.setTarget(path);
op.setVerb(verb);
op.setAuthType(methodDef.path("x-auth-type").asText(""));
JsonNode throttlingNode = methodDef.path("x-throttling-tier");
if (!throttlingNode.isMissingNode() && !throttlingNode.asText().isEmpty() && !throttlingNode.asText().equalsIgnoreCase("null")) {
op.setThrottlingPolicy(throttlingNode.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;
}
}