Skip to content

Commit

Permalink
Merge pull request #46 from aodn/features/5522-update-config-logo
Browse files Browse the repository at this point in the history
Features/5522 update config logo
  • Loading branch information
utas-raymondng authored May 15, 2024
2 parents 6ab40d3 + 30427c9 commit 89067f4
Show file tree
Hide file tree
Showing 13 changed files with 119 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.*;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClientException;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
Expand All @@ -25,10 +27,12 @@ public class LogosHelper {

protected static final String IMAGE = "image";
protected Logger logger = LogManager.getLogger(LogosHelper.class);
protected ResourceLoader resourceLoader;
protected LogosApiExt api;

public LogosHelper(LogosApiExt api) {
public LogosHelper(LogosApiExt api, ResourceLoader resourceLoader) {
this.api = api;
this.resourceLoader = resourceLoader;
}

public LogosApiExt getApi() {
Expand All @@ -52,18 +56,24 @@ public List<Status> createLogos(List<String> config) {

parsed = parser.parseLogosConfig(v);
try {
logger.info("Processing logo config -> {}", v);
// Read the link and download the file
URL url = new URL(parsed.getJsonObject().getString("link"));
Resource resource = resourceLoader.getResource(parsed.getJsonObject().getString("link"));

try (InputStream is = url.openStream()) {
try (InputStream is = resource.getInputStream()) {
// Store in temp folder
File file = File.createTempFile("img", "img");
file.deleteOnExit();

FileUtils.copyInputStreamToFile(is, file);

// Delete before add
getApi().deleteLogoWithHttpInfo(parsed.getJsonObject().getString(IMAGE));
try {
getApi().deleteLogoWithHttpInfo(parsed.getJsonObject().getString(IMAGE));
}
catch(Exception e) {
logger.warn("Ignore error because delete file do not exist");
}

ResponseEntity<String> response = getApi().addLogoWithHttpInfo(
file,
Expand All @@ -83,19 +93,19 @@ public List<Status> createLogos(List<String> config) {
}
return status;
}
catch(HttpServerErrorException.InternalServerError | HttpClientErrorException.BadRequest i){
catch(HttpServerErrorException.InternalServerError | HttpClientErrorException.BadRequest i) {
status.setStatus(i.getStatusCode());
status.setMessage("File already exist in folder? " + i.getMessage());
logger.error(status.getMessage());
return status;
}
catch (MalformedURLException e) {
status.setStatus(HttpStatus.BAD_REQUEST);
status.setMessage("Invalid URL in the config : " + parsed.getJsonObject().getString("link"));
logger.error(status.getMessage());
return status;
catch(RestClientException restClientException) {
// This error indicate file already exist so it is fine
logger.info("Ignore error {} for {}", restClientException.getMessage(), v);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package au.org.aodn.geonetwork_api.openapi.api.helper;

import au.org.aodn.geonetwork_api.openapi.api.LogosApiExt;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ResourceUtils;
import org.springframework.web.server.ResponseStatusException;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

public class LogoHelperTest {
/**
* The create logo function will try to delete logo before add, this test is used to verify even
* the logo do not exist and not found exception throw from server, the function still works.
*/
@Test
public void verifyAddNewLogoWorks() throws IOException {
LogosApiExt api = Mockito.mock(LogosApiExt.class);
LogosHelper helper = new LogosHelper(api, new DefaultResourceLoader());

when(api.deleteLogoWithHttpInfo(anyString()))
.thenThrow(new ResponseStatusException(HttpStatus.NOT_FOUND, "entity not found"));

when(api.addLogoWithHttpInfo(any(File.class), anyString(), eq(Boolean.TRUE)))
.thenReturn(ResponseEntity.ok(null));

String json1 = FileUtils.readFileToString(
ResourceUtils.getFile("classpath:aad_logo.json"),
StandardCharsets.UTF_8);

// The logo gif do not exist in the test resources, so this is a negative test case
String json2 = FileUtils.readFileToString(
ResourceUtils.getFile("classpath:not_exist_logo.json"),
StandardCharsets.UTF_8);

helper.createLogos(List.of(json1, json2));

// Only called once because if the logo file not exist then it won't call addLogo
verify(api, times(1)).addLogoWithHttpInfo(any(File.class), anyString(), eq(Boolean.TRUE));
}
}
Binary file added geonetwork-api/src/test/resources/AAD_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions geonetwork-api/src/test/resources/aad_logo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"id": "aad_logo",
"image": "AAD_logo.gif",
"link": "classpath:AAD_logo.png"
}
5 changes: 5 additions & 0 deletions geonetwork-api/src/test/resources/not_exist_logo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"id": "not_exist_logo",
"image": "not_exist_logo.gif",
"link": "file:not_exist_logo.gif"
}
2 changes: 1 addition & 1 deletion geonetwork-config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
},
{
"type": "logos",
"jsonFileName": "imas_colour_logo.json"
"jsonFileName": "imos_colour_logo.json"
},
{
"type": "logos",
Expand Down
4 changes: 2 additions & 2 deletions geonetwork-config/logos/imas_colour_logo.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"id": "imas_colour_logo",
"image": "IMAS_colour_logo.gif",
"link": "https://content.aodn.org.au/Documents/Images/Logos/AODN_Partner/IMAS_colour_logo.gif"
"image": "IMAS_colour_logo.png",
"link": "https://content.aodn.org.au/Documents/Images/Logos/AODN_Partner/IMAS_colour_logo.png"
}
4 changes: 2 additions & 2 deletions geonetwork-config/logos/imos_colour_logo.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"id": "imos_colour_logo",
"image": "IMOS_logo.gif",
"link": "https://content.aodn.org.au/Documents/Images/Logos/IMOS/IMOS_colour_logo.gif"
"image": "IMOS_colour_logo.gif",
"link": "https://content.aodn.org.au/Documents/Images/Logos/AODN_Partner/IMOS_colour_logo.gif"
}
25 changes: 13 additions & 12 deletions geonetwork/src/main/java/au/org/aodn/geonetwork4/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import org.fao.geonet.ApplicationContextHolder;

import org.springframework.core.io.ResourceLoader;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.support.BasicAuthenticationInterceptor;
Expand All @@ -40,7 +41,6 @@
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;

@Aspect
@Configuration
Expand Down Expand Up @@ -105,12 +105,11 @@ public class Config {
* Use aspectJ to intercept all call that ends with WithHttpInfo, we must always use geonetwork api call
* ends with WithHttpInfo because the way geonetworks works is you must present an X-XSRF-TOKEN and session
* in the call with username password, otherwise it will fail.
*
* You need to make an init call to get the X-XSRF-TOKEN, the call will have status forbidden
* and comes back with the token in cookie, then you need to set the token before next call.
*/
@Pointcut("execution(public * au.org.aodn.geonetwork_api.openapi.api..*.*WithHttpInfo(..))")
public void interceptWithHttpInfo() {};
public void interceptWithHttpInfo() {}

@Around("interceptWithHttpInfo()")
public ResponseEntity<?> aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
Expand Down Expand Up @@ -139,25 +138,26 @@ public ResponseEntity<?> aroundAdvice(ProceedingJoinPoint joinPoint) throws Thro
public void init() throws NoSuchAlgorithmException, KeyManagementException {
logger.info("AODN - Done set logger info");

/**
/*
* No need to do host verfication, this should apply to dev env only
*/
if(environment == Environment.DEV) {
HttpsTrustManager.allowAllSSL();
}

/**
/*
* The key here is to use the application context of a child JeevesApplicationContext where its parent
* is ApplicationContext.
*/
ConfigurableApplicationContext jeevesContext = ApplicationContextHolder.get();
jeevesContext.getBeanFactory().registerSingleton("genericEntityListener", genericEntityListener);
}
/**
* The reason we need is to setup the WEB_ROOT context to be use by Actuator. In springboot application it is
* The reason we need is to set the WEB_ROOT context to be used by Actuator. In springboot application it is
* set on start, but this geonetwork is a different species that it isn't a springboot app so this setting
* is missing
* @param sc
*
* @param sc servlet context that pass around
*/
@Autowired
public void setRootContext(ServletContext sc, ConfigurableApplicationContext context) {
Expand All @@ -177,9 +177,9 @@ public GenericEntityListener createGenericEntityListener() {
* Must use prototype scope as there is a XSRF-TOKEN header for each api, that cannot share
* with the same api.
*
* @param username
* @param password
* @return
* @param username geonetwork admin user name
* @param password geonetwork admin password
* @return The api client connects geonetwork
*/
@Bean("apiClient")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
Expand Down Expand Up @@ -261,7 +261,8 @@ RegistriesApiExt getRegistriesApi(@Qualifier("apiClient") ApiClient client) {
}

@Bean
public Setup getSetup(MeApi meApi,
public Setup getSetup(ResourceLoader resourceLoader,
MeApi meApi,
LogosApiExt logosApi,
GroupsApi groupsApi,
TagsApi tagsApi,
Expand All @@ -271,7 +272,7 @@ public Setup getSetup(MeApi meApi,
@Qualifier("harvestersApiLegacy") HarvestersApiLegacy harvestersApiLegacy,
@Qualifier("harvestersApi") HarvestersApi harvestersApi) {

return new Setup(meApi, logosApi, groupsApi, tagsApi, registriesApi, siteApi, usersApi, harvestersApiLegacy, harvestersApi);
return new Setup(resourceLoader, meApi, logosApi, groupsApi, tagsApi, registriesApi, siteApi, usersApi, harvestersApiLegacy, harvestersApi);
}
/**
* By default it use the main branch, however when you do your development, you can use a different branch
Expand Down
12 changes: 7 additions & 5 deletions geonetwork/src/main/java/au/org/aodn/geonetwork4/Setup.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@

import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.ResponseEntity;

import java.util.List;

import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
Expand All @@ -36,7 +38,8 @@ public class Setup {
protected HarvestersApiLegacy harvestersApiLegacy;
protected GroupsHelper groupsHelper;

public Setup(MeApi meApi,
public Setup(ResourceLoader resourceLoader,
MeApi meApi,
LogosApiExt logosApi,
GroupsApi groupsApi,
TagsApi tagsApi,
Expand All @@ -47,7 +50,7 @@ public Setup(MeApi meApi,
HarvestersApi harvestersApi) {

this.meApi = meApi;
this.logosHelper = new LogosHelper(logosApi);
this.logosHelper = new LogosHelper(logosApi, resourceLoader);
this.groupsHelper = new GroupsHelper(groupsApi);
this.tagsHelper = new TagsHelper(tagsApi);
this.vocabulariesHelper = new VocabulariesHelper(registriesApi);
Expand All @@ -63,8 +66,8 @@ public void getMe() {

public ResponseEntity<Map<String, Object>> getSystemInfo() {
return ResponseEntity.ok(Map.of(
"systemInfo", siteHelper.getApi().getSystemInfoWithHttpInfo().getBody(),
"siteInfo", siteHelper.getApi().getInformationWithHttpInfo().getBody()
"systemInfo", Objects.requireNonNull(siteHelper.getApi().getSystemInfoWithHttpInfo().getBody()),
"siteInfo", Objects.requireNonNull(siteHelper.getApi().getInformationWithHttpInfo().getBody())
));
}

Expand All @@ -76,7 +79,6 @@ public void deleteAllHarvesters() {
/**
* The getAllHarvesters is used to get the json format of harvester setting of geonetwork4. It will add
* extra fields so works better across different instance of geonetwork4.
*
* However, before we store it into repo, we need to break it down so that each harvester json contains 1 harvester
* setting only.
*
Expand Down
5 changes: 5 additions & 0 deletions geonetwork/src/main/resources/log4j-imos-index.xml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@
<AppenderRef ref="File"/>
</Logger>

<Logger name="au.org.aodn.geonetwork_api" level="debug" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="File"/>
</Logger>

<!-- Turn off logging except when explicitly declared above -->
<Root level="off">
<AppenderRef ref="File"/>
Expand Down
5 changes: 5 additions & 0 deletions geonetwork/src/main/resources/log4j-imos.xml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@
<AppenderRef ref="File"/>
</Logger>

<Logger name="au.org.aodn.geonetwork_api" level="debug" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="File"/>
</Logger>

<!-- Turn off logging except when explicitly declared above -->
<Root level="off">
<AppenderRef ref="File"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import java.nio.charset.StandardCharsets;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
Expand Down Expand Up @@ -50,6 +49,7 @@ public void verifyGetAllHarvesters() throws IOException {
.thenReturn(ResponseEntity.ok(groups));

Setup setup = new Setup(
null,
null,
null,
groupsApi,
Expand Down

0 comments on commit 89067f4

Please sign in to comment.