From 1cea844a2a3c3b3592c772d6be0c893db8920137 Mon Sep 17 00:00:00 2001 From: Radek Davidek Date: Wed, 11 Mar 2026 11:07:30 +0100 Subject: [PATCH] apps from filesystem to wso2 --- .gitignore | 1 + .../cz/trask/migration/AbstractProcess.java | 25 ++++-- src/main/java/cz/trask/migration/ApiSync.java | 5 ++ .../migration/impl/v45/ApiFilesToWso2.java | 4 +- .../migration/impl/v45/AppFilesToWso2.java | 88 +++++++++++++++++++ .../impl/v45/ExportAppsToWso2FromV32.java | 26 ------ .../migration/model/ApplicationConfig.java | 2 + src/main/resources/apicurio-migrator.yaml | 1 + 8 files changed, 118 insertions(+), 34 deletions(-) create mode 100644 src/main/java/cz/trask/migration/impl/v45/AppFilesToWso2.java diff --git a/.gitignore b/.gitignore index 30d18ed..6f7c7f0 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,6 @@ bin /api.yaml *.zip apis +apps tmp apicurio-migrator.yaml \ No newline at end of file diff --git a/src/main/java/cz/trask/migration/AbstractProcess.java b/src/main/java/cz/trask/migration/AbstractProcess.java index 21db0a6..f122b35 100644 --- a/src/main/java/cz/trask/migration/AbstractProcess.java +++ b/src/main/java/cz/trask/migration/AbstractProcess.java @@ -513,17 +513,11 @@ public abstract class AbstractProcess { try { String url = config.getTarget().getPublisherApiUrl() .concat(String.format("?preserveProvider=false&overwrite=true")); - log.info("API Import URL: " + url); - Map httpHeaders = new HashMap<>(); - httpHeaders.put("Authorization", "Bearer " + tokenResponse.getAccess_token()); - HttpResponse response = makeFileRequest("POST", url, httpHeaders, data, fileName); - responseCode = response.getResponseCode(); - if (response.getResponseCode() != 201 && response.getResponseCode() != 200) { log.info("Cannot import API file: " + fileName + ", response code: " + response.getResponseCode()); } @@ -533,6 +527,25 @@ public abstract class AbstractProcess { return responseCode; } + protected int publishAppToWso2(String fileName, byte[] data, TokenResponse tokenResponse) { + int responseCode = -1; + try { + String url = config.getTarget().getDevPortalApiUrl().concat(String.format( + "/v3/applications/import?preserveOwner=true&skipSubscriptions=false&skipApplicationKeys=false&update=true")); + log.info("App Import URL: " + url); + Map httpHeaders = new HashMap<>(); + httpHeaders.put("Authorization", "Bearer " + tokenResponse.getAccess_token()); + HttpResponse response = makeFileRequest("POST", url, httpHeaders, data, fileName); + responseCode = response.getResponseCode(); + if (response.getResponseCode() < 200 || response.getResponseCode() > 299) { + log.info("Cannot import App file: " + fileName + ", response code: " + response.getResponseCode()); + } + } catch (Exception e) { + log.error("IO error while importing App file: " + fileName + ", error: " + e.getMessage(), e); + } + return responseCode; + } + protected void setArtifactMetaData(ArtifactMetaData meta, String name, String description, Map props) { EditableMetaData metaData = new EditableMetaData(); metaData.setName(name); diff --git a/src/main/java/cz/trask/migration/ApiSync.java b/src/main/java/cz/trask/migration/ApiSync.java index cb7487a..41f12e3 100644 --- a/src/main/java/cz/trask/migration/ApiSync.java +++ b/src/main/java/cz/trask/migration/ApiSync.java @@ -7,6 +7,7 @@ import cz.trask.migration.impl.v32.Wso2AppsToApicurio; import cz.trask.migration.impl.v32.Wso2v32ToApicurio; import cz.trask.migration.impl.v32.Wso2v32ToApicurioFromDir; import cz.trask.migration.impl.v45.ApiFilesToWso2; +import cz.trask.migration.impl.v45.AppFilesToWso2; import cz.trask.migration.impl.v45.ExportApisToWso2FromV32; import cz.trask.migration.impl.v45.ExportAppsToWso2FromV32; import cz.trask.migration.model.StartParameters; @@ -49,6 +50,10 @@ public class ApiSync { log.info("apiFilesToWso2 command selected."); ApiFilesToWso2 imp = new ApiFilesToWso2(); imp.process(); + } else if (sp.getCommand().equalsIgnoreCase("appFilesToWso2")) { + log.info("appFilesToWso2 command selected."); + AppFilesToWso2 imp = new AppFilesToWso2(); + imp.process(); } else { log.error("Unknown command: " + sp.getCommand()); printHelp(); diff --git a/src/main/java/cz/trask/migration/impl/v45/ApiFilesToWso2.java b/src/main/java/cz/trask/migration/impl/v45/ApiFilesToWso2.java index 697adde..c45b712 100644 --- a/src/main/java/cz/trask/migration/impl/v45/ApiFilesToWso2.java +++ b/src/main/java/cz/trask/migration/impl/v45/ApiFilesToWso2.java @@ -69,9 +69,9 @@ public class ApiFilesToWso2 extends AbstractProcess { if (data != null && data.length > 0 && fileName != null && !fileName.isEmpty()) { int responseCode = publishApiToWso2(fileName, data, token); if (responseCode == 200 || responseCode == 201) { - log.info(" - API version {} imported successfully", fileName); + log.info(" - API version {} imported successfully with response code: {}", fileName, responseCode); } else { - log.warn(" - API version {} import failed with response code {}", fileName, + log.warn(" - API version {} import failed with response code: {}", fileName, responseCode); } } diff --git a/src/main/java/cz/trask/migration/impl/v45/AppFilesToWso2.java b/src/main/java/cz/trask/migration/impl/v45/AppFilesToWso2.java new file mode 100644 index 0000000..ebe0275 --- /dev/null +++ b/src/main/java/cz/trask/migration/impl/v45/AppFilesToWso2.java @@ -0,0 +1,88 @@ +package cz.trask.migration.impl.v45; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.concurrent.atomic.AtomicInteger; + +import cz.trask.migration.AbstractProcess; +import cz.trask.migration.model.TokenResponse; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +public class AppFilesToWso2 extends AbstractProcess { + + private final AtomicInteger apiCounter = new AtomicInteger(1); + + /** + * Main entry point for the import process. + * + * @throws RuntimeException if any error occurs + */ + public void process() { + try { + log.info("Starting App import to WSO2 from directory..."); + + TokenResponse token = authenticateToWso2AndGetToken(config.getTarget()); + + File root = new File(config.getSource().getWso2AppsDir()); + + File[] appFiles = root.listFiles((dir, name) -> name.endsWith(".zip")); + if (appFiles == null || appFiles.length == 0) { + log.warn("No App zip files found in directory: {}", config.getSource().getWso2AppsDir()); + return; + } + + log.info("Found {} Apps", appFiles.length); + + for (File app : appFiles) { + final int index = apiCounter.getAndIncrement(); + processApp(app, token, index, appFiles.length); + } + + log.info("Finished processing Apps."); + } catch (Exception e) { + log.error("Error while importing Apps.", e); + throw new RuntimeException("Import failed", e); + } + } + + /** + * Process a single App – fetches the data, creates or updates the corresponding + * artifact in WSO2. + */ + private void processApp(File appFile, TokenResponse token, int index, int total) { + long start = System.currentTimeMillis(); + + try { + log.info("Processing App {} of {}", index, total); + + String fileName = appFile.getName(); + byte[] data = null; + try { + data = Files.readAllBytes(appFile.toPath()); + } catch (IOException e) { + log.error("Failed to read App file '{}': {}", appFile.getName(), e.getMessage(), e); + return; + } + + if (data != null && data.length > 0 && fileName != null && !fileName.isEmpty()) { + int responseCode = publishAppToWso2(fileName, data, token); + if (responseCode == 200 || responseCode == 201) { + log.info(" - Application {} imported successfully with response code: {}", fileName, + responseCode); + } else { + log.warn(" - Application {} import failed with response code: {}", fileName, + responseCode); + } + } + + log.info("Successfully imported App '{}' ({}). Took {} ms", appFile.getName(), + appFile.getName(), + System.currentTimeMillis() - start); + } catch (Exception e) { + log.error("Cannot export App '{}': {}", appFile.getName(), e.getMessage(), e); + } + } + +} diff --git a/src/main/java/cz/trask/migration/impl/v45/ExportAppsToWso2FromV32.java b/src/main/java/cz/trask/migration/impl/v45/ExportAppsToWso2FromV32.java index 0c84aba..e6addbe 100644 --- a/src/main/java/cz/trask/migration/impl/v45/ExportAppsToWso2FromV32.java +++ b/src/main/java/cz/trask/migration/impl/v45/ExportAppsToWso2FromV32.java @@ -267,30 +267,4 @@ public class ExportAppsToWso2FromV32 extends AbstractProcess { return yamlApp; } - - private int publishAppToWso2(String fileName, byte[] data, TokenResponse tokenResponse) { - int responseCode = -1; - try { - String url = config.getTarget().getDevPortalApiUrl().concat(String.format( - "/v3/applications/import?preserveOwner=true&skipSubscriptions=false&skipApplicationKeys=false&update=true")); - - log.info("App Import URL: " + url); - - Map httpHeaders = new HashMap<>(); - - httpHeaders.put("Authorization", "Bearer " + tokenResponse.getAccess_token()); - - HttpResponse response = makeFileRequest("POST", url, httpHeaders, data, fileName); - - responseCode = response.getResponseCode(); - - if (response.getResponseCode() < 200 || response.getResponseCode() > 299) { - log.info("Cannot import App file: " + fileName + ", response code: " + response.getResponseCode()); - } - } catch (Exception e) { - log.error("IO error while importing App file: " + fileName + ", error: " + e.getMessage(), e); - } - return responseCode; - } - } \ No newline at end of file diff --git a/src/main/java/cz/trask/migration/model/ApplicationConfig.java b/src/main/java/cz/trask/migration/model/ApplicationConfig.java index a0d6cb4..d79f9e5 100644 --- a/src/main/java/cz/trask/migration/model/ApplicationConfig.java +++ b/src/main/java/cz/trask/migration/model/ApplicationConfig.java @@ -66,6 +66,8 @@ public class ApplicationConfig { private String wso2User; @JsonProperty("wso2_apis_dir") private String wso2ApisDir; + @JsonProperty("wso2_apps_dir") + private String wso2AppsDir; @JsonProperty("secrets_decryption_cert") private String secretsDecryptionCert; } diff --git a/src/main/resources/apicurio-migrator.yaml b/src/main/resources/apicurio-migrator.yaml index 1421ac5..fc168f4 100644 --- a/src/main/resources/apicurio-migrator.yaml +++ b/src/main/resources/apicurio-migrator.yaml @@ -11,6 +11,7 @@ source: secrets_decryption_cert: wso2apim32-pk.pem wso2_user: YWRtaW46YWRtaW4= wso2_apis_dir: ./apis + wso2_apps_dir: ./apps target: registration_api_url: https://localhost:9443/client-registration/v0.17/register