[WIP] 9720-get-scholix-links-related-to-openaireid #9
3
.env
3
.env
|
@ -1,4 +1,5 @@
|
||||||
ZK_HOSTS=zookeeper-solr-openaire-dev-1:2181,zookeeper-solr-openaire-dev-2:2181,zookeeper-solr-openaire-dev-3:2181
|
ZK_HOSTS=zookeeper-solr-openaire-dev-1:2181,zookeeper-solr-openaire-dev-2:2181,zookeeper-solr-openaire-dev-3:2181
|
||||||
SOLR_COLLECTION=public
|
SOLR_COLLECTION=public
|
||||||
OPENAPI_SERVER_BASE_URL=http://localhost:8080/graph
|
OPENAPI_SERVER_BASE_URL=http://localhost:8080/graph
|
||||||
CONTEXT_PATH=/graph
|
CONTEXT_PATH=/graph
|
||||||
|
SCHOLIX_SERVER_BASE_URL=https://test.api.scholexplorer.openaire.eu
|
1
pom.xml
1
pom.xml
|
@ -106,7 +106,6 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.solr</groupId>
|
<groupId>org.apache.solr</groupId>
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package eu.openaire.api.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.client.RestClient;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ScholixClientConfig {
|
||||||
|
@Value("${scholix.server-base-url}")
|
||||||
|
private String baseUrl;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RestClient restClient() {
|
||||||
|
return RestClient.builder()
|
||||||
|
.baseUrl(baseUrl)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package eu.openaire.api.controllers;
|
||||||
|
|
||||||
|
import eu.dnetlib.dhp.schema.sx.api.model.v2.PageResultType;
|
||||||
|
import eu.openaire.api.dto.request.validators.PaginationValidator;
|
||||||
|
import eu.openaire.api.errors.ErrorResponse;
|
||||||
|
import eu.openaire.api.services.ScholixService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.WebDataBinder;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.InitBinder;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Tag(name = "Scholix Relations", description = "API endpoints to explore scholix")
|
||||||
|
public class ScholixController {
|
||||||
|
private final ScholixService scholixService;
|
||||||
|
|
||||||
|
// common validator to check pagination parameters
|
||||||
|
private final PaginationValidator paginationValidator;
|
||||||
|
|
||||||
|
@InitBinder
|
||||||
|
protected void initBinder(WebDataBinder binder) {
|
||||||
|
binder.addValidators(paginationValidator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "Retrieve scholix links by sourcePid and sourceType",
|
||||||
|
description = "Retrieve scholix links by sourcePid and sourceType"
|
||||||
|
)
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(responseCode = "200", content = { @Content(schema = @Schema(implementation = PageResultType.class), mediaType = "application/json") }),
|
||||||
|
@ApiResponse(responseCode = "404", content = { @Content(schema = @Schema(implementation = ErrorResponse.class), mediaType = "application/json") }),
|
||||||
|
@ApiResponse(responseCode = "500", content = { @Content(schema = @Schema(implementation = ErrorResponse.class), mediaType = "application/json") })
|
||||||
|
})
|
||||||
|
@GetMapping("/links")
|
||||||
|
public PageResultType getLinks(@RequestParam
|
||||||
|
@Parameter(description = "The OpenAIRE Id") String sourcePid,
|
||||||
|
@RequestParam(required = false)
|
||||||
|
@Parameter(description = "The OpenAIRE Source Type") String sourceType,
|
||||||
|
@RequestParam(defaultValue = "0")
|
||||||
|
@Parameter(description = "Page number of the results") int page) {
|
||||||
|
|
||||||
|
return scholixService.getLinks(sourcePid, sourceType, page);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,10 +5,12 @@ import eu.openaire.api.errors.exceptions.NotFoundException;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.HttpStatusCode;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
import org.springframework.web.client.RestClientResponseException;
|
||||||
import org.springframework.web.context.request.ServletWebRequest;
|
import org.springframework.web.context.request.ServletWebRequest;
|
||||||
import org.springframework.web.context.request.WebRequest;
|
import org.springframework.web.context.request.WebRequest;
|
||||||
import org.springframework.web.servlet.resource.NoResourceFoundException;
|
import org.springframework.web.servlet.resource.NoResourceFoundException;
|
||||||
|
@ -60,6 +62,22 @@ public class ServiceExceptionHandler {
|
||||||
return this.handleException(e.getMessage(), request, HttpStatus.INTERNAL_SERVER_ERROR);
|
return this.handleException(e.getMessage(), request, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(RestClientResponseException.class)
|
||||||
|
public ResponseEntity<ErrorResponse> handleRestClientResponseException(RestClientResponseException e, WebRequest request) {
|
||||||
|
HttpStatusCode status = e.getStatusCode();
|
||||||
|
String path = ((ServletWebRequest) request).getRequest().getRequestURI();
|
||||||
|
|
||||||
|
ErrorResponse response = ErrorResponse.builder()
|
||||||
|
.message(e.getMessage())
|
||||||
|
.error(status.toString())
|
||||||
|
.code(status.value())
|
||||||
|
.timestamp(new Date())
|
||||||
|
.path(path)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return ResponseEntity.status(status.value()).body(response);
|
||||||
|
}
|
||||||
|
|
||||||
private ResponseEntity<ErrorResponse> handleException(String message, WebRequest request, HttpStatus httpStatus) {
|
private ResponseEntity<ErrorResponse> handleException(String message, WebRequest request, HttpStatus httpStatus) {
|
||||||
var req = ((ServletWebRequest)request).getRequest();
|
var req = ((ServletWebRequest)request).getRequest();
|
||||||
String path = String.format("%s?%s", req.getRequestURI(), req.getQueryString());
|
String path = String.format("%s?%s", req.getRequestURI(), req.getQueryString());
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package eu.openaire.api.services;
|
||||||
|
|
||||||
|
import eu.dnetlib.dhp.schema.sx.api.model.v2.PageResultType;
|
||||||
|
import io.micrometer.core.annotation.Timed;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestClient;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class ScholixService {
|
||||||
|
|
||||||
|
private final RestClient restClient;
|
||||||
|
private final Logger log = LogManager.getLogger(this.getClass());
|
||||||
|
private static final String OPENAIRE_ID_PREFIX = "50|";
|
||||||
|
|
||||||
|
@Timed
|
||||||
|
public PageResultType getLinks(String sourcePid, String sourceType, int page) {
|
||||||
|
try {
|
||||||
|
if (!sourcePid.startsWith(OPENAIRE_ID_PREFIX)) {
|
||||||
|
sourcePid = OPENAIRE_ID_PREFIX + sourcePid;
|
||||||
|
}
|
||||||
|
|
||||||
|
String finalSourcePid = sourcePid;
|
||||||
|
|
||||||
|
return restClient.get()
|
||||||
|
.uri(uriBuilder -> uriBuilder
|
||||||
|
.path("/v2/Links")
|
||||||
|
.queryParam("sourcePid", finalSourcePid)
|
||||||
|
.queryParam("sourceType", sourceType)
|
||||||
|
.queryParam("page", page)
|
||||||
|
.build())
|
||||||
|
.retrieve()
|
||||||
|
.body(PageResultType.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
throw new RuntimeException("Unexpected error: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ openapi.description=The Graph API allows developers to access metadata records o
|
||||||
solr.collection=${SOLR_COLLECTION}
|
solr.collection=${SOLR_COLLECTION}
|
||||||
solr.zkHosts=${ZK_HOSTS}
|
solr.zkHosts=${ZK_HOSTS}
|
||||||
|
|
||||||
|
scholix.server-base-url=${SCHOLIX_SERVER_BASE_URL}
|
||||||
|
|
||||||
logging.level.org.springframework.web=DEBUG
|
logging.level.org.springframework.web=DEBUG
|
||||||
|
|
||||||
#removes 'trace' field from error responses; alternatively remove 'spring-boot-devtools' dependency
|
#removes 'trace' field from error responses; alternatively remove 'spring-boot-devtools' dependency
|
||||||
|
|
Loading…
Reference in New Issue