Skip to content

Commit

Permalink
initial tests for request validation against OpenApi spec
Browse files Browse the repository at this point in the history
  • Loading branch information
azakrzewski-hy committed Dec 16, 2024
1 parent 80919c3 commit 6b7208c
Show file tree
Hide file tree
Showing 10 changed files with 347 additions and 0 deletions.
5 changes: 5 additions & 0 deletions live-ingester/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.openapi4j</groupId>
<artifactId>openapi-operation-validator</artifactId>
<version>1.0.7</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package org.alfresco.hxi_connector.live_ingester.domain.usecase.e2e.repository;

import org.alfresco.hxi_connector.live_ingester.util.insight_api.HxInsightRequest;
import org.alfresco.hxi_connector.live_ingester.util.insight_api.RequestLoader;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openapi4j.operation.validator.model.Request;
import org.openapi4j.operation.validator.model.impl.Body;
import org.openapi4j.operation.validator.model.impl.DefaultRequest;
import org.openapi4j.operation.validator.validation.OperationValidator;
import org.openapi4j.parser.OpenApi3Parser;
import org.openapi4j.parser.model.v3.OpenApi3;
import org.openapi4j.schema.validator.ValidationData;

import java.net.URL;

import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openapi4j.operation.validator.model.Request.Method.POST;

public class OpenApiRequestValidationTest {

private static final String SPECIFICATION_URL = "http://hxai-data-platform-dev-swagger-ui.s3-website-us-east-1.amazonaws.com/docs/insight-ingestion-api-swagger.json";
private static URL specificationUrl;

@BeforeAll
public static void setUp() throws Exception {
specificationUrl = new URL(SPECIFICATION_URL);
}

@Test
public void testRequestToPresignedUrls() throws Exception {

OperationValidator operationValidator = loadOperationValidator(specificationUrl, "presignedUrls");

HxInsightRequest hxInsightRequest = RequestLoader.load("/expected-hxinsight-requests/get-presigned-urls-request.yml");

Request request = makeRequest(hxInsightRequest);

checkRequest(request, operationValidator);
}

@Test
public void testCreateRequestToIngestionEvents() throws Exception {

OperationValidator operationValidator = loadOperationValidator(specificationUrl, "ingestionEvents");

HxInsightRequest hxInsightRequest = RequestLoader.load("/expected-hxinsight-requests/create-document-request.yml");

Request request = makeRequest(hxInsightRequest);

checkRequest(request, operationValidator);
}

@Test
public void testCreateRequestToIngestionEventsWithoutSourceId() throws Exception {

OperationValidator operationValidator = loadOperationValidator(specificationUrl, "ingestionEvents");

HxInsightRequest hxInsightRequest = RequestLoader.load("/expected-hxinsight-requests/create-document-request-without-source-id.yml");

Request request = makeRequest(hxInsightRequest);

checkRequest(request, operationValidator);
}

@Test
public void testCreateRequestToIngestionEventsWithEmptyProperties() throws Exception {

OperationValidator operationValidator = loadOperationValidator(specificationUrl, "ingestionEvents");

HxInsightRequest hxInsightRequest = RequestLoader.load("/expected-hxinsight-requests/create-document-request-empty-properties.yml");

Request request = makeRequest(hxInsightRequest);

checkRequest(request, operationValidator);
}

protected OperationValidator loadOperationValidator(URL specification, String operationId) throws Exception {
OpenApi3 openApi = new OpenApi3Parser().parse(specification, true);

return new OperationValidator(
openApi,
openApi.getPathItemByOperationId(operationId),
openApi.getOperationById(operationId));
}

private static Request makeRequest(HxInsightRequest hxInsightRequest) {
DefaultRequest.Builder builder = new DefaultRequest.Builder(hxInsightRequest.url(), POST);
hxInsightRequest.headers().forEach(builder::header);
if (hxInsightRequest.body() != null) {
builder.body(Body.from(hxInsightRequest.body()));
}
return builder.build();
}

protected void checkRequest(Request sentRequest, OperationValidator operationValidator) {
ValidationData<Void> validation = new ValidationData<>();
operationValidator.validateBody(sentRequest, validation);
operationValidator.validateHeaders(sentRequest, validation);

assertTrue(validation.isValid(), validation.results().toString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.alfresco.hxi_connector.live_ingester.util.insight_api;

import java.util.Map;

public record HxInsightRequest(String url, Map<String, String> headers, String body) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.alfresco.hxi_connector.live_ingester.util.insight_api;

import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import org.alfresco.hxi_connector.live_ingester.domain.exception.LiveIngesterRuntimeException;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class RequestLoader {
private final static ObjectMapper JSON_MAPPER = new ObjectMapper();
private final static ObjectMapper YAML_MAPPER = new ObjectMapper(new YAMLFactory());

public static HxInsightRequest load(String path)
{
Map<String, Object> data;
try (InputStream stream = HxInsightRequest.class.getResourceAsStream(path))
{
data = YAML_MAPPER.readValue(stream.readAllBytes(), HashMap.class);
}
catch (IOException e)
{
throw new UncheckedIOException(e);
}
Object body = data.get("body");
String bodyAsString = null;
if (body != null)
{
try
{
bodyAsString = JSON_MAPPER.writeValueAsString(body);
}
catch (JsonProcessingException e)
{
throw new LiveIngesterRuntimeException(e);
}
}
return new HxInsightRequest((String) data.get("url"), (Map) data.get("headers"), bodyAsString);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
url: /v1/ingestion-events
headers:
authorization: string
content-type: application/json
hxp-environment: string
user-agent: string
body: [
{
"objectId": "d71dd823-82c7-477c-8490-04cb0e826e65",
"sourceId" : "alfresco-dummy-source-id-0a63de491876",
"eventType": "create",
"sourceTimestamp": 1611227656423,
"properties": {

}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
url: /v1/ingestion-events
headers:
authorization: string
content-type: application/json
hxp-environment: string
user-agent: string
body: [
{
"objectId": "d71dd823-82c7-477c-8490-04cb0e826e65",
"eventType": "create",
"sourceTimestamp": 1611227656423,
"properties": {
"cm:autoVersion": {"value": true},
"createdAt": {"value": 1611227655695},
"modifiedAt": {"value" : 1611227655695},
"cm:versionType": {"value": "MAJOR"},
"aspectsNames": {"value": ["cm:versionable", "cm:auditable"]},
"cm:name": {
"value": "purchase-order-scan.doc",
"annotation" : "name"
},
"type": {"value": "cm:content"},
"createdBy": {"value": "admin"},
"modifiedBy": {"value": "admin"},
"cm:content": {
"file": {
"content-metadata": {
"size": 531152,
"name": "purchase-order-scan.doc",
"content-type": "application/msword"
}
}
},
"ALLOW_ACCESS": {"value": ["GROUP_EVERYONE"]},
"DENY_ACCESS": {"value": []}
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
url: /v1/ingestion-events
headers:
authorization: string
content-type: application/json
hxp-environment: string
user-agent: string
body: [
{
"objectId": "d71dd823-82c7-477c-8490-04cb0e826e65",
"sourceId" : "alfresco-dummy-source-id-0a63de491876",
"eventType": "create",
"sourceTimestamp": 1611227656423,
"properties": {
"cm:autoVersion": {"value": true},
"createdAt": {"value": 1611227655695},
"modifiedAt": {"value" : 1611227655695},
"cm:versionType": {"value": "MAJOR"},
"aspectsNames": {"value": ["cm:versionable", "cm:auditable"]},
"cm:name": {
"value": "purchase-order-scan.doc",
"annotation" : "name"
},
"type": {"value": "cm:content"},
"createdBy": {"value": "admin"},
"modifiedBy": {"value": "admin"},
"cm:content": {
"file": {
"content-metadata": {
"size": 531152,
"name": "purchase-order-scan.doc",
"content-type": "application/msword"
}
}
},
"ALLOW_ACCESS": {"value": ["GROUP_EVERYONE"]},
"DENY_ACCESS": {"value": []}
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
url: /v1/ingestion-events
headers:
authorization: string
content-type: application/json
hxp-environment: string
user-agent: string
body: [
{
"objectId": "d71dd823-82c7-477c-8490-04cb0e826e65",
"sourceId" : "alfresco-dummy-source-id-0a63de491876",
"eventType": "delete",
"sourceTimestamp": 1611656982995
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
url: /v1/presigned-urls
headers:
authorization: string
content-type: application/json
hxp-environment: string
user-agent: string
count: string
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
url: /v1/ingestion-events
headers:
authorization: string
content-type: application/json
hxp-environment: string
user-agent: string
body: [
{
"objectId": "d71dd823-82c7-477c-8490-04cb0e826e65",
"sourceId": "alfresco-dummy-source-id-0a63de491876",
"eventType": "update",
"sourceTimestamp": 1611656982995,
"properties": {
"cm:title": {
"value": "Purchase Order"
},
"aspectsNames": {
"value": [
"cm:versionable",
"cm:author",
"cm:titled"
]
},
"modifiedBy": {
"value": "abeecher"
},
"createdAt": {
"value": 1611227655695
},
"modifiedAt": {
"value": 1611227655695
},
"cm:versionLabel": {
"value": "1.0"
},
"createdBy": {
"value": "admin"
},
"ALLOW_ACCESS": {
"value": [
"GROUP_EVERYONE"
]
},
"cm:name": {
"value": "purchase-order-scan.pdf",
"annotation": "name"
},
"type": {
"value": "cm:content"
},
"DENY_ACCESS": {
"value": []
},
"cm:content": {
"file": {
"content-metadata": {
"size": 531152,
"name": "purchase-order-scan.pdf",
"content-type": "application/pdf"
}
}
}
},
"removedProperties": [
"cm:versionType",
"cm:description"
]
}
]

0 comments on commit 6b7208c

Please sign in to comment.