first working draft

This commit is contained in:
Radek Davidek 2025-10-02 17:23:32 +02:00
parent c164ff7802
commit eb9cbdcfde
3 changed files with 161 additions and 6 deletions

View File

@ -1,6 +1,7 @@
package cz.trask.apioperator;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
@ -309,4 +310,79 @@ public abstract class AbstractProcess {
}
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;
}
}

View File

@ -1,10 +1,18 @@
package cz.trask.apioperator.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
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 java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -12,10 +20,13 @@ import org.apache.logging.log4j.Logger;
import com.google.gson.Gson;
import cz.trask.apioperator.AbstractProcess;
import cz.trask.apioperator.model.FileType;
import cz.trask.apioperator.model.HttpResponse;
import cz.trask.apioperator.model.RegisterResponse;
import cz.trask.apioperator.model.TokenResponse;
import io.apicurio.registry.rest.client.RegistryClient;
import io.apicurio.registry.rest.client.RegistryClientFactory;
import io.apicurio.registry.rest.v2.beans.ArtifactMetaData;
import io.apicurio.registry.rest.v2.beans.ArtifactReference;
import io.apicurio.registry.rest.v2.beans.ArtifactSearchResults;
import io.apicurio.registry.rest.v2.beans.SearchedArtifact;
@ -90,17 +101,25 @@ public class ExportToWso2 extends AbstractProcess {
try {
log.info("Processing API {} of {}", index, total);
VersionSearchResults versions = client.listArtifactVersions(config.getDefaultApiGroup(), api.getId(), null, null);
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());
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 = prepareApiZipFile(ver, ref);
String fileName = api.getName() + "-" + ver.getVersion() + ".zip";
if (data != null && data.length > 0 && fileName != null && !fileName.isEmpty()) {
publishApiToWso2(fileName, data, tokenResponse);
}
}
}
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);
}
@ -110,4 +129,64 @@ public class ExportToWso2 extends AbstractProcess {
/* 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;
}
private byte[] prepareApiZipFile(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();
}
}
}

View File

@ -5,7 +5,7 @@ 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
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=