Compare commits

..

No commits in common. "master" and "jsonPayload" have entirely different histories.

22 changed files with 134 additions and 302 deletions

15
pom.xml
View File

@ -163,21 +163,6 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<!-- Add dump schema dependency -->
<dependency>
<groupId>eu.dnetlib.dhp</groupId>

View File

@ -2,10 +2,8 @@ package eu.openaire.api;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
@EnableAspectJAutoProxy
public class OpenaireRestApiApplication {
public static void main(String[] args) {

View File

@ -1,50 +0,0 @@
package eu.openaire.api.config.metrics;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class MetricsAspect {
private final MeterRegistry meterRegistry;
@Autowired
public MetricsAspect(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
/***
* Advice for timing methods annotated with {@link Timed}.
*/
@Around("@annotation(io.micrometer.core.annotation.Timed)")
public Object timeAnnotatedMethods(ProceedingJoinPoint joinPoint) throws Throwable {
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
String className = joinPoint.getTarget().getClass().getSimpleName();
String methodName = method.getName();
String timerName = className + "." + methodName;
Timer.Sample sample = Timer.start(meterRegistry);
try {
return joinPoint.proceed();
} finally {
sample.stop(Timer.builder(timerName)
.tags("application", "openaire-search-api")
.tags("class", className)
.tags("method", methodName)
.publishPercentiles(0.5, 0.95)
.register(meterRegistry));
}
}
}

View File

@ -10,10 +10,6 @@ import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import static eu.openaire.api.mappers.Utils.API_CURSOR_DESC;
import static eu.openaire.api.mappers.Utils.API_PAGE_DESC;
import static eu.openaire.api.mappers.Utils.API_PAGE_SIZE_DESC;
@Getter
@Setter
@Data
@ -96,7 +92,7 @@ public class DataSourceRequest implements PaginatedRequest {
@Min(value = 1)
@Parameter(
description = API_PAGE_DESC,
description = "Page number of the results",
schema = @Schema(defaultValue = "1", type = "integer")
)
private int page = 1;
@ -104,17 +100,11 @@ public class DataSourceRequest implements PaginatedRequest {
@Min(value = 1, message = "Page size must be at least 1")
@Max(value = 100, message = "Page size must be at most 100")
@Parameter(
description = API_PAGE_SIZE_DESC,
description = "Number of results per page",
schema = @Schema(defaultValue = "10", type = "integer")
)
private int pageSize = 10;
@Parameter(
description = API_CURSOR_DESC,
schema = @Schema(type = "string")
)
private String cursor;
@Parameter(
description = "The field to sort the results by and the sort direction. The format should be in the format `fieldname ASC|DESC`, organizations can be only sorted by the 'relevance'." ,
schema = @Schema(defaultValue = "relevance DESC")

View File

@ -10,10 +10,6 @@ import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import static eu.openaire.api.mappers.Utils.API_CURSOR_DESC;
import static eu.openaire.api.mappers.Utils.API_PAGE_DESC;
import static eu.openaire.api.mappers.Utils.API_PAGE_SIZE_DESC;
@Getter
@Setter
@Data
@ -75,22 +71,19 @@ public class OrganizationRequest implements PaginatedRequest {
@Min(value = 1)
@Parameter(
description = API_PAGE_DESC,
schema = @Schema(defaultValue = "1", type = "integer"))
description = "Page number of the results",
schema = @Schema(defaultValue = "1", type = "integer")
)
private int page = 1;
@Min(value = 1, message = "Page size must be at least 1")
@Max(value = 100, message = "Page size must be at most 100")
@Parameter(
description = API_PAGE_SIZE_DESC,
schema = @Schema(defaultValue = "10", type = "integer"))
description = "Number of results per page",
schema = @Schema(defaultValue = "10", type = "integer")
)
private int pageSize = 10;
@Parameter(
description = API_CURSOR_DESC,
schema = @Schema(type = "string"))
private String cursor;
@Parameter(
description = "The field to sort the results by and the sort direction. The format should be in the format `fieldname ASC|DESC`, organizations can be only sorted by the 'relevance'." ,
schema = @Schema(defaultValue = "relevance DESC")

View File

@ -1,7 +1,8 @@
package eu.openaire.api.dto.request;
public interface PaginatedRequest {
int getPage();
int getPageSize();
String getCursor();
}

View File

@ -9,10 +9,9 @@ import jakarta.validation.constraints.Pattern;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import static eu.openaire.api.mappers.Utils.API_CURSOR_DESC;
import static eu.openaire.api.mappers.Utils.API_PAGE_DESC;
import static eu.openaire.api.mappers.Utils.API_PAGE_SIZE_DESC;
import java.time.LocalDate;
@Getter
@Setter
@ -74,28 +73,32 @@ public class ProjectRequest implements PaginatedRequest {
private String[] fundingStreamId;
@Parameter(
description = "Gets the projects with start date greater than or equal to the given date. Provide a date in YYYY or YYYY-MM-DD format",
schema = @Schema(type = "string")
description = "Gets the projects with start date greater than or equal to the given date. Please provide a date formatted as YYYY-MM-DD",
schema = @Schema(type = "string", format = "date")
)
private String fromStartDate;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate fromStartDate;
@Parameter(
description = "Gets the projects with start date less than or equal to the given date. Provide a date in YYYY or YYYY-MM-DD format",
schema = @Schema(type = "string")
description = "Gets the projects with start date less than or equal to the given date. Please provide a date formatted as YYYY-MM-DD",
schema = @Schema(type = "string", format = "date")
)
private String toStartDate;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate toStartDate;
@Parameter(
description = "Gets the projects with end date greater than or equal to the given date. Provide a date in YYYY or YYYY-MM-DD format",
schema = @Schema(type = "string")
description = "Gets the projects with end date greater than or equal to the given date. Please provide a date formatted as YYYY-MM-DD",
schema = @Schema(type = "string", format = "date")
)
private String fromEndDate;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate fromEndDate;
@Parameter(
description = "Gets the projects with end date less than or equal to the given date. Provide a date in YYYY or YYYY-MM-DD format",
schema = @Schema(type = "string")
description = "Gets the projects with end date less than or equal to the given date. Please provide a date formatted as YYYY-MM-DD",
schema = @Schema(type = "string", format = "date")
)
private String toEndDate;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate toEndDate;
@Parameter(
description = "The name or short name of the related organization",
@ -135,22 +138,19 @@ public class ProjectRequest implements PaginatedRequest {
@Min(value = 1)
@Parameter(
description = API_PAGE_DESC,
schema = @Schema(defaultValue = "1", type = "integer"))
description = "Page number of the results",
schema = @Schema(defaultValue = "1", type = "integer")
)
private int page = 1;
@Min(value = 1, message = "Page size must be at least 1")
@Max(value = 100, message = "Page size must be at most 100")
@Parameter(
description = API_PAGE_SIZE_DESC,
schema = @Schema(defaultValue = "10", type = "integer"))
description = "Number of results per page",
schema = @Schema(defaultValue = "10", type = "integer")
)
private int pageSize = 10;
@Parameter(
description = API_CURSOR_DESC,
schema = @Schema(type = "string"))
private String cursor;
@Parameter(
description = "The field to sort the results by and the sort direction. The format should be in the format `fieldname ASC|DESC`, where fieldname is one of 'relevance', 'startDate', 'endDate'. Multiple sorting parameters should be comma-separated." ,
schema = @Schema(defaultValue = "relevance DESC")

View File

@ -9,10 +9,9 @@ import jakarta.validation.constraints.Pattern;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import static eu.openaire.api.mappers.Utils.API_CURSOR_DESC;
import static eu.openaire.api.mappers.Utils.API_PAGE_DESC;
import static eu.openaire.api.mappers.Utils.API_PAGE_SIZE_DESC;
import java.time.LocalDate;
@Getter
@Setter
@ -73,14 +72,18 @@ public class ResearchProductsRequest implements PaginatedRequest {
private String[] type;
@Parameter(
description = "Gets the research products whose publication date is greater than or equal to he given date. Provide a date in YYYY or YYYY-MM-DD format",
schema = @Schema(type = "string"))
private String fromPublicationDate;
description = "Gets the research products whose publication date is greater than or equal to he given date. Please provide a date formatted as YYYY-MM-DD",
schema = @Schema(type = "string", format = "date")
)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate fromPublicationDate;
@Parameter(
description = "Gets the research products whose publication date is less than or equal to the given date. Provide a date in YYYY or YYYY-MM-DD format",
schema = @Schema(type = "string"))
private String toPublicationDate;
description = "Gets the research products whose publication date is less than or equal to the given date. Please provide a date formatted as YYYY-MM-DD",
schema = @Schema(type = "string", format = "date")
)
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate toPublicationDate;
@Parameter(
description = "List of subjects associated to the research product",
@ -291,7 +294,7 @@ public class ResearchProductsRequest implements PaginatedRequest {
@Min(value = 1)
@Parameter(
description = API_PAGE_DESC,
description = "Page number of the results",
schema = @Schema(defaultValue = "1", type = "integer")
)
private int page = 1;
@ -299,17 +302,11 @@ public class ResearchProductsRequest implements PaginatedRequest {
@Min(value = 1, message = "Page size must be at least 1")
@Max(value = 100, message = "Page size must be at most 100")
@Parameter(
description = API_PAGE_SIZE_DESC,
description = "Number of results per page",
schema = @Schema(defaultValue = "10", type = "integer")
)
private int pageSize = 10;
@Parameter(
description = API_CURSOR_DESC,
schema = @Schema(type = "string")
)
private String cursor;
@Parameter(
description = "The field to sort the results by and the sort direction. The format should be in the format `fieldname ASC|DESC`, where fieldname is one of 'relevance', 'publicationDate', 'dateOfCollection', 'influence', 'popularity', 'citationCount', 'impulse'. Multiple sorting parameters should be comma-separated.",
schema = @Schema(defaultValue = "relevance DESC")

View File

@ -11,7 +11,7 @@ public class PaginationValidator implements Validator {
private final HttpServletRequest request;
private static final int MAX_RESULTS = 10000;
private final int MAX_RESULTS = 10000;
public PaginationValidator(HttpServletRequest request) {
this.request = request;

View File

@ -1,21 +1,22 @@
package eu.openaire.api.dto.response;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import static eu.openaire.api.mappers.Utils.API_NEXT_CURSOR_DESC;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SearchHeader {
private SearchHeaderDebug debug;
private Long numFound;
private Float maxScore;
private Integer queryTime;
private Integer page;
private Integer pageSize;
@Schema(description = API_NEXT_CURSOR_DESC)
private String nextCursor;
private SearchHeaderDebug debug;
private long numFound;
private float maxScore;
private int queryTime;
private int page;
private int pageSize;
}

View File

@ -14,8 +14,6 @@ import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@RestControllerAdvice
@ -23,9 +21,6 @@ public class ServiceExceptionHandler {
private final Logger log = LogManager.getLogger(this.getClass());
private static final String URL_REGEX = "https?://\\S*";
private static final Pattern URL_PATTERN = Pattern.compile(URL_REGEX);
@ExceptionHandler(NotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFoundException(NotFoundException e, WebRequest request) {
return this.handleException(e.getMessage(), request, HttpStatus.NOT_FOUND);
@ -55,9 +50,8 @@ public class ServiceExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleAllOtherExceptions(Exception e, WebRequest request) {
//todo: log4j2.xml - add error appender
e.printStackTrace();
return this.handleException(e.getMessage(), request, HttpStatus.INTERNAL_SERVER_ERROR);
return this.handleException("An internal server error occurred", request, HttpStatus.INTERNAL_SERVER_ERROR);
}
private ResponseEntity<ErrorResponse> handleException(String message, WebRequest request, HttpStatus httpStatus) {
@ -65,7 +59,7 @@ public class ServiceExceptionHandler {
String path = String.format("%s?%s", req.getRequestURI(), req.getQueryString());
ErrorResponse response = ErrorResponse.builder()
.message(obfuscateUrlsInMessage(message))
.message(message)
.error(httpStatus.getReasonPhrase())
.code(httpStatus.value())
.timestamp(new Date())
@ -76,9 +70,4 @@ public class ServiceExceptionHandler {
.status(httpStatus)
.body(response);
}
private static String obfuscateUrlsInMessage(String message) {
Matcher matcher = URL_PATTERN.matcher(message);
return matcher.replaceAll("[https://***].");
}
}

View File

@ -9,37 +9,11 @@ import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
public class Utils {
private Utils() {}
public static final String API_PAGE_DESC = """
Page number of the results,\s
used for basic start/rows pagination.\s
Max dataset to retrieve - 10000 records.\s
To get more than that, use cursor-based pagination.""";
public static final String API_PAGE_SIZE_DESC = "Number of results per page";
/* todo: maybe mention that if a big dataset is required, then download directly the compressed data file
like this, we avoid high load on this microservice */
public static final String API_CURSOR_DESC = """
Cursor-based pagination. Initial value: `cursor=*`.\s
Cursor should be used when it is required to retrieve a big dataset (more than 10000 records).\s
To get the next page of results, use nextCursor returned in the response.
""";
public static final String API_NEXT_CURSOR_DESC = """
nextCursor - to be used in the next request to get the next page of results.\s
You can repeat this process until youve fetched as many results as you want,\s
or until the nextCursor returned matches the current cursor youve already specified,\s
indicating that there are no more results.
""";
public static String escapeAndJoin(String[] tokens, String predicate, boolean addQuotes, String suffix) {
static public String escapeAndJoin(String[] tokens, String predicate, boolean addQuotes, String suffix) {
tokens = Arrays.stream(tokens)
// remove empty tokens
@ -52,7 +26,7 @@ public class Utils {
return String.join(" " + predicate + " ", tokens);
}
public static String handleInput(String token, boolean addQuotes, String suffix) {
static public String handleInput(String token, boolean addQuotes, String suffix) {
boolean hasLogicalOperator = containsLogicalOperator(token);
@ -74,11 +48,11 @@ public class Utils {
return sb.toString();
}
private static boolean containsLogicalOperator(String input) {
static private boolean containsLogicalOperator(String input) {
return input.contains("AND") || input.contains("OR") || input.contains("NOT");
}
public static String escapeInput(String input, String suffix) {
static public String escapeInput(String input, String suffix) {
// Split the input into tokens at whitespace or parentheses or quotes
String[] tokens = input.split("(\\s+|(?=[()\\\"]|(?<=[()\\\"])))");
@ -164,66 +138,24 @@ public class Utils {
}
return value;
}
private static void removeLastElementIfSpace(List<String> list) {
static private void removeLastElementIfSpace(List<String> list) {
if (list.get(list.size() - 1).equals(" ")) {
list.remove(list.size() - 1);
}
}
public static boolean isNullOrEmpty(String str) {
static public boolean isNullOrEmpty(String str) {
return str == null || str.isBlank();
}
public static boolean isNullOrEmpty(String[] str) {
static public boolean isNullOrEmpty(String[] str) {
return str == null || str.length == 0;
}
public static String formatSolrDateRange(String fieldName, String fromDate, String toDate) {
if (fromDate != null && toDate != null) {
return String.format(fieldName,
appendHHMMSS(appendMMDD(fromDate, "-01-01")),
appendHHMMSS(appendMMDD(toDate, "-12-31")));
} else {
if (fromDate != null) {
return String.format(fieldName,
appendHHMMSS(appendMMDD(fromDate, "-01-01")), "*");
}
if (toDate != null) {
return String.format(fieldName, "*",
appendHHMMSS(appendMMDD(toDate, "-12-31")));
}
}
return null;
}
/***
* Append -mm-dd if date came in yyyy format
* @return LocalDate in yyyy-mm-dd format
*/
private static LocalDate appendMMDD(String date, String monthDaySuffix) {
try {
if (date.length() == 10) { //yyyy-mm-dd
return LocalDate.parse(date);
} else if (date.length() == 4) { //yyyy
return LocalDate.parse(date + monthDaySuffix);
} else {
throw new IllegalArgumentException("Invalid date format");
}
} catch (DateTimeParseException e) {
throw new IllegalArgumentException("Failed to parse date: " + date, e);
}
}
/***
* The incoming date comes in yyyy-mm-dd, so we have to append hh-mm-ss, also.
* @return String in yyyy-MM-dd'T'HH:mm:ss'Z' format
*/
private static String appendHHMMSS(LocalDate date) {
static private String formatDate(LocalDate date) {
// IMPORTANT: all dates are indexed in 12:00:00 in the index (not sure why)
// so we need to set this time to the date (this should change if dates are indexed in a different way)
@ -243,7 +175,23 @@ public class Utils {
return zdt.format(formatter);
}
public static List<SolrQuery.SortClause> formatSortByParam(String sortBy, Map<String, String> fieldMapping) {
static public String formatSolrDateRange(String fieldName, LocalDate fromDate, LocalDate toDate) {
if (fromDate != null && toDate != null) {
return String.format(fieldName, Utils.formatDate(fromDate), Utils.formatDate(toDate));
} else {
if (fromDate != null) {
return String.format(fieldName, Utils.formatDate(fromDate), "*");
}
if (toDate != null) {
return String.format(fieldName, "*", Utils.formatDate(toDate));
}
}
return null;
}
static public List<SolrQuery.SortClause> formatSortByParam(String sortBy, Map<String, String> fieldMapping) {
if (Utils.isNullOrEmpty(sortBy)) {
return null;

View File

@ -14,7 +14,6 @@ public interface DataSourceRequestMapper {
@Mapping(target = "start", expression = "java( calculateStart(src.getPage(), src.getPageSize()) )")
@Mapping(target = "rows", source = "pageSize")
@Mapping(target = "debugQuery", source = "debugQuery")
@Mapping(target = "cursor", source = "cursor")
@Mapping(target = "sort", expression = "java( eu.openaire.api.mappers.Utils.formatSortByParam(src.getSortBy(), SolrFieldsMapper.dataSourceSortMapping) )")
SolrQueryParams toSolrQuery(DataSourceRequest src);

View File

@ -4,33 +4,23 @@ import eu.openaire.api.dto.response.SearchHeader;
import eu.openaire.api.dto.response.SearchHeaderDebug;
import eu.openaire.api.solr.SolrQueryParams;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import java.util.Optional;
@Mapper(componentModel = "spring")
public interface ResponseHeaderMapper {
@Mapping(target = "numFound", expression = "java( Long.valueOf(queryResponse.getResults().getNumFound()) )")
@Mapping(target = "numFound", source = "queryResponse.results.numFound")
@Mapping(target = "maxScore", source = "queryResponse.results.maxScore")
@Mapping(target = "page", source = "page")
@Mapping(target = "pageSize", source = "pageSize")
@Mapping(target = "nextCursor", source = "queryResponse.nextCursorMark")
@Mapping(target = "queryTime", expression = "java( (int) queryResponse.getHeader().get(\"QTime\") )")
@Mapping(target = "debug", expression = "java( mapDebug(queryResponse, solrQueryParams, debugQuery) )")
SearchHeader toSearchHeader(QueryResponse queryResponse, SolrQueryParams solrQueryParams,
boolean debugQuery, int page, int pageSize);
@AfterMapping
default void removePage(@MappingTarget SearchHeader searchHeader) {
if (searchHeader.getNextCursor() != null) {
searchHeader.setPage(null);
}
}
default SearchHeaderDebug mapDebug(QueryResponse queryResponse, SolrQueryParams solrQueryParams, boolean debugQuery) {
if (!debugQuery) {
return null;

View File

@ -139,8 +139,11 @@ public interface ResearchProductMapper {
return null;
List<Pid> orcid = authorPidList
.stream()
.filter(ap -> ModelConstants.ORCID.equals(ap.getTypeCode()))
.toList();
.filter(
ap -> ap
.getTypeCode()
.equals(ModelConstants.ORCID))
.collect(Collectors.toList());
if (orcid.size() == 1) {
return getAuthorPid(orcid.get(0));
}
@ -148,8 +151,11 @@ public interface ResearchProductMapper {
return null;
orcid = authorPidList
.stream()
.filter(ap -> ModelConstants.ORCID_PENDING.equals(ap.getTypeCode()))
.toList();
.filter(
ap -> ap
.getTypeCode()
.equals(ModelConstants.ORCID_PENDING))
.collect(Collectors.toList());
if (orcid.size() == 1) {
return getAuthorPid(orcid.get(0));
}

View File

@ -10,7 +10,6 @@ import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.SolrPingResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.params.CursorMarkParams;
import org.springframework.stereotype.Repository;
import java.io.IOException;
@ -20,33 +19,31 @@ import java.io.IOException;
public class SolrRepository {
private final SolrConnectionManager solrConnectionManager;
private final Logger log = LogManager.getLogger(this.getClass());
private static final String UNIQUE_KEY = "__indexrecordidentifier";
public SolrDocument getById(String id) throws SolrServerException, IOException {
return solrConnectionManager.getSolrClient().getById(id);
}
public QueryResponse query(SolrQueryParams queryParams) throws SolrServerException, IOException {
SolrQuery query = new SolrQuery();
query.setQuery(queryParams.getQueryString()); // add Q
for (String fq : queryParams.getFilterQueries()) { // add FQ
SolrQuery query = new SolrQuery();
// add Q
query.setQuery(queryParams.getQueryString());
// add FQ
for (String fq : queryParams.getFilterQueries()) {
query.addFilterQuery(fq);
}
query.addField(queryParams.getFieldList()); // add FL
// add FL
query.addField(queryParams.getFieldList());
// set pagination
query.setRows(queryParams.getRows());
String cursor = queryParams.getCursor();
if (cursor != null && !cursor.isEmpty()) { // set cursor-based pagination
query.set(CursorMarkParams.CURSOR_MARK_PARAM, cursor);
query.addSort(UNIQUE_KEY, SolrQuery.ORDER.asc);
} else { // set basic page/page-size pagination
// set pagination parameters
query.setStart(queryParams.getStart());
}
query.setRows(queryParams.getRows());
// set sorting
for (var sortClause : queryParams.getSort()) {
@ -58,16 +55,10 @@ public class SolrRepository {
query.set("debugQuery", "on");
}
try {
log.info(query);
return solrConnectionManager.getSolrClient().query(query);
} catch (SolrServerException e) {
log.error(e.getMessage());
throw new SolrServerException(e);
} catch (IOException e) {
log.error(e.getMessage());
throw new IOException(e);
}
}
public SolrPingResponse ping() throws SolrServerException, IOException {

View File

@ -11,7 +11,6 @@ import eu.openaire.api.mappers.response.ResponseResultsMapper;
import eu.openaire.api.mappers.response.entities.DatasourceMapper;
import eu.openaire.api.repositories.SolrRepository;
import eu.openaire.api.solr.SolrQueryParams;
import io.micrometer.core.annotation.Timed;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.logging.log4j.LogManager;
@ -38,7 +37,6 @@ public class DataSourceService {
private final Logger log = LogManager.getLogger(this.getClass());
@SneakyThrows
@Timed
public Datasource getById(String id) {
var doc = solrRepository.getById(id);
@ -50,7 +48,6 @@ public class DataSourceService {
}
@SneakyThrows
@Timed
public SearchResponse<Datasource> search(DataSourceRequest request) {
SolrQueryParams solrQueryParams = dataSourceRequestMapper.toSolrQuery(request);

View File

@ -11,7 +11,6 @@ import eu.openaire.api.mappers.response.ResponseResultsMapper;
import eu.openaire.api.mappers.response.entities.OrganizationMapper;
import eu.openaire.api.repositories.SolrRepository;
import eu.openaire.api.solr.SolrQueryParams;
import io.micrometer.core.annotation.Timed;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.logging.log4j.LogManager;
@ -38,7 +37,6 @@ public class OrganizationService {
private final Logger log = LogManager.getLogger(this.getClass());
@SneakyThrows
@Timed
public Organization getById(String id) {
var doc = solrRepository.getById(id);
@ -50,7 +48,6 @@ public class OrganizationService {
}
@SneakyThrows
@Timed
public SearchResponse<Organization> search(OrganizationRequest request) {
SolrQueryParams solrQueryParams = organizationRequestMapper.toSolrQuery(request);

View File

@ -11,7 +11,6 @@ import eu.openaire.api.mappers.response.ResponseResultsMapper;
import eu.openaire.api.mappers.response.entities.ProjectMapper;
import eu.openaire.api.repositories.SolrRepository;
import eu.openaire.api.solr.SolrQueryParams;
import io.micrometer.core.annotation.Timed;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.logging.log4j.LogManager;
@ -38,7 +37,6 @@ public class ProjectService {
private final Logger log = LogManager.getLogger(this.getClass());
@SneakyThrows
@Timed
public Project getById(String id) {
var doc = solrRepository.getById(id);
@ -50,7 +48,6 @@ public class ProjectService {
}
@SneakyThrows
@Timed
public SearchResponse<Project> search(ProjectRequest request) {
SolrQueryParams solrQueryParams = projectRequestMapper.toSolrQuery(request);

View File

@ -11,7 +11,6 @@ import eu.openaire.api.mappers.response.ResponseResultsMapper;
import eu.openaire.api.mappers.response.entities.ResearchProductMapper;
import eu.openaire.api.repositories.SolrRepository;
import eu.openaire.api.solr.SolrQueryParams;
import io.micrometer.core.annotation.Timed;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.logging.log4j.LogManager;
@ -38,7 +37,6 @@ public class ResearchProductService {
private final Logger log = LogManager.getLogger(this.getClass());
@SneakyThrows
@Timed
public GraphResult getById(String id) {
var doc = solrRepository.getById(id);
@ -51,7 +49,6 @@ public class ResearchProductService {
}
@SneakyThrows
@Timed
public SearchResponse<GraphResult> search(ResearchProductsRequest request) {
SolrQueryParams solrQueryParams = researchProductsRequestMapper.toSolrQuery(request);

View File

@ -2,16 +2,24 @@ package eu.openaire.api.solr;
import lombok.Data;
import org.apache.solr.client.solrj.SolrQuery;
import java.util.List;
@Data
public class SolrQueryParams {
private String queryString = "*:*";
private List<String> filterQueries;
private String fieldList = "__json";
private Boolean debugQuery = false;
private int start;
private int rows;
private List<SolrQuery.SortClause> sort;
private String cursor;
String queryString = "*:*";
List<String> filterQueries;
String fieldList = "__json";
Boolean debugQuery = false;
int start;
int rows;
List<SolrQuery.SortClause> sort;
}

View File

@ -15,10 +15,8 @@ server.error.include-stacktrace=never
# Enable the health endpoint
management.endpoint.health.enabled=true
# Expose health, info and metrics endpoint
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.prometheus.enabled=true
management.metrics.export.prometheus.enabled=true
# Expose the health endpoint
management.endpoints.web.exposure.include=health,info
# Customize health endpoint settings
management.endpoint.health.show-details=always