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 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) swaggerData.get("info")).get("description") != null ? ((Map) 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 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 endpointProd = (Map) 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 endpointSand = (Map) 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 endpointSecurity = (Map) endpointConfig.get("endpoint_security"); Map sandbox = endpointSecurity.get("sandbox") != null && endpointSecurity.get("sandbox") instanceof Map ? (Map) endpointSecurity.get("sandbox") : null; Map production = endpointSecurity.get("production") != null && endpointSecurity.get("production") instanceof Map ? (Map) 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 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 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 mapAdditionalProperties(Map additionalProperties) { if (additionalProperties != null && !additionalProperties.isEmpty()) { List list = new ArrayList<>(); for (Map.Entry entry : additionalProperties.entrySet()) { Map 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 mapAdditionalPropertiesMap(Map additionalProperties) { if (additionalProperties != null && !additionalProperties.isEmpty()) { Map res = new HashMap<>(); for (Map.Entry entry : additionalProperties.entrySet()) { Map 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 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 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 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("")); 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; } }