From 32164ade3ec95b5eb78693bd12abf4cd53a59dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Mon, 27 Nov 2023 15:49:19 +0100 Subject: [PATCH] INSPIRE Validator - exception handling improvements and Sonalint fixes --- .../geonet/api/GlobalExceptionController.java | 2 + .../geonet/api/processing/ValidateApi.java | 6 +- .../api/records/InspireValidationApi.java | 40 ++-- .../validator}/InspireValidationRunnable.java | 26 ++- .../validator/InspireValidatorException.java | 80 +++++++ .../validator}/InspireValidatorUtils.java | 204 +++++++++--------- .../MInspireEtfValidateProcess.java | 66 +++--- .../resources/config-spring-geonetwork.xml | 2 +- .../editing/InspireValidatorUtilsTest.java | 1 + .../GnmdInspireValidationDirective.js | 4 +- 10 files changed, 260 insertions(+), 171 deletions(-) rename services/src/main/java/org/fao/geonet/{api/records => inspire/validator}/InspireValidationRunnable.java (75%) create mode 100644 services/src/main/java/org/fao/geonet/inspire/validator/InspireValidatorException.java rename services/src/main/java/org/fao/geonet/{api/records/editing => inspire/validator}/InspireValidatorUtils.java (78%) rename services/src/main/java/org/fao/geonet/{api/processing => inspire/validator}/MInspireEtfValidateProcess.java (87%) diff --git a/services/src/main/java/org/fao/geonet/api/GlobalExceptionController.java b/services/src/main/java/org/fao/geonet/api/GlobalExceptionController.java index fc2f4efc25c..e7a89ad1ec9 100644 --- a/services/src/main/java/org/fao/geonet/api/GlobalExceptionController.java +++ b/services/src/main/java/org/fao/geonet/api/GlobalExceptionController.java @@ -34,6 +34,7 @@ import org.fao.geonet.exceptions.ServiceNotAllowedEx; import org.fao.geonet.exceptions.UserNotFoundEx; import org.fao.geonet.exceptions.XSDValidationErrorEx; +import org.fao.geonet.inspire.validator.InspireValidatorException; import org.fao.geonet.utils.Log; import org.json.JSONException; import org.springframework.beans.factory.annotation.Autowired; @@ -164,6 +165,7 @@ public ApiError maxFileExceededHandler(final Exception exception) { @ExceptionHandler({ HttpMessageNotReadableException.class, Exception.class, + InspireValidatorException.class, RuntimeException.class }) public ApiError runtimeExceptionHandler(final Exception exception, final HttpServletRequest request) { diff --git a/services/src/main/java/org/fao/geonet/api/processing/ValidateApi.java b/services/src/main/java/org/fao/geonet/api/processing/ValidateApi.java index 4feae357817..56734ce5db1 100644 --- a/services/src/main/java/org/fao/geonet/api/processing/ValidateApi.java +++ b/services/src/main/java/org/fao/geonet/api/processing/ValidateApi.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * Copyright (C) 2001-2023 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -37,12 +37,13 @@ import org.fao.geonet.api.ApiUtils; import org.fao.geonet.api.processing.report.SimpleMetadataProcessingReport; import org.fao.geonet.api.processing.report.registry.IProcessingReportRegistry; -import org.fao.geonet.api.records.editing.InspireValidatorUtils; +import org.fao.geonet.inspire.validator.InspireValidatorUtils; import org.fao.geonet.domain.AbstractMetadata; import org.fao.geonet.domain.MetadataValidation; import org.fao.geonet.domain.Pair; import org.fao.geonet.domain.SchematronRequirement; import org.fao.geonet.events.history.RecordValidationTriggeredEvent; +import org.fao.geonet.inspire.validator.MInspireEtfValidateProcess; import org.fao.geonet.kernel.AccessManager; import org.fao.geonet.kernel.DataManager; import org.fao.geonet.kernel.SchemaManager; @@ -55,7 +56,6 @@ import org.fao.geonet.utils.Xml; import org.jdom.Element; import org.jdom.Namespace; -import org.jdom.Text; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpStatus; diff --git a/services/src/main/java/org/fao/geonet/api/records/InspireValidationApi.java b/services/src/main/java/org/fao/geonet/api/records/InspireValidationApi.java index cf54416b94a..9e3a015780a 100644 --- a/services/src/main/java/org/fao/geonet/api/records/InspireValidationApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/InspireValidationApi.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * Copyright (C) 2001-2023 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -33,11 +33,11 @@ import org.apache.http.HttpStatus; import org.fao.geonet.ApplicationContextHolder; import org.fao.geonet.NodeInfo; -import org.fao.geonet.api.API; import org.fao.geonet.api.ApiParams; import org.fao.geonet.api.ApiUtils; import org.fao.geonet.api.exception.ResourceNotFoundException; -import org.fao.geonet.api.records.editing.InspireValidatorUtils; +import org.fao.geonet.inspire.validator.InspireValidationRunnable; +import org.fao.geonet.inspire.validator.InspireValidatorUtils; import org.fao.geonet.api.records.formatters.FormatType; import org.fao.geonet.api.records.formatters.FormatterApi; import org.fao.geonet.api.records.formatters.FormatterWidth; @@ -52,7 +52,6 @@ import org.fao.geonet.kernel.SchemaManager; import org.fao.geonet.kernel.setting.SettingManager; import org.fao.geonet.kernel.setting.Settings; -import org.fao.geonet.repository.MetadataValidationRepository; import org.fao.geonet.repository.SourceRepository; import org.fao.geonet.schema.iso19139.ISO19139Namespaces; import org.fao.geonet.util.ThreadPool; @@ -126,8 +125,7 @@ public class InspireValidationApi { @io.swagger.v3.oas.annotations.Operation( summary = "Get test suites available.", description = "TG13, TG2, ...") - @RequestMapping(value = "/{metadataUuid}/validate/inspire/testsuites", - method = RequestMethod.GET, + @GetMapping(value = "/{metadataUuid}/validate/inspire/testsuites", produces = { MediaType.APPLICATION_JSON_VALUE }) @@ -154,8 +152,7 @@ Map getTestSuites( + "An INSPIRE endpoint must be configured in Settings. " + "This activates an asyncronous process, this method does not return any report. " + "This method returns an id to be used to get the report.") - @RequestMapping(value = "/{metadataUuid}/validate/inspire", - method = RequestMethod.PUT, + @PutMapping(value = "/{metadataUuid}/validate/inspire", produces = { MediaType.TEXT_PLAIN_VALUE }) @@ -205,16 +202,16 @@ String validateRecordForInspire( String schema = metadata.getDataInfo().getSchemaId(); if (!schema.matches(supportedSchemaRegex)) { response.setStatus(HttpStatus.SC_NOT_ACCEPTABLE); - return String.format("INSPIRE validator does not support records in schema '%'. Schema must match expression '%' and have an ISO19139 formatter.", + return String.format("INSPIRE validator does not support records in schema '%s'. Schema must match expression '%s' and have an ISO19139 formatter.", schema, supportedSchemaRegex); } String id = String.valueOf(metadata.getId()); - String URL = settingManager.getValue(Settings.SYSTEM_INSPIRE_REMOTE_VALIDATION_URL); - String URL_QUERY = settingManager.getValue(Settings.SYSTEM_INSPIRE_REMOTE_VALIDATION_URL_QUERY); - if (StringUtils.isEmpty(URL_QUERY)) { - URL_QUERY = URL; + String inspireValidatorUrl = settingManager.getValue(Settings.SYSTEM_INSPIRE_REMOTE_VALIDATION_URL); + String inspireValidatorQueryUrl = settingManager.getValue(Settings.SYSTEM_INSPIRE_REMOTE_VALIDATION_URL_QUERY); + if (StringUtils.isEmpty(inspireValidatorQueryUrl)) { + inspireValidatorQueryUrl = inspireValidatorUrl; } ServiceContext context = ApiUtils.createServiceContext(request); @@ -268,7 +265,7 @@ String validateRecordForInspire( InputStream metadataToTest = convertElement2InputStream(md); - testId = inspireValidatorUtils.submitFile(context, URL, URL_QUERY, metadataToTest, testsuite, metadata.getUuid()); + testId = inspireValidatorUtils.submitFile(context, inspireValidatorUrl, inspireValidatorQueryUrl, metadataToTest, testsuite, metadata.getUuid()); } else { String portal = NodeInfo.DEFAULT_NODE; if (!NodeInfo.DEFAULT_NODE.equals(mode)) { @@ -288,10 +285,10 @@ String validateRecordForInspire( portal, ISO19139Namespaces.GMD.getURI(), metadataUuid); - testId = inspireValidatorUtils.submitUrl(context, URL, URL_QUERY, getRecordByIdUrl, testsuite, metadata.getUuid()); + testId = inspireValidatorUtils.submitUrl(context, inspireValidatorUrl, inspireValidatorQueryUrl, getRecordByIdUrl, testsuite, metadata.getUuid()); } - threadPool.runTask(new InspireValidationRunnable(context, URL, testId, metadata.getId())); + threadPool.runTask(new InspireValidationRunnable(context, inspireValidatorUrl, testId, metadata.getId())); return testId; } @@ -313,8 +310,7 @@ private InputStream convertElement2InputStream(Element md) description = "User MUST be able to edit the record to validate it. " + "An INSPIRE endpoint must be configured in Settings. " + "If the process is complete an object with status is returned. ") - @RequestMapping(value = "/{testId}/validate/inspire", - method = RequestMethod.GET, + @GetMapping(value = "/{testId}/validate/inspire", produces = { MediaType.APPLICATION_JSON_VALUE } @@ -341,15 +337,15 @@ Map checkValidation( HttpSession session ) throws Exception { - String URL = settingManager.getValue(Settings.SYSTEM_INSPIRE_REMOTE_VALIDATION_URL); + String inspireValidatorUrl = settingManager.getValue(Settings.SYSTEM_INSPIRE_REMOTE_VALIDATION_URL); ServiceContext context = ApiUtils.createServiceContext(request); try { - if (inspireValidatorUtils.isReady(context, URL, testId)) { + if (inspireValidatorUtils.isReady(context, inspireValidatorUrl, testId)) { Map values = new HashMap<>(); - values.put("status", inspireValidatorUtils.isPassed(context, URL, testId)); - values.put("report", inspireValidatorUtils.getReportUrl(URL, testId)); + values.put("status", inspireValidatorUtils.isPassed(context, inspireValidatorUrl, testId)); + values.put("report", inspireValidatorUtils.getReportUrl(inspireValidatorUrl, testId)); response.setStatus(HttpStatus.SC_OK); return values; diff --git a/services/src/main/java/org/fao/geonet/api/records/InspireValidationRunnable.java b/services/src/main/java/org/fao/geonet/inspire/validator/InspireValidationRunnable.java similarity index 75% rename from services/src/main/java/org/fao/geonet/api/records/InspireValidationRunnable.java rename to services/src/main/java/org/fao/geonet/inspire/validator/InspireValidationRunnable.java index 7413f2f115c..ab8d64557b6 100644 --- a/services/src/main/java/org/fao/geonet/api/records/InspireValidationRunnable.java +++ b/services/src/main/java/org/fao/geonet/inspire/validator/InspireValidationRunnable.java @@ -1,10 +1,32 @@ -package org.fao.geonet.api.records; +/* + * Copyright (C) 2001-2023 Food and Agriculture Organization of the + * United Nations (FAO-UN), United Nations World Food Programme (WFP) + * and United Nations Environment Programme (UNEP) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, + * Rome - Italy. email: geonetwork@osgeo.org + */ +package org.fao.geonet.inspire.validator; import jeeves.server.context.ServiceContext; import jeeves.transaction.TransactionManager; import jeeves.transaction.TransactionTask; import org.fao.geonet.ApplicationContextHolder; -import org.fao.geonet.api.records.editing.InspireValidatorUtils; +import org.fao.geonet.inspire.validator.InspireValidatorUtils; import org.fao.geonet.domain.MetadataValidation; import org.fao.geonet.domain.MetadataValidationId; import org.fao.geonet.domain.MetadataValidationStatus; diff --git a/services/src/main/java/org/fao/geonet/inspire/validator/InspireValidatorException.java b/services/src/main/java/org/fao/geonet/inspire/validator/InspireValidatorException.java new file mode 100644 index 00000000000..7d42bd91f44 --- /dev/null +++ b/services/src/main/java/org/fao/geonet/inspire/validator/InspireValidatorException.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2001-2023 Food and Agriculture Organization of the + * United Nations (FAO-UN), United Nations World Food Programme (WFP) + * and United Nations Environment Programme (UNEP) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, + * Rome - Italy. email: geonetwork@osgeo.org + */ + +package org.fao.geonet.inspire.validator; + +import org.fao.geonet.exceptions.LocalizedException; + +import java.util.Locale; + +public class InspireValidatorException extends LocalizedException { + public InspireValidatorException() { + super(); + } + + public InspireValidatorException(String message) { + super(message); + } + + public InspireValidatorException(String message, Throwable cause) { + super(message, cause); + } + + public InspireValidatorException(Throwable cause) { + super(cause); + } + + protected String getResourceBundleBeanQualifier() { + return "apiMessages"; + } + + @Override + public InspireValidatorException withMessageKey(String messageKey) { + super.withMessageKey(messageKey); + return this; + } + + @Override + public InspireValidatorException withMessageKey(String messageKey, Object[] messageKeyArgs) { + super.withMessageKey(messageKey, messageKeyArgs); + return this; + } + + @Override + public InspireValidatorException withDescriptionKey(String descriptionKey) { + super.withDescriptionKey(descriptionKey); + return this; + } + + @Override + public InspireValidatorException withDescriptionKey(String descriptionKey, Object[] descriptionKeyArgs) { + super.withDescriptionKey(descriptionKey, descriptionKeyArgs); + return this; + } + + @Override + public InspireValidatorException withLocale(Locale locale) { + super.withLocale(locale); + return this; + } +} diff --git a/services/src/main/java/org/fao/geonet/api/records/editing/InspireValidatorUtils.java b/services/src/main/java/org/fao/geonet/inspire/validator/InspireValidatorUtils.java similarity index 78% rename from services/src/main/java/org/fao/geonet/api/records/editing/InspireValidatorUtils.java rename to services/src/main/java/org/fao/geonet/inspire/validator/InspireValidatorUtils.java index 8eab1aa74cb..c996c49f208 100644 --- a/services/src/main/java/org/fao/geonet/api/records/editing/InspireValidatorUtils.java +++ b/services/src/main/java/org/fao/geonet/inspire/validator/InspireValidatorUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * Copyright (C) 2001-2023 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -21,7 +21,7 @@ * Rome - Italy. email: geonetwork@osgeo.org */ -package org.fao.geonet.api.records.editing; +package org.fao.geonet.inspire.validator; import com.google.common.base.Function; import com.google.common.io.CharStreams; @@ -29,6 +29,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; import org.apache.http.client.methods.*; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; @@ -59,6 +60,7 @@ import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -84,62 +86,62 @@ public class InspireValidatorUtils { /** * The Constant USER_AGENT. */ - private final static String USER_AGENT = "Mozilla/5.0"; + private static final String USER_AGENT = "Mozilla/5.0"; /** * The Constant ACCEPT. */ - private final static String ACCEPT = "application/json"; + private static final String ACCEPT = "application/json"; /** * The Constant CheckStatus_URL. */ - private final static String CheckStatus_URL = "/v2/status"; + private static final String CHECKSTATUS_URL = "/v2/status"; /** * The Constant ExecutableTestSuites_URL. */ - private final static String ExecutableTestSuites_URL = "/v2/ExecutableTestSuites"; + private static final String EXECUTABLETESTSUITES_URL = "/v2/ExecutableTestSuites"; /** * The Constant TestObjects_URL. */ - private final static String TestObjects_URL = "/v2/TestObjects"; + private static final String TESTOBJECTS_URL = "/v2/TestObjects"; /** * The Constant TestRuns_URL. */ - private final static String TestRuns_URL = "/v2/TestRuns"; + private static final String TESTRUNS_URL = "/v2/TestRuns"; /** * Test status PASSED. */ - public final static String TEST_STATUS_PASSED = "PASSED"; + public static final String TEST_STATUS_PASSED = "PASSED"; /** * Test status FAILED. */ - public final static String TEST_STATUS_FAILED = "FAILED"; + public static final String TEST_STATUS_FAILED = "FAILED"; /** * Test status PASSED_MANUAL. */ - public final static String TEST_STATUS_PASSED_MANUAL = "PASSED_MANUAL"; + public static final String TEST_STATUS_PASSED_MANUAL = "PASSED_MANUAL"; /** * Test status UNDEFINED. */ - public final static String TEST_STATUS_UNDEFINED = "UNDEFINED"; + public static final String TEST_STATUS_UNDEFINED = "UNDEFINED"; /** * Test status NOT_APPLICABLE. */ - public final static String TEST_STATUS_NOT_APPLICABLE = "NOT_APPLICABLE"; + public static final String TEST_STATUS_NOT_APPLICABLE = "NOT_APPLICABLE"; /** * Test status INTERNAL_ERROR. */ - public final static String TEST_STATUS_INTERNAL_ERROR = "INTERNAL_ERROR"; + public static final String TEST_STATUS_INTERNAL_ERROR = "INTERNAL_ERROR"; @Value("#{validatorAdditionalConfig['defaultTestSuite']}") public String defaultTestSuite; @@ -170,7 +172,7 @@ public void setTestsuites(Map testsuites) { this.testsuites = testsuites; } - public Map getTestsuites() { + public Map getTestsuites() { return testsuites; } @@ -178,7 +180,7 @@ public void setTestsuitesConditions(Map testsuitesConditions) { this.testsuitesConditions = testsuitesConditions; } - public Map getTestsuitesConditions() { + public Map getTestsuitesConditions() { return testsuitesConditions; } @@ -208,18 +210,18 @@ public InspireValidatorUtils() { * @return true, if successful * @throws IOException */ - public boolean checkServiceStatus(ServiceContext context, String endPoint) throws IOException { - HttpGet request = new HttpGet(StringUtils.removeEnd(endPoint, "/") + CheckStatus_URL); + public boolean checkServiceStatus(ServiceContext context, String endPoint) { + HttpGet request = new HttpGet(StringUtils.removeEnd(endPoint, "/") + CHECKSTATUS_URL); // add request header request.addHeader("User-Agent", USER_AGENT); request.addHeader("Accept", ACCEPT); try (ClientHttpResponse response = this.execute(context, request)) { - if (response.getStatusCode().value() == 200) { + if (response.getStatusCode().value() == HttpStatus.SC_OK) { return true; } else { - Log.warning(Log.SERVICE, "INSPIRE service not available: " + endPoint + CheckStatus_URL); + Log.warning(Log.SERVICE, "INSPIRE service not available: " + endPoint + CHECKSTATUS_URL); return false; } } catch (Exception e) { @@ -235,9 +237,9 @@ public boolean checkServiceStatus(ServiceContext context, String endPoint) throw * @param xml the xml * @return the string */ - private String uploadMetadataFile(ServiceContext context, String endPoint, InputStream xml) { + private String uploadMetadataFile(ServiceContext context, String endPoint, InputStream xml) throws InspireValidatorException { - HttpPost request = new HttpPost(StringUtils.removeEnd(endPoint, "/") + TestObjects_URL + "?action=upload"); + HttpPost request = new HttpPost(StringUtils.removeEnd(endPoint, "/") + TESTOBJECTS_URL + "?action=upload"); request.addHeader("User-Agent", USER_AGENT); request.addHeader("Accept", ACCEPT); @@ -254,20 +256,22 @@ private String uploadMetadataFile(ServiceContext context, String endPoint, Input response = this.execute(context, request); - if (response.getStatusCode().value() == 200) { + if (response.getStatusCode().value() == HttpStatus.SC_OK) { new BasicResponseHandler(); String body = CharStreams.toString(new InputStreamReader(response.getBody())); JSONObject jsonRoot = new JSONObject(body); return jsonRoot.getJSONObject("testObject").getString("id"); } else { - Log.warning(Log.SERVICE, - "WARNING: INSPIRE service HTTP response: " + response.getStatusCode().value() + " for " + TestObjects_URL); - return null; + Log.error(Log.SERVICE, + "INSPIRE service HTTP response: " + response.getStatusCode().value() + " for " + TESTOBJECTS_URL); + throw new InspireValidatorException(String.format("INSPIRE service - error uploading file: %s, error code: %d", response.getStatusText(), response.getStatusCode().value())); } + } catch (InspireValidatorException e) { + throw e; } catch (Exception e) { Log.error(Log.SERVICE, "Error calling INSPIRE service: " + endPoint, e); - return null; + throw new InspireValidatorException(String.format("Error calling INSPIRE service: %s, %s", endPoint, e.getMessage())); } finally { IOUtils.closeQuietly(response); } @@ -285,18 +289,15 @@ private List getTests(ServiceContext context, String endPoint, String te testsuite = getDefaultTestSuite(); } - HttpGet request = new HttpGet(StringUtils.removeEnd(endPoint, "/") + ExecutableTestSuites_URL); + HttpGet request = new HttpGet(StringUtils.removeEnd(endPoint, "/") + EXECUTABLETESTSUITES_URL); request.addHeader("User-Agent", USER_AGENT); request.addHeader("Accept", ACCEPT); - ClientHttpResponse response = null; - try { + try(ClientHttpResponse response = this.execute(context, request)) { String[] tests = testsuites.get(testsuite); - response = this.execute(context, request); - - if (response.getStatusCode().value() == 200) { + if (response.getStatusCode().value() == HttpStatus.SC_OK) { List testList = new ArrayList<>(); @@ -326,14 +327,12 @@ private List getTests(ServiceContext context, String endPoint, String te return testList; } else { Log.warning(Log.SERVICE, - "WARNING: INSPIRE service HTTP response: " + response.getStatusCode().value() + " for " + ExecutableTestSuites_URL); - return null; + "WARNING: INSPIRE service HTTP response: " + response.getStatusCode().value() + " for " + EXECUTABLETESTSUITES_URL); + return Collections.emptyList(); } } catch (Exception e) { Log.error(Log.SERVICE, "Exception in INSPIRE service: " + endPoint, e); - return null; - } finally { - IOUtils.closeQuietly(response); + return Collections.emptyList(); } } @@ -348,9 +347,9 @@ private List getTests(ServiceContext context, String endPoint, String te * @throws IOException Signals that an I/O exception has occurred. * @throws JSONException the JSON exception */ - private String testRun(ServiceContext context, String endPoint, String fileId, List testList, String testTitle) throws JSONException, IOException { + private String testRun(ServiceContext context, String endPoint, String fileId, List testList, String testTitle) throws InspireValidatorException { - HttpPost request = new HttpPost(StringUtils.removeEnd(endPoint, "/") + TestRuns_URL); + HttpPost request = new HttpPost(StringUtils.removeEnd(endPoint, "/") + TESTRUNS_URL); request.setHeader("Content-type", ACCEPT); request.addHeader("User-Agent", USER_AGENT); request.addHeader("Accept", ACCEPT); @@ -387,9 +386,10 @@ private String testRun(ServiceContext context, String endPoint, String fileId, L StringEntity entity = new StringEntity(json.toString()); request.setEntity(entity); + response = this.execute(context, request); - if (response.getStatusCode().value() == 201) { + if (response.getStatusCode().value() == HttpStatus.SC_CREATED) { String body = CharStreams.toString(new InputStreamReader(response.getBody())); @@ -400,8 +400,8 @@ private String testRun(ServiceContext context, String endPoint, String fileId, L return testId; } else { Log.warning(Log.SERVICE, - "WARNING: INSPIRE service HTTP response: " + response.getStatusCode().value() + " for " + TestRuns_URL); - throw new IOException(String.format("Error while creating test on validator side. Status is: %d (%s). Error: %s", + "WARNING: INSPIRE service HTTP response: " + response.getStatusCode().value() + " for " + TESTRUNS_URL); + throw new InspireValidatorException(String.format("Error while creating test on validator side. Status is: %d (%s). Error: %s", response.getStatusCode().value(), response.getStatusText(), response.getBody() != null @@ -409,9 +409,11 @@ private String testRun(ServiceContext context, String endPoint, String fileId, L )); } + } catch (InspireValidatorException e) { + throw e; } catch (Exception e) { Log.error(Log.SERVICE, "Exception in INSPIRE service: " + endPoint, e); - throw e; + throw new InspireValidatorException(String.format("Error calling INSPIRE service: %s, %s", endPoint, e.getMessage())); } finally { IOUtils.closeQuietly(response); } @@ -436,19 +438,19 @@ private void addApiKey(HttpRequestBase request) { * @return true, if is ready * @throws Exception */ - public boolean isReady(ServiceContext context, String endPoint, String testId) throws Exception { + public boolean isReady(ServiceContext context, String endPoint, String testId) throws ResourceNotFoundException, InspireValidatorException { if (testId == null) { return false; } - HttpGet request = new HttpGet(StringUtils.removeEnd(endPoint, "/") + TestRuns_URL + "/" + testId + "/progress"); + HttpGet request = new HttpGet(StringUtils.removeEnd(endPoint, "/") + TESTRUNS_URL + "/" + testId + "/progress"); request.addHeader("User-Agent", USER_AGENT); request.addHeader("Accept", ACCEPT); addApiKey(request); try (ClientHttpResponse response = this.execute(context, request)) { - if (response.getStatusCode().value() == 200) { + if (response.getStatusCode().value() == HttpStatus.SC_OK) { String body = CharStreams.toString(new InputStreamReader(response.getBody())); JSONObject jsonRoot = new JSONObject(body); @@ -456,22 +458,19 @@ public boolean isReady(ServiceContext context, String endPoint, String testId) t // Completed when estimated number of Test Steps is equal to completed Test Steps // Somehow this condition is necessary but not sufficient // so another check on real value of test is evaluated - return jsonRoot.getInt("val") == jsonRoot.getInt("max") & isPassed(context, endPoint, testId) != null; - - } else if (response.getStatusCode().value() == 404) { - + return jsonRoot.getInt("val") == jsonRoot.getInt("max") && isPassed(context, endPoint, testId) != null; + } else if (response.getStatusCode().value() == HttpStatus.SC_NOT_FOUND) { throw new ResourceNotFoundException("Test not found"); - } else { Log.warning(Log.SERVICE, - "WARNING: INSPIRE service HTTP response: " + response.getStatusCode().value() + " for " + TestRuns_URL + "WARNING: INSPIRE service HTTP response: " + response.getStatusCode().value() + " for " + TESTRUNS_URL + "?view=progress"); } } catch (ResourceNotFoundException e) { throw e; } catch (Exception e) { Log.error(Log.SERVICE, "Exception in INSPIRE service: " + endPoint, e); - throw e; + throw new InspireValidatorException(String.format("Exception in INSPIRE service: %s, %s", endPoint, e)); } return false; @@ -485,22 +484,20 @@ public boolean isReady(ServiceContext context, String endPoint, String testId) t * @return the string * @throws Exception */ - public String isPassed(ServiceContext context, String endPoint, String testId) throws Exception { + public String isPassed(ServiceContext context, String endPoint, String testId) throws InspireValidatorException { if (testId == null) { - throw new Exception(""); + throw new InspireValidatorException(String.format("Exception in INSPIRE service: %s, test not provided", endPoint)); } - HttpGet request = new HttpGet(StringUtils.removeEnd(endPoint, "/") + TestRuns_URL + "/" + testId); + HttpGet request = new HttpGet(StringUtils.removeEnd(endPoint, "/") + TESTRUNS_URL + "/" + testId); request.addHeader("User-Agent", USER_AGENT); request.addHeader("Accept", ACCEPT); addApiKey(request); try (ClientHttpResponse response = this.execute(context, request)) { - - if (response.getStatusCode().value() == 200) { - + if (response.getStatusCode().value() == HttpStatus.SC_OK) { String body = CharStreams.toString(new InputStreamReader(response.getBody())); JSONObject jsonRoot = new JSONObject(body); @@ -511,19 +508,16 @@ public String isPassed(ServiceContext context, String endPoint, String testId) t } catch (JSONException e) { return null; } - - } else if (response.getStatusCode().value() == 404) { - + } else if (response.getStatusCode().value() == HttpStatus.SC_NOT_FOUND) { throw new ResourceNotFoundException("Test not found"); - } else { Log.warning(Log.SERVICE, - "WARNING: INSPIRE service HTTP response: " + response.getStatusCode().value() + " for " + TestRuns_URL + "WARNING: INSPIRE service HTTP response: " + response.getStatusCode().value() + " for " + TESTRUNS_URL + "?view=progress"); } } catch (Exception e) { Log.error(Log.SERVICE, "Exception in INSPIRE service: " + endPoint, e); - throw e; + throw new InspireValidatorException(String.format("Exception in INSPIRE service: %s, %s", endPoint, e)); } return null; @@ -538,7 +532,7 @@ public String isPassed(ServiceContext context, String endPoint, String testId) t */ public String getReportUrl(String endPoint, String testId) { - return endPoint + TestRuns_URL + "/" + testId + ".html"; + return endPoint + TESTRUNS_URL + "/" + testId + ".html"; } /** @@ -550,7 +544,7 @@ public String getReportUrl(String endPoint, String testId) { */ public static String getReportUrlJSON(String endPoint, String testId) { - return endPoint + TestRuns_URL + "/" + testId + ".json"; + return endPoint + TESTRUNS_URL + "/" + testId + ".json"; } /** @@ -562,35 +556,35 @@ public static String getReportUrlJSON(String endPoint, String testId) { */ public static String getReportUrlXML(String endPoint, String testId) { - return endPoint + TestRuns_URL + "/" + testId + ".xml"; + return endPoint + TESTRUNS_URL + "/" + testId + ".xml"; } /** * Submit file to the external ETF validator. * - * @param record the record + * @param metadataRecord the metadata record * @param testsuite * @return the string * @throws IOException Signals that an I/O exception has occurred. * @throws JSONException the JSON exception */ - public String submitFile(ServiceContext context, String serviceEndpoint, String serviceQueryEndpoint, InputStream record, String testsuite, String testTitle) - throws IOException, JSONException { + public String submitFile(ServiceContext context, String serviceEndpoint, String serviceQueryEndpoint, InputStream metadataRecord, String testsuite, String testTitle) + throws InspireValidatorException { if (checkServiceStatus(context, serviceQueryEndpoint)) { // Get the tests to execute List tests = getTests(context, serviceQueryEndpoint, testsuite); // Upload file to test - String testFileId = uploadMetadataFile(context, serviceQueryEndpoint, record); + String testFileId = uploadMetadataFile(context, serviceQueryEndpoint, metadataRecord); if (testFileId == null) { Log.error(Log.SERVICE, "File not valid.", new IllegalArgumentException()); return null; } - if (tests == null || tests.size() == 0) { + if (tests.isEmpty()) { Log.error(Log.SERVICE, - "Default test sequence not supported. Check org.fao.geonet.api.records.editing.InspireValidatorUtils.TESTS_TO_RUN_TG13.", + "Default test sequence not supported. Check org.fao.geonet.inspire.validator.InspireValidatorUtils.TESTS_TO_RUN_TG13.", new Exception()); return null; } @@ -598,9 +592,8 @@ public String submitFile(ServiceContext context, String serviceEndpoint, String return testRun(context, serviceEndpoint, testFileId, tests, testTitle); } else { - ServiceNotFoundEx ex = new ServiceNotFoundEx(serviceEndpoint); - Log.error(Log.SERVICE, "Service unavailable.", ex); - throw ex; + Log.error(Log.SERVICE, String.format("INSPIRE service end-point unavailable: %s", serviceEndpoint), new InspireValidatorException()); + throw new InspireValidatorException(String.format("INSPIRE service end-point unavailable: %s", serviceEndpoint)); } } @@ -613,32 +606,28 @@ public String submitFile(ServiceContext context, String serviceEndpoint, String * @throws JSONException the JSON exception */ public String submitUrl(ServiceContext context, String serviceEndpoint, String serviceEndpointQuery, String getRecordById, String testsuite, String testTitle) - throws IOException, JSONException { + throws InspireValidatorException { - try { - if (checkServiceStatus(context, serviceEndpointQuery)) { - // Get the tests to execute - List tests = getTests(context, serviceEndpoint, testsuite); - if (tests == null || tests.size() == 0) { - Log.error(Log.SERVICE, - "Default test sequence not supported. Check org.fao.geonet.api.records.editing.InspireValidatorUtils.TESTS_TO_RUN_TG13.", - new Exception()); - return null; - } - // Return test id from Inspire service - return testRun(context, serviceEndpoint, getRecordById, tests, testTitle); - - } else { - ServiceNotFoundEx ex = new ServiceNotFoundEx(serviceEndpoint); - Log.error(Log.SERVICE, "Service unavailable.", ex); - throw ex; + if (checkServiceStatus(context, serviceEndpointQuery)) { + // Get the tests to execute + List tests = getTests(context, serviceEndpoint, testsuite); + if (tests.isEmpty()) { + Log.error(Log.SERVICE, + "Default test sequence not supported. Check org.fao.geonet.inspire.validator.InspireValidatorUtils.TESTS_TO_RUN_TG13.", + new Exception()); + return null; } - } finally { - // client.close(); + // Return test id from Inspire service + return testRun(context, serviceEndpoint, getRecordById, tests, testTitle); + + } else { + ServiceNotFoundEx ex = new ServiceNotFoundEx(serviceEndpoint); + Log.error(Log.SERVICE, "Service unavailable.", ex); + throw ex; } } - public String retrieveReport(ServiceContext context, String endPoint) throws Exception { + public String retrieveReport(ServiceContext context, String endPoint) throws InspireValidatorException { HttpGet request = new HttpGet(endPoint); @@ -650,11 +639,12 @@ public String retrieveReport(ServiceContext context, String endPoint) throws Exc return IOUtils.toString(response.getBody(), StandardCharsets.UTF_8.name()); } catch (Exception e) { Log.warning(Log.SERVICE, "Error calling INSPIRE service to retrieve the result report: " + endPoint, e); - throw e; + throw new InspireValidatorException(String.format("Error calling INSPIRE service to retrieve the result report: %s, %s", endPoint, e.getMessage())); } } - public void waitUntilReady(ServiceContext context, String endPoint, String testId) throws Exception { + public void waitUntilReady(ServiceContext context, String endPoint, String testId) throws + ResourceNotFoundException, InterruptedException, InspireValidatorException { int checkCounter = 1; while (checkCounter++ <= maxNumberOfEtfChecks) { @@ -665,7 +655,7 @@ public void waitUntilReady(ServiceContext context, String endPoint, String testI Thread.sleep(intervalBetweenEtfChecks); } - throw new Exception("ETF validation task hasn't finish after " + maxNumberOfEtfChecks + " checks."); + throw new InspireValidatorException(String.format("ETF validation task hasn't finish after %d checks.", maxNumberOfEtfChecks)); } /** @@ -710,12 +700,12 @@ public MetadataValidationStatus calculateValidationStatus(String validationStatu * @return */ public Map calculateTestsuitesToApply(String schemaid, IMetadataSchemaUtils metadataSchemaUtils) { - Map testsuitesConditions = getTestsuitesConditions(); + Map allTestsuitesConditions = getTestsuitesConditions(); // Check for rules for the schema - Map testsuitesConditionsForSchema = testsuitesConditions.entrySet().stream() + Map testsuitesConditionsForSchema = allTestsuitesConditions.entrySet().stream() .filter(x -> x.getKey().split("::")[0].equalsIgnoreCase(schemaid)) - .collect(Collectors.toMap(map -> map.getKey().split("::")[1], map -> map.getValue())); + .collect(Collectors.toMap(map -> map.getKey().split("::")[1], Map.Entry::getValue)); // If no rules found, check the rules in the dependencies of the schema if (testsuitesConditionsForSchema.isEmpty()) { @@ -732,9 +722,9 @@ public Map calculateTestsuitesToApply(String schemaid, IMetadata schemasProcessed.add(schemaDependsOn); String schemaDependsOnFilter = schemaDependsOn; - testsuitesConditionsForSchema = testsuitesConditions.entrySet().stream() + testsuitesConditionsForSchema = allTestsuitesConditions.entrySet().stream() .filter(x -> x.getKey().split("::")[0].equalsIgnoreCase(schemaDependsOnFilter)) - .collect(Collectors.toMap(map -> map.getKey().split("::")[1], map -> map.getValue())); + .collect(Collectors.toMap(map -> map.getKey().split("::")[1], Map.Entry::getValue)); conditionsFound = !testsuitesConditionsForSchema.isEmpty(); diff --git a/services/src/main/java/org/fao/geonet/api/processing/MInspireEtfValidateProcess.java b/services/src/main/java/org/fao/geonet/inspire/validator/MInspireEtfValidateProcess.java similarity index 87% rename from services/src/main/java/org/fao/geonet/api/processing/MInspireEtfValidateProcess.java rename to services/src/main/java/org/fao/geonet/inspire/validator/MInspireEtfValidateProcess.java index 9f640f7e80a..07c1faf1c71 100644 --- a/services/src/main/java/org/fao/geonet/api/processing/MInspireEtfValidateProcess.java +++ b/services/src/main/java/org/fao/geonet/inspire/validator/MInspireEtfValidateProcess.java @@ -1,13 +1,11 @@ -package org.fao.geonet.api.processing; +package org.fao.geonet.inspire.validator; import jeeves.server.context.ServiceContext; import jeeves.transaction.TransactionManager; import jeeves.transaction.TransactionTask; import org.apache.commons.lang.StringUtils; -import org.apache.http.HttpStatus; import org.fao.geonet.NodeInfo; import org.fao.geonet.api.API; -import org.fao.geonet.api.records.editing.InspireValidatorUtils; import org.fao.geonet.api.records.formatters.FormatType; import org.fao.geonet.api.records.formatters.FormatterApi; import org.fao.geonet.api.records.formatters.FormatterWidth; @@ -48,8 +46,8 @@ public class MInspireEtfValidateProcess implements SelfNaming { private final ApplicationContext appContext; private final ServiceContext serviceContext; - private final String URL; - private final String URL_QUERY; + private final String url; + private final String urlQuery; private ObjectName probeName; private int metadataToAnalyseCount = -1; @@ -62,11 +60,11 @@ public class MInspireEtfValidateProcess implements SelfNaming { public MInspireEtfValidateProcess(String catalogueId, - String URL, String URL_QUERY, + String url, String urlQuery, ServiceContext serviceContext, ApplicationContext appContext) { - this.URL = URL; - this.URL_QUERY = URL_QUERY; + this.url = url; + this.urlQuery = urlQuery; this.serviceContext = serviceContext; this.appContext = appContext; @@ -151,9 +149,9 @@ public void processMetadata(Set uuids, String mode) throws Exception { continue; } - for (AbstractMetadata record : metadataRepository.findAllByUuid(uuid)) { + for (AbstractMetadata metadataRecord : metadataRepository.findAllByUuid(uuid)) { try { - if (!accessManager.canEdit(serviceContext, String.valueOf(record.getId()))) { + if (!accessManager.canEdit(serviceContext, String.valueOf(metadataRecord.getId()))) { metadataAnalysed++; metadataNotAllowed++; } else { @@ -162,11 +160,11 @@ public void processMetadata(Set uuids, String mode) throws Exception { public Object doInTransaction(TransactionStatus transaction) throws Throwable { // Evaluate test conditions for INSPIRE test suites to apply to the metadata Map testsuiteConditions = - inspireValidatorUtils.calculateTestsuitesToApply(record.getDataInfo().getSchemaId(), metadataSchemaUtils); + inspireValidatorUtils.calculateTestsuitesToApply(metadataRecord.getDataInfo().getSchemaId(), metadataSchemaUtils); boolean reindexMetadata = false; - String mdToValidate = retrieveMetadataToValidate(context, record); + String mdToValidate = retrieveMetadataToValidate(context, metadataRecord); try { boolean inspireMetadata = false; @@ -176,12 +174,12 @@ public Object doInTransaction(TransactionStatus transaction) throws Throwable { boolean applyCondition = false; try { // Checks the condition in the original record - applyCondition = Xml.selectBoolean(record.getXmlData(false), + applyCondition = Xml.selectBoolean(metadataRecord.getXmlData(false), entry.getValue(), - schemaManager.getSchema(record.getDataInfo().getSchemaId()).getNamespaces()); + schemaManager.getSchema(metadataRecord.getDataInfo().getSchemaId()).getNamespaces()); } catch (Exception ex) { Log.error(API.LOG_MODULE_NAME, String.format("Error checking INSPIRE rule %s to apply to metadata: %s", - entry.getKey(), record.getUuid()), ex); + entry.getKey(), metadataRecord.getUuid()), ex); } if (applyCondition) { @@ -189,8 +187,8 @@ public Object doInTransaction(TransactionStatus transaction) throws Throwable { String testId = null; String getRecordByIdUrl = null; if (StringUtils.isEmpty(mode)) { - testId = inspireValidatorUtils.submitFile(serviceContext, URL, URL_QUERY, - new ByteArrayInputStream(mdToValidate.getBytes()), entry.getKey(), record.getUuid()); + testId = inspireValidatorUtils.submitFile(serviceContext, url, urlQuery, + new ByteArrayInputStream(mdToValidate.getBytes()), entry.getKey(), metadataRecord.getUuid()); } else { String portal = null; if (!NodeInfo.DEFAULT_NODE.equals(mode)) { @@ -213,25 +211,25 @@ public Object doInTransaction(TransactionStatus transaction) throws Throwable { appContext.getBean(SettingManager.class).getBaseURL(), portal, ISO19139Namespaces.GMD.getURI(), - record.getUuid()); - testId = inspireValidatorUtils.submitUrl(serviceContext, URL, URL_QUERY, getRecordByIdUrl, entry.getKey(), record.getUuid()); + metadataRecord.getUuid()); + testId = inspireValidatorUtils.submitUrl(serviceContext, url, urlQuery, getRecordByIdUrl, entry.getKey(), metadataRecord.getUuid()); } } if (testId != null) { - inspireValidatorUtils.waitUntilReady(serviceContext, URL, testId); + inspireValidatorUtils.waitUntilReady(serviceContext, url, testId); - String reportUrl = inspireValidatorUtils.getReportUrl(URL, testId); - String reportXmlUrl = InspireValidatorUtils.getReportUrlXML(URL, testId); + String reportUrl = inspireValidatorUtils.getReportUrl(url, testId); + String reportXmlUrl = InspireValidatorUtils.getReportUrlXML(url, testId); String reportXml = inspireValidatorUtils.retrieveReport(serviceContext, reportXmlUrl); - String validationStatus = inspireValidatorUtils.isPassed(serviceContext, URL, testId); + String validationStatus = inspireValidatorUtils.isPassed(serviceContext, url, testId); MetadataValidationStatus metadataValidationStatus = inspireValidatorUtils.calculateValidationStatus(validationStatus); MetadataValidation metadataValidation = new MetadataValidation() - .setId(new MetadataValidationId(record.getId(), "inspire")) + .setId(new MetadataValidationId(metadataRecord.getId(), "inspire")) .setStatus(metadataValidationStatus).setRequired(false) .setReportUrl(reportUrl).setReportContent(reportXml); @@ -252,7 +250,7 @@ public Object doInTransaction(TransactionStatus transaction) throws Throwable { metadataNotInspire++; MetadataValidation metadataValidation = new MetadataValidation() - .setId(new MetadataValidationId(record.getId(), "inspire")) + .setId(new MetadataValidationId(metadataRecord.getId(), "inspire")) .setStatus(MetadataValidationStatus.DOES_NOT_APPLY).setRequired(false); metadataValidationRepository.save(metadataValidation); @@ -265,14 +263,14 @@ public Object doInTransaction(TransactionStatus transaction) throws Throwable { } if (reindexMetadata) { - dataManager.indexMetadata(new ArrayList<>(Arrays.asList(record.getId() + ""))); + dataManager.indexMetadata(new ArrayList<>(Arrays.asList(metadataRecord.getId() + ""))); } } catch (Exception ex) { metadataAnalysedInError++; Log.error(API.LOG_MODULE_NAME, String.format("Error validating metadata %s in INSPIRE validator: %s", - record.getUuid(), ex.getMessage()), ex); + metadataRecord.getUuid(), ex.getMessage()), ex); } metadataAnalysed++; @@ -286,7 +284,7 @@ public Object doInTransaction(TransactionStatus transaction) throws Throwable { metadataAnalysedInError++; Log.error(API.LOG_MODULE_NAME, String.format("Error validating metadata %s in INSPIRE validator: %s", - record.getUuid(), ex.getMessage()), ex); + metadataRecord.getUuid(), ex.getMessage()), ex); } @@ -306,15 +304,15 @@ private final void runInNewTransaction(String name, TransactionTask tran * otherwise if not available an iso19139 formatter returns null. * * @param context - * @param record + * @param metadataRecord * @return Metadata to validate or null if can't be converted to iso19139 format. */ - private String retrieveMetadataToValidate(ServiceContext context, AbstractMetadata record) { + private String retrieveMetadataToValidate(ServiceContext context, AbstractMetadata metadataRecord) { String mdToValidate = null; - if (!record.getDataInfo().getSchemaId().equals(ISO19139SchemaPlugin.IDENTIFIER)) { + if (!metadataRecord.getDataInfo().getSchemaId().equals(ISO19139SchemaPlugin.IDENTIFIER)) { try { - Key key = new Key(record.getId(), "eng", FormatType.xml, "iso19139", true, FormatterWidth._100); + Key key = new Key(metadataRecord.getId(), "eng", FormatType.xml, "iso19139", true, FormatterWidth._100); final FormatterApi.FormatMetadata formatMetadata = new FormatterApi().new FormatMetadata(context, key, null); @@ -323,10 +321,10 @@ private String retrieveMetadataToValidate(ServiceContext context, AbstractMetada } catch (Exception ex) { Log.error(API.LOG_MODULE_NAME, String.format("Error converting metadata %s to ISO19139 for INSPIRE validator: %s", - record.getUuid(), ex.getMessage()), ex); + metadataRecord.getUuid(), ex.getMessage()), ex); } } else { - mdToValidate = record.getData(); + mdToValidate = metadataRecord.getData(); } return mdToValidate; diff --git a/services/src/main/resources/config-spring-geonetwork.xml b/services/src/main/resources/config-spring-geonetwork.xml index e5baa797a34..33f965c8d9f 100644 --- a/services/src/main/resources/config-spring-geonetwork.xml +++ b/services/src/main/resources/config-spring-geonetwork.xml @@ -64,7 +64,7 @@ diff --git a/services/src/test/java/org/fao/geonet/api/records/editing/InspireValidatorUtilsTest.java b/services/src/test/java/org/fao/geonet/api/records/editing/InspireValidatorUtilsTest.java index 77805a1a416..07d95187e81 100644 --- a/services/src/test/java/org/fao/geonet/api/records/editing/InspireValidatorUtilsTest.java +++ b/services/src/test/java/org/fao/geonet/api/records/editing/InspireValidatorUtilsTest.java @@ -3,6 +3,7 @@ import jeeves.server.context.ServiceContext; import org.fao.geonet.api.exception.ResourceNotFoundException; import org.fao.geonet.domain.MetadataValidationStatus; +import org.fao.geonet.inspire.validator.InspireValidatorUtils; import org.fao.geonet.services.AbstractServiceIntegrationTest; import org.junit.Before; import org.junit.Ignore; diff --git a/web-ui/src/main/resources/catalog/components/validationtools/GnmdInspireValidationDirective.js b/web-ui/src/main/resources/catalog/components/validationtools/GnmdInspireValidationDirective.js index 7f40ff3a3aa..95dd2c871bd 100644 --- a/web-ui/src/main/resources/catalog/components/validationtools/GnmdInspireValidationDirective.js +++ b/web-ui/src/main/resources/catalog/components/validationtools/GnmdInspireValidationDirective.js @@ -108,7 +108,7 @@ }).then( function mySucces(response) { if (angular.isDefined(response.data) && response.data != null) { - scope.checkInBackgroud(response.data); + scope.checkInBackground(response.data); } else { scope.isDownloadingRecord = false; scope.isDownloadedRecord = false; @@ -165,7 +165,7 @@ scope.md = new Metadata(data.metadata[0]); }); } - scope.checkInBackgroud = function (token) { + scope.checkInBackground = function (token) { scope.stop = undefined; if (token === "") { gnAlertService.addAlert({