getServers() {
+ if (swaggerVersion() == SwaggerVersion.SWAGGER_V2) {
+ if (host == null || host.isBlank()) {
+ return List.of();
+ }
+
+ String base = host;
+ if (basePath != null && !basePath.isBlank()) {
+ base += basePath;
+ }
+
+ return List.of(schemes.stream().findFirst().orElse("https") + "://" + base);
+ }
+
+ if (servers == null || servers.isEmpty()) {
+ return List.of();
+ }
+
+ return servers.stream().map(Server::url).toList();
+ }
+
+ /**
+ * Resolves a schema reference to a Schema object.
+ *
+ * It does not resolve nested references.
+ */
+ public Schema resolveSchema(String ref) {
+ if (isSwaggerV2()) {
+ return resolveRefSwaggerV2(ref);
+ } else {
+ return resolveRefOpenAPI(ref);
+ }
+ }
+
+ private Schema resolveRefOpenAPI(String ref) {
+ if (ref == null || !ref.startsWith("#/components/schemas/")) {
+ return null;
+ }
+
+ if (components == null || components.schemas() == null) {
+ return null;
+ }
+
+ String name = ref.substring("#/components/schemas/".length());
+ return components.schemas().get(name);
+ }
+
+ private Schema resolveRefSwaggerV2(String ref) {
+ if (ref == null || !ref.startsWith("#/definitions/")) {
+ return null;
+ }
+
+ if (definitions == null) {
+ return null;
+ }
+
+ String name = ref.substring("#/definitions/".length());
+
+ return definitions.get(name);
+ }
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public record Server(String url) {}
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public record PathItem(
+ Operation get,
+ Operation post,
+ Operation put,
+ Operation delete,
+ Operation patch,
+ Operation head,
+ Operation options) {
+
+ Set methods() {
+ return Set.of(
+ new HttpOperation("get", get),
+ new HttpOperation("post", post),
+ new HttpOperation("put", put),
+ new HttpOperation("delete", delete),
+ new HttpOperation("patch", patch),
+ new HttpOperation("head", head),
+ new HttpOperation("options", options));
+ }
+ }
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ record HttpOperation(String method, Operation operation) {}
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public record Operation(String operationId, List parameters, RequestBody requestBody) {
+
+ public boolean hasParameters() {
+ return parameters != null && !parameters.isEmpty();
+ }
+
+ public boolean hasRequestBody() {
+ return requestBody != null;
+ }
+ }
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public record Parameter(String name, String in, Boolean required, Schema schema) {}
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public record RequestBody(Content content) {}
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public record Content(@JsonProperty("application/json") MediaType applicationJson) {
+ public boolean isApplicationJson() {
+ return applicationJson != null;
+ }
+ }
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public record MediaType(Schema schema) {}
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public record Components(Map schemas) {}
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public record Schema(
+ String type,
+ Map properties,
+ List required,
+ @JsonProperty("$ref") String ref,
+ @JsonProperty("default") JsonNode _default) {
+
+ public boolean hasRef() {
+ return ref != null && !ref.isBlank();
+ }
+
+ public boolean hasProperties() {
+ return properties != null && !properties.isEmpty();
+ }
+
+ public Set requiredFields() {
+ return required == null ? Set.of() : Set.copyOf(required);
+ }
+ }
+}
diff --git a/impl/openapi/src/test/java/io/serverlessworkflow/impl/executors/openapi/OpenAPIProcessorTest.java b/impl/openapi/src/test/java/io/serverlessworkflow/impl/executors/openapi/OpenAPIProcessorTest.java
index c89df6b7..58d9164b 100644
--- a/impl/openapi/src/test/java/io/serverlessworkflow/impl/executors/openapi/OpenAPIProcessorTest.java
+++ b/impl/openapi/src/test/java/io/serverlessworkflow/impl/executors/openapi/OpenAPIProcessorTest.java
@@ -19,9 +19,11 @@
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.serverlessworkflow.api.WorkflowFormat;
+import io.serverlessworkflow.impl.resources.ClasspathResource;
import java.io.IOException;
import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
import java.util.List;
import org.junit.jupiter.api.Test;
@@ -29,41 +31,41 @@ public class OpenAPIProcessorTest {
@Test
public void testGetPetByIdSwaggerV2() {
- String json = readResource("schema/swagger/petstore.json");
- testGetPetById(json);
+ UnifiedOpenAPI openAPI = readResource("schema/swagger/petstore.json");
+ testGetPetById(openAPI);
}
@Test
public void testGetPetByIdOpenAPI() {
- String json = readResource("schema/openapi/petstore.json");
- testGetPetById(json);
+ UnifiedOpenAPI openAPI = readResource("schema/openapi/petstore.json");
+ testGetPetById(openAPI);
}
- public void testGetPetById(String json) {
+ public void testGetPetById(UnifiedOpenAPI json) {
OperationDefinition definition = new OpenAPIProcessor("getPetById").parse(json);
assertEquals("GET", definition.getMethod());
assertEquals("/pet/{petId}", definition.getPath());
assertTrue(checkServer(definition.getServers(), "https://petstore.swagger.io/v2"));
assertEquals(1, definition.getParameters().size());
ParameterDefinition param = definition.getParameters().get(0);
- assertEquals("path", param.getIn());
- assertEquals("petId", param.getName());
- assertTrue(param.getRequired());
+ assertEquals("path", param.in());
+ assertEquals("petId", param.name());
+ assertTrue(param.required());
}
@Test
public void testAddPetByIdSwaggerV2() {
- String swaggerJson = readResource("schema/swagger/petstore.json");
- testAddPetById(swaggerJson);
+ UnifiedOpenAPI openAPI = readResource("schema/swagger/petstore.json");
+ testAddPetById(openAPI);
}
@Test
public void testAddPetByIdOpenAPI() {
- String json = readResource("schema/openapi/petstore.json");
- testAddPetById(json);
+ UnifiedOpenAPI openAPI = readResource("schema/openapi/petstore.json");
+ testAddPetById(openAPI);
}
- public void testAddPetById(String json) {
+ public void testAddPetById(UnifiedOpenAPI json) {
OperationDefinition definition = new OpenAPIProcessor("addPet").parse(json);
assertEquals("POST", definition.getMethod());
@@ -72,44 +74,44 @@ public void testAddPetById(String json) {
assertEquals(6, definition.getParameters().size());
ParameterDefinition param = definition.getParameters().get(0);
- assertEquals("body", param.getIn());
- assertEquals("id", param.getName());
- assertFalse(param.getRequired());
+ assertEquals("body", param.in());
+ assertEquals("id", param.name());
+ assertFalse(param.required());
param = definition.getParameters().get(1);
- assertEquals("body", param.getIn());
- assertEquals("category", param.getName());
- assertFalse(param.getRequired());
+ assertEquals("body", param.in());
+ assertEquals("category", param.name());
+ assertFalse(param.required());
param = definition.getParameters().get(2);
- assertEquals("body", param.getIn());
- assertEquals("name", param.getName());
- assertTrue(param.getRequired());
+ assertEquals("body", param.in());
+ assertEquals("name", param.name());
+ assertTrue(param.required());
param = definition.getParameters().get(3);
- assertEquals("body", param.getIn());
- assertEquals("photoUrls", param.getName());
- assertTrue(param.getRequired());
+ assertEquals("body", param.in());
+ assertEquals("photoUrls", param.name());
+ assertTrue(param.required());
param = definition.getParameters().get(4);
- assertEquals("body", param.getIn());
- assertEquals("tags", param.getName());
- assertFalse(param.getRequired());
+ assertEquals("body", param.in());
+ assertEquals("tags", param.name());
+ assertFalse(param.required());
param = definition.getParameters().get(5);
- assertEquals("body", param.getIn());
- assertEquals("status", param.getName());
- assertFalse(param.getRequired());
+ assertEquals("body", param.in());
+ assertEquals("status", param.name());
+ assertFalse(param.required());
}
@Test
public void testGetInventorySwaggerV2() {
- String swaggerJson = readResource("schema/swagger/petstore.json");
- testGetInventory(swaggerJson);
+ UnifiedOpenAPI openAPI = readResource("schema/swagger/petstore.json");
+ testGetInventory(openAPI);
}
@Test
public void testGetInventoryOpenAPI() {
- String json = readResource("schema/openapi/petstore.json");
- testGetInventory(json);
+ UnifiedOpenAPI openAPI = readResource("schema/openapi/petstore.json");
+ testGetInventory(openAPI);
}
- public void testGetInventory(String json) {
+ public void testGetInventory(UnifiedOpenAPI json) {
OperationDefinition definition = new OpenAPIProcessor("getInventory").parse(json);
assertEquals("GET", definition.getMethod());
@@ -120,17 +122,17 @@ public void testGetInventory(String json) {
@Test
public void testPlaceOrderSwaggerV2() {
- String json = readResource("schema/swagger/petstore.json");
+ UnifiedOpenAPI json = readResource("schema/swagger/petstore.json");
testPlaceOrder(json);
}
@Test
public void testPlaceOrderOpenAPI() {
- String json = readResource("schema/openapi/petstore.json");
- testPlaceOrder(json);
+ UnifiedOpenAPI openAPI = readResource("schema/openapi/petstore.json");
+ testPlaceOrder(openAPI);
}
- public void testPlaceOrder(String json) {
+ public void testPlaceOrder(UnifiedOpenAPI json) {
OperationDefinition definition = new OpenAPIProcessor("placeOrder").parse(json);
assertEquals("POST", definition.getMethod());
@@ -138,45 +140,45 @@ public void testPlaceOrder(String json) {
assertTrue(checkServer(definition.getServers(), "https://petstore.swagger.io/v2"));
assertEquals(6, definition.getParameters().size());
ParameterDefinition param = definition.getParameters().get(0);
- assertEquals("body", param.getIn());
- assertEquals("id", param.getName());
- assertFalse(param.getRequired());
+ assertEquals("body", param.in());
+ assertEquals("id", param.name());
+ assertFalse(param.required());
param = definition.getParameters().get(1);
- assertEquals("body", param.getIn());
- assertEquals("petId", param.getName());
- assertFalse(param.getRequired());
+ assertEquals("body", param.in());
+ assertEquals("petId", param.name());
+ assertFalse(param.required());
param = definition.getParameters().get(2);
- assertEquals("body", param.getIn());
- assertEquals("quantity", param.getName());
- assertFalse(param.getRequired());
+ assertEquals("body", param.in());
+ assertEquals("quantity", param.name());
+ assertFalse(param.required());
param = definition.getParameters().get(3);
- assertEquals("body", param.getIn());
- assertEquals("shipDate", param.getName());
- assertFalse(param.getRequired());
+ assertEquals("body", param.in());
+ assertEquals("shipDate", param.name());
+ assertFalse(param.required());
param = definition.getParameters().get(4);
- assertEquals("body", param.getIn());
- assertEquals("status", param.getName());
- assertFalse(param.getRequired());
+ assertEquals("body", param.in());
+ assertEquals("status", param.name());
+ assertFalse(param.required());
param = definition.getParameters().get(5);
- assertEquals("body", param.getIn());
- assertEquals("complete", param.getName());
- assertFalse(param.getRequired());
+ assertEquals("body", param.in());
+ assertEquals("complete", param.name());
+ assertFalse(param.required());
}
@Test
public void testLoginUserSwaggerV2() {
- String json = readResource("schema/swagger/petstore.json");
- testLoginUser(json);
+ UnifiedOpenAPI openAPI = readResource("schema/swagger/petstore.json");
+ testLoginUser(openAPI);
}
@Test
public void testLoginUserOpenAPI() {
- String json = readResource("schema/openapi/petstore.json");
- testLoginUser(json);
+ UnifiedOpenAPI openAPI = readResource("schema/openapi/petstore.json");
+ testLoginUser(openAPI);
}
- public void testLoginUser(String json) {
+ public void testLoginUser(UnifiedOpenAPI json) {
OperationDefinition definition = new OpenAPIProcessor("loginUser").parse(json);
assertEquals("GET", definition.getMethod());
@@ -184,13 +186,13 @@ public void testLoginUser(String json) {
assertTrue(checkServer(definition.getServers(), "https://petstore.swagger.io/v2"));
assertEquals(2, definition.getParameters().size());
ParameterDefinition param1 = definition.getParameters().get(0);
- assertEquals("query", param1.getIn());
- assertEquals("username", param1.getName());
- assertTrue(param1.getRequired());
+ assertEquals("query", param1.in());
+ assertEquals("username", param1.name());
+ assertTrue(param1.required());
ParameterDefinition param2 = definition.getParameters().get(1);
- assertEquals("query", param2.getIn());
- assertEquals("password", param2.getName());
- assertTrue(param2.getRequired());
+ assertEquals("query", param2.in());
+ assertEquals("password", param2.name());
+ assertTrue(param2.required());
}
private boolean checkServer(List servers, String expected) {
@@ -202,15 +204,15 @@ private boolean checkServer(List servers, String expected) {
return false;
}
- public static String readResource(String path) {
- try (InputStream is =
- Thread.currentThread().getContextClassLoader().getResourceAsStream(path)) {
- if (is == null) {
- throw new IllegalArgumentException("Resource not found: " + path);
- }
- return new String(is.readAllBytes(), StandardCharsets.UTF_8);
+ public static UnifiedOpenAPI readResource(String path) {
+
+ ClasspathResource classpathResource = new ClasspathResource(path);
+ ObjectMapper mapper = WorkflowFormat.fromFileName(classpathResource.name()).mapper();
+
+ try (InputStream is = classpathResource.open()) {
+ return mapper.readValue(is, UnifiedOpenAPI.class);
} catch (IOException e) {
- throw new RuntimeException("Failed to read resource: " + path, e);
+ throw new RuntimeException("Failed to read OpenAPI resource: " + path, e);
}
}
}
diff --git a/pom.xml b/pom.xml
index fd63d277..cf156e59 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,8 +94,6 @@
2.0.17
9.1.0.Final
6.0.0
-
- 2.1.37
true
java