changed to yaml for config

This commit is contained in:
Radek Davidek 2025-10-26 10:44:47 +01:00
parent 5eb12c6526
commit 6d289e3cc8
7 changed files with 133 additions and 218 deletions

View File

@ -24,6 +24,7 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import cz.trask.migration.config.ConfigManager; import cz.trask.migration.config.ConfigManager;
import cz.trask.migration.model.APIList; import cz.trask.migration.model.APIList;
import cz.trask.migration.model.ApplicationConfig;
import cz.trask.migration.model.HttpResponse; import cz.trask.migration.model.HttpResponse;
import cz.trask.migration.model.RegisterResponse; import cz.trask.migration.model.RegisterResponse;
import cz.trask.migration.model.TokenResponse; import cz.trask.migration.model.TokenResponse;
@ -40,7 +41,7 @@ public abstract class AbstractProcess {
public static ObjectMapper mapper; public static ObjectMapper mapper;
public static ObjectMapper mapperYaml; public static ObjectMapper mapperYaml;
protected ConfigManager config = ConfigManager.getInstance(); protected ApplicationConfig config;
protected AbstractProcess() { protected AbstractProcess() {
mapper = new ObjectMapper(); mapper = new ObjectMapper();
@ -51,6 +52,8 @@ public abstract class AbstractProcess {
yamlFactory.configure(YAMLGenerator.Feature.SPLIT_LINES, false); yamlFactory.configure(YAMLGenerator.Feature.SPLIT_LINES, false);
mapperYaml = new ObjectMapper(yamlFactory); mapperYaml = new ObjectMapper(yamlFactory);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
config = ConfigManager.getInstance().getConfig();
setTrustStoreCredentials(); setTrustStoreCredentials();
@ -62,18 +65,18 @@ public abstract class AbstractProcess {
} }
protected void setTrustStoreCredentials() { protected void setTrustStoreCredentials() {
log.info("Setting truststore: " + config.getTruststorePath()); log.info("Setting truststore: " + config.getTrustStore().getPath());
System.setProperty("javax.net.ssl.trustStore", config.getTruststorePath()); System.setProperty("javax.net.ssl.trustStore", config.getTrustStore().getPath());
System.setProperty("javax.net.ssl.trustStorePassword", config.getTruststorePassword()); System.setProperty("javax.net.ssl.trustStorePassword", config.getTrustStore().getPassword());
} }
protected TokenResponse authenticateToWso2AndGetToken() throws Exception { protected TokenResponse authenticateToWso2AndGetToken() throws Exception {
RegisterResponse register = register(config.getSourceRegistrationApiUrl(), config.getSourceWso2User()); RegisterResponse register = register(config.getSource().getRegistrationApiUrl(), config.getSource().getWso2User());
String clientId = register.getClientId(); String clientId = register.getClientId();
log.info("Registered with clientId: {}", clientId); log.info("Registered with clientId: {}", clientId);
TokenResponse token = getToken(config.getSourcePublisherTokenUrl(), config.getSourceWso2User(), register, TokenResponse token = getToken(config.getSource().getPublisherTokenUrl(), config.getSource().getWso2User(), register,
"apim:api_view apim:api_create apim:api_manage apim:api_delete apim:api_publish " "apim:api_view apim:api_create apim:api_manage apim:api_delete apim:api_publish "
+ "apim:subscription_view apim:subscription_block apim:subscription_manage apim:external_services_discover " + "apim:subscription_view apim:subscription_block apim:subscription_manage apim:external_services_discover "
+ "apim:threat_protection_policy_create apim:threat_protection_policy_manage apim:document_create apim:document_manage " + "apim:threat_protection_policy_create apim:threat_protection_policy_manage apim:document_create apim:document_manage "

View File

@ -3,85 +3,19 @@ package cz.trask.migration.config;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.Properties;
import org.apache.logging.log4j.LogManager; import cz.trask.migration.AbstractProcess;
import org.apache.logging.log4j.Logger; import cz.trask.migration.model.ApplicationConfig;
import lombok.extern.log4j.Log4j2;
@Log4j2
public final class ConfigManager { public final class ConfigManager {
/* -------------------------------------------------------------------- */ private static final String PROPERTY_FILENAME = "apicurio-migrator.yaml";
/* LOGIC & CONSTANTS */
/* -------------------------------------------------------------------- */
private static final Logger log = LogManager.getLogger(ConfigManager.class);
private static final String PROPERTY_FILENAME = "apicurio-migrator.properties";
// SOURCE
public static final String PROP_SOURCE_REGISTRATION_API_URL = "SOURCE_REGISTRATION_API_URL";
public static final String PROP_SOURCE_PUBLISHER_API_URL = "SOURCE_PUBLISHER_API_URL";
public static final String PROP_SOURCE_DEVPORTAL_API_URL = "SOURCE_DEVPORTAL_API_URL";
public static final String PROP_SOURCE_PUBLISHER_TOKEN_URL = "SOURCE_PUBLISHER_TOKEN_URL";
public static final String PROP_SOURCE_WSO2_USER = "SOURCE_WSO2_USER";
// TARGET
public static final String PROP_TARGET_REGISTRATION_API_URL = "TARGET_REGISTRATION_API_URL";
public static final String PROP_TARGET_PUBLISHER_API_URL = "TARGET_PUBLISHER_API_URL";
public static final String PROP_TARGET_DEVPORTAL_API_URL = "TARGET_DEVPORTAL_API_URL";
public static final String PROP_TARGET_PUBLISHER_TOKEN_URL = "TARGET_PUBLISHER_TOKEN_URL";
public static final String PROP_TARGET_WSO2_USER = "TARGET_WSO2_USER";
// TRUSTSTORE
public static final String PROP_TRUSTSTORE_PATH = "TRUSTSTORE_PATH";
public static final String PROP_TRUSTSTORE_PASSWORD = "TRUSTSTORE_PASSWORD";
// URL PATTERNS
public static final String PROP_PUBLISHER_URL_PATTERN = "PUBLISHER_URL_PATTERN";
public static final String PROP_DEVPORTAL_URL_PATTERN = "DEVPORTAL_URL_PATTERN";
// APICURIO & GROUP
public static final String PROP_APICURIO_API_URL = "APICURIO_API_URL";
public static final String PROP_DEFAULT_API_GROUP = "DEFAULT_API_GROUP";
// MAX THREADS
public static final String PROP_MAX_THREADS = "MAX_THREADS";
/* -------------------------------------------------------------------- */
/* CONFIGURATION FIELDS */
/* -------------------------------------------------------------------- */
private final String sourceRegistrationApiUrl;
private final String sourcePublisherApiUrl;
private final String sourceDevportalApiUrl;
private final String sourcePublisherTokenUrl;
private final String sourceWso2User;
private final String targetRegistrationApiUrl;
private final String targetPublisherApiUrl;
private final String targetDevportalApiUrl;
private final String targetPublisherTokenUrl;
private final String targetWso2User;
private final String truststorePath;
private final String truststorePassword;
private final String publisherUrlPattern;
private final String devportalUrlPattern;
private final String apicurioApiUrl;
private final String defaultApiGroup;
private final int maxThreads;
private static volatile ConfigManager INSTANCE; private static volatile ConfigManager INSTANCE;
/** Všechny načtené hodnoty. */ private static ApplicationConfig config = new ApplicationConfig();
private final Properties props = new Properties();
/* -------------------------------------------------------------------- */
/* SINGLETON lazyinitializationon-demand holder */
/* -------------------------------------------------------------------- */
private ConfigManager() { private ConfigManager() {
@ -116,7 +50,7 @@ public final class ConfigManager {
try (InputStream input = in) { try (InputStream input = in) {
if (input != null) { if (input != null) {
props.load(input); config = AbstractProcess.mapperYaml.readValue(input, ApplicationConfig.class);
log.info("Property file loaded successfully."); log.info("Property file loaded successfully.");
} else { } else {
log.warn("No property source available; proceeding with defaults where possible."); log.warn("No property source available; proceeding with defaults where possible.");
@ -124,29 +58,6 @@ public final class ConfigManager {
} catch (Exception e) { } catch (Exception e) {
log.error("Cannot load property file.", e); log.error("Cannot load property file.", e);
} }
sourceRegistrationApiUrl = getRequired(PROP_SOURCE_REGISTRATION_API_URL);
sourcePublisherApiUrl = getRequired(PROP_SOURCE_PUBLISHER_API_URL);
sourceDevportalApiUrl = getRequired(PROP_SOURCE_DEVPORTAL_API_URL);
sourcePublisherTokenUrl = getRequired(PROP_SOURCE_PUBLISHER_TOKEN_URL);
sourceWso2User = getRequired(PROP_SOURCE_WSO2_USER);
targetRegistrationApiUrl = getRequired(PROP_TARGET_REGISTRATION_API_URL);
targetPublisherApiUrl = getRequired(PROP_TARGET_PUBLISHER_API_URL);
targetDevportalApiUrl = getRequired(PROP_TARGET_DEVPORTAL_API_URL);
targetPublisherTokenUrl = getRequired(PROP_TARGET_PUBLISHER_TOKEN_URL);
targetWso2User = getRequired(PROP_TARGET_WSO2_USER);
truststorePath = getRequired(PROP_TRUSTSTORE_PATH);
truststorePassword = getRequired(PROP_TRUSTSTORE_PASSWORD);
publisherUrlPattern = getRequired(PROP_PUBLISHER_URL_PATTERN);
devportalUrlPattern = getRequired(PROP_DEVPORTAL_URL_PATTERN);
apicurioApiUrl = getRequired(PROP_APICURIO_API_URL);
defaultApiGroup = getRequired(PROP_DEFAULT_API_GROUP);
maxThreads = Integer.parseInt(props.getProperty(PROP_MAX_THREADS, "10"));
} }
public static ConfigManager getInstance() { public static ConfigManager getInstance() {
@ -160,83 +71,7 @@ public final class ConfigManager {
return INSTANCE; return INSTANCE;
} }
private String getRequired(String key) { public ApplicationConfig getConfig() {
String value = props.getProperty(key); return config;
if (value == null) {
throw new IllegalStateException("Missing required property: " + key);
}
return value.trim();
}
/* -------------------------------------------------------------------- */
/* PUBLIC GETTERS */
/* -------------------------------------------------------------------- */
public String getSourceRegistrationApiUrl() {
return sourceRegistrationApiUrl;
}
public String getSourcePublisherApiUrl() {
return sourcePublisherApiUrl;
}
public String getSourceDevportalApiUrl() {
return sourceDevportalApiUrl;
}
public String getSourcePublisherTokenUrl() {
return sourcePublisherTokenUrl;
}
public String getSourceWso2User() {
return sourceWso2User;
}
public String getTargetRegistrationApiUrl() {
return targetRegistrationApiUrl;
}
public String getTargetPublisherApiUrl() {
return targetPublisherApiUrl;
}
public String getTargetDevportalApiUrl() {
return targetDevportalApiUrl;
}
public String getTargetPublisherTokenUrl() {
return targetPublisherTokenUrl;
}
public String getTargetWso2User() {
return targetWso2User;
}
public String getTruststorePath() {
return truststorePath;
}
public String getTruststorePassword() {
return truststorePassword;
}
public String getPublisherUrlPattern() {
return publisherUrlPattern;
}
public String getDevportalUrlPattern() {
return devportalUrlPattern;
}
public String getApicurioApiUrl() {
return apicurioApiUrl;
}
public String getDefaultApiGroup() {
return defaultApiGroup;
}
public int getMaxThreads() {
return maxThreads;
} }
} }

View File

@ -44,7 +44,7 @@ public class ImportToApicurio extends AbstractProcess {
private final RegistryClient client; private final RegistryClient client;
public ImportToApicurio() throws Exception { public ImportToApicurio() throws Exception {
this.client = RegistryClientFactory.create(config.getApicurioApiUrl()); this.client = RegistryClientFactory.create(config.getApicurio().getApiUrl());
} }
/** /**
@ -58,7 +58,7 @@ public class ImportToApicurio extends AbstractProcess {
TokenResponse token = authenticateToWso2AndGetToken(); TokenResponse token = authenticateToWso2AndGetToken();
APIList apis = getList(config.getSourcePublisherApiUrl(), token); APIList apis = getList(config.getSource().getPublisherApiUrl(), token);
if (apis == null || apis.getList() == null || apis.getList().length == 0) { if (apis == null || apis.getList() == null || apis.getList().length == 0) {
throw new IllegalStateException( throw new IllegalStateException(
"No APIs to export that match your criteria! Check the name of the API you want to export."); "No APIs to export that match your criteria! Check the name of the API you want to export.");
@ -105,16 +105,16 @@ public class ImportToApicurio extends AbstractProcess {
"Bearer " + tokenResponse.getAccess_token()); "Bearer " + tokenResponse.getAccess_token());
// 1) Retrieve basic information // 1) Retrieve basic information
HttpResponse apiInfoResp = makeRequest("GET", config.getSourceDevportalApiUrl() + "/apis/" + api.getId(), HttpResponse apiInfoResp = makeRequest("GET", config.getSource().getDevPortalApiUrl() + "/apis/" + api.getId(),
httpHeaders, Collections.emptyMap()); httpHeaders, Collections.emptyMap());
HttpResponse subsResp = makeRequest("GET", HttpResponse subsResp = makeRequest("GET",
config.getSourcePublisherApiUrl() + "/subscriptions?apiId=" + api.getId(), httpHeaders, config.getSource().getPublisherApiUrl() + "/subscriptions?apiId=" + api.getId(), httpHeaders,
Collections.emptyMap()); Collections.emptyMap());
// 2) Export the API as a zip // 2) Export the API as a zip
HttpResponse exportedZip = makeRequest("GET", HttpResponse exportedZip = makeRequest("GET",
config.getSourcePublisherApiUrl() + "/apis/export?apiId=" + api.getId(), httpHeaders, config.getSource().getPublisherApiUrl() + "/apis/export?apiId=" + api.getId(), httpHeaders,
Collections.emptyMap(), true); Collections.emptyMap(), true);
List<ZipEntryData> zipEntries = ZipUtils.extractFilesFromZip(exportedZip.getResponseBytes()); List<ZipEntryData> zipEntries = ZipUtils.extractFilesFromZip(exportedZip.getResponseBytes());
@ -147,8 +147,8 @@ public class ImportToApicurio extends AbstractProcess {
// 5) Build the description that contains the publisher & devportal URLs // 5) Build the description that contains the publisher & devportal URLs
String baseDesc = api.getDescription() != null ? api.getDescription() : ""; String baseDesc = api.getDescription() != null ? api.getDescription() : "";
String pubUrl = config.getPublisherUrlPattern().replace("{API_ID}", api.getId()); String pubUrl = config.getPatterns().getPublisherUrlPattern().replace("{API_ID}", api.getId());
String devPortUrl = config.getDevportalUrlPattern().replace("{API_ID}", api.getId()); String devPortUrl = config.getPatterns().getDevPortalUrlPattern().replace("{API_ID}", api.getId());
String fullDesc = baseDesc + " ***** PUBLISHER URL ***** " + pubUrl + " ***** DEVPORTAL URL ***** " String fullDesc = baseDesc + " ***** PUBLISHER URL ***** " + pubUrl + " ***** DEVPORTAL URL ***** "
+ devPortUrl; + devPortUrl;
@ -159,7 +159,7 @@ public class ImportToApicurio extends AbstractProcess {
updateSwagger(swaggerObj, apiMap, fullDesc); updateSwagger(swaggerObj, apiMap, fullDesc);
// 7) Prepare artifact creation/update // 7) Prepare artifact creation/update
String group = config.getDefaultApiGroup(); String group = config.getApicurio().getDefaultApiGroup();
String mainArtifactId = api.getName() + api.getContext(); String mainArtifactId = api.getName() + api.getContext();
VersionSearchResults existingArtifacts; VersionSearchResults existingArtifacts;

View File

@ -48,7 +48,7 @@ public class ExportToWso2FromV32 extends AbstractProcess {
private final RegistryClient client; private final RegistryClient client;
public ExportToWso2FromV32() throws Exception { public ExportToWso2FromV32() throws Exception {
this.client = RegistryClientFactory.create(config.getApicurioApiUrl()); this.client = RegistryClientFactory.create(config.getApicurio().getApiUrl());
} }
/** /**
@ -62,7 +62,7 @@ public class ExportToWso2FromV32 extends AbstractProcess {
TokenResponse token = authenticateToWso2AndGetToken(); TokenResponse token = authenticateToWso2AndGetToken();
ArtifactSearchResults apis = client.searchArtifacts(config.getDefaultApiGroup(), null, null, null, null, ArtifactSearchResults apis = client.searchArtifacts(config.getApicurio().getDefaultApiGroup(), null, null, null, null,
null, null, null, null); null, null, null, null);
log.info("Found {} APIs", apis.getCount()); log.info("Found {} APIs", apis.getCount());
@ -92,12 +92,12 @@ public class ExportToWso2FromV32 extends AbstractProcess {
try { try {
log.info("Processing API {} of {}", index, total); log.info("Processing API {} of {}", index, total);
VersionSearchResults versions = client.listArtifactVersions(config.getDefaultApiGroup(), api.getId(), null, VersionSearchResults versions = client.listArtifactVersions(config.getApicurio().getDefaultApiGroup(), api.getId(), null,
null); null);
for (SearchedVersion ver : versions.getVersions()) { for (SearchedVersion ver : versions.getVersions()) {
log.info(" - Found version: {}", ver.getVersion()); log.info(" - Found version: {}", ver.getVersion());
List<ArtifactReference> ref = client.getArtifactReferencesByCoordinates(config.getDefaultApiGroup(), List<ArtifactReference> ref = client.getArtifactReferencesByCoordinates(config.getApicurio().getDefaultApiGroup(),
api.getId(), ver.getVersion()); api.getId(), ver.getVersion());
if (ref != null && !ref.isEmpty()) { if (ref != null && !ref.isEmpty()) {
log.info("Artifact has {} references", ref.size()); log.info("Artifact has {} references", ref.size());
@ -135,7 +135,7 @@ public class ExportToWso2FromV32 extends AbstractProcess {
private int publishApiToWso2(String fileName, byte[] data, TokenResponse tokenResponse) { private int publishApiToWso2(String fileName, byte[] data, TokenResponse tokenResponse) {
int responseCode = -1; int responseCode = -1;
try { try {
String url = config.getTargetPublisherApiUrl() String url = config.getTarget().getPublisherApiUrl()
.concat(String.format("?preserveProvider=false&overwrite=true")); .concat(String.format("?preserveProvider=false&overwrite=true"));
log.info("API Import URL: " + url); log.info("API Import URL: " + url);

View File

@ -0,0 +1,75 @@
package cz.trask.migration.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class ApplicationConfig {
@JsonProperty("source")
private Source source;
@JsonProperty("target")
private Target target;
@JsonProperty("truststore")
private TrustStore trustStore;
@JsonProperty("patterns")
private Patterns patterns;
@JsonProperty("apicurio")
private Apicurio apicurio;
@JsonProperty("max_threads")
private int maxThreads;
@Data
public static class Source {
@JsonProperty("registration_api_url")
private String registrationApiUrl;
@JsonProperty("publisher_api_url")
private String publisherApiUrl;
@JsonProperty("devportal_api_url")
private String devPortalApiUrl;
@JsonProperty("publisher_token_url")
private String publisherTokenUrl;
@JsonProperty("wso2_user")
private String wso2User;
}
@Data
public static class TrustStore {
@JsonProperty("path")
private String path;
@JsonProperty("password")
private String password;
}
@Data
public static class Patterns {
@JsonProperty("publisher_url_pattern")
private String publisherUrlPattern;
@JsonProperty("devportal_url_pattern")
private String devPortalUrlPattern;
}
@Data
public static class Apicurio {
@JsonProperty("api_url")
private String apiUrl;
@JsonProperty("default_api_group")
private String defaultApiGroup;
}
@Data
public static class Target {
@JsonProperty("registration_api_url")
private String registrationApiUrl;
@JsonProperty("publisher_api_url")
private String publisherApiUrl;
@JsonProperty("devportal_api_url")
private String devPortalApiUrl;
@JsonProperty("publisher_token_url")
private String publisherTokenUrl;
@JsonProperty("wso2_user")
private String wso2User;
}
}

View File

@ -1,25 +0,0 @@
# Source WSO2 API Manager v3.2.0
SOURCE_REGISTRATION_API_URL = https://localhost:9443/client-registration/v0.17/register
SOURCE_PUBLISHER_API_URL = https://localhost:9443/api/am/publisher
SOURCE_DEVPORTAL_API_URL = https://localhost:9443/api/am/store
SOURCE_PUBLISHER_TOKEN_URL = https://localhost:9443/oauth2/token
SOURCE_WSO2_USER = YWRtaW46YWRtaW4=
# Target WSO2 API Manager v4.5.0
TARGET_REGISTRATION_API_URL = https://localhost:9443/client-registration/v0.17/register
TARGET_PUBLISHER_API_URL = https://localhost:9443/api/am/publisher/v4/apis/import
TARGET_DEVPORTAL_API_URL = https://localhost:9443/api/am/devportal
TARGET_PUBLISHER_TOKEN_URL = https://localhost:9443/oauth2/token
TARGET_WSO2_USER = YWRtaW46YWRtaW4=
TRUSTSTORE_PATH = client-truststore.jks
TRUSTSTORE_PASSWORD = wso2carbon
PUBLISHER_URL_PATTERN = https://api-developers.dev.koop.appl.services/publisher/apis/{API_ID}/overview
DEVPORTAL_URL_PATTERN = https://api-developers.dev.koop.appl.services/devportal/apis/{API_ID}/overview
#APICURIO_API_URL = http://10.0.0.190:8080/apis/registry/v2
APICURIO_API_URL = http://apicurio:8095/apis/registry/v2
DEFAULT_API_GROUP = api
MAX_THREADS = 1

View File

@ -0,0 +1,27 @@
source:
registration_api_url: https://localhost:9443/client-registration/v0.17/register
publisher_api_url: https://localhost:9443/api/am/publisher
devportal_api_url: https://localhost:9443/api/am/store
publisher_token_url: https://localhost:9443/oauth2/token
wso2_user: YWRtaW46YWRtaW4=
target:
registration_api_url: https://localhost:9443/client-registration/v0.17/register
publisher_api_url: https://localhost:9443/api/am/publisher/v4/apis/import
devportal_api_url: https://localhost:9443/api/am/devportal
publisher_token_url: https://localhost:9443/oauth2/token
wso2_user: YWRtaW46YWRtaW4=
truststore:
path: client-truststore.jks
password: wso2carbon
patterns:
publisher_url_pattern: https://api-developers.dev.koop.appl.services/publisher/apis/{API_ID}/overview
devportal_url_pattern: https://api-developers.dev.koop.appl.services/devportal/apis/{API_ID}/overview
apicurio:
api_url: http://apicurio:8095/apis/registry/v2
default_api_group: api
max_threads: 1