Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OGC API Records #23

Merged
merged 93 commits into from
Dec 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
2eb32fd
Rendering HTML.
fxprunayre Nov 20, 2020
ac82e27
Checkstyle.
fxprunayre Nov 23, 2020
5c81376
jwt, very base unit test at resource server side
cmangeat Nov 23, 2020
25ca168
Add configuration for standalone profile and services to retrieve inf…
josegar74 Nov 23, 2020
76dd70c
reident and make unit tests work disabling eureka
cmangeat Nov 23, 2020
16bbdc6
Add errors handling. Add localized message. Add XSLTViewResolver.
fxprunayre Nov 23, 2020
6d6d663
Checkstyle.
fxprunayre Nov 23, 2020
4e276ad
Persistence / Move configuration to dedicated module.
fxprunayre Nov 24, 2020
0ce166b
Persistence / Move configuration to dedicated module / Missing file.
fxprunayre Nov 24, 2020
acb4092
Persistence / Move configuration to dedicated module / Duplicates and…
fxprunayre Nov 24, 2020
e71c2ad
Lib / Avoid to load saxon 9 globally. Organize view in order to load …
fxprunayre Nov 24, 2020
50e213b
Force usage of Saxon (remove xerces). OGC API / tentative to output X…
fxprunayre Nov 24, 2020
b04cf02
Add method in ElasticSearchProxy to return the results instead of str…
josegar74 Nov 24, 2020
b0a2efa
OGC API Records service - /collections/{collectionId}/items and /coll…
josegar74 Nov 24, 2020
3784fed
Checkstyle.
josegar74 Nov 24, 2020
8063633
OGC API Records service - /collections/{collectionId}/sortables service
josegar74 Nov 24, 2020
c4bf081
OGC API Records / Collections / HTML output first draft.
fxprunayre Nov 24, 2020
1e4a53b
Checkstyle.
fxprunayre Nov 24, 2020
279593e
Only one local resolver.
fxprunayre Nov 24, 2020
aa27f8e
lighter spring footprint for test tending to unit
cmangeat Nov 24, 2020
aa50fbb
Only one local resolver.
fxprunayre Nov 24, 2020
13ce44d
OGC API Records / Collections/id / HTML output first draft.
fxprunayre Nov 24, 2020
14ccc31
Checkstyle.
fxprunayre Nov 24, 2020
11b9636
OGC API Records / Doc.
fxprunayre Nov 24, 2020
e25ffb8
OGC API Records / Collection / Styling and harvester logo.
fxprunayre Nov 25, 2020
a472a8c
OGC API Records / Collection / Fix link
fxprunayre Nov 25, 2020
91d456a
XSLT / Add utility function.
fxprunayre Nov 25, 2020
5f73fbc
OGC API Records - Fix url creation for CollectionInfo elements and c…
josegar74 Nov 25, 2020
3895339
OGC API Records - Fix base url for describe collection
josegar74 Nov 25, 2020
a6f01b3
Add XSLT model.
fxprunayre Nov 25, 2020
c8e783e
OGC API Records - Cleanup unused imports
josegar74 Nov 25, 2020
ff77db5
Add XmlResponseProcessor to return metadata in xml format and add API…
josegar74 Nov 25, 2020
5ca8158
XSLT / i18n using a map loaded from messages properties.
fxprunayre Nov 25, 2020
73d9ed0
jwt, testing for name and authorities consumption
cmangeat Nov 25, 2020
2419ba6
OGC API / Add examples for what we support.
fxprunayre Nov 25, 2020
e175dc2
jwt, one 'flat' gn authority converted from token to OAuth2UserAuthority
cmangeat Nov 25, 2020
b964ae9
OGC API / Add configuration for sources.
fxprunayre Nov 25, 2020
fe86d30
OGC API / Add configuration for sortables.
fxprunayre Nov 25, 2020
d46b0d4
refactor test
cmangeat Nov 25, 2020
eec5ded
OGC API / Support DCAT formatting. Add support for xslt transformati…
josegar74 Nov 25, 2020
ab16be6
no need for jjwt anymore
cmangeat Nov 25, 2020
2eff22f
OGC API records / We can now use http://localhost:9991/collections?f=xml
fxprunayre Nov 25, 2020
0bf1b4c
OGC API Record / Experiment on rendering one record as HTML.
fxprunayre Nov 25, 2020
5edec1e
OCG API Record / First landing page renderer test.
fxprunayre Nov 25, 2020
4618afe
jwt, there is no group directly associated with higher profile
cmangeat Nov 25, 2020
4c9a423
jwt, grouping by profile in oauth2 authority attributes
cmangeat Nov 26, 2020
8ac54b0
rename test
cmangeat Nov 26, 2020
4c94bf1
OGC API Record / Items / Standard translations.
fxprunayre Nov 26, 2020
ea713d4
OGC API records / HTML mode can browse all operations (almost /items …
fxprunayre Nov 26, 2020
1375c50
XSLT clean up.
fxprunayre Nov 26, 2020
3a58b7e
Update ElasticSearch proxy to use f parameter with format and Elastic…
josegar74 Nov 26, 2020
6070534
Landing page / Add header.
fxprunayre Nov 26, 2020
e4d29e1
ElastiSearch proxy don't send accept-encoding to Elastic Search in ha…
josegar74 Nov 26, 2020
4d4b714
ElasticSearch proxy - method to return the results as Java object
josegar74 Nov 26, 2020
e3cc5e9
Fix response content type when using f parameter in /collections/{col…
josegar74 Nov 26, 2020
fb7fd13
refactor test
cmangeat Nov 26, 2020
15f144d
test authentification
cmangeat Nov 26, 2020
f627343
jwt, refactor
cmangeat Nov 26, 2020
05cd5cb
remove dead code
cmangeat Nov 27, 2020
6873b90
jwt, binding attempt
cmangeat Nov 27, 2020
15db787
Cacheable methods / eg. loading message.properties or labels.xml.
fxprunayre Nov 26, 2020
d9a28fc
OGC API Records / Item / Improve layout.
fxprunayre Nov 26, 2020
260b7ba
OGC API Records / List items now.
fxprunayre Nov 26, 2020
fa2e47d
Doc.
fxprunayre Nov 27, 2020
d1db4ac
Doc.
fxprunayre Nov 27, 2020
9c6a916
Fixed missing dependency when running as JAR app.
fxprunayre Nov 27, 2020
285bbf0
OGC API Record / Make it work as standalone JAR app.
fxprunayre Dec 2, 2020
8850ebf
refactor (not tested)
cmangeat Nov 24, 2020
ce42081
first thought is was not possible to address static method
cmangeat Nov 25, 2020
13c8067
Locale resolver with URL parameter or header.
fxprunayre Dec 2, 2020
22c1fa0
OGC API Record / Configure landing page links.
fxprunayre Dec 2, 2020
810944f
XSLT / Introduce base url which may comes from X-forwarded-Headers.
fxprunayre Dec 2, 2020
dcc22c8
OGC API / Fix link to main coll.
fxprunayre Dec 2, 2020
4f24ccd
Build error.
fxprunayre Dec 8, 2020
701a976
Error controller - handle error message and avoid returning in json n…
josegar74 Dec 14, 2020
2c79b31
OGC API Record / Use message source for exception messages
josegar74 Dec 14, 2020
25dfe82
XSLT / Refactor.
fxprunayre Dec 14, 2020
199d850
Item not found.
fxprunayre Dec 14, 2020
91abcd2
Fix some links. Add index name to config.
fxprunayre Dec 15, 2020
a7efbc2
OGC API Records / Add navigation to other formats from HTML.
fxprunayre Dec 15, 2020
a488f14
Add GnMediaType.
fxprunayre Dec 15, 2020
685f885
OGC API Records / items / Register formats available.
fxprunayre Dec 15, 2020
8b81747
Move index model to dedicated module.
fxprunayre Dec 15, 2020
d995f8c
Fix link based on request URL which may have a trailing slash or not.
fxprunayre Dec 15, 2020
5350f92
Move index model to dedicated module.
fxprunayre Dec 15, 2020
5a8195f
Add test for index model and draft JSONLD format.
fxprunayre Dec 15, 2020
3c1b7dc
JSONLD draft test.
fxprunayre Dec 15, 2020
d5b2a4b
Fix test.
fxprunayre Dec 15, 2020
1934048
OGC API / Item / Allow empty label.
fxprunayre Dec 15, 2020
1710a23
OGC API / Fix main collection link.
fxprunayre Dec 16, 2020
5c0efd2
CI - fixing travis / introducing gh actions (#26)
pmauduit Dec 16, 2020
df2ccf0
logging - using longbok to define the logger
pmauduit Dec 17, 2020
130cfbe
Security / Build permission filter based on user info.
fxprunayre Dec 30, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
on:
push:
pull_request:

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: "Checking out"
uses: actions/checkout@v2

- name: "Setting up Java"
uses: actions/setup-java@v1
with:
java-version: '11.x'

- name: "Maven repository caching"
uses: actions/cache@v1
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-

- name: "Run the testsuite"
run: ./mvnw clean install -P-docker --no-transfer-progress -B
14 changes: 0 additions & 14 deletions .travis.yml

This file was deleted.

2 changes: 2 additions & 0 deletions config/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ jwt.secret: geonetwork
gn:
datadir: ${java.io.tmpdir}/gn-datadir
baseurl: http://geonetwork:8080
legacy.url: http://geonetwork:8080/geonetwork
index:
url: http://elasticsearch:9200
records: gn-records
indexing:
batch.size: 40
threadPool.size: 20


# Enable actuator endpoints by default
management:
endpoint:
Expand Down
27 changes: 27 additions & 0 deletions modules/library/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Logging configuration

Slf4j is used as a logging facade, and by default the logs will be redirected
onto the standard output.


Create a topic in the class and use the log:
```java
@Slf4j(topic = "org.fao.geonet.indexing.tasks")
public class IndexingService {
...
log.info(String.format(
"Index %s removed.",
index));
```


If one need to tweak the log level, it can be done by modifying the
`bootstrap.yml` file of the spring-boot application, e.g.:

```
logging.level:
org.springframework: DEBUG
org.hibernate.SQL: DEBUG
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
```

36 changes: 36 additions & 0 deletions modules/library/common-error/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
## Error

The error module defines rules and core implementation of error handling and capacity to return multilingual error messages in format corresponding to the request.


Errors handling conventions:

* All errors are localized. Use `exception.properties` file:

```java
new IllegalArgumentException(messages.getMessage(
"api.exception.record.notFound", new String[]{"abcd"},
request.getLocale()))
```

And add in `src/main/resources/messages/(exception|api|view).properties` the corresponding property:

```properties
api.exception.record.notFound=No record could be found with id {0}.
```

* Errors return the error cause but also if possible options to solve the problem. eg. an invalid parameter based on an enum, error MUST return the possibilities.


* Errors can be returned as JSON/XML/HTML depending on `Accept` header:

```shell script
curl -v -H "Accept:application/json" -H "Accept-language:en" http://localhost:9902/errortestlocalized

curl -v -H "Accept:application/json" -H "Accept-language:fr" http://localhost:9902/errortestlocalized

curl -v -H "Accept:application/xml" -H "Accept-language:fr" http://localhost:9902/errortestlocalized

curl -v -H "Accept:text/html" -H "Accept-language:fr" http://localhost:9902/errortestlocalized
```

42 changes: 42 additions & 0 deletions modules/library/common-error/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>gn-cloud-lib</artifactId>
<groupId>org.geonetwork-opensource.cloud</groupId>
<version>0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>gn-cloud-common-error</artifactId>
<name>GeoNetwork common error</name>
<url>http://geonetwork-opensource.org</url>

<dependencies>
<dependency>
<groupId>org.geonetwork-opensource.cloud</groupId>
<artifactId>gn-cloud-common-view</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* (c) 2020 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/

package org.fao.geonet.errors;

import java.util.Map;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.WebRequest;

@Component
public class GeoNetworkErrorAttributes extends DefaultErrorAttributes {

@Override
public Map<String, Object> getErrorAttributes(
WebRequest webRequest, ErrorAttributeOptions options) {
Map<String, Object> errorAttributes =
super.getErrorAttributes(webRequest, options);
errorAttributes.put("locale", webRequest.getLocale()
.toString());
//errorAttributes.remove("error");

//...
// overriding the Whitelabel Page

return errorAttributes;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* (c) 2020 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/

package org.fao.geonet.errors;

import org.fao.geonet.errors.model.GeoNetworkError;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class GeoNetworkExceptionHandler extends ResponseEntityExceptionHandler {

// @ExceptionHandler(EntityNotFoundException.class)
// protected ResponseEntity<Object> handleEntityNotFound(
// EntityNotFoundException ex) {
// Error apiError = new Error(ex, NOT_FOUND);
// return buildResponseEntity(apiError);
// }

private ResponseEntity<Object> buildResponseEntity(GeoNetworkError apiError) {
return new ResponseEntity<>(apiError, apiError.getStatus());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* (c) 2020 Open Source Geospatial Foundation - all rights reserved This code is licensed under the
* GPL 2.0 license, available at the root application directory.
*/

package org.fao.geonet.errors.controller;

import java.io.StringWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.apache.commons.io.IOUtils;
import org.fao.geonet.errors.model.GeoNetworkError;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* Basic Controller which is called for unhandled Error.
*/
@Controller
public class GeoNetworkErrorController implements ErrorController {

@Autowired
MessageSource messages;

/**
* Test error.
*/
@GetMapping(value = "/errortest")
public String errorTest() {
throw new IllegalArgumentException("Error reported");
}


/**
* Test error localized.
*/
@GetMapping(value = "/errortestlocalized")
public String errorTestException(
HttpServletRequest request) {
throw new IllegalArgumentException(messages.getMessage(
"api.exception.record.notFound", new String[]{"abcd"},
request.getLocale()));
}

/**
* XML or JSON error.
*/
@RequestMapping(
value = "/error",
produces = {
MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE
}
)
@ResponseBody
public HttpEntity<GeoNetworkError> handleError(
HttpServletRequest request) {
GeoNetworkError error = getError(request);
return ResponseEntity
.status(error.getStatus())
.body(error);
}

/**
* HTML version of an error.
*/
@RequestMapping(
value = "/error",
produces = {
MediaType.TEXT_HTML_VALUE,
MediaType.APPLICATION_XHTML_XML_VALUE
}
)
public String handleErrorAsHtml(
HttpServletRequest request,
Model model) {
StringWriter sw = new StringWriter();
try {
JAXBContext context = JAXBContext.newInstance(GeoNetworkError.class);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(getError(request), sw);
} catch (JAXBException e) {
e.printStackTrace();
}
model.addAttribute("source", IOUtils.toInputStream(sw.toString()));
return "core/errors/error";
}

protected GeoNetworkError getError(HttpServletRequest request) {
Integer status = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
Exception exception = (Exception) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
String errorMessage = (String) request.getAttribute(RequestDispatcher.ERROR_MESSAGE);
String path = (String) request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI);
return new GeoNetworkError(exception, errorMessage, HttpStatus.valueOf(status), path);
}

@Override
public String getErrorPath() {
return null;
}
}
Loading