diff --git a/pom.xml b/pom.xml
index 5128eea..188e44e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,9 +48,9 @@
UTF-8
- 1.7.6
+ 1.7.9-SNAPSHOT
- 0.1.3
+ 0.1.7-SNAPSHOT
2.18.3
5.7.2
3.17.0
@@ -87,6 +87,12 @@
${version-api-commons-sb3}
+
+ eu.europeana.api
+ commons-sb3-definitions
+ ${version-api-commons-sb3}
+
+
eu.europeana.api
entity-management-definitions
diff --git a/src/main/java/eu/europeana/entity/client/EntityApiClient.java b/src/main/java/eu/europeana/entity/client/EntityApiClient.java
index 9a697a5..748f908 100644
--- a/src/main/java/eu/europeana/entity/client/EntityApiClient.java
+++ b/src/main/java/eu/europeana/entity/client/EntityApiClient.java
@@ -10,6 +10,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/**
* Entity Api Client
@@ -82,6 +83,12 @@ public List enrichEntity(String text, String lang, String type, String r
return getMetadata(enrichResults);
}
+ @Override
+ public List enrichEntity(String type, Map textLangMap, int rows) throws EntityClientException {
+ List enrichResults = getEntityClientApiConnection().retrieveEnrichment(type, textLangMap, rows);
+ return getMetadata(enrichResults);
+ }
+
@Override
public Entity getEntity(String entityId) throws EntityClientException {
return getEntityClientApiConnection().getEntityById(entityId);
diff --git a/src/main/java/eu/europeana/entity/client/connection/EntityClientApiConnection.java b/src/main/java/eu/europeana/entity/client/connection/EntityClientApiConnection.java
index b7b69b1..8f9f00f 100644
--- a/src/main/java/eu/europeana/entity/client/connection/EntityClientApiConnection.java
+++ b/src/main/java/eu/europeana/entity/client/connection/EntityClientApiConnection.java
@@ -13,13 +13,16 @@
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.ProtocolException;
+import org.apache.hc.core5.net.URIBuilder;
import org.apache.hc.core5.reactor.IOReactorConfig;
import java.io.IOException;
import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.ExecutionException;
import static eu.europeana.entity.client.utils.EntityApiConstants.*;
@@ -140,6 +143,48 @@ public List retrieveEnrichment(String text, String language, String type
return Collections.emptyList();
}
+ /**
+ * Entity Enrichment retrieval
+ * @param textLangMap text lang map for entity enrich
+ * @param type type of entity
+ * @param rows rows
+ * @return lis of entity ids
+ * @throws EntityClientException throws if there is an error in post request or reading the response
+ */
+ public List retrieveEnrichment(String type, Map textLangMap, int rows) throws EntityClientException{
+ try {
+ URI enrichUrl = new URIBuilder(entityApiUri + PATH_SEPERATOR + ENRICH_PATH).build();
+ String jsonBody = EntityClientUtils.buildEnrichRequest(type, textLangMap, rows);
+ LOGGER.debug("{} ",jsonBody);
+
+ SimpleHttpResponse response = entityApiConnection.post(
+ enrichUrl.toString(),
+ jsonBody,
+ ContentType.APPLICATION_JSON.getMimeType(),
+ this.auth);
+
+ if (response.getCode() == HttpStatus.SC_OK) {
+ List entities = EntityClientUtils.getEntityApiResults(response.getBodyText());
+ if (entities != null) {
+ LOGGER.debug("{} entities found for enrich text/lang={}, type={}", entities.size(), textLangMap, type);
+ return entities;
+ }
+ } else {
+ LOGGER.error("Error in enrichment response {}", response.getBodyText());
+ }
+ } catch (URISyntaxException e) {
+ throw new EntityClientException("Error creating enrich Urls " +e.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR, e);
+ } catch (ExecutionException | IOException e) {
+ throw new EntityClientException(ERROR_MESSAGE + e.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR, e);
+ } catch (InterruptedException e) { // the interrupted state is restored
+ LOGGER.warn(INTERRUPTED_MESSAGE, e);
+ /* Clean up whatever needs to be handled before interrupting */
+ Thread.currentThread().interrupt();
+ }
+ LOGGER.debug("No entity found for enrich text/lang: {}, type={}", textLangMap, type);
+ return Collections.emptyList();
+ }
+
/**
* Returns the Entity matching the entity id
* This method executes the entity Retrieval method of EM.
diff --git a/src/main/java/eu/europeana/entity/client/utils/EntityClientUtils.java b/src/main/java/eu/europeana/entity/client/utils/EntityClientUtils.java
index aebf1c8..986fc21 100644
--- a/src/main/java/eu/europeana/entity/client/utils/EntityClientUtils.java
+++ b/src/main/java/eu/europeana/entity/client/utils/EntityClientUtils.java
@@ -1,9 +1,13 @@
package eu.europeana.entity.client.utils;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import eu.europeana.api.commons_sb3.definitions.search.enrich.EnrichQuery;
+import eu.europeana.api.commons_sb3.definitions.search.enrich.EnrichRequest;
import eu.europeana.entity.client.exception.EntityClientException;
import org.apache.commons.lang3.StringUtils;
import org.apache.hc.core5.http.HttpStatus;
@@ -16,6 +20,7 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import static eu.europeana.entity.client.utils.EntityApiConstants.*;
@@ -25,7 +30,7 @@
public class EntityClientUtils {
private static final Logger LOGGER = LogManager.getLogger(EntityClientUtils.class);
- private static final ObjectMapper mapper = new ObjectMapper();
+ private static final ObjectMapper mapper = buildMapper();
private EntityClientUtils() {
// to hide implicit one
@@ -98,6 +103,21 @@ public static URI buildEntityEnrichUrl(String url, String text, String lang, Str
}
}
+ public static String buildEnrichRequest(String type, Map textLangMap, int rows) throws EntityClientException {
+ if (textLangMap == null || textLangMap.isEmpty()) {
+ throw new EntityClientException("No values provided for enrichment request");
+ }
+ try {
+ List query = new ArrayList<>();
+ for (Map.Entry entry : textLangMap.entrySet()) {
+ query.add(new EnrichQuery(entry.getKey(), entry.getValue()));
+ }
+ return mapper.writeValueAsString(new EnrichRequest(type, query, rows));
+ } catch (JsonProcessingException e) {
+ throw new EntityClientException("Error creating enrich request " +e.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
/**
* Builds the Entity Api resolve url
@@ -168,4 +188,28 @@ public static List getEntityApiResults(String json) throws JsonProcessin
}
return entities;
}
+
+ /**
+ * Extracts an error message from the given JSON response string.
+ *
+ * @param response the JSON response string to parse for an error message
+ * @return the extracted error message if available, or an empty string if the parsing fails
+ */
+ public static String getErrorMessage(String response) {
+ try {
+ return mapper.readTree(response).get("message").asText();
+ } catch (JsonProcessingException e) {
+ LOGGER.error("Error while parsing the response", e);
+ }
+ return "";
+ }
+
+ private static ObjectMapper buildMapper() {
+ ObjectMapper mapper = new ObjectMapper();
+ SimpleModule module = new SimpleModule();
+ mapper.registerModule(module);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ mapper.findAndRegisterModules();
+ return mapper;
+ }
}
diff --git a/src/main/java/eu/europeana/entity/client/web/EntityApi.java b/src/main/java/eu/europeana/entity/client/web/EntityApi.java
index 0d3afa7..d702fd2 100644
--- a/src/main/java/eu/europeana/entity/client/web/EntityApi.java
+++ b/src/main/java/eu/europeana/entity/client/web/EntityApi.java
@@ -5,6 +5,7 @@
import eu.europeana.entitymanagement.definitions.model.Entity;
import java.util.List;
+import java.util.Map;
/**
* Entity client api interface
@@ -31,6 +32,14 @@ public interface EntityApi {
*/
public List enrichEntity(String text, String lang, String type, String rows) throws EntityClientException;
+ /**
+ * This method returns entity enrichment depending on given text, types and language.
+ * @param type
+ * @param textLangMap
+ * @param rows
+ */
+ public List enrichEntity(String type, Map textLangMap, int rows) throws EntityClientException;
+
/**
* Get Entity by EntityId
* @param entityId
diff --git a/src/test/java/eu/europeana/entity/client/web/EntityClientEnrichTest.java b/src/test/java/eu/europeana/entity/client/web/EntityClientEnrichTest.java
new file mode 100644
index 0000000..9d8be5d
--- /dev/null
+++ b/src/test/java/eu/europeana/entity/client/web/EntityClientEnrichTest.java
@@ -0,0 +1,124 @@
+package eu.europeana.entity.client.web;
+
+import eu.europeana.entity.client.EntityApiClient;
+import eu.europeana.entity.client.config.EntityClientConfiguration;
+import eu.europeana.entity.client.exception.EntityClientException;
+import eu.europeana.entitymanagement.definitions.model.Entity;
+import eu.europeana.entitymanagement.vocabulary.EntityTypes;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+public class EntityClientEnrichTest {
+
+ EntityApi apiClient ;
+
+ /**
+ * This constructor will create a Entity api client based on values present in properties file.
+ * @throws EntityClientException
+ */
+ @BeforeAll
+ void setup() throws EntityClientException {
+ apiClient = new EntityApiClient(new EntityClientConfiguration());
+ }
+
+ /**
+ * Tests the behavior - when called with null values for the text
+ * and language map parameters.
+ *
+ * Expected behavior:
+ * - An {@link EntityClientException} is thrown.
+ * - The exception message is "No values provided for enrichment request".
+ */
+ @Test
+ public void testEnrichment_1() {
+ EntityClientException exception = assertThrows(EntityClientException.class, () ->
+ apiClient.enrichEntity("place", null, 0));
+
+ assertEquals("No values provided for enrichment request", exception.getMessage());
+ }
+
+ /**
+ * Test scenario - rows invalid value for enrichment
+ * @throws EntityClientException
+ */
+ @Test
+ public void testEnrichment_2() throws EntityClientException {
+ List enrichments = apiClient.enrichEntity("place", Collections.singletonMap("paris", "en"), -1);
+ assertTrue(enrichments.isEmpty());
+
+ enrichments = apiClient.enrichEntity("place", Collections.singletonMap("paris", "en"), 60);
+ assertTrue(enrichments.isEmpty());
+ }
+
+ /**
+ * Test scenario - empty rows or zero rows
+ * Enrichments results should be present as the default value of rows is 10
+ * @throws EntityClientException
+ */
+ @Test
+ public void testEnrichment_3() throws EntityClientException {
+ List enrichments = apiClient.enrichEntity("place", Collections.singletonMap("paris", "en"), 0);
+ assertNotNull(enrichments);
+ assertEquals(EntityTypes.Place.getEntityType(), enrichments.get(0).getType());
+ }
+
+ /**
+ * Test scenario - empty lang in the map
+ * @throws EntityClientException
+ */
+ @Test
+ public void testEnrichment_4() throws EntityClientException {
+ List enrichments = apiClient.enrichEntity("place", Collections.singletonMap("paris", null), 0);
+ assertNotNull(enrichments);
+ assertEquals(EntityTypes.Place.getEntityType(), enrichments.get(0).getType());
+ assertTrue(StringUtils.contains(enrichments.get(0).getEntityId(), "place/41488"));
+
+ enrichments = apiClient.enrichEntity("agent", Collections.singletonMap("paris", ""), 0);
+ assertNotNull(enrichments);
+ assertEquals(EntityTypes.Agent.getEntityType(), enrichments.get(0).getType());
+ assertTrue(StringUtils.contains(enrichments.get(0).getEntityId(), "agent/52295"));
+ }
+
+ /**
+ * Test scenario - empty type
+ * @throws EntityClientException
+ */
+ @Test
+ public void testEnrichment_5() throws EntityClientException {
+ List enrichments = apiClient.enrichEntity("", Collections.singletonMap("paris", ""), 0);
+ assertNotNull(enrichments);
+ assertEquals(2, enrichments.size());
+
+ assertEquals(EntityTypes.Place.getEntityType(), enrichments.get(0).getType());
+ assertTrue(StringUtils.contains(enrichments.get(0).getEntityId(), "place/41488"));
+
+ assertEquals(EntityTypes.Agent.getEntityType(), enrichments.get(1).getType());
+ assertTrue(StringUtils.contains(enrichments.get(1).getEntityId(), "agent/52295"));
+ }
+
+ /**
+ * Test scenario - multiple values
+ * @throws EntityClientException
+ */
+ @Test
+ public void testEnrichment_6() throws EntityClientException {
+ Map map = new HashMap<>();
+ map.put("paris", "en");
+ map.put("India", null);
+ map.put("France", "fr");
+ List enrichments = apiClient.enrichEntity("", map, 0);
+ assertNotNull(enrichments);
+ assertEquals(7, enrichments.size());
+ }
+
+}
diff --git a/src/test/java/eu/europeana/entity/client/web/EntityClientTest.java b/src/test/java/eu/europeana/entity/client/web/EntityClientTest.java
index 44be286..2819010 100644
--- a/src/test/java/eu/europeana/entity/client/web/EntityClientTest.java
+++ b/src/test/java/eu/europeana/entity/client/web/EntityClientTest.java
@@ -68,11 +68,9 @@ void testGetEntity_2() throws EntityClientException {
* @throws JsonProcessingException
*/
@Test
- @Disabled ("testGetEntity_3 disabled because the temp fix shows Aggregator as organisation")
void testGetEntity_3() throws EntityClientException {
Organization entity = (Organization) apiClient.getEntity("http://data.europeana.eu/organization/4563");
assertNotNull(entity);
- assertEquals(EntityTypes.Organization.getEntityType(), entity.getType());
assertEquals(EntityTypes.Aggregator.getEntityType(), entity.getType());
assertNotNull(entity.getAggregatesFrom());
@@ -124,7 +122,6 @@ void testResolveEntity_2() throws EntityClientException {
void testEnrichment_1() throws EntityClientException {
List enrichments = apiClient.enrichEntity("CulturaItalia", null, "organization", null);
assertNotNull(enrichments);
- assertFalse(enrichments.isEmpty());
}