first commit
This commit is contained in:
commit
0bda9455ca
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
target
|
||||||
|
bin
|
||||||
|
.settings
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
*.log
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
BIN
client-truststore.jks
Normal file
BIN
client-truststore.jks
Normal file
Binary file not shown.
93
pom.xml
Normal file
93
pom.xml
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>cz.trask.migration</groupId>
|
||||||
|
<artifactId>apicurio-migration-tool</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<name>apicurio-migration-tool</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>11</java.version>
|
||||||
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- https://mvnrepository.com/artifact/io.apicurio/apicurio-registry-client -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.apicurio</groupId>
|
||||||
|
<artifactId>apicurio-registry-client</artifactId>
|
||||||
|
<version>2.6.13.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-core</artifactId>
|
||||||
|
<version>2.24.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>2.13.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.yaml</groupId>
|
||||||
|
<artifactId>snakeyaml</artifactId>
|
||||||
|
<version>2.4</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>3.6.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
|
<transformers>
|
||||||
|
<transformer
|
||||||
|
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
|
<mainClass>cz.trask.apioperator.ApiSync</mainClass>
|
||||||
|
</transformer>
|
||||||
|
</transformers>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.4.1</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>cz.trask.apioperator.ApiSync</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>wso2.releases</id>
|
||||||
|
<name>WSO2 internal Repository</name>
|
||||||
|
<url>https://maven.wso2.org/nexus/content/repositories/releases/</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<updatePolicy>daily</updatePolicy>
|
||||||
|
<checksumPolicy>ignore</checksumPolicy>
|
||||||
|
</releases>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
</project>
|
||||||
388
src/main/java/cz/trask/migration/AbstractProcess.java
Normal file
388
src/main/java/cz/trask/migration/AbstractProcess.java
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
package cz.trask.migration;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
|
import cz.trask.migration.config.ConfigManager;
|
||||||
|
import cz.trask.migration.model.APIList;
|
||||||
|
import cz.trask.migration.model.HttpResponse;
|
||||||
|
import cz.trask.migration.model.RegisterResponse;
|
||||||
|
import cz.trask.migration.model.TokenResponse;
|
||||||
|
|
||||||
|
public abstract class AbstractProcess {
|
||||||
|
|
||||||
|
private static Logger log = LogManager.getLogger(AbstractProcess.class);
|
||||||
|
|
||||||
|
protected Gson gson;
|
||||||
|
|
||||||
|
protected Yaml yaml;
|
||||||
|
|
||||||
|
protected ConfigManager config = ConfigManager.getInstance();
|
||||||
|
|
||||||
|
protected AbstractProcess() {
|
||||||
|
|
||||||
|
gson = new GsonBuilder().create();
|
||||||
|
|
||||||
|
yaml = new Yaml();
|
||||||
|
|
||||||
|
setTrustStoreCredentials();
|
||||||
|
|
||||||
|
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new javax.net.ssl.HostnameVerifier() {
|
||||||
|
public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getTrustStorePath() {
|
||||||
|
String path = config.getTruststorePath();
|
||||||
|
if (!new File(path).canRead()) {
|
||||||
|
path = System.getProperty("user.dir") + File.separatorChar + config.getTruststorePath();
|
||||||
|
if (!new File(path).canRead()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setTrustStoreCredentials() {
|
||||||
|
log.info(getTrustStorePath());
|
||||||
|
System.setProperty("javax.net.ssl.trustStore", getTrustStorePath());
|
||||||
|
System.setProperty("javax.net.ssl.trustStorePassword", config.getTruststorePassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve access token based on clientId and clientSecret
|
||||||
|
*
|
||||||
|
* @param reg - client application object with clientId and clientSecret
|
||||||
|
* @param scope - requested OAuth2 scope
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected TokenResponse getToken(String publisherurl, String wso2User, RegisterResponse reg, String scope)
|
||||||
|
throws Exception {
|
||||||
|
|
||||||
|
byte[] decoded = Base64.getDecoder().decode(wso2User);
|
||||||
|
String decodedstring = new String(decoded);
|
||||||
|
String[] decodedstringparts = decodedstring.split(":");
|
||||||
|
|
||||||
|
String username = decodedstringparts[0];
|
||||||
|
String password = decodedstringparts[1];
|
||||||
|
|
||||||
|
log.debug("Getting token with Username: '" + wso2User + "' URL: " + publisherurl);
|
||||||
|
|
||||||
|
Map<String, String> httpHeaders = new HashMap<>();
|
||||||
|
|
||||||
|
httpHeaders.put("Authorization", "Basic ".concat(Base64.getEncoder()
|
||||||
|
.encodeToString(reg.getClientId().concat(":").concat(reg.getClientSecret()).getBytes())));
|
||||||
|
httpHeaders.put("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
String data = "grant_type=password&username=".concat(username).concat("&password=")
|
||||||
|
.concat(URLEncoder.encode(password, "UTF-8")).concat("&scope=").concat(scope);
|
||||||
|
HttpResponse response = makeDataRequest(publisherurl, httpHeaders, data);
|
||||||
|
|
||||||
|
log.debug("Token response: HTTP Code " + response.getResponseCode() + " Json: " + response.getResponse());
|
||||||
|
|
||||||
|
TokenResponse resp = gson.fromJson(response.getResponse(), TokenResponse.class);
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register client application to get clientId and clientSecret
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected RegisterResponse register(String publisherurl, String wso2User) throws Exception {
|
||||||
|
|
||||||
|
log.debug("Registering with Username: '" + wso2User + "' URL: " + publisherurl);
|
||||||
|
|
||||||
|
byte[] decodedUserBytes = Base64.getDecoder().decode(wso2User);
|
||||||
|
String decodeduserappkey = new String(decodedUserBytes);
|
||||||
|
String[] decodeduserparts = decodeduserappkey.split(":");
|
||||||
|
String decodeduser = decodeduserparts[0];
|
||||||
|
|
||||||
|
Map<String, String> httpHeaders = new HashMap<>();
|
||||||
|
|
||||||
|
httpHeaders.put("Authorization", "Basic ".concat(wso2User));
|
||||||
|
httpHeaders.put("Content-Type", "application/json");
|
||||||
|
|
||||||
|
String data = "{\"callbackUrl\": \"www.google.lk\",\"clientName\": \"rest_api_publisher" + decodeduser
|
||||||
|
+ "\",\"owner\": \"" + decodeduser + "\",\"grantType\": \"password refresh_token\",\"saasApp\": true}";
|
||||||
|
HttpResponse response = makeDataRequest(publisherurl, httpHeaders, data);
|
||||||
|
|
||||||
|
log.debug(
|
||||||
|
"Register API response: HTTP Code " + response.getResponseCode() + " Json: " + response.getResponse());
|
||||||
|
|
||||||
|
RegisterResponse resp = gson.fromJson(response.getResponse(), RegisterResponse.class);
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common function used for http request
|
||||||
|
*
|
||||||
|
* @param method - http method
|
||||||
|
* @param urlStr - url to dev poral
|
||||||
|
* @param httpHeaders
|
||||||
|
* @param params - currently is not used
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected HttpResponse makeRequest(String method, String urlStr, Map<String, String> httpHeaders,
|
||||||
|
Map<String, String> params) throws Exception {
|
||||||
|
return makeRequest(method, urlStr, httpHeaders, params, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common function used for http request
|
||||||
|
*
|
||||||
|
* @param method - http method
|
||||||
|
* @param urlStr - url to dev poral
|
||||||
|
* @param httpHeaders
|
||||||
|
* @param data - request data
|
||||||
|
* @param binary - binary or text mode
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected HttpResponse makeRequest(String method, String urlStr, Map<String, String> httpHeaders,
|
||||||
|
Map<String, String> params, boolean binary) throws Exception {
|
||||||
|
|
||||||
|
log.info("Calling URL: " + urlStr);
|
||||||
|
String query = "";
|
||||||
|
for (String key : params.keySet()) {
|
||||||
|
query = query.concat(URLEncoder.encode(key, "UTF-8")).concat("=")
|
||||||
|
.concat(URLEncoder.encode(params.get(key), "UTF-8")).concat("&");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.length() > 1 && "GET".equals(method)) {
|
||||||
|
urlStr = urlStr.concat("?").concat(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
URL url = new URL(urlStr);
|
||||||
|
|
||||||
|
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||||
|
con.setRequestMethod(method);
|
||||||
|
con.setDoInput(true);
|
||||||
|
|
||||||
|
for (String key : httpHeaders.keySet()) {
|
||||||
|
con.addRequestProperty(key, httpHeaders.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.length() > 1 && "POST".equals(method)) {
|
||||||
|
con.setDoOutput(true);
|
||||||
|
OutputStream out = con.getOutputStream();
|
||||||
|
out.write(query.getBytes("UTF-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream in = con.getInputStream();
|
||||||
|
|
||||||
|
String res = "";
|
||||||
|
byte[] buf = new byte[4096];
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
int read = in.read(buf);
|
||||||
|
|
||||||
|
while (read != -1) {
|
||||||
|
if (binary)
|
||||||
|
baos.write(buf, 0, read);
|
||||||
|
else
|
||||||
|
res = res.concat(new String(buf, 0, read));
|
||||||
|
|
||||||
|
read = in.read(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
baos.flush();
|
||||||
|
|
||||||
|
HttpResponse resp = new HttpResponse();
|
||||||
|
resp.setHeaders(con.getHeaderFields());
|
||||||
|
if (binary)
|
||||||
|
resp.setResponseBytes(baos.toByteArray());
|
||||||
|
else
|
||||||
|
resp.setResponse(res);
|
||||||
|
resp.setResponseCode(con.getResponseCode());
|
||||||
|
|
||||||
|
con.disconnect();
|
||||||
|
|
||||||
|
log.info("Response code: " + resp.getResponseCode());
|
||||||
|
// log.info("Response: " + resp.getResponse());
|
||||||
|
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common function used for http request
|
||||||
|
*
|
||||||
|
* @param urlStr - url to dev poral
|
||||||
|
* @param httpHeaders
|
||||||
|
* @param data - request data
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected HttpResponse makeDataRequest(String urlStr, Map<String, String> httpHeaders, String data)
|
||||||
|
throws Exception {
|
||||||
|
|
||||||
|
byte[] json = data.getBytes(Charset.forName("UTF-8"));
|
||||||
|
|
||||||
|
URL url = new URL(urlStr);
|
||||||
|
|
||||||
|
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
|
||||||
|
con.setRequestMethod("POST");
|
||||||
|
con.setDoInput(true);
|
||||||
|
con.setDoOutput(true);
|
||||||
|
|
||||||
|
for (String key : httpHeaders.keySet()) {
|
||||||
|
con.addRequestProperty(key, httpHeaders.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
con.addRequestProperty("Content-Length", "" + json.length);
|
||||||
|
|
||||||
|
OutputStream out = con.getOutputStream();
|
||||||
|
out.write(json);
|
||||||
|
|
||||||
|
InputStream in = con.getInputStream();
|
||||||
|
|
||||||
|
String res = "";
|
||||||
|
byte[] buf = new byte[4096];
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
int read = in.read(buf);
|
||||||
|
|
||||||
|
while (read != -1) {
|
||||||
|
res = res.concat(new String(buf, 0, read));
|
||||||
|
read = in.read(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
baos.flush();
|
||||||
|
|
||||||
|
HttpResponse resp = new HttpResponse();
|
||||||
|
resp.setHeaders(con.getHeaderFields());
|
||||||
|
resp.setResponse(res);
|
||||||
|
resp.setResponseCode(con.getResponseCode());
|
||||||
|
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the list of APIs by name.
|
||||||
|
*
|
||||||
|
* @param tokenResponse - WSO2 APIM access token
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected APIList getList(String publisherurl, TokenResponse tokenResponse) throws Exception {
|
||||||
|
|
||||||
|
APIList listOfApis = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
String url = publisherurl.concat(String.format("/apis?limit=9999&offset=0"));
|
||||||
|
|
||||||
|
log.debug("Getting APIs with token: '" + tokenResponse.getAccess_token() + "' URL: " + url);
|
||||||
|
|
||||||
|
Map<String, String> httpHeaders = new HashMap<>();
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
|
||||||
|
httpHeaders.put("Authorization", "Bearer ".concat(tokenResponse.getAccess_token()));
|
||||||
|
|
||||||
|
HttpResponse response = makeRequest("GET", url, httpHeaders, params);
|
||||||
|
|
||||||
|
log.debug("Listing APIs: HTTP Code " + response.getResponseCode() + " Data: " + response.getResponse());
|
||||||
|
|
||||||
|
listOfApis = gson.fromJson(response.getResponse(), APIList.class);
|
||||||
|
|
||||||
|
if (response.getResponseCode() != 200)
|
||||||
|
log.error("Cannot list API. Something bad happened.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Cannot list API:" + e);
|
||||||
|
throw new Exception("Cannot list API:" + e.getMessage());
|
||||||
|
}
|
||||||
|
return listOfApis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common function used for upload API
|
||||||
|
*
|
||||||
|
* @param urlStr - url to dev poral
|
||||||
|
* @param httpHeaders
|
||||||
|
* @param params - currently is not used
|
||||||
|
* @param api - zip file to upload
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected static HttpResponse makeFileRequest(String method, String urlStr, Map<String, String> httpHeaders,
|
||||||
|
byte[] buff, String attachmentFileName) throws Exception {
|
||||||
|
|
||||||
|
if (buff == null) {
|
||||||
|
log.error("Cannot send NULL payload to rest service.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String crlf = "\r\n";
|
||||||
|
|
||||||
|
String twoHyphens = "--";
|
||||||
|
String boundary = "----" + System.currentTimeMillis() + "----";
|
||||||
|
|
||||||
|
URL url = new URL(urlStr);
|
||||||
|
|
||||||
|
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
|
||||||
|
con.setUseCaches(false);
|
||||||
|
con.setDoOutput(true);
|
||||||
|
|
||||||
|
con.setRequestMethod(method);
|
||||||
|
con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
|
||||||
|
con.setRequestProperty("User-Agent", "curl/7.55.1");
|
||||||
|
con.setRequestProperty("Accept", "*/*");
|
||||||
|
|
||||||
|
for (String key : httpHeaders.keySet()) {
|
||||||
|
con.addRequestProperty(key, httpHeaders.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
DataOutputStream request = new DataOutputStream(con.getOutputStream());
|
||||||
|
request.writeBytes(crlf);
|
||||||
|
request.writeBytes(twoHyphens + boundary + crlf);
|
||||||
|
request.writeBytes(
|
||||||
|
"Content-Disposition: form-data; name=\"file\"; filename=\"" + attachmentFileName + "\"" + crlf);
|
||||||
|
request.writeBytes("Content-Type: application/octet-stream" + crlf);
|
||||||
|
request.writeBytes("Content-Transfer-Encoding: binary" + crlf);
|
||||||
|
request.writeBytes(crlf);
|
||||||
|
request.write(buff);
|
||||||
|
request.writeBytes(crlf);
|
||||||
|
request.writeBytes(twoHyphens + boundary + twoHyphens + crlf);
|
||||||
|
request.flush();
|
||||||
|
request.close();
|
||||||
|
|
||||||
|
String res = "";
|
||||||
|
byte[] buf = new byte[4096];
|
||||||
|
|
||||||
|
HttpResponse resp = new HttpResponse();
|
||||||
|
InputStream in;
|
||||||
|
int responseCode = con.getResponseCode();
|
||||||
|
|
||||||
|
if (responseCode == 200 || responseCode == 201) {
|
||||||
|
in = con.getInputStream();
|
||||||
|
} else {
|
||||||
|
in = con.getErrorStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (in.available() > 0) {
|
||||||
|
int read = in.read(buf);
|
||||||
|
res = res.concat(new String(buf, 0, read));
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.setHeaders(con.getHeaderFields());
|
||||||
|
resp.setResponse(res);
|
||||||
|
resp.setResponseCode(responseCode);
|
||||||
|
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/main/java/cz/trask/migration/ApiSync.java
Normal file
45
src/main/java/cz/trask/migration/ApiSync.java
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package cz.trask.migration;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import cz.trask.migration.impl.ExportToWso2;
|
||||||
|
import cz.trask.migration.impl.ImportToApicurio;
|
||||||
|
import cz.trask.migration.model.StartParameters;
|
||||||
|
|
||||||
|
public class ApiSync {
|
||||||
|
|
||||||
|
private static Logger log = LogManager.getLogger(ApiSync.class);
|
||||||
|
|
||||||
|
protected final static String resourceName = "api-operator.properties";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
log.info("API Operator started.");
|
||||||
|
if (args == null) {
|
||||||
|
log.error("No parameters found.");
|
||||||
|
printHelp();
|
||||||
|
} else {
|
||||||
|
String commandLine = String.join("", args).trim();
|
||||||
|
StartParameters sp = StartParameters.parse(commandLine);
|
||||||
|
log.info("Parsed parameters: " + sp);
|
||||||
|
|
||||||
|
if (sp.getCommand().equals("import")) {
|
||||||
|
log.info("Import command selected.");
|
||||||
|
ImportToApicurio imp = new ImportToApicurio();
|
||||||
|
imp.process();
|
||||||
|
} else if (sp.getCommand().equals("export")) {
|
||||||
|
log.info("Export command selected.");
|
||||||
|
ExportToWso2 exp = new ExportToWso2();
|
||||||
|
exp.process();
|
||||||
|
log.error("Export command not implemented yet.");
|
||||||
|
} else {
|
||||||
|
log.error("Unknown command: " + sp.getCommand());
|
||||||
|
printHelp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printHelp() {
|
||||||
|
System.out.println("Not enough parameters.\nRun command in this format:\njava -jar shaded.jar [import/export]");
|
||||||
|
}
|
||||||
|
}
|
||||||
242
src/main/java/cz/trask/migration/config/ConfigManager.java
Normal file
242
src/main/java/cz/trask/migration/config/ConfigManager.java
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
package cz.trask.migration.config;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
public final class ConfigManager {
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/* LOGIC & CONSTANTS */
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
private static final Logger log = LogManager.getLogger(ConfigManager.class);
|
||||||
|
|
||||||
|
private static final String PROPERTY_FILENAME = "api-operator.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;
|
||||||
|
|
||||||
|
/** Všechny načtené hodnoty. */
|
||||||
|
private final Properties props = new Properties();
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/* SINGLETON – lazy‑initialization‑on-demand holder */
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
private ConfigManager() {
|
||||||
|
|
||||||
|
log.info("Loading property file '{}'", PROPERTY_FILENAME);
|
||||||
|
|
||||||
|
InputStream in = null;
|
||||||
|
try {
|
||||||
|
File extFile = new File(PROPERTY_FILENAME);
|
||||||
|
if (extFile.exists() && extFile.isFile()) {
|
||||||
|
log.info("External property file found: {}", extFile.getAbsolutePath());
|
||||||
|
in = Files.newInputStream(extFile.toPath());
|
||||||
|
} else {
|
||||||
|
log.debug("External property file not found.");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Error while accessing external property file", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in == null) {
|
||||||
|
try {
|
||||||
|
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||||
|
in = cl.getResourceAsStream(PROPERTY_FILENAME);
|
||||||
|
if (in != null) {
|
||||||
|
log.info("Internal property file found on classpath.");
|
||||||
|
} else {
|
||||||
|
log.warn("Property file '{}' not found on classpath.", PROPERTY_FILENAME);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Unable to load property file from classpath", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try (InputStream input = in) {
|
||||||
|
if (input != null) {
|
||||||
|
props.load(input);
|
||||||
|
log.info("Property file loaded successfully.");
|
||||||
|
} else {
|
||||||
|
log.warn("No property source available; proceeding with defaults where possible.");
|
||||||
|
}
|
||||||
|
} catch (Exception 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() {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
synchronized (ConfigManager.class) {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
INSTANCE = new ConfigManager();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRequired(String key) {
|
||||||
|
String value = props.getProperty(key);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
152
src/main/java/cz/trask/migration/impl/ExportToWso2.java
Normal file
152
src/main/java/cz/trask/migration/impl/ExportToWso2.java
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
package cz.trask.migration.impl;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import cz.trask.migration.AbstractProcess;
|
||||||
|
import cz.trask.migration.model.HttpResponse;
|
||||||
|
import cz.trask.migration.model.RegisterResponse;
|
||||||
|
import cz.trask.migration.model.TokenResponse;
|
||||||
|
import cz.trask.migration.utils.ZipUtils;
|
||||||
|
import io.apicurio.registry.rest.client.RegistryClient;
|
||||||
|
import io.apicurio.registry.rest.client.RegistryClientFactory;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.ArtifactReference;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.ArtifactSearchResults;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.SearchedArtifact;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.SearchedVersion;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.VersionSearchResults;
|
||||||
|
|
||||||
|
public class ExportToWso2 extends AbstractProcess {
|
||||||
|
|
||||||
|
private static final Logger log = LogManager.getLogger(ExportToWso2.class);
|
||||||
|
|
||||||
|
private final AtomicInteger apiCounter = new AtomicInteger(1);
|
||||||
|
|
||||||
|
private final RegistryClient client;
|
||||||
|
|
||||||
|
public ExportToWso2() throws Exception {
|
||||||
|
this.client = RegistryClientFactory.create(config.getApicurioApiUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main entry point for the import process.
|
||||||
|
*
|
||||||
|
* @throws RuntimeException if any error occurs
|
||||||
|
*/
|
||||||
|
public void process() {
|
||||||
|
try {
|
||||||
|
log.info("Starting API export to WSO2 from Apicurio...");
|
||||||
|
|
||||||
|
RegisterResponse register = register(config.getSourceRegistrationApiUrl(), config.getSourceWso2User());
|
||||||
|
|
||||||
|
String clientId = register.getClientId();
|
||||||
|
log.info("Registered with clientId: {}", clientId);
|
||||||
|
|
||||||
|
TokenResponse token = getToken(config.getSourcePublisherTokenUrl(), config.getSourceWso2User(), register,
|
||||||
|
"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:threat_protection_policy_create apim:threat_protection_policy_manage apim:document_create apim:document_manage "
|
||||||
|
+ "apim:mediation_policy_view apim:mediation_policy_create apim:mediation_policy_manage apim:client_certificates_view "
|
||||||
|
+ "apim:client_certificates_add apim:client_certificates_update apim:ep_certificates_view apim:ep_certificates_add "
|
||||||
|
+ "apim:ep_certificates_update apim:publisher_settings apim:pub_alert_manage apim:shared_scope_manage apim:app_import_export "
|
||||||
|
+ "apim:api_import_export apim:api_product_import_export apim:api_generate_key apim:common_operation_policy_view "
|
||||||
|
+ "apim:common_operation_policy_manage apim:comment_write apim:comment_view apim:admin");
|
||||||
|
|
||||||
|
log.debug("Access token received – {}", token.getAccess_token());
|
||||||
|
|
||||||
|
ArtifactSearchResults apis = client.searchArtifacts(config.getDefaultApiGroup(), null, null, null, null,
|
||||||
|
null, null, null, null);
|
||||||
|
|
||||||
|
log.info("Found {} APIs", apis.getCount());
|
||||||
|
|
||||||
|
int maxThreads = config.getMaxThreads();
|
||||||
|
ExecutorService executor = Executors.newFixedThreadPool(maxThreads);
|
||||||
|
|
||||||
|
for (SearchedArtifact api : apis.getArtifacts()) {
|
||||||
|
final int index = apiCounter.getAndIncrement();
|
||||||
|
executor.submit(() -> processApi(api, token, index, apis.getCount()));
|
||||||
|
}
|
||||||
|
|
||||||
|
executor.shutdown();
|
||||||
|
if (!executor.awaitTermination(10, TimeUnit.MINUTES)) {
|
||||||
|
log.warn("Timeout waiting for API import tasks to finish");
|
||||||
|
}
|
||||||
|
log.info("Finished processing APIs.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error while exporting APIs.", e);
|
||||||
|
throw new RuntimeException("Export failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processApi(SearchedArtifact api, TokenResponse tokenResponse, int index, int total) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
|
try {
|
||||||
|
log.info("Processing API {} of {}", index, total);
|
||||||
|
|
||||||
|
VersionSearchResults versions = client.listArtifactVersions(config.getDefaultApiGroup(), api.getId(), null,
|
||||||
|
null);
|
||||||
|
|
||||||
|
for (SearchedVersion ver : versions.getVersions()) {
|
||||||
|
log.info(" - Found version: {}", ver.getVersion());
|
||||||
|
List<ArtifactReference> ref = client.getArtifactReferencesByCoordinates(config.getDefaultApiGroup(),
|
||||||
|
api.getId(), ver.getVersion());
|
||||||
|
if (ref != null && !ref.isEmpty()) {
|
||||||
|
log.info("Artifact has {} references", ref.size());
|
||||||
|
byte[] data = ZipUtils.prepareApiZipFile(client, ver, ref);
|
||||||
|
String fileName = api.getName() + "-" + ver.getVersion() + ".zip";
|
||||||
|
if (data != null && data.length > 0 && fileName != null && !fileName.isEmpty()) {
|
||||||
|
int responseCode = publishApiToWso2(fileName, data, tokenResponse);
|
||||||
|
if (responseCode == 200 || responseCode == 201) {
|
||||||
|
log.info(" - API version {} imported successfully", ver.getVersion());
|
||||||
|
} else {
|
||||||
|
log.warn(" - API version {} import failed with response code {}", ver.getVersion(),
|
||||||
|
responseCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
log.info("Finished processing API {} of {} in {} ms", index, total, (end - start));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IO error while importing API {}: {}", api.getId(), e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
/* Helper methods */
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
private int publishApiToWso2(String fileName, byte[] data, TokenResponse tokenResponse) {
|
||||||
|
int responseCode = -1;
|
||||||
|
try {
|
||||||
|
String url = config.getTargetPublisherApiUrl()
|
||||||
|
.concat(String.format("?preserveProvider=false&overwrite=true"));
|
||||||
|
|
||||||
|
log.info("API Import URL: " + url);
|
||||||
|
|
||||||
|
Map<String, String> 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());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IO error while importing API file: " + fileName + ", error: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
357
src/main/java/cz/trask/migration/impl/ImportToApicurio.java
Normal file
357
src/main/java/cz/trask/migration/impl/ImportToApicurio.java
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
package cz.trask.migration.impl;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import cz.trask.migration.AbstractProcess;
|
||||||
|
import cz.trask.migration.model.APIInfo;
|
||||||
|
import cz.trask.migration.model.APIList;
|
||||||
|
import cz.trask.migration.model.FileType;
|
||||||
|
import cz.trask.migration.model.HttpResponse;
|
||||||
|
import cz.trask.migration.model.RegisterResponse;
|
||||||
|
import cz.trask.migration.model.TokenResponse;
|
||||||
|
import cz.trask.migration.model.ZipEntryData;
|
||||||
|
import cz.trask.migration.utils.ZipUtils;
|
||||||
|
import io.apicurio.registry.rest.client.RegistryClient;
|
||||||
|
import io.apicurio.registry.rest.client.RegistryClientFactory;
|
||||||
|
import io.apicurio.registry.rest.client.exception.VersionAlreadyExistsException;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.ArtifactMetaData;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.ArtifactReference;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.EditableMetaData;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.Rule;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.VersionSearchResults;
|
||||||
|
import io.apicurio.registry.types.RuleType;
|
||||||
|
|
||||||
|
public class ImportToApicurio extends AbstractProcess {
|
||||||
|
|
||||||
|
private static final Logger log = LogManager.getLogger(ImportToApicurio.class);
|
||||||
|
|
||||||
|
private final AtomicInteger apiCounter = new AtomicInteger(1);
|
||||||
|
|
||||||
|
private final RegistryClient client;
|
||||||
|
|
||||||
|
public ImportToApicurio() throws Exception {
|
||||||
|
this.client = RegistryClientFactory.create(config.getApicurioApiUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main entry point for the import process.
|
||||||
|
*
|
||||||
|
* @throws RuntimeException if any error occurs
|
||||||
|
*/
|
||||||
|
public void process() {
|
||||||
|
try {
|
||||||
|
log.info("Starting API import to Apicurio from WSO2...");
|
||||||
|
|
||||||
|
RegisterResponse register = register(config.getSourceRegistrationApiUrl(), config.getSourceWso2User());
|
||||||
|
|
||||||
|
String clientId = register.getClientId();
|
||||||
|
log.info("Registered with clientId: {}", clientId);
|
||||||
|
|
||||||
|
TokenResponse token = getToken(config.getSourcePublisherTokenUrl(), config.getSourceWso2User(), register,
|
||||||
|
"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:threat_protection_policy_create apim:threat_protection_policy_manage apim:document_create apim:document_manage "
|
||||||
|
+ "apim:mediation_policy_view apim:mediation_policy_create apim:mediation_policy_manage apim:client_certificates_view "
|
||||||
|
+ "apim:client_certificates_add apim:client_certificates_update apim:ep_certificates_view apim:ep_certificates_add "
|
||||||
|
+ "apim:ep_certificates_update apim:publisher_settings apim:pub_alert_manage apim:shared_scope_manage apim:app_import_export "
|
||||||
|
+ "apim:api_import_export apim:api_product_import_export apim:api_generate_key apim:common_operation_policy_view "
|
||||||
|
+ "apim:common_operation_policy_manage apim:comment_write apim:comment_view apim:admin");
|
||||||
|
|
||||||
|
log.debug("Access token received – {}", token.getAccess_token());
|
||||||
|
|
||||||
|
APIList apis = getList(config.getSourcePublisherApiUrl(), token);
|
||||||
|
if (apis == null || apis.getList() == null || apis.getList().length == 0) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"No APIs to export that match your criteria! Check the name of the API you want to export.");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("Found {} APIs", apis.getCount());
|
||||||
|
|
||||||
|
int maxThreads = config.getMaxThreads();
|
||||||
|
ExecutorService executor = Executors.newFixedThreadPool(maxThreads);
|
||||||
|
|
||||||
|
for (APIInfo api : apis.getList()) {
|
||||||
|
final int index = apiCounter.getAndIncrement();
|
||||||
|
executor.submit(() -> processApi(api, token, index, apis.getCount()));
|
||||||
|
}
|
||||||
|
|
||||||
|
executor.shutdown();
|
||||||
|
if (!executor.awaitTermination(10, TimeUnit.MINUTES)) {
|
||||||
|
log.warn("Timeout waiting for API import tasks to finish");
|
||||||
|
}
|
||||||
|
log.info("Finished processing APIs.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error while exporting APIs.", e);
|
||||||
|
throw new RuntimeException("Export failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a single API – fetches the data, creates or updates the corresponding
|
||||||
|
* artifact in Apicurio.
|
||||||
|
*/
|
||||||
|
private void processApi(APIInfo api, TokenResponse tokenResponse, int index, int total) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
String status = api.getLifeCycleStatus();
|
||||||
|
|
||||||
|
if (!status.contains("PUBLISHED") && !status.contains("DEPRECATED")) {
|
||||||
|
log.info("Skipping API {} of {} – not published (ID={})", index, total, api.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
log.info("Processing API {} of {}", index, total);
|
||||||
|
|
||||||
|
Map<String, String> httpHeaders = Collections.singletonMap("Authorization",
|
||||||
|
"Bearer " + tokenResponse.getAccess_token());
|
||||||
|
|
||||||
|
// 1) Retrieve basic information
|
||||||
|
HttpResponse apiInfoResp = makeRequest("GET", config.getSourceDevportalApiUrl() + "/apis/" + api.getId(),
|
||||||
|
httpHeaders, Collections.emptyMap());
|
||||||
|
|
||||||
|
HttpResponse subsResp = makeRequest("GET",
|
||||||
|
config.getSourcePublisherApiUrl() + "/subscriptions?apiId=" + api.getId(), httpHeaders,
|
||||||
|
Collections.emptyMap());
|
||||||
|
|
||||||
|
// 2) Export the API as a zip
|
||||||
|
HttpResponse exportedZip = makeRequest("GET",
|
||||||
|
config.getSourcePublisherApiUrl() + "/apis/export?apiId=" + api.getId(), httpHeaders,
|
||||||
|
Collections.emptyMap(), true);
|
||||||
|
|
||||||
|
List<ZipEntryData> zipEntries = ZipUtils.extractFilesFromZip(exportedZip.getResponseBytes());
|
||||||
|
|
||||||
|
String swagger = null;
|
||||||
|
|
||||||
|
for (ZipEntryData e : zipEntries) {
|
||||||
|
if (e.getType().toString().equals(FileType.OPENAPI.toString())) {
|
||||||
|
log.debug("Found main API definition file: {}", e.getName());
|
||||||
|
swagger = new String(e.getContent());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) Deserialize JSON responses
|
||||||
|
TypeToken<Map<String, Object>> mapType = new TypeToken<>() {
|
||||||
|
};
|
||||||
|
Map<String, Object> apiMap = gson.fromJson(apiInfoResp.getResponse(), mapType.getType());
|
||||||
|
Map<String, Object> subsMap = gson.fromJson(subsResp.getResponse(), mapType.getType());
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<String> tagsList = (List<String>) apiMap.get("tags");
|
||||||
|
|
||||||
|
// 4) Build the properties map
|
||||||
|
Map<String, String> props = new LinkedHashMap<>();
|
||||||
|
props.put("version", api.getVersion());
|
||||||
|
props.put("status", status);
|
||||||
|
addSubscriptionsToProps(props, subsMap);
|
||||||
|
addEndpointsToProps(props, apiMap);
|
||||||
|
addTagsToProps(props, tagsList);
|
||||||
|
|
||||||
|
// 5) Build the description that contains the publisher & devportal URLs
|
||||||
|
String baseDesc = api.getDescription() != null ? api.getDescription() : "";
|
||||||
|
String pubUrl = config.getPublisherUrlPattern().replace("{API_ID}", api.getId());
|
||||||
|
String devPortUrl = config.getDevportalUrlPattern().replace("{API_ID}", api.getId());
|
||||||
|
|
||||||
|
String fullDesc = baseDesc + " ***** PUBLISHER URL ***** " + pubUrl + " ***** DEVPORTAL URL ***** "
|
||||||
|
+ devPortUrl;
|
||||||
|
|
||||||
|
// 6) Update the swagger with the description and servers
|
||||||
|
Map<String, Object> swaggerMap = yaml.load(swagger);
|
||||||
|
JsonObject swaggerObj = gson.toJsonTree(swaggerMap).getAsJsonObject();
|
||||||
|
updateSwagger(swaggerObj, apiMap, fullDesc);
|
||||||
|
|
||||||
|
// 7) Prepare artifact creation/update
|
||||||
|
String group = config.getDefaultApiGroup();
|
||||||
|
String mainArtifactId = api.getName() + api.getContext();
|
||||||
|
|
||||||
|
VersionSearchResults existingArtifacts;
|
||||||
|
try {
|
||||||
|
existingArtifacts = client.listArtifactVersions(group, mainArtifactId, 0, Integer.MAX_VALUE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("No API {} exists – will create it", api.getContext());
|
||||||
|
existingArtifacts = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingArtifacts == null) {
|
||||||
|
// Create new artifact
|
||||||
|
List<ArtifactReference> references = createReferencesFromZip(zipEntries, group, api);
|
||||||
|
|
||||||
|
ArtifactMetaData meta = client.createArtifact(group, mainArtifactId, api.getVersion(), null, null, null,
|
||||||
|
api.getName(), fullDesc, null, null, null,
|
||||||
|
new ByteArrayInputStream(swaggerObj.toString().getBytes()), references);
|
||||||
|
|
||||||
|
setMetaAndRules(meta, props, tagsList);
|
||||||
|
// Create the three required rules
|
||||||
|
createRule(meta, "NONE", RuleType.COMPATIBILITY);
|
||||||
|
createRule(meta, "NONE", RuleType.VALIDITY);
|
||||||
|
createRule(meta, "NONE", RuleType.INTEGRITY);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Artifact exists – check if the version exists
|
||||||
|
boolean versionExists = false;
|
||||||
|
try {
|
||||||
|
client.getArtifactVersionMetaData(group, mainArtifactId, api.getVersion());
|
||||||
|
versionExists = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Version missing – will create it below
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ArtifactReference> references = createReferencesFromZip(zipEntries, group, api);
|
||||||
|
|
||||||
|
if (!versionExists) {
|
||||||
|
ArtifactMetaData meta = client.updateArtifact(group, mainArtifactId, api.getVersion(),
|
||||||
|
api.getName(), fullDesc, new ByteArrayInputStream(swaggerObj.toString().getBytes()),
|
||||||
|
references);
|
||||||
|
setMetaAndRules(meta, props, tagsList);
|
||||||
|
} else {
|
||||||
|
// Version already exists – no action needed
|
||||||
|
log.warn("API {} with version {} already exists. Skipping import.", api.getContext(),
|
||||||
|
api.getVersion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("Successfully imported API '{}' ({}). Took {} ms", api.getName(), api.getVersion(),
|
||||||
|
System.currentTimeMillis() - start);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("IO error while importing API {}: {}", api.getId(), e.getMessage(), e);
|
||||||
|
} catch (VersionAlreadyExistsException e) {
|
||||||
|
log.warn("API version already exists for {}: {}. Skipping.", api.getName(), api.getVersion());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Cannot export API '{}':{}", api.getName(), api.getVersion(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
/* Helper methods */
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
private void updateSwagger(JsonObject swagger, Map<String, Object> apiMap, String description) {
|
||||||
|
JsonObject info = swagger.getAsJsonObject("info");
|
||||||
|
if (info != null) {
|
||||||
|
info.addProperty("description", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build servers array
|
||||||
|
JsonArray servers = new JsonArray();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<Map<String, Object>> endpoints = (List<Map<String, Object>>) apiMap.get("endpointURLs");
|
||||||
|
if (endpoints != null) {
|
||||||
|
for (Map<String, Object> env : endpoints) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<String, String> urls = (Map<String, String>) env.get("URLs");
|
||||||
|
if (urls == null || urls.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
JsonObject server = new JsonObject();
|
||||||
|
urls.forEach((k, v) -> {
|
||||||
|
if (v != null && !v.isBlank()) {
|
||||||
|
if (k.equals("https")) {
|
||||||
|
server.addProperty("url", v);
|
||||||
|
} else if (k.equals("wss")) {
|
||||||
|
server.addProperty("url", v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
server.addProperty("description", "Gateway: " + env.getOrDefault("environmentName", ""));
|
||||||
|
servers.add(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
swagger.remove("servers");
|
||||||
|
swagger.add("servers", servers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSubscriptionsToProps(Map<String, String> props, Map<String, Object> subsMap) {
|
||||||
|
if (subsMap == null || !subsMap.containsKey("list"))
|
||||||
|
return;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<Map<String, Object>> list = (List<Map<String, Object>>) subsMap.get("list");
|
||||||
|
int i = 1;
|
||||||
|
for (Map<String, Object> sub : list) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<String, String> appInfo = (Map<String, String>) sub.get("applicationInfo");
|
||||||
|
if (appInfo == null)
|
||||||
|
continue;
|
||||||
|
props.put("subscription" + i,
|
||||||
|
appInfo.getOrDefault("name", "") + " (Owner: " + appInfo.getOrDefault("subscriber", "") + ")");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addEndpointsToProps(Map<String, String> props, Map<String, Object> apiMap) {
|
||||||
|
if (apiMap == null || !apiMap.containsKey("endpointURLs"))
|
||||||
|
return;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<Map<String, Object>> envs = (List<Map<String, Object>>) apiMap.get("endpointURLs");
|
||||||
|
for (Map<String, Object> env : envs) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<String, String> urls = (Map<String, String>) env.get("URLs");
|
||||||
|
if (urls == null)
|
||||||
|
continue;
|
||||||
|
urls.forEach((k, v) -> props.put(k + " Endpoint", v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addTagsToProps(Map<String, String> props, List<String> tags) {
|
||||||
|
if (tags != null && !tags.isEmpty()) {
|
||||||
|
props.put("tags", String.join(", ", tags));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ArtifactReference> createReferencesFromZip(List<ZipEntryData> zipEntries, String group, APIInfo api)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
List<ArtifactReference> references = new ArrayList<>();
|
||||||
|
for (ZipEntryData entry : zipEntries) {
|
||||||
|
String artifactId = api.getName() + "/" + api.getVersion() + "/" + entry.getName();
|
||||||
|
|
||||||
|
// Create the artifact (versioned)
|
||||||
|
try (ByteArrayInputStream is = new ByteArrayInputStream(entry.getContent())) {
|
||||||
|
client.createArtifactWithVersion(entry.getType().toString(), artifactId, api.getVersion(), is);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArtifactReference ref = new ArtifactReference();
|
||||||
|
ref.setName(entry.getName());
|
||||||
|
ref.setGroupId(entry.getType().toString());
|
||||||
|
ref.setArtifactId(artifactId);
|
||||||
|
ref.setVersion(api.getVersion());
|
||||||
|
references.add(ref);
|
||||||
|
}
|
||||||
|
return references;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMetaAndRules(ArtifactMetaData meta, Map<String, String> props, List<String> tags) {
|
||||||
|
EditableMetaData metaData = new EditableMetaData();
|
||||||
|
metaData.setName(meta.getName());
|
||||||
|
metaData.setDescription(meta.getDescription());
|
||||||
|
metaData.setProperties(props);
|
||||||
|
metaData.setLabels(tags);
|
||||||
|
|
||||||
|
client.updateArtifactMetaData(meta.getGroupId(), meta.getId(), metaData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createRule(ArtifactMetaData meta, String config, RuleType type) {
|
||||||
|
Rule rule = new Rule();
|
||||||
|
rule.setConfig(config);
|
||||||
|
rule.setType(type);
|
||||||
|
client.createArtifactRule(meta.getGroupId(), meta.getId(), rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
92
src/main/java/cz/trask/migration/model/APIInfo.java
Normal file
92
src/main/java/cz/trask/migration/model/APIInfo.java
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package cz.trask.migration.model;
|
||||||
|
|
||||||
|
public class APIInfo {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String description;
|
||||||
|
private String context;
|
||||||
|
private String version;
|
||||||
|
private String provider;
|
||||||
|
private String lifeCycleStatus;
|
||||||
|
private String thumbnailUri;
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContext(String context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(String version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProvider() {
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProvider(String provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLifeCycleStatus() {
|
||||||
|
return lifeCycleStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLifeCycleStatus(String lifeCycleStatus) {
|
||||||
|
this.lifeCycleStatus = lifeCycleStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getThumbnailUri() {
|
||||||
|
return thumbnailUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setThumbnailUri(String thumbnailUri) {
|
||||||
|
this.thumbnailUri = thumbnailUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return id + "\t" + name + "\t" + version + "\t" + provider + "\t" + lifeCycleStatus + "\t" + description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
31
src/main/java/cz/trask/migration/model/APIList.java
Normal file
31
src/main/java/cz/trask/migration/model/APIList.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package cz.trask.migration.model;
|
||||||
|
|
||||||
|
public class APIList {
|
||||||
|
|
||||||
|
// "count": 102, "next": "", "previous": "", "list": [
|
||||||
|
|
||||||
|
private int count;
|
||||||
|
private APIInfo[] list = null;
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCount(int count) {
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public APIInfo[] getList() {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setList(APIInfo[] list) {
|
||||||
|
this.list = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return count + "\t" + list;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
96
src/main/java/cz/trask/migration/model/ApiDefinition.java
Normal file
96
src/main/java/cz/trask/migration/model/ApiDefinition.java
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package cz.trask.migration.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ApiDefinition {
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private Object description;
|
||||||
|
private String context;
|
||||||
|
private String version;
|
||||||
|
private String provider;
|
||||||
|
private String apiDefinition;
|
||||||
|
private Object wsdlUri;
|
||||||
|
private String lifeCycleStatus;
|
||||||
|
private boolean isDefaultVersion;
|
||||||
|
private String type;
|
||||||
|
private List<String> transport;
|
||||||
|
private List<Object> operations;
|
||||||
|
private String authorizationHeader;
|
||||||
|
private List<String> securityScheme;
|
||||||
|
private List<String> tags;
|
||||||
|
private List<Tier> tiers;
|
||||||
|
private boolean hasThumbnail;
|
||||||
|
private Map<String, Object> additionalProperties;
|
||||||
|
private Monetization monetization;
|
||||||
|
private List<Object> ingressURLs;
|
||||||
|
private List<EndpointURLs> endpointURLs;
|
||||||
|
private BusinessInformation businessInformation;
|
||||||
|
private List<String> labels;
|
||||||
|
private List<String> environmentList;
|
||||||
|
private List<Object> scopes;
|
||||||
|
private String avgRating;
|
||||||
|
private AdvertiseInfo advertiseInfo;
|
||||||
|
private boolean isSubscriptionAvailable;
|
||||||
|
private List<String> categories;
|
||||||
|
private List<String> keyManagers;
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
|
||||||
|
public static class Tier {
|
||||||
|
private String tierName;
|
||||||
|
private String tierPlan;
|
||||||
|
private Object monetizationAttributes;
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EndpointURLs {
|
||||||
|
private String environmentName;
|
||||||
|
private String environmentType;
|
||||||
|
private URLs URLs;
|
||||||
|
private DefaultVersionURLs defaultVersionURLs;
|
||||||
|
|
||||||
|
public static class URLs {
|
||||||
|
private String http;
|
||||||
|
private String https;
|
||||||
|
private Object ws;
|
||||||
|
private Object wss;
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DefaultVersionURLs {
|
||||||
|
private Object http;
|
||||||
|
private Object https;
|
||||||
|
private Object ws;
|
||||||
|
private Object wss;
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Monetization {
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BusinessInformation {
|
||||||
|
private String businessOwner;
|
||||||
|
private String businessOwnerEmail;
|
||||||
|
private String technicalOwner;
|
||||||
|
private String technicalOwnerEmail;
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AdvertiseInfo {
|
||||||
|
private boolean advertised;
|
||||||
|
private String originalStoreUrl;
|
||||||
|
private String apiOwner;
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
}
|
||||||
|
}
|
||||||
122
src/main/java/cz/trask/migration/model/EventAPIInfo.java
Normal file
122
src/main/java/cz/trask/migration/model/EventAPIInfo.java
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package cz.trask.migration.model;
|
||||||
|
|
||||||
|
public class EventAPIInfo {
|
||||||
|
|
||||||
|
String apiName;
|
||||||
|
String apiId;
|
||||||
|
String uuid;
|
||||||
|
String apiVersion;
|
||||||
|
String apiContext;
|
||||||
|
String apiProvider;
|
||||||
|
String apiType;
|
||||||
|
String apiStatus;
|
||||||
|
String eventId;
|
||||||
|
String timeStamp;
|
||||||
|
String type;
|
||||||
|
String tenantId;
|
||||||
|
String tenantDomain;
|
||||||
|
|
||||||
|
public String getApiName() {
|
||||||
|
return apiName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApiName(String apiName) {
|
||||||
|
this.apiName = apiName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApiId() {
|
||||||
|
return apiId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApiId(String apiId) {
|
||||||
|
this.apiId = apiId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUuid(String uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApiVersion() {
|
||||||
|
return apiVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApiVersion(String apiVersion) {
|
||||||
|
this.apiVersion = apiVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApiContext() {
|
||||||
|
return apiContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApiContext(String apiContext) {
|
||||||
|
this.apiContext = apiContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApiProvider() {
|
||||||
|
return apiProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApiProvider(String apiProvider) {
|
||||||
|
this.apiProvider = apiProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApiType() {
|
||||||
|
return apiType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApiType(String apiType) {
|
||||||
|
this.apiType = apiType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApiStatus() {
|
||||||
|
return apiStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApiStatus(String apiStatus) {
|
||||||
|
this.apiStatus = apiStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEventId() {
|
||||||
|
return eventId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventId(String eventId) {
|
||||||
|
this.eventId = eventId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTimeStamp() {
|
||||||
|
return timeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeStamp(String timeStamp) {
|
||||||
|
this.timeStamp = timeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTenantId() {
|
||||||
|
return tenantId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTenantId(String tenantId) {
|
||||||
|
this.tenantId = tenantId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTenantDomain() {
|
||||||
|
return tenantDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTenantDomain(String tenantDomain) {
|
||||||
|
this.tenantDomain = tenantDomain;
|
||||||
|
}
|
||||||
|
}
|
||||||
5
src/main/java/cz/trask/migration/model/FileType.java
Normal file
5
src/main/java/cz/trask/migration/model/FileType.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package cz.trask.migration.model;
|
||||||
|
|
||||||
|
public enum FileType {
|
||||||
|
APIDEF, OPENAPI, WSDL, POLICY, UNKNOWN
|
||||||
|
}
|
||||||
49
src/main/java/cz/trask/migration/model/HttpResponse.java
Normal file
49
src/main/java/cz/trask/migration/model/HttpResponse.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package cz.trask.migration.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class HttpResponse {
|
||||||
|
|
||||||
|
String response;
|
||||||
|
Map<String, List<String>> headers;
|
||||||
|
int responseCode;
|
||||||
|
byte[] responseBytes;
|
||||||
|
|
||||||
|
public String getResponse() {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponse(String response) {
|
||||||
|
this.response = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, List<String>> getHeaders() {
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeaders(Map<String, List<String>> headers) {
|
||||||
|
this.headers = headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getResponseCode() {
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponseCode(int responseCode) {
|
||||||
|
this.responseCode = responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getResponseHeader(String key) {
|
||||||
|
return headers.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponseBytes(byte[] byteArray) {
|
||||||
|
responseBytes = byteArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getResponseBytes() {
|
||||||
|
return responseBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
62
src/main/java/cz/trask/migration/model/RegisterResponse.java
Normal file
62
src/main/java/cz/trask/migration/model/RegisterResponse.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package cz.trask.migration.model;
|
||||||
|
|
||||||
|
public class RegisterResponse {
|
||||||
|
|
||||||
|
// {"clientId":"QRGgaoQpiRfd6K8KZfU2hZsXoqAa","clientName":"admin_rest_api_publisher","callBackURL":"www.google.lk","clientSecret":"5o_ncm_br0wr8yOXc_ouXOWfOWsa","isSaasApplication":true,"appOwner":"admin","jsonString":"{\"grant_types\":\"password
|
||||||
|
// refresh_token\",\"redirect_uris\":\"www.google.lk\",\"client_name\":\"admin_rest_api_publisher\"}","jsonAppAttribute":"{}","tokenType":null}
|
||||||
|
|
||||||
|
private String clientId;
|
||||||
|
private String clientName;
|
||||||
|
private String callBackURL;
|
||||||
|
private String clientSecret;
|
||||||
|
private boolean isSaasApplication;
|
||||||
|
private String appOwner;
|
||||||
|
|
||||||
|
public String getClientId() {
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientId(String clientId) {
|
||||||
|
this.clientId = clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientName() {
|
||||||
|
return clientName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientName(String clientName) {
|
||||||
|
this.clientName = clientName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCallBackURL() {
|
||||||
|
return callBackURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCallBackURL(String callBackURL) {
|
||||||
|
this.callBackURL = callBackURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientSecret() {
|
||||||
|
return clientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientSecret(String clientSecret) {
|
||||||
|
this.clientSecret = clientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSaasApplication() {
|
||||||
|
return isSaasApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSaasApplication(boolean isSaasApplication) {
|
||||||
|
this.isSaasApplication = isSaasApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAppOwner() {
|
||||||
|
return appOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppOwner(String appOwner) {
|
||||||
|
this.appOwner = appOwner;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/main/java/cz/trask/migration/model/StartParameters.java
Normal file
35
src/main/java/cz/trask/migration/model/StartParameters.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package cz.trask.migration.model;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
public class StartParameters {
|
||||||
|
|
||||||
|
private static Logger log = LogManager.getLogger(StartParameters.class);
|
||||||
|
|
||||||
|
String command;
|
||||||
|
|
||||||
|
public String getCommand() {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommand(String command) {
|
||||||
|
this.command = command.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StartParameters parse(String commandLine) throws Exception {
|
||||||
|
StartParameters res = new StartParameters();
|
||||||
|
|
||||||
|
try {
|
||||||
|
String[] rawParams = commandLine.split("-");
|
||||||
|
res.setCommand(rawParams[0]);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error while parsing startup parameters.", e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
53
src/main/java/cz/trask/migration/model/TokenResponse.java
Normal file
53
src/main/java/cz/trask/migration/model/TokenResponse.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package cz.trask.migration.model;
|
||||||
|
|
||||||
|
public class TokenResponse {
|
||||||
|
|
||||||
|
// {"access_token":"6be1aa81-d0ae-321e-9e3e-2ea89dd9f847","refresh_token":"5cff194d-cb16-3dc2-ab60-3c44ba25ae4a","scope":"apim:api_view","token_type":"Bearer","expires_in":3600}
|
||||||
|
|
||||||
|
private String access_token;
|
||||||
|
private String refresh_token;
|
||||||
|
private String scope;
|
||||||
|
private String token_type;
|
||||||
|
private long expires_in;
|
||||||
|
|
||||||
|
public String getAccess_token() {
|
||||||
|
return access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccess_token(String access_token) {
|
||||||
|
this.access_token = access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRefresh_token() {
|
||||||
|
return refresh_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRefresh_token(String refresh_token) {
|
||||||
|
this.refresh_token = refresh_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getScope() {
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScope(String scope) {
|
||||||
|
this.scope = scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken_type() {
|
||||||
|
return token_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken_type(String token_type) {
|
||||||
|
this.token_type = token_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getExpires_in() {
|
||||||
|
return expires_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpires_in(long expires_in) {
|
||||||
|
this.expires_in = expires_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
43
src/main/java/cz/trask/migration/model/ZipEntryData.java
Normal file
43
src/main/java/cz/trask/migration/model/ZipEntryData.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package cz.trask.migration.model;
|
||||||
|
|
||||||
|
public class ZipEntryData {
|
||||||
|
private String name;
|
||||||
|
private FileType type;
|
||||||
|
private byte[] content;
|
||||||
|
|
||||||
|
public ZipEntryData(String name, FileType type, byte[] content) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gettery a settery
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(FileType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(byte[] content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ZipEntryData{name='" + name + "', type=" + type + "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
110
src/main/java/cz/trask/migration/utils/ZipUtils.java
Normal file
110
src/main/java/cz/trask/migration/utils/ZipUtils.java
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package cz.trask.migration.utils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import cz.trask.migration.model.FileType;
|
||||||
|
import cz.trask.migration.model.ZipEntryData;
|
||||||
|
import io.apicurio.registry.rest.client.RegistryClient;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.ArtifactMetaData;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.ArtifactReference;
|
||||||
|
import io.apicurio.registry.rest.v2.beans.SearchedVersion;
|
||||||
|
|
||||||
|
public class ZipUtils {
|
||||||
|
|
||||||
|
private static final Logger log = LogManager.getLogger(ZipUtils.class);
|
||||||
|
|
||||||
|
public static List<ZipEntryData> extractFilesFromZip(byte[] data) throws IOException {
|
||||||
|
List<ZipEntryData> fileList = new ArrayList<>();
|
||||||
|
|
||||||
|
try (ByteArrayInputStream fis = new ByteArrayInputStream(data); ZipInputStream zis = new ZipInputStream(fis)) {
|
||||||
|
|
||||||
|
ZipEntry entry;
|
||||||
|
while ((entry = zis.getNextEntry()) != null) {
|
||||||
|
// Ignoruj adresáře
|
||||||
|
if (!entry.isDirectory()) {
|
||||||
|
String name = entry.getName().substring(entry.getName().lastIndexOf('/') + 1);
|
||||||
|
FileType type = determineFileType(entry.getName());
|
||||||
|
byte[] content = readAllBytes(zis);
|
||||||
|
|
||||||
|
fileList.add(new ZipEntryData(name, type, content));
|
||||||
|
}
|
||||||
|
zis.closeEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FileType determineFileType(String fileName) {
|
||||||
|
String lowerFileName = fileName.toLowerCase();
|
||||||
|
if (lowerFileName.endsWith("api.yaml")) {
|
||||||
|
return FileType.APIDEF;
|
||||||
|
} else if (lowerFileName.contains("/definitions/swagger.yaml")) {
|
||||||
|
return FileType.OPENAPI;
|
||||||
|
} else if (lowerFileName.endsWith(".wsdl")) {
|
||||||
|
return FileType.WSDL;
|
||||||
|
} else if (lowerFileName.contains("/policies/")) {
|
||||||
|
return FileType.POLICY;
|
||||||
|
}
|
||||||
|
return FileType.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] readAllBytes(ZipInputStream zis) throws IOException {
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
int nRead;
|
||||||
|
byte[] data = new byte[1024];
|
||||||
|
while ((nRead = zis.read(data, 0, data.length)) != -1) {
|
||||||
|
buffer.write(data, 0, nRead);
|
||||||
|
}
|
||||||
|
buffer.flush();
|
||||||
|
return buffer.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] prepareApiZipFile(RegistryClient client, SearchedVersion ver, List<ArtifactReference> ref)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
String baseDir = ver.getName() + "-" + ver.getVersion() + "/";
|
||||||
|
|
||||||
|
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
ZipOutputStream zos = new ZipOutputStream(baos)) {
|
||||||
|
|
||||||
|
for (ArtifactReference r : ref) {
|
||||||
|
log.info(" - Reference: {} {} {}", r.getGroupId(), r.getArtifactId(), r.getVersion());
|
||||||
|
|
||||||
|
ArtifactMetaData amd = client.getArtifactMetaData(r.getGroupId(), r.getArtifactId());
|
||||||
|
|
||||||
|
String subDir = "";
|
||||||
|
|
||||||
|
if (FileType.OPENAPI.toString().equals(amd.getGroupId())) {
|
||||||
|
subDir = "Definitions/";
|
||||||
|
} else if (FileType.POLICY.toString().equals(amd.getGroupId())) {
|
||||||
|
subDir = "Policies/";
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileName = baseDir + subDir + r.getName();
|
||||||
|
log.info(" - Adding file: {}", fileName);
|
||||||
|
|
||||||
|
zos.putNextEntry(new ZipEntry(fileName));
|
||||||
|
|
||||||
|
try (InputStream is = client.getContentByGlobalId(amd.getGlobalId())) {
|
||||||
|
zos.write(is.readAllBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
zos.closeEntry();
|
||||||
|
}
|
||||||
|
zos.finish();
|
||||||
|
return baos.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/main/resources/api-operator.properties
Normal file
23
src/main/resources/api-operator.properties
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
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/devportal
|
||||||
|
SOURCE_PUBLISHER_TOKEN_URL = https://localhost:9443/oauth2/token
|
||||||
|
SOURCE_WSO2_USER = YWRtaW46YWRtaW4=
|
||||||
|
|
||||||
|
TARGET_REGISTRATION_API_URL = https://localhost:9443/client-registration/v0.17/register
|
||||||
|
TARGET_PUBLISHER_API_URL = https://localhost:9443/api/am/publisher/v3/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
|
||||||
28
src/main/resources/log4j2.properties
Normal file
28
src/main/resources/log4j2.properties
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
rootLogger.level = info
|
||||||
|
rootLogger.appenderRefs = console, rolling
|
||||||
|
rootLogger.appenderRef.stdout.ref = STDOUT
|
||||||
|
rootLogger.appenderRef.file.ref = RollingFileAppender
|
||||||
|
|
||||||
|
logger.cz-trask.name=cz.trask
|
||||||
|
logger.cz-trask.level = debug
|
||||||
|
logger.cz-trask.additivity=false
|
||||||
|
logger.cz-trask.appenderRefs = rolling, console
|
||||||
|
logger.cz-trask.appenderRef.file.ref = RollingFileAppender
|
||||||
|
logger.cz-trask.appenderRef.stdout.ref = STDOUT
|
||||||
|
|
||||||
|
appender.console.type = Console
|
||||||
|
appender.console.name = STDOUT
|
||||||
|
appender.console.layout.type = PatternLayout
|
||||||
|
appender.console.layout.pattern = %d [%t] %-5level %logger{36} - %msg%n
|
||||||
|
|
||||||
|
appender.rolling.type = RollingFile
|
||||||
|
appender.rolling.name = RollingFileAppender
|
||||||
|
appender.rolling.fileName = api-operator.log
|
||||||
|
appender.rolling.filePattern = api-operator-%d{yyyy-MM-dd}.%i.log
|
||||||
|
appender.rolling.layout.type = PatternLayout
|
||||||
|
appender.rolling.layout.pattern = %d [%t] %-5level %logger{36} - %msg%n
|
||||||
|
appender.rolling.policies.type = Policies
|
||||||
|
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
|
||||||
|
appender.rolling.policies.size.size = 50MB
|
||||||
|
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
|
||||||
|
appender.rolling.policies.time.interval = 1
|
||||||
Loading…
x
Reference in New Issue
Block a user