From e6a905bc1a3a8e611d9662f689618fe2e5bcd030 Mon Sep 17 00:00:00 2001 From: utas-raymondng Date: Fri, 17 May 2024 17:20:23 +1000 Subject: [PATCH 1/4] Add new API call to get needed info --- .../java/au/org/aodn/geonetwork4/Setup.java | 12 ++- .../org/aodn/geonetwork4/controller/Api.java | 95 ++++++++++++++++++- 2 files changed, 100 insertions(+), 7 deletions(-) diff --git a/geonetwork/src/main/java/au/org/aodn/geonetwork4/Setup.java b/geonetwork/src/main/java/au/org/aodn/geonetwork4/Setup.java index defa995..1782e46 100644 --- a/geonetwork/src/main/java/au/org/aodn/geonetwork4/Setup.java +++ b/geonetwork/src/main/java/au/org/aodn/geonetwork4/Setup.java @@ -5,6 +5,7 @@ import au.org.aodn.geonetwork_api.openapi.model.Group; import au.org.aodn.geonetwork_api.openapi.model.HarvestersApiLegacyResponse; +import au.org.aodn.geonetwork_api.openapi.model.MeResponse; import au.org.aodn.geonetwork_api.openapi.model.MetadataCategory; import com.github.underscore.U; import org.apache.logging.log4j.LogManager; @@ -26,6 +27,9 @@ */ public class Setup { + public static final String SYSTEM_INFO = "systemInfo"; + public static final String SITE_INFO = "siteInfo"; + protected Logger logger = LogManager.getLogger(Setup.class); protected MeApi meApi; @@ -60,14 +64,14 @@ public Setup(ResourceLoader resourceLoader, this.harvestersApi = harvestersApi; } - public void getMe() { - logger.info("Login user is {}", meApi.getMeWithHttpInfo().getBody()); + public ResponseEntity getMe() { + return ResponseEntity.ok(meApi.getMeWithHttpInfo().getBody()); } public ResponseEntity> getSystemInfo() { return ResponseEntity.ok(Map.of( - "systemInfo", Objects.requireNonNull(siteHelper.getApi().getSystemInfoWithHttpInfo().getBody()), - "siteInfo", Objects.requireNonNull(siteHelper.getApi().getInformationWithHttpInfo().getBody()) + SYSTEM_INFO, Objects.requireNonNull(siteHelper.getApi().getSystemInfoWithHttpInfo().getBody()), + SITE_INFO, Objects.requireNonNull(siteHelper.getApi().getInformationWithHttpInfo().getBody()) )); } diff --git a/geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java b/geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java index 0d8d82b..2c2a61e 100644 --- a/geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java +++ b/geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java @@ -2,25 +2,38 @@ import au.org.aodn.geonetwork4.Setup; import au.org.aodn.geonetwork4.model.*; +import au.org.aodn.geonetwork_api.openapi.model.SiteInformation; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import jeeves.services.ReadWriteController; +import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; + +import org.fao.geonet.domain.Metadata; +import org.fao.geonet.kernel.harvest.HarvestManagerImpl; +import org.fao.geonet.kernel.harvest.harvester.csw.CswHarvester; +import org.fao.geonet.kernel.harvest.harvester.geonet.GeonetHarvester; +import org.fao.geonet.kernel.harvest.harvester.geonet20.Geonet20Harvester; +import org.fao.geonet.kernel.harvest.harvester.oaipmh.OaiPmhHarvester; +import org.fao.geonet.kernel.harvest.harvester.ogcwxs.OgcWxSHarvester; +import org.fao.geonet.repository.MetadataRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; +import static au.org.aodn.geonetwork4.Setup.SITE_INFO; +import static au.org.aodn.geonetwork4.Setup.SYSTEM_INFO; + /** * Any api call here request a header X-XSRF-TOKEN to be presented, this is due to geonetwork4 enabled crsf(). The token * can be obtained by making a call with username/password, then the return header contains a XSRF-TOKEN which contains @@ -39,6 +52,12 @@ public class Api { @Autowired protected ObjectMapper objectMapper; + @Autowired + MetadataRepository repository; + + @Autowired + HarvestManagerImpl harvestManager; + @Autowired @Qualifier("remoteSources") protected Map remoteConfigMap; @@ -46,6 +65,76 @@ public class Api { protected RemoteConfig getRemoteConfig(String type) { return remoteConfigMap.get(type); } + /** + * HACK!! + * This function is used to expose something not found in the rest api, it used the jpa api to get the + * metadata object itself and then expose the additional values, this object contains the sourceId + * which is the uuid of the record from the source system being harvested, it different from the + * UUID use in this geonetwork, because harvested record get assign a new UUID locally. + * + * This source id can be useful because the geonetwork may download the logo + * + * @param uuid - UUID of the record use by this geonetwork + * @return - A data structure contains the UUID of the record in the source system. + */ + @GetMapping("/records/{uuid}/info") + public ResponseEntity getRecordSource(@PathVariable("uuid") String uuid) { + Map info = new HashMap<>(); + info.put("logos", new ArrayList()); + + Metadata metadata = repository.findOneByUuid(uuid); + if(metadata != null) { + // Here we can get the source id + if(metadata.getSourceInfo() != null) { + info.put("sourceId", metadata.getSourceInfo().getSourceId()); + + if(info.get("logos") instanceof ArrayList) { + String homeURL = ServletUriComponentsBuilder.fromCurrentContextPath().toUriString(); + ((ArrayList) info.get("logos")) + .add(String.format("%s/images/logos/%s.png", homeURL, info.get("sourceId"))); + } + } + + // We can also get the harvester uuid, from there we can get the harvester url + if(metadata.getHarvestInfo() != null) { + + info.put("isHarvested", metadata.getHarvestInfo().isHarvested()); + + Object harvester = harvestManager.getHarvester(metadata.getHarvestInfo().getUuid()); + if(harvester instanceof GeonetHarvester) { + info.put("harvesterUri", StringUtils.removeEnd(((GeonetHarvester) harvester).getParams().host, "/")); + info.put("harvesterType", "GeonetHarvester"); + // The geonetwork store logo under this dir with the uuid name, we provide a list of suggestion + // on where to find the logo + if(info.get("logos") instanceof ArrayList) { + ((ArrayList) info.get("logos")) + .add(String.format("%s/images/logos/%s.png", info.get("harvesterUri"), info.get("sourceId"))); + } + } + else if(harvester instanceof OaiPmhHarvester) { + info.put("harvesterUri", StringUtils.removeEnd(((OaiPmhHarvester) harvester).getParams().url, "/")); + info.put("harvesterType", "OaiPmhHarvester"); + } + else if(harvester instanceof CswHarvester) { + info.put("harvesterUri", StringUtils.removeEnd(((CswHarvester) harvester).getParams().capabUrl, "/")); + info.put("harvesterType", "CswHarvester"); + } + else if(harvester instanceof OgcWxSHarvester) { + info.put("harvesterUri", StringUtils.removeEnd(((OgcWxSHarvester) harvester).getParams().url, "/")); + info.put("harvesterType", "OgcWxSHarvester"); + } + else if(harvester instanceof Geonet20Harvester) { + info.put("harvesterUri", StringUtils.removeEnd(((Geonet20Harvester) harvester).getParams().host, "/")); + info.put("harvesterType", "Geonet20Harvester"); + } + } + + if(metadata.getDataInfo() != null) { + info.put("schemaid", metadata.getDataInfo().getSchemaId()); + } + } + return ResponseEntity.ok(info); + } @GetMapping("/setup/harvesters") public ResponseEntity getAllHarvesters() { From 4a98e30abf1cdb5465314d6d87e5ee8c8baa01e9 Mon Sep 17 00:00:00 2001 From: utas-raymondng Date: Mon, 20 May 2024 15:25:49 +1000 Subject: [PATCH 2/4] Checkin to add suggest_logos --- .../openapi/api/helper/SiteHelper.java | 44 +++++--- .../openapi/api/helper/SiteHelperTest.java | 52 +++++++++ .../java/au/org/aodn/geonetwork4/Setup.java | 4 + .../org/aodn/geonetwork4/controller/Api.java | 68 ++++++++---- .../aodn/geonetwork4/controller/ApiTest.java | 104 ++++++++++++++++++ 5 files changed, 230 insertions(+), 42 deletions(-) create mode 100644 geonetwork-api/src/test/java/au/org/aodn/geonetwork_api/openapi/api/helper/SiteHelperTest.java create mode 100644 geonetwork/src/test/java/au/org/aodn/geonetwork4/controller/ApiTest.java diff --git a/geonetwork-api/src/main/java/au/org/aodn/geonetwork_api/openapi/api/helper/SiteHelper.java b/geonetwork-api/src/main/java/au/org/aodn/geonetwork_api/openapi/api/helper/SiteHelper.java index 1de3698..6c38227 100644 --- a/geonetwork-api/src/main/java/au/org/aodn/geonetwork_api/openapi/api/helper/SiteHelper.java +++ b/geonetwork-api/src/main/java/au/org/aodn/geonetwork_api/openapi/api/helper/SiteHelper.java @@ -3,7 +3,7 @@ import au.org.aodn.geonetwork_api.openapi.api.SiteApi; import au.org.aodn.geonetwork_api.openapi.api.Status; import au.org.aodn.geonetwork_api.openapi.model.Setting; -import au.org.aodn.geonetwork_api.openapi.model.SystemInfo; + import org.json.JSONObject; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -11,10 +11,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.client.HttpClientErrorException; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; public class SiteHelper { @@ -22,6 +20,10 @@ public class SiteHelper { protected static final String SETTINGS = "settings"; protected static final String DATA = "data"; + public final static String HOST = "system/server/host"; + public final static String PROTOCOL = "system/server/protocol"; + public final static String PORT = "system/server/port"; + protected Logger logger = LogManager.getLogger(SiteHelper.class); protected SiteApi api; @@ -30,6 +32,24 @@ public SiteHelper(SiteApi api) { } public SiteApi getApi() { return api; } + /** + * Get the system setting from geonetwork + * @return - A map with key as the setting path and value contains the details. + */ + public Map getAllSettingsDetails() { + Map s = new HashMap<>(); + + ResponseEntity> storedSetting = this.api.getSettingsDetailsWithHttpInfo(null, null); + + if(storedSetting.getStatusCode().is2xxSuccessful()) { + // Get the available keys and value + s.putAll(Objects.requireNonNull(storedSetting.getBody()) + .stream() + .collect(Collectors.toMap(Setting::getName, Function.identity()))); + } + + return s; + } public List createSettings(List json) { return json.stream() @@ -42,19 +62,7 @@ public List createSettings(List json) { if(jsonObject.optJSONObject(SETTINGS) != null && jsonObject.optJSONObject(SETTINGS).optJSONObject(DATA) != null) { - Set keys = new HashSet<>(); - - ResponseEntity> storedSetting = this.api.getSettingsDetailsWithHttpInfo(null, null); - - if(storedSetting.getStatusCode().is2xxSuccessful()) { - // Get the available keys in the geonetwork4 system. - Set s = storedSetting.getBody() - .stream() - .map(k -> k.getName()) - .collect(Collectors.toSet()); - - keys.addAll(s); - } + Set keys = getAllSettingsDetails().keySet(); // Convert map from to Map settings = jsonObject. diff --git a/geonetwork-api/src/test/java/au/org/aodn/geonetwork_api/openapi/api/helper/SiteHelperTest.java b/geonetwork-api/src/test/java/au/org/aodn/geonetwork_api/openapi/api/helper/SiteHelperTest.java new file mode 100644 index 0000000..c00fd10 --- /dev/null +++ b/geonetwork-api/src/test/java/au/org/aodn/geonetwork_api/openapi/api/helper/SiteHelperTest.java @@ -0,0 +1,52 @@ +package au.org.aodn.geonetwork_api.openapi.api.helper; + +import au.org.aodn.geonetwork_api.openapi.api.SiteApi; +import au.org.aodn.geonetwork_api.openapi.model.Setting; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.http.ResponseEntity; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +public class SiteHelperTest { + + /** + * Function test only, we do not have docker image to run for this test, the + * integration test in geonetwork should test it more. + */ + @Test + public void verifyGetAllSettingsDetails() { + Setting s1 = new Setting(); + s1.setName(SiteHelper.HOST); + s1.setValue("geonetwork-edge.edge.aodn.org.au"); + + Setting s2 = new Setting(); + s2.setName(SiteHelper.PROTOCOL); + s2.setValue("https"); + + List result = new ArrayList<>(); + result.add(s1); + result.add(s2); + + SiteApi api = Mockito.mock(SiteApi.class); + when(api.getSettingsDetailsWithHttpInfo(eq(null), eq(null))) + .thenReturn(ResponseEntity.ok(result)); + + SiteHelper helper = new SiteHelper(api); + + Set v = helper.getAllSettingsDetails().keySet(); + assertTrue("Contains host", v.contains(SiteHelper.HOST)); + assertTrue("Contains protocol", v.contains(SiteHelper.PROTOCOL)); + + assertEquals("Host equals", + "geonetwork-edge.edge.aodn.org.au", + helper.getAllSettingsDetails().get(SiteHelper.HOST).getValue()); + } +} diff --git a/geonetwork/src/main/java/au/org/aodn/geonetwork4/Setup.java b/geonetwork/src/main/java/au/org/aodn/geonetwork4/Setup.java index 1782e46..fa78936 100644 --- a/geonetwork/src/main/java/au/org/aodn/geonetwork4/Setup.java +++ b/geonetwork/src/main/java/au/org/aodn/geonetwork4/Setup.java @@ -143,6 +143,10 @@ public ResponseEntity getAllHarvesters() { public ResponseEntity> insertHarvester(List config) { return ResponseEntity.of(Optional.of(harvestersApiLegacy.createHarvesters(config))); } + + public String getSiteSetting(String path) { + return siteHelper.getAllSettingsDetails().get(path).getValue(); + } /** * TODO: The return type is a bit messy * @param config - The json config diff --git a/geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java b/geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java index 2c2a61e..4381256 100644 --- a/geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java +++ b/geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java @@ -2,7 +2,7 @@ import au.org.aodn.geonetwork4.Setup; import au.org.aodn.geonetwork4.model.*; -import au.org.aodn.geonetwork_api.openapi.model.SiteInformation; +import au.org.aodn.geonetwork_api.openapi.api.helper.SiteHelper; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; @@ -31,9 +31,6 @@ import java.util.stream.Collectors; -import static au.org.aodn.geonetwork4.Setup.SITE_INFO; -import static au.org.aodn.geonetwork4.Setup.SYSTEM_INFO; - /** * Any api call here request a header X-XSRF-TOKEN to be presented, this is due to geonetwork4 enabled crsf(). The token * can be obtained by making a call with username/password, then the return header contains a XSRF-TOKEN which contains @@ -44,24 +41,26 @@ @RequestMapping(value = {"/{portal}/api/aodn"}) public class Api { + public static final String SUGGEST_LOGOS = "suggest_logos"; + protected Logger logger = LogManager.getLogger(Api.class); - @Autowired protected Setup setup; - - @Autowired + protected MetadataRepository repository; + protected HarvestManagerImpl harvestManager; protected ObjectMapper objectMapper; - @Autowired - MetadataRepository repository; - - @Autowired - HarvestManagerImpl harvestManager; - @Autowired @Qualifier("remoteSources") protected Map remoteConfigMap; + public Api(Setup setup, MetadataRepository metadataRepository, HarvestManagerImpl harvestManager, ObjectMapper objectMapper) { + this.harvestManager = harvestManager; + this.repository = metadataRepository; + this.setup = setup; + this.objectMapper = objectMapper; + } + protected RemoteConfig getRemoteConfig(String type) { return remoteConfigMap.get(type); } @@ -72,26 +71,43 @@ protected RemoteConfig getRemoteConfig(String type) { * which is the uuid of the record from the source system being harvested, it different from the * UUID use in this geonetwork, because harvested record get assign a new UUID locally. * - * This source id can be useful because the geonetwork may download the logo + * This source id can be useful because the geonetwork may download the log, this all depends on which harvester + * you use, for GeonetHarvester, it will download others don't, therefore the logo list will be different + * + * TODO: We should add suggestion based on group logo. * * @param uuid - UUID of the record use by this geonetwork - * @return - A data structure contains the UUID of the record in the source system. + * @return - A data structure contains the UUID of the record in the source system as well as suggested logo in order of possibility + * { + * "sourceId": "dbee258b-8730-4072-96d4-2818a69a4afd", + * "schemaid": "iso19115-3.2018", + * "harvesterUri": "https://catalogue-imos.aodn.org.au/geonetwork", + * "suggest_logos": [ + * "http://localhost:8080/geonetwork/images/logos/dbee258b-8730-4072-96d4-2818a69a4afd.png", + * "https://catalogue-imos.aodn.org.au/geonetwork/images/logos/dbee258b-8730-4072-96d4-2818a69a4afd.png" + * ], + * "isHarvested": true, + * "harvesterType": "GeonetHarvester" + * } */ @GetMapping("/records/{uuid}/info") - public ResponseEntity getRecordSource(@PathVariable("uuid") String uuid) { + public ResponseEntity> getRecordExtraInfo(@PathVariable("uuid") String uuid) { Map info = new HashMap<>(); - info.put("logos", new ArrayList()); + info.put(SUGGEST_LOGOS, new ArrayList()); Metadata metadata = repository.findOneByUuid(uuid); if(metadata != null) { - // Here we can get the source id if(metadata.getSourceInfo() != null) { + // Here we can get the source id, then we can create the first option for logo + // which is extract logo from this host info.put("sourceId", metadata.getSourceInfo().getSourceId()); - if(info.get("logos") instanceof ArrayList) { - String homeURL = ServletUriComponentsBuilder.fromCurrentContextPath().toUriString(); - ((ArrayList) info.get("logos")) - .add(String.format("%s/images/logos/%s.png", homeURL, info.get("sourceId"))); + if(info.get(SUGGEST_LOGOS) instanceof ArrayList) { + String host = setup.getSiteSetting(SiteHelper.HOST); + String port = setup.getSiteSetting(SiteHelper.PORT); + String protocol = setup.getSiteSetting(SiteHelper.PROTOCOL); + ((ArrayList) info.get(SUGGEST_LOGOS)) + .add(String.format("%s://%s:%s/geonetwork/images/logos/%s.png", protocol, host, port, info.get("sourceId"))); } } @@ -106,24 +122,28 @@ public ResponseEntity getRecordSource(@PathVariable("uuid") String uuid) { info.put("harvesterType", "GeonetHarvester"); // The geonetwork store logo under this dir with the uuid name, we provide a list of suggestion // on where to find the logo - if(info.get("logos") instanceof ArrayList) { - ((ArrayList) info.get("logos")) + if(info.get(SUGGEST_LOGOS) instanceof ArrayList) { + ((ArrayList) info.get(SUGGEST_LOGOS)) .add(String.format("%s/images/logos/%s.png", info.get("harvesterUri"), info.get("sourceId"))); } } else if(harvester instanceof OaiPmhHarvester) { + // Will have remote link to logo info.put("harvesterUri", StringUtils.removeEnd(((OaiPmhHarvester) harvester).getParams().url, "/")); info.put("harvesterType", "OaiPmhHarvester"); } else if(harvester instanceof CswHarvester) { + // Will have remote link to logo info.put("harvesterUri", StringUtils.removeEnd(((CswHarvester) harvester).getParams().capabUrl, "/")); info.put("harvesterType", "CswHarvester"); } else if(harvester instanceof OgcWxSHarvester) { + // Will have remote link to logo info.put("harvesterUri", StringUtils.removeEnd(((OgcWxSHarvester) harvester).getParams().url, "/")); info.put("harvesterType", "OgcWxSHarvester"); } else if(harvester instanceof Geonet20Harvester) { + // Will have remote link to logo info.put("harvesterUri", StringUtils.removeEnd(((Geonet20Harvester) harvester).getParams().host, "/")); info.put("harvesterType", "Geonet20Harvester"); } diff --git a/geonetwork/src/test/java/au/org/aodn/geonetwork4/controller/ApiTest.java b/geonetwork/src/test/java/au/org/aodn/geonetwork4/controller/ApiTest.java new file mode 100644 index 0000000..12f2266 --- /dev/null +++ b/geonetwork/src/test/java/au/org/aodn/geonetwork4/controller/ApiTest.java @@ -0,0 +1,104 @@ +package au.org.aodn.geonetwork4.controller; + +import au.org.aodn.geonetwork4.Setup; +import au.org.aodn.geonetwork_api.openapi.api.helper.SiteHelper; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.fao.geonet.domain.Metadata; +import org.fao.geonet.domain.MetadataHarvestInfo; +import org.fao.geonet.domain.MetadataSourceInfo; +import org.fao.geonet.kernel.harvest.HarvestManagerImpl; +import org.fao.geonet.kernel.harvest.harvester.geonet.GeonetHarvester; +import org.fao.geonet.kernel.harvest.harvester.geonet.GeonetParams; +import org.fao.geonet.kernel.harvest.harvester.oaipmh.OaiPmhHarvester; +import org.fao.geonet.kernel.harvest.harvester.oaipmh.OaiPmhParams; +import org.fao.geonet.repository.MetadataRepository; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.http.ResponseEntity; + +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +public class ApiTest { + + @Test + public void verifyRecordExtraInfoWorks() { + String uuid = "2852a776-cbfc-4bc8-a126-f3c036814892"; + String sourceId = "dbee258b-8730-4072-96d4-2818a69a4afd"; + String harvesterUuid = "1234"; + String oaiHarvesterUuid = "oai1234"; + + MetadataRepository metadataRepository = Mockito.mock(MetadataRepository.class); + + Metadata metadata = new Metadata(); + + metadata.setSourceInfo(new MetadataSourceInfo()); + metadata.getSourceInfo().setSourceId(sourceId); + + metadata.setHarvestInfo(new MetadataHarvestInfo()); + metadata.getHarvestInfo().setHarvested(true); + metadata.getHarvestInfo().setUuid(harvesterUuid); + + when(metadataRepository.findOneByUuid(eq(uuid))) + .thenReturn(metadata); + + Setup setup = Mockito.mock(Setup.class); + + when(setup.getSiteSetting(eq(SiteHelper.HOST))) + .thenReturn("localhost"); + when(setup.getSiteSetting(eq(SiteHelper.PORT))) + .thenReturn("8080"); + when(setup.getSiteSetting(eq(SiteHelper.PROTOCOL))) + .thenReturn("http"); + + // Geonetwork harvester + GeonetHarvester harvester = new GeonetHarvester(); + GeonetParams params = Mockito.mock(GeonetParams.class); + params.host = "https://catalogue-imos.aodn.org.au/geonetwork"; + harvester.setParams(params); + + HarvestManagerImpl harvestManager = Mockito.mock(HarvestManagerImpl.class); + when(harvestManager.getHarvester(eq(harvesterUuid))) + .thenReturn(harvester); + + Api api = new Api(setup, metadataRepository, harvestManager, new ObjectMapper()); + + ResponseEntity> v = api.getRecordExtraInfo(uuid); + + assertEquals("Logo have two suggestions", 2, ((List)v.getBody().get(Api.SUGGEST_LOGOS)).size()); + assertEquals("Logo link 1", + "http://localhost:8080/geonetwork/images/logos/dbee258b-8730-4072-96d4-2818a69a4afd.png", + ((List)v.getBody().get(Api.SUGGEST_LOGOS)).get(0)); + assertEquals("Logo link 2", + "https://catalogue-imos.aodn.org.au/geonetwork/images/logos/dbee258b-8730-4072-96d4-2818a69a4afd.png", + ((List)v.getBody().get(Api.SUGGEST_LOGOS)).get(1)); + + // If use other harvester then we will not have remote section + String oaiHarvesterUrl = "oaiHarvesterUrl"; + OaiPmhHarvester oaiPmhHarvester = Mockito.mock(OaiPmhHarvester.class); + OaiPmhParams pmhParams = Mockito.mock(OaiPmhParams.class); + pmhParams.url = oaiHarvesterUrl; + + when(oaiPmhHarvester.getParams()) + .thenReturn(pmhParams); + + when(harvestManager.getHarvester(eq(oaiHarvesterUuid))) + .thenReturn(oaiPmhHarvester); + + // Set the metadata to use Oai Harvester + metadata.getHarvestInfo().setUuid(oaiHarvesterUuid); + + v = api.getRecordExtraInfo(uuid); + + // Only one link this time and suggestion is localhost + assertEquals("Logo have two suggestions", 1, ((List)v.getBody().get(Api.SUGGEST_LOGOS)).size()); + assertEquals("Logo link 1", + "http://localhost:8080/geonetwork/images/logos/dbee258b-8730-4072-96d4-2818a69a4afd.png", + ((List)v.getBody().get(Api.SUGGEST_LOGOS)).get(0)); + + } +} From 30959452190671603e84772b9bf55ce0abc9ded2 Mon Sep 17 00:00:00 2001 From: utas-raymondng Date: Mon, 20 May 2024 15:30:00 +1000 Subject: [PATCH 3/4] Update Readme --- README.md | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ff4ede2..88d2ef2 100644 --- a/README.md +++ b/README.md @@ -77,19 +77,20 @@ endpoint to view the log file directly as cloud watch is not so easy to use. ### Endpoints: > You need to present X-XSRF-TOKEN in your header to call Setup endpoints, please read comments -in [Api.java](./geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java) - -| Description | Method | Endpoints | Param | Environment | -|-------------------------------|--------|---------------------------------------------|----------------------------------|-------------| -| Logfile | GET | `/geonetwork/srv/api/manage/logfile` | | Edge | -| Beans info | GET | `/geonetwork/srv/api/manage/beans` | |Edge | -| Env info | GET | `/geonetwork/srv/api/manage/env` | |Edge | -| Info | GET | `/geonetwork/srv/api/manage/info` | |Edge | -| Health check | GET | `/geonetwork/srv/api/manage/health` | |Edge | -| Read Harvester - Config | GET | `/geonetwork/srv/api/aodn/setup/harvesters` | |Edge | -| Delete All Harvester - Config | DELETE | `/geonetwork/srv/api/aodn/setup/harvesters` | |Edge | -| Delete All Category - Config | DELETE | `/geonetwork/srv/api/aodn/setup/categories` | |Edge | -| Setup from github config | POST | `/geonetwork/srv/api/aodn/setup` | source=github |Edge | +> in [Api.java](./geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java) + +| Description | Method | Endpoints | Param | Environment | +|-------------------------------|--------|------------------------------------------------|---------------|---------------| +| Logfile | GET | `/geonetwork/srv/api/manage/logfile` | | Edge, Staging | +| Beans info | GET | `/geonetwork/srv/api/manage/beans` | | Edge, Staging | +| Env info | GET | `/geonetwork/srv/api/manage/env` | | Edge, Staging | +| Info | GET | `/geonetwork/srv/api/manage/info` | | Edge, Staging | +| Health check | GET | `/geonetwork/srv/api/manage/health` | | Edge, Staging | +| Read Record Misc Info | GET | `/geonetwork/srv/api/aodn/records/{uuid}/info` | | Edge, Staging | +| Read Harvester - Config | GET | `/geonetwork/srv/api/aodn/setup/harvesters` | | Edge, Staging | +| Delete All Harvester - Config | DELETE | `/geonetwork/srv/api/aodn/setup/harvesters` | | Edge, Staging | +| Delete All Category - Config | DELETE | `/geonetwork/srv/api/aodn/setup/categories` | | Edge, Staging | +| Setup from github config | POST | `/geonetwork/srv/api/aodn/setup` | source=github | Edge, Staging | ### How the Setup works? @@ -105,6 +106,9 @@ Given the configuration is store in main branch, that means changes to configura > The POST method can carry a body with the same format as the config.json file, if this appears, then the content > in the body will be use instead of the config.json in github. Hence, you can run individual setup one by one +### Read Record Misc Info endpoint +Info not expose in regular api endpoints but needed for indexing, for example logo url of a dataset. + ## Schema folder The schema folder contains an open-api schema file from Genetwork4, you can get it from any instance From ea30c1f2c8a33367f34bcfab3b980dfbde59ae5a Mon Sep 17 00:00:00 2001 From: utas-raymondng Date: Mon, 20 May 2024 15:58:31 +1000 Subject: [PATCH 4/4] update due to PR comments --- .../openapi/api/helper/SiteHelperTest.java | 6 +- .../org/aodn/geonetwork4/controller/Api.java | 60 +++++++++---------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/geonetwork-api/src/test/java/au/org/aodn/geonetwork_api/openapi/api/helper/SiteHelperTest.java b/geonetwork-api/src/test/java/au/org/aodn/geonetwork_api/openapi/api/helper/SiteHelperTest.java index c00fd10..bd15193 100644 --- a/geonetwork-api/src/test/java/au/org/aodn/geonetwork_api/openapi/api/helper/SiteHelperTest.java +++ b/geonetwork-api/src/test/java/au/org/aodn/geonetwork_api/openapi/api/helper/SiteHelperTest.java @@ -23,9 +23,11 @@ public class SiteHelperTest { */ @Test public void verifyGetAllSettingsDetails() { + String url = "geonetwork-edge.edge.aodn.org.au"; + Setting s1 = new Setting(); s1.setName(SiteHelper.HOST); - s1.setValue("geonetwork-edge.edge.aodn.org.au"); + s1.setValue(url); Setting s2 = new Setting(); s2.setName(SiteHelper.PROTOCOL); @@ -46,7 +48,7 @@ public void verifyGetAllSettingsDetails() { assertTrue("Contains protocol", v.contains(SiteHelper.PROTOCOL)); assertEquals("Host equals", - "geonetwork-edge.edge.aodn.org.au", + url, helper.getAllSettingsDetails().get(SiteHelper.HOST).getValue()); } } diff --git a/geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java b/geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java index 4381256..ead8e0a 100644 --- a/geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java +++ b/geonetwork/src/main/java/au/org/aodn/geonetwork4/controller/Api.java @@ -25,7 +25,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import java.util.*; @@ -71,8 +70,8 @@ protected RemoteConfig getRemoteConfig(String type) { * which is the uuid of the record from the source system being harvested, it different from the * UUID use in this geonetwork, because harvested record get assign a new UUID locally. * - * This source id can be useful because the geonetwork may download the log, this all depends on which harvester - * you use, for GeonetHarvester, it will download others don't, therefore the logo list will be different + * This source id can be useful because the geonetwork may download the logo, it all depends on which harvester + * you use, for GeonetHarvester, it will download but others don't, therefore the logo list will be different * * TODO: We should add suggestion based on group logo. * @@ -117,35 +116,34 @@ public ResponseEntity> getRecordExtraInfo(@PathVariable("uui info.put("isHarvested", metadata.getHarvestInfo().isHarvested()); Object harvester = harvestManager.getHarvester(metadata.getHarvestInfo().getUuid()); - if(harvester instanceof GeonetHarvester) { - info.put("harvesterUri", StringUtils.removeEnd(((GeonetHarvester) harvester).getParams().host, "/")); - info.put("harvesterType", "GeonetHarvester"); - // The geonetwork store logo under this dir with the uuid name, we provide a list of suggestion - // on where to find the logo - if(info.get(SUGGEST_LOGOS) instanceof ArrayList) { - ((ArrayList) info.get(SUGGEST_LOGOS)) - .add(String.format("%s/images/logos/%s.png", info.get("harvesterUri"), info.get("sourceId"))); + if(harvester != null) { + // Set the harvester class + info.put("harvesterType", harvester.getClass()); + + if (harvester instanceof GeonetHarvester) { + info.put("harvesterUri", StringUtils.removeEnd(((GeonetHarvester) harvester).getParams().host, "/")); + // The geonetwork store logo under this dir with the uuid name, we provide a list of suggestion + // on where to find the logo + if (info.get(SUGGEST_LOGOS) instanceof ArrayList) { + ((ArrayList) info.get(SUGGEST_LOGOS)) + .add(String.format("%s/images/logos/%s.png", info.get("harvesterUri"), info.get("sourceId"))); + } + } else if (harvester instanceof OaiPmhHarvester) { + // Will have remote link to logo + info.put("harvesterUri", StringUtils.removeEnd(((OaiPmhHarvester) harvester).getParams().url, "/")); + } else if (harvester instanceof CswHarvester) { + // Will have remote link to logo + info.put("harvesterUri", StringUtils.removeEnd(((CswHarvester) harvester).getParams().capabUrl, "/")); + } else if (harvester instanceof OgcWxSHarvester) { + // Will have remote link to logo + info.put("harvesterUri", StringUtils.removeEnd(((OgcWxSHarvester) harvester).getParams().url, "/")); + } else if (harvester instanceof Geonet20Harvester) { + // Will have remote link to logo + info.put("harvesterUri", StringUtils.removeEnd(((Geonet20Harvester) harvester).getParams().host, "/")); + } + else { + logger.error("Unknown instanceof type for harvester {}", harvester.getClass()); } - } - else if(harvester instanceof OaiPmhHarvester) { - // Will have remote link to logo - info.put("harvesterUri", StringUtils.removeEnd(((OaiPmhHarvester) harvester).getParams().url, "/")); - info.put("harvesterType", "OaiPmhHarvester"); - } - else if(harvester instanceof CswHarvester) { - // Will have remote link to logo - info.put("harvesterUri", StringUtils.removeEnd(((CswHarvester) harvester).getParams().capabUrl, "/")); - info.put("harvesterType", "CswHarvester"); - } - else if(harvester instanceof OgcWxSHarvester) { - // Will have remote link to logo - info.put("harvesterUri", StringUtils.removeEnd(((OgcWxSHarvester) harvester).getParams().url, "/")); - info.put("harvesterType", "OgcWxSHarvester"); - } - else if(harvester instanceof Geonet20Harvester) { - // Will have remote link to logo - info.put("harvesterUri", StringUtils.removeEnd(((Geonet20Harvester) harvester).getParams().host, "/")); - info.put("harvesterType", "Geonet20Harvester"); } }