Skip to content

Commit

Permalink
Merge branch 'dev' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
cgendreau committed Nov 13, 2024
2 parents 2c5d9f7 + de2d239 commit 6ce23a9
Show file tree
Hide file tree
Showing 16 changed files with 362 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,9 @@
}
}
},
"eventGeom": {
"type": "geo_point"
},
"determination" : {
"properties" : {
"verbatimDeterminer": {
Expand Down
9 changes: 8 additions & 1 deletion owasp-suppression.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@
<notes>no AuthenticatedVoter</notes>
<cve>CVE-2024-22257</cve>
</suppress>

<suppress>
<notes>Not applicable</notes>
<cve>CVE-2024-38816</cve>
</suppress>
<suppress>
<notes>No WebFlux</notes>
<cve>CVE-2024-38821</cve>
</suppress>
<suppress>
<notes>not valid for search-api</notes>
<packageUrl regex="true">^pkg:maven/org\.springframework/spring.*$</packageUrl>
Expand Down
9 changes: 5 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.aafc-bicoe</groupId>
<artifactId>search-api-parent</artifactId>
<version>0.36</version>
<version>0.37</version>

<packaging>pom</packaging>

Expand All @@ -29,7 +29,7 @@
<java.version>21</java.version>

<jakarta.json.version>2.0.1</jakarta.json.version>
<dina-base-api.version>0.128</dina-base-api.version>
<dina-base-api.version>0.131</dina-base-api.version>

<!-- Build plugin properties -->
<maven-checkstyle-plugin.version>3.4.0</maven-checkstyle-plugin.version>
Expand All @@ -47,8 +47,9 @@
<testcontainers.version>1.16.2</testcontainers.version>
<json-path.version>2.7.0</json-path.version>

<!-- Versions override-->
<org.springframework.version>5.3.32</org.springframework.version>
<!-- versions override-->
<spring-framework.version>5.3.39</spring-framework.version>

</properties>

<!-- Common sub module dependencies -->
Expand Down
6 changes: 3 additions & 3 deletions search-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
<parent>
<artifactId>search-api-parent</artifactId>
<groupId>io.github.aafc-bicoe</groupId>
<version>0.36</version>
<version>0.37</version>
</parent>

<artifactId>search-cli</artifactId>
<name>search-cli</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.shell.version>2.1.8</spring.shell.version>
<spring.shell.version>2.1.15</spring.shell.version>
<json-path.version>2.5.0</json-path.version>
<mockserver.version>5.11.2</mockserver.version>
</properties>
Expand All @@ -27,7 +27,7 @@
<dependency>
<groupId>io.github.aafc-bicoe</groupId>
<artifactId>search-messaging</artifactId>
<version>0.36</version>
<version>0.37</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*
*/
@Component
public class CacheableApiAccess {
public class CacheableApiAccess implements DinaApiAccess {

public static final String CACHE_NAME = "apiAccess";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ca.gc.aafc.dina.search.cli.http;

import ca.gc.aafc.dina.search.cli.config.EndpointDescriptor;
import ca.gc.aafc.dina.search.cli.exceptions.SearchApiException;

public interface DinaApiAccess {

String getFromApi(EndpointDescriptor endpointDescriptor, String objectId) throws SearchApiException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public void reIndexDocuments(List<DocumentInfo> documentsToIndex) {
});
}

record DocumentInfo(String type, String id) {
public record DocumentInfo(String type, String id) {
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ca.gc.aafc.dina.search.cli.indexing;

import ca.gc.aafc.dina.search.cli.http.CacheableApiAccess;
import ca.gc.aafc.dina.search.cli.http.DinaApiAccess;
import ca.gc.aafc.dina.search.cli.json.JSONApiDocumentStructure;
import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.core.JsonProcessingException;
Expand All @@ -15,7 +15,9 @@

import lombok.extern.log4j.Log4j2;

import java.util.List;
import java.util.Optional;
import java.util.function.Function;

/**
* This class handles merging DINA API document with external document references embedded in the
Expand All @@ -34,11 +36,18 @@ public class IndexableDocumentHandler {

public static final ObjectMapper OM = new ObjectMapper();

private final CacheableApiAccess client;
private static final List<JsonNodeTransformation>
INCLUDED_NODE_TRANSFORMATION =
List.of(
new JsonNodeTransformation(JSONApiDocumentStructure.ATTRIBUTES, "eventGeom",
JsonNodeTransformer::extractCoordinates));


private final DinaApiAccess apiAccess;
private final ServiceEndpointProperties svcEndpointProps;

public IndexableDocumentHandler(CacheableApiAccess client, ServiceEndpointProperties svcEndpointProps) {
this.client = client;
public IndexableDocumentHandler(DinaApiAccess apiAccess, ServiceEndpointProperties svcEndpointProps) {
this.apiAccess = apiAccess;
this.svcEndpointProps = svcEndpointProps;
}

Expand Down Expand Up @@ -101,6 +110,13 @@ private void processIncluded(JsonNode includedArray) {
}

for (JsonNode curObject : includedArray) {
//Check for potential node transformations
for (JsonNodeTransformation jst : INCLUDED_NODE_TRANSFORMATION) {
if (curObject.has(jst.nodeName())) {
JsonNodeTransformer.transformNode(curObject.get(jst.nodeName()), jst.attribute(), jst.transformer());
}
}

if (curObject.get(JSONApiDocumentStructure.ATTRIBUTES) != null || !curObject.isObject()) {
// Already have the attributes or the node is not an object ... skip the current entry
continue;
Expand All @@ -117,7 +133,7 @@ private void processIncluded(JsonNode includedArray) {

// Best effort processing for assembling of include section
try {
String rawPayload = client.getFromApi(svcEndpointProps.getEndpoints().get(type), curObjectId);
String rawPayload = apiAccess.getFromApi(svcEndpointProps.getEndpoints().get(type), curObjectId);
JsonNode document = OM.readTree(rawPayload);
// Take the data.attributes section to be embedded
Optional<JsonNode> dataObject = atJsonPtr(document, JSONApiDocumentStructure.ATTRIBUTES_PTR);
Expand Down Expand Up @@ -153,4 +169,7 @@ private static void processMeta(JsonNode metaObject) {
((ObjectNode) metaObject).remove("external");
}
}

record JsonNodeTransformation(String nodeName, String attribute, Function<JsonNode, JsonNode> transformer) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package ca.gc.aafc.dina.search.cli.indexing;

import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.log4j.Log4j2;

import java.util.function.Function;

/**
* Gets a node from a JONS:API document and transforms its value.
*/
@Log4j2
public final class JsonNodeTransformer {

private static final JsonPointer COORDINATES_PTR = JsonPointer.valueOf("/coordinates");

private JsonNodeTransformer() {
// utility class
}

/**
* Extracts the JsonNode under the property "coordinates".
* @param eventGeomNode
* @return
*/
public static JsonNode extractCoordinates(JsonNode eventGeomNode) {
return eventGeomNode.at(COORDINATES_PTR);
}

/**
* From a node, get the JsonNode from an attribute and apply the transformer to it.
* Replace its value with the result of the transformation.
*
* @param nodeToTransform
* @param attribute
* @param transformer
*/
public static void transformNode(JsonNode nodeToTransform, String attribute, Function<JsonNode, JsonNode> transformer) {
JsonNode node = nodeToTransform.get(attribute);
if (node != null && !node.isMissingNode()) {
if (nodeToTransform instanceof ObjectNode objectNode) {
objectNode.replace(attribute, transformer.apply(node));
} else {
log.debug("Not and instance of ObjectNode");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package ca.gc.aafc.dina.search.cli.indexing;

import ca.gc.aafc.dina.search.cli.TestConstants;
import ca.gc.aafc.dina.search.cli.config.ServiceEndpointProperties;
import ca.gc.aafc.dina.search.cli.containers.DinaElasticSearchContainer;
import ca.gc.aafc.dina.search.cli.exceptions.SearchApiException;
import ca.gc.aafc.dina.search.cli.utils.JsonTestUtils;
import ca.gc.aafc.dina.testsupport.TestResourceHelper;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.SneakyThrows;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
import org.testcontainers.junit.jupiter.Container;

import java.io.IOException;

import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest(properties = {
"spring.shell.interactive.enabled=false",
"dina.messaging.isProducer=false",
"dina.messaging.isConsumer=false"
})
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class IndexableDocumentHandlerIT {

private final String DOC_ID = "01930c2a-f299-7464-ad27-ce3828421e6e";

@Container
private static final ElasticsearchContainer ELASTICSEARCH_CONTAINER = new DinaElasticSearchContainer();

@Autowired
private ElasticsearchClient elasticSearchClient;

@Autowired
private ServiceEndpointProperties svcEndpointProps;

@BeforeAll
static void beforeAll() {
// Start elastic search container.
ELASTICSEARCH_CONTAINER.start();
}

@AfterAll
static void afterAll() {
ELASTICSEARCH_CONTAINER.stop();
}

@Test
@SneakyThrows({ IOException.class })
public void indexGeoPointDocuments() throws SearchApiException {

ca.gc.aafc.dina.testsupport.elasticsearch.ElasticSearchTestUtils.createIndex(elasticSearchClient,
TestConstants.MATERIAL_SAMPLE_INDEX, TestConstants.MATERIAL_SAMPLE_INDEX_MAPPING_FILE);

// Create a specific instance to ignore api calls since we don't have external relationships to resolve
IndexableDocumentHandler idh = new IndexableDocumentHandler(
(endpointDescriptor, objectId) -> "",
svcEndpointProps
);

// assemble the document which includes a geo point
ObjectNode result = idh.assembleDocument(TestResourceHelper.readContentAsString("material_sample_document.json"));


ca.gc.aafc.dina.testsupport.elasticsearch.ElasticSearchTestUtils.indexDocument(elasticSearchClient, TestConstants.MATERIAL_SAMPLE_INDEX, DOC_ID,
JsonTestUtils.OBJECT_MAPPER.writeValueAsString(result));

SearchResponse<JsonNode> searchResponse = ca.gc.aafc.dina.search.cli.utils.ElasticSearchTestUtils.search(elasticSearchClient, TestConstants.MATERIAL_SAMPLE_INDEX,
"data.id", DOC_ID);

assertEquals(1, searchResponse.hits().hits().size());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public void reIndexRelatedDocuments() {
"data.id", TestConstants.PERSON_DOCUMENT_ID);

assertEquals(1, searchResponse.hits().hits().size());
JsonNode doc = searchResponse.hits().hits().get(0).source();
JsonNode doc = searchResponse.hits().hits().getFirst().source();

assertEquals("test org", doc.at("/included/0/attributes/displayName").asText());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,9 @@
}
}
},
"eventGeom": {
"type": "geo_point"
},
"determination" : {
"properties" : {
"verbatimDeterminer": {
Expand Down
Loading

0 comments on commit 6ce23a9

Please sign in to comment.