swagger as yaml from exported zip
This commit is contained in:
parent
ca01fb657f
commit
d3eaa644b3
5
pom.xml
5
pom.xml
@ -33,6 +33,11 @@
|
|||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.13.1</version>
|
<version>2.13.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.yaml</groupId>
|
||||||
|
<artifactId>snakeyaml</artifactId>
|
||||||
|
<version>2.4</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import javax.net.ssl.HttpsURLConnection;
|
|||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
@ -31,12 +32,16 @@ public abstract class AbstractProcess {
|
|||||||
private static Logger log = LogManager.getLogger(AbstractProcess.class);
|
private static Logger log = LogManager.getLogger(AbstractProcess.class);
|
||||||
|
|
||||||
protected Gson gson;
|
protected Gson gson;
|
||||||
|
|
||||||
|
protected Yaml yaml;
|
||||||
|
|
||||||
protected ConfigManager config = ConfigManager.getInstance();
|
protected ConfigManager config = ConfigManager.getInstance();
|
||||||
|
|
||||||
protected AbstractProcess() {
|
protected AbstractProcess() {
|
||||||
|
|
||||||
gson = new GsonBuilder().create();
|
gson = new GsonBuilder().create();
|
||||||
|
|
||||||
|
yaml = new Yaml();
|
||||||
|
|
||||||
setTrustStoreCredentials();
|
setTrustStoreCredentials();
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ public class ApiSync {
|
|||||||
|
|
||||||
if (sp.getCommand().equalsIgnoreCase("import")) {
|
if (sp.getCommand().equalsIgnoreCase("import")) {
|
||||||
log.info("Import command selected.");
|
log.info("Import command selected.");
|
||||||
Import imp = new Import(sp);
|
Import imp = new Import();
|
||||||
imp.process();
|
imp.process();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,15 +18,14 @@ import org.apache.logging.log4j.Logger;
|
|||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import cz.trask.apioperator.AbstractProcess;
|
import cz.trask.apioperator.AbstractProcess;
|
||||||
import cz.trask.apioperator.model.APIInfo;
|
import cz.trask.apioperator.model.APIInfo;
|
||||||
import cz.trask.apioperator.model.APIList;
|
import cz.trask.apioperator.model.APIList;
|
||||||
|
import cz.trask.apioperator.model.FileType;
|
||||||
import cz.trask.apioperator.model.HttpResponse;
|
import cz.trask.apioperator.model.HttpResponse;
|
||||||
import cz.trask.apioperator.model.RegisterResponse;
|
import cz.trask.apioperator.model.RegisterResponse;
|
||||||
import cz.trask.apioperator.model.StartParameters;
|
|
||||||
import cz.trask.apioperator.model.TokenResponse;
|
import cz.trask.apioperator.model.TokenResponse;
|
||||||
import cz.trask.apioperator.model.ZipEntryData;
|
import cz.trask.apioperator.model.ZipEntryData;
|
||||||
import cz.trask.apioperator.utils.ZipExtractor;
|
import cz.trask.apioperator.utils.ZipExtractor;
|
||||||
@ -40,22 +39,6 @@ import io.apicurio.registry.rest.v2.beans.Rule;
|
|||||||
import io.apicurio.registry.rest.v2.beans.VersionSearchResults;
|
import io.apicurio.registry.rest.v2.beans.VersionSearchResults;
|
||||||
import io.apicurio.registry.types.RuleType;
|
import io.apicurio.registry.types.RuleType;
|
||||||
|
|
||||||
/**
|
|
||||||
* Import class – reads APIs from WSO2 APIM and publishes them to Apicurio.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* All major improvements from the original code:
|
|
||||||
* <ul>
|
|
||||||
* <li>Thread‑safe counter using {@link AtomicInteger}</li>
|
|
||||||
* <li>Parameterized Log4j messages</li>
|
|
||||||
* <li>Safe JSON deserialization with {@code TypeToken}</li>
|
|
||||||
* <li>Try‑with‑resources for all streams</li>
|
|
||||||
* <li>Artifact creation – references first, then parent</li>
|
|
||||||
* <li>Cleaner metadata handling (no trailing spaces)</li>
|
|
||||||
* <li>Specific exception handling and wrapping in a runtime exception</li>
|
|
||||||
* </ul>
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public class Import extends AbstractProcess {
|
public class Import extends AbstractProcess {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(Import.class);
|
private static final Logger log = LogManager.getLogger(Import.class);
|
||||||
@ -63,11 +46,9 @@ public class Import extends AbstractProcess {
|
|||||||
private final AtomicInteger apiCounter = new AtomicInteger(1);
|
private final AtomicInteger apiCounter = new AtomicInteger(1);
|
||||||
private final Gson gson = new Gson();
|
private final Gson gson = new Gson();
|
||||||
|
|
||||||
private final StartParameters sp;
|
|
||||||
private final RegistryClient client;
|
private final RegistryClient client;
|
||||||
|
|
||||||
public Import(StartParameters sp) throws Exception {
|
public Import() throws Exception {
|
||||||
this.sp = sp;
|
|
||||||
this.client = RegistryClientFactory.create(config.getApicurioApiUrl());
|
this.client = RegistryClientFactory.create(config.getApicurioApiUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,8 +124,6 @@ public class Import extends AbstractProcess {
|
|||||||
Map<String, String> httpHeaders = Collections.singletonMap("Authorization",
|
Map<String, String> httpHeaders = Collections.singletonMap("Authorization",
|
||||||
"Bearer " + tokenResponse.getAccess_token());
|
"Bearer " + tokenResponse.getAccess_token());
|
||||||
|
|
||||||
String type = mapApiType(api.getType());
|
|
||||||
|
|
||||||
// 1) Retrieve basic information
|
// 1) Retrieve basic information
|
||||||
HttpResponse apiInfoResp = makeRequest("GET", config.getSourceDevportalApiUrl() + "/apis/" + api.getId(),
|
HttpResponse apiInfoResp = makeRequest("GET", config.getSourceDevportalApiUrl() + "/apis/" + api.getId(),
|
||||||
httpHeaders, Collections.emptyMap());
|
httpHeaders, Collections.emptyMap());
|
||||||
@ -153,17 +132,23 @@ public class Import extends AbstractProcess {
|
|||||||
config.getSourcePublisherApiUrl() + "/subscriptions?apiId=" + api.getId(), httpHeaders,
|
config.getSourcePublisherApiUrl() + "/subscriptions?apiId=" + api.getId(), httpHeaders,
|
||||||
Collections.emptyMap());
|
Collections.emptyMap());
|
||||||
|
|
||||||
HttpResponse swaggerResp = makeRequest("GET",
|
|
||||||
config.getSourcePublisherApiUrl() + "/apis/" + api.getId() + "/swagger", httpHeaders,
|
|
||||||
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.getSourcePublisherApiUrl() + "/apis/export?apiId=" + api.getId(), httpHeaders,
|
||||||
Collections.emptyMap(), true);
|
Collections.emptyMap(), true);
|
||||||
|
|
||||||
List<ZipEntryData> zipEntries = ZipExtractor.extractFilesFromZip(exportedZip.getResponseBytes());
|
List<ZipEntryData> zipEntries = ZipExtractor.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
|
// 3) Deserialize JSON responses
|
||||||
TypeToken<Map<String, Object>> mapType = new TypeToken<>() {
|
TypeToken<Map<String, Object>> mapType = new TypeToken<>() {
|
||||||
};
|
};
|
||||||
@ -190,7 +175,8 @@ public class Import extends AbstractProcess {
|
|||||||
+ devPortUrl;
|
+ devPortUrl;
|
||||||
|
|
||||||
// 6) Update the swagger with the description and servers
|
// 6) Update the swagger with the description and servers
|
||||||
JsonObject swaggerObj = JsonParser.parseString(swaggerResp.getResponse()).getAsJsonObject();
|
Map<String, Object> swaggerMap = yaml.load(swagger);
|
||||||
|
JsonObject swaggerObj = gson.toJsonTree(swaggerMap).getAsJsonObject();
|
||||||
updateSwagger(swaggerObj, apiMap, fullDesc);
|
updateSwagger(swaggerObj, apiMap, fullDesc);
|
||||||
|
|
||||||
// 7) Prepare artifact creation/update
|
// 7) Prepare artifact creation/update
|
||||||
@ -258,22 +244,6 @@ public class Import extends AbstractProcess {
|
|||||||
/* Helper methods */
|
/* Helper methods */
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
private String mapApiType(String type) {
|
|
||||||
// Java 11 does not support switch‑expressions
|
|
||||||
switch (type) {
|
|
||||||
case "HTTP":
|
|
||||||
return "OPENAPI";
|
|
||||||
case "GRAPHQL":
|
|
||||||
return "GRAPHQL";
|
|
||||||
case "WS":
|
|
||||||
return "ASYNCAPI";
|
|
||||||
case "SOAP":
|
|
||||||
return "WSDL";
|
|
||||||
default:
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateSwagger(JsonObject swagger, Map<String, Object> apiMap, String description) {
|
private void updateSwagger(JsonObject swagger, Map<String, Object> apiMap, String description) {
|
||||||
JsonObject info = swagger.getAsJsonObject("info");
|
JsonObject info = swagger.getAsJsonObject("info");
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user