partial import of existing modules

This commit is contained in:
Michele Artini 2023-09-14 15:54:09 +02:00
parent 7bfce4fa6d
commit 7ee950801f
189 changed files with 11051 additions and 168 deletions

View File

@ -12,14 +12,13 @@
<packaging>jar</packaging>
<dependencies>
<!-- CSV -->
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.4</version>
</dependency>
<groupId>${project.groupId}</groupId>
<artifactId>dnet-db-common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- hot swapping, disable cache for template, enable live reload -->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -0,0 +1,22 @@
package eu.dnetlib.services.collector.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import eu.dnetlib.base.AbstractDnetController;
import eu.dnetlib.params.ProtocolDesc;
import eu.dnetlib.services.collector.service.ProtocolService;
public class AbstractProtocolController extends AbstractDnetController {
@Autowired
protected ProtocolService protocolService;
@GetMapping("/")
public List<ProtocolDesc> listProtocols() {
return protocolService.listProtocols();
}
}

View File

@ -0,0 +1,29 @@
package eu.dnetlib.services.collector.controller;
import java.util.List;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.params.ProtocolDesc;
@RestController
@RequestMapping("/ajax/protocols")
public class ProtocolAjaxController extends AbstractProtocolController {
@DeleteMapping("/{protocol}")
public List<ProtocolDesc> deleteProtocol(@PathVariable final String protocol) {
protocolService.deleteProtocols(protocol);
return protocolService.listProtocols();
}
@PostMapping("/{protocol}/terms")
public List<ProtocolDesc> saveTerm(@PathVariable final ProtocolDesc protocol) {
protocolService.saveProtocol(protocol);
return protocolService.listProtocols();
}
}

View File

@ -0,0 +1,11 @@
package eu.dnetlib.services.collector.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/protocols")
public class ProtocolApiController extends AbstractProtocolController {
}

View File

@ -9,7 +9,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.collections4.IteratorUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -63,7 +63,6 @@ public class FileSystemIterator implements Iterator<String> {
*
* @return the next element to be returned by next call of this.next()
*/
@SuppressWarnings("unchecked")
private synchronized String walkTillNext() {
while (pathIterator.hasNext()) {
final Path nextFilePath = pathIterator.next();

View File

@ -0,0 +1,14 @@
package eu.dnetlib.services.collector.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import eu.dnetlib.data.model.protocol.ProtocolParam;
import eu.dnetlib.data.model.protocol.ProtocolParamPK;
public interface ProtocolParamRepository extends JpaRepository<ProtocolParam, ProtocolParamPK> {
Iterable<ProtocolParam> findByProtocol(String protocol);
void deleteByProtocol(String protocol);
}

View File

@ -0,0 +1,9 @@
package eu.dnetlib.services.collector.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import eu.dnetlib.data.model.protocol.Protocol;
public interface ProtocolRepository extends JpaRepository<Protocol, String> {
}

View File

@ -0,0 +1,72 @@
package eu.dnetlib.services.collector.service;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import eu.dnetlib.data.model.protocol.Protocol;
import eu.dnetlib.data.model.protocol.ProtocolParam;
import eu.dnetlib.params.ProtocolDesc;
import eu.dnetlib.services.collector.repository.ProtocolParamRepository;
import eu.dnetlib.services.collector.repository.ProtocolRepository;
import jakarta.transaction.Transactional;
@Service
public class ProtocolService {
@Autowired
private ProtocolRepository protocolRepository;
@Autowired
private ProtocolParamRepository protocolParamRepository;
private static final Log log = LogFactory.getLog(ProtocolService.class);
@Transactional
public List<ProtocolDesc> listProtocols() {
final Map<String, List<ProtocolParam>> params = protocolParamRepository.findAll()
.stream()
.collect(Collectors.groupingBy(ProtocolParam::getProtocol));
return protocolRepository.findAll()
.stream()
.map(Protocol::getId)
.map(id -> new ProtocolDesc(id, params.containsKey(id) ? params.get(id) : new ArrayList<>()))
.sorted(Comparator.comparing(ProtocolDesc::getId))
.collect(Collectors.toList());
}
@Transactional
public void deleteProtocols(final String... ids) {
for (final String id : ids) {
protocolRepository.deleteById(id);
}
}
@Transactional
public void saveProtocol(final ProtocolDesc protocol) {
log.info("Saving protocol: " + protocol);
if (protocolRepository.existsById(protocol.getId())) {
protocolParamRepository.deleteByProtocol(protocol.getId());
} else {
protocolRepository.save(new Protocol(protocol.getId()));
}
for (final ProtocolParam p : protocol.getParams()) {
p.setProtocol(protocol.getId());
protocolParamRepository.save(p);
}
}
}

View File

@ -0,0 +1,46 @@
package eu.dnetlib.services.collector.utils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import eu.dnetlib.data.mdstore.model.records.MetadataRecord;
import eu.dnetlib.data.mdstore.model.records.MetadataRecordImpl;
import eu.dnetlib.data.mdstore.model.records.Provenance;
import eu.dnetlib.params.ApiDesc;
public class MetadataBuilder {
private final String xpath;
private final Provenance provenance;
public MetadataBuilder(final ApiDesc api) {
this.xpath = api.getMetadataIdentifierPath();
this.provenance = new Provenance(api.getDatasourceId(), api.getDatasourceName(), api.getNsPrefix());
}
public MetadataRecord mapRecord(final String xml) throws Exception {
try {
final Document doc = DocumentHelper.parseText(xml);
final String origId = doc.valueOf(xpath);
// TODO populate the xml record with missing oaf fields, see:
// https://svn.driver.research-infrastructures.eu/driver/dnet45/modules/dnet-openaireplus-workflows/trunk/src/main/resources/eu/dnetlib/msro/openaireplus/workflows/repo-hi/xslt/openaireMdBuilder.xslt.st
final MetadataRecord md = new MetadataRecordImpl();
md.setId(MetadataRecord.generateIdentifier(origId, provenance.getNsPrefix()));
md.setOriginalId(origId);
md.setBody(doc.asXML());
md.setEncoding("XML");
md.setDateOfCollection(System.currentTimeMillis());
md.setDateOfTransformation(null);
md.setProvenance(provenance);
return md;
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -13,6 +13,12 @@
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>dnet-db-common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- hot swapping, disable cache for template, enable live reload -->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -0,0 +1,119 @@
package eu.dnetlib.services.dsm.controller;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import eu.dnetlib.base.AbstractDnetController;
import eu.dnetlib.errors.DsmException;
import eu.dnetlib.errors.DsmForbiddenException;
import eu.dnetlib.errors.DsmNotFoundException;
import eu.dnetlib.services.dsm.domain.Response;
/**
* Created by claudio on 18/07/2017.
*/
public abstract class AbstractDsmController extends AbstractDnetController {
private static final Log log = LogFactory.getLog(DsmException.class); // NOPMD by marko on 11/24/08 5:02 PM
@ResponseBody
@ExceptionHandler({
DsmException.class
})
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorMessage handleDSMException(final Exception e) {
return _handleError(e);
}
@ResponseBody
@ExceptionHandler(DsmForbiddenException.class)
@ResponseStatus(value = HttpStatus.FORBIDDEN)
public ErrorMessage handleForbiddenException(final Exception e) {
return _handleError(e);
}
@ResponseBody
@ExceptionHandler({
DsmNotFoundException.class
})
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public ErrorMessage handleNotFoundException(final Exception e) {
return _handleError(e);
}
@ResponseBody
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public List<ErrorMessage> processValidationError(final MethodArgumentNotValidException e) {
return e.getBindingResult()
.getFieldErrors()
.stream()
.map(fe -> new ErrorMessage(
String.format("field '%s'", fe.getField()),
String.format("rejected value '%s'", fe.getRejectedValue()),
fe.getDefaultMessage()))
.collect(Collectors.toList());
}
private ErrorMessage _handleError(final Exception e) {
log.error(e);
if (StringUtils.containsIgnoreCase(ExceptionUtils.getRootCauseMessage(e), "Broken pipe")) {
return null; // socket is closed, cannot return any response
} else {
return new ErrorMessage(e);
}
}
// HELPERS
protected <T extends Response> T prepareResponse(final int page, final int size, final StopWatch stopWatch, final T rsp) {
rsp.getHeader()
.setTime(stopWatch.getTime())
.setPage(page)
.setSize(size);
return rsp;
}
@JsonAutoDetect
public class ErrorMessage {
private final String message;
private final String details;
private final String stacktrace;
public ErrorMessage(final Exception e) {
this(e.getMessage(), "", ExceptionUtils.getStackTrace(e));
}
public ErrorMessage(final String message, final String details, final String stacktrace) {
this.message = message;
this.details = details;
this.stacktrace = stacktrace;
}
public String getMessage() {
return this.message;
}
public String getStacktrace() {
return this.stacktrace;
}
public String getDetails() {
return details;
}
}
}

View File

@ -0,0 +1,87 @@
package eu.dnetlib.services.dsm.controller;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.base.AbstractDnetController;
import eu.dnetlib.data.model.dsm.Api;
import eu.dnetlib.data.model.dsm.BrowseTerm;
import eu.dnetlib.data.model.dsm.readonly.SimpleDsWithApis;
import eu.dnetlib.errors.DsmException;
import eu.dnetlib.params.KeyValue;
import eu.dnetlib.services.dsm.service.DsmService;
import eu.dnetlib.services.dsm.utils.CollectorClient;
import eu.dnetlib.services.dsm.utils.DsmBrowsableFields;
import eu.dnetlib.services.dsm.utils.VocabularyClient;
@RestController
@RequestMapping("/ajax/dsm")
public class DsmAjaxController extends AbstractDnetController {
@Autowired
private DsmService dsmService;
@Autowired
private VocabularyClient vocabularyClient;
@Autowired
private CollectorClient collectorClient;
@GetMapping("/browsableFields")
public List<KeyValue<String>> browsableFields() {
return Arrays.stream(DsmBrowsableFields.values())
.map(f -> new KeyValue<>(f.name(), f.desc))
.collect(Collectors.toList());
}
@GetMapping("/conf")
public Map<String, Iterable<?>> configuration() {
final Map<String, Iterable<?>> map = new LinkedHashMap<>();
map.put("protocols", collectorClient.listProtocols());
map.put("compatibilityLevels", vocabularyClient.findTermsByVocabulary("dnet:compatibilityLevel"));
map.put("contentDescTypes", vocabularyClient.findTermsByVocabulary("dnet:content_description_typologies"));
return map;
}
@GetMapping("/browse/{field}")
public List<BrowseTerm> browse(@PathVariable final String field) {
return dsmService.browseTerm(DsmBrowsableFields.valueOf(field));
}
@GetMapping("/searchByField/{field}/{page}/{size}")
public Page<SimpleDsWithApis> searchByField(@PathVariable final String field,
@PathVariable final int page,
@PathVariable final int size,
@RequestParam final String value) {
return dsmService.searchByField(DsmBrowsableFields.valueOf(field), value, page, size);
}
@GetMapping("/search/{page}/{size}")
public Page<SimpleDsWithApis> search(@RequestParam final String value, @PathVariable final int page, @PathVariable final int size) {
return dsmService.search(value, page, size);
}
@GetMapping("/api")
public Api findApi(@RequestParam final String id) throws DsmException {
return dsmService.findApi(id);
}
@PostMapping("/api")
public Api saveApi(@RequestBody final Api api) throws DsmException {
throw new DsmException("TO BE IMPLEMENTED");
}
}

View File

@ -0,0 +1,277 @@
package eu.dnetlib.services.dsm.controller;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.data.model.dsm.Api;
import eu.dnetlib.data.model.dsm.Datasource;
import eu.dnetlib.data.model.dsm.Identity;
import eu.dnetlib.errors.DsmException;
import eu.dnetlib.errors.DsmForbiddenException;
import eu.dnetlib.errors.DsmNotFoundException;
import eu.dnetlib.services.dsm.domain.AggregationHistoryResponse;
import eu.dnetlib.services.dsm.domain.AggregationInfo;
import eu.dnetlib.services.dsm.domain.ApiDetails;
import eu.dnetlib.services.dsm.domain.ApiDetailsResponse;
import eu.dnetlib.services.dsm.domain.Country;
import eu.dnetlib.services.dsm.domain.DatasourceDetailResponse;
import eu.dnetlib.services.dsm.domain.DatasourceDetails;
import eu.dnetlib.services.dsm.domain.DatasourceDetailsUpdate;
import eu.dnetlib.services.dsm.domain.DatasourceDetailsWithApis;
import eu.dnetlib.services.dsm.domain.DatasourceSnippetResponse;
import eu.dnetlib.services.dsm.domain.RegisteredDatasourceInfo;
import eu.dnetlib.services.dsm.domain.RequestFilter;
import eu.dnetlib.services.dsm.domain.RequestSort;
import eu.dnetlib.services.dsm.domain.RequestSortOrder;
import eu.dnetlib.services.dsm.domain.SimpleResponse;
import eu.dnetlib.services.dsm.service.DsmService;
import eu.dnetlib.services.dsm.utils.DsmMappingUtils;
import eu.dnetlib.services.dsm.utils.ResponseUtils;
import eu.dnetlib.services.dsm.utils.WfLoggerClient;
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 jakarta.validation.Valid;
@RestController
@RequestMapping("/api/dsm/1.0")
@ConditionalOnProperty(value = "openaire.api.enable.dsm", havingValue = "true")
@Tag(name = "OpenAIRE DSM API", description = "the OpenAIRE Datasource Manager API")
public class DsmApiControllerV1 extends AbstractDsmController {
private static final Log log = LogFactory.getLog(DsmApiControllerV1.class);
@Autowired
private WfLoggerClient wfLoggerClient;
@Autowired
private DsmService dsmService;
@GetMapping("/ds/countries")
public List<Country> listCountries() throws DsmException {
return dsmService.listCountries();
}
@PostMapping("/ds/searchdetails/{page}/{size}")
public DatasourceDetailResponse searchDsDetails(
@RequestParam final RequestSort requestSortBy,
@RequestParam final RequestSortOrder order,
@RequestBody final RequestFilter requestFilter,
@PathVariable final int page,
@PathVariable final int size) throws DsmException {
final StopWatch stop = StopWatch.createStarted();
final DatasourceDetailResponse rsp = dsmService.searchDetails(requestSortBy, order, requestFilter, page, size);
return prepareResponse(page, size, stop, rsp);
}
@GetMapping("/ds/aggregationhistory/{dsId}")
public AggregationHistoryResponse aggregationHistory(@PathVariable final String dsId) throws DsmException {
final StopWatch stop = StopWatch.createStarted();
final List<AggregationInfo> history = wfLoggerClient.getAggregationHistory(dsId);
final AggregationHistoryResponse rsp = new AggregationHistoryResponse(history);
rsp.setHeader(ResponseUtils.header(history.size()));
return prepareResponse(0, rsp.getAggregationInfo().size(), stop, rsp);
}
@PostMapping("/ds/searchsnippet/{page}/{size}")
public DatasourceSnippetResponse searchSnippet(
@RequestParam final RequestSort requestSortBy,
@RequestParam final RequestSortOrder order,
@RequestBody final RequestFilter requestFilter,
@PathVariable final int page,
@PathVariable final int size) throws DsmException {
final StopWatch stop = StopWatch.createStarted();
final DatasourceSnippetResponse rsp = dsmService.searchSnippet(requestSortBy, order, requestFilter, page, size);
return prepareResponse(page, size, stop, rsp);
}
@PostMapping("/ds/searchregistered/{page}/{size}")
public DatasourceSnippetResponse searchRegistered(
@RequestParam final RequestSort requestSortBy,
@RequestParam final RequestSortOrder order,
@RequestBody final RequestFilter requestFilter,
@PathVariable final int page,
@PathVariable final int size) throws DsmException {
final StopWatch stop = StopWatch.createStarted();
final Page<Datasource> dsPage = dsmService.searchRegistered(requestSortBy, order, requestFilter, page, size);
final DatasourceSnippetResponse rsp =
ResponseUtils.snippetResponse(dsPage.map(DsmMappingUtils::asSnippetExtended).getContent(), dsPage.getTotalElements());
return prepareResponse(page, size, stop, rsp);
}
@GetMapping("/ds/recentregistered/{size}")
public SimpleResponse<RegisteredDatasourceInfo> recentRegistered(@PathVariable final int size) throws Throwable {
final StopWatch stop = StopWatch.createStarted();
final SimpleResponse<RegisteredDatasourceInfo> rsp = dsmService.searchRecentRegistered(size);
return prepareResponse(1, size, stop, rsp);
}
@GetMapping("/ds/countregistered")
public Long countRegistered(@RequestParam final String fromDate,
@RequestParam(required = false) final String typologyFilter) throws Throwable {
return dsmService.countRegisteredAfter(fromDate, typologyFilter);
}
@GetMapping("/ds/api/{dsId}")
public ApiDetailsResponse getApi(
@PathVariable final String dsId) throws DsmException {
final StopWatch stop = StopWatch.createStarted();
final Datasource ds = dsmService.findDs(dsId);
final List<Api> apis = dsmService.findApis(dsId);
final List<ApiDetails> api = apis.stream()
.map(DsmMappingUtils::asDetails)
.map(a -> a.setEoscDatasourceType(ds.getEoscDatasourceType()))
.map(a -> a.setTypology(ds.getTypology()))
.collect(Collectors.toList());
final ApiDetailsResponse rsp = ResponseUtils.apiResponse(api, api.size());
return prepareResponse(0, rsp.getApi().size(), stop, rsp);
}
@PostMapping("/api/baseurl/{page}/{size}")
public List<String> searchBaseUrls(
@RequestBody final RequestFilter requestFilter,
@PathVariable final int page,
@PathVariable final int size) throws DsmException {
return dsmService.findApiBaseURLs(requestFilter, page, size);
}
@DeleteMapping("/ds/api/{apiId}")
public void deleteApi(@PathVariable final String apiId) throws DsmForbiddenException, DsmNotFoundException {
dsmService.deleteApi(null, apiId);
}
@PostMapping("/ds/manage")
public void setManaged(
@RequestParam final String id,
@RequestParam final boolean managed) throws DsmException {
log.info(String.format("updated ds '%s' managed with '%s'", id, managed));
dsmService.setManaged(id, managed);
}
@GetMapping("/ds/managed/{id}")
public boolean isManaged(@PathVariable final String id) throws DsmException {
return dsmService.isManaged(id);
}
@PostMapping("/ds/add")
public void saveDs(@Valid @RequestBody final DatasourceDetails datasource) throws DsmException {
if (dsmService.existDs(datasource.getId())) { // TODO further check that the DS doesn't have any API
throw new DsmException(String.format("cannot register, datasource already defined '%s'", datasource.getId()));
}
dsmService.saveDs(DsmMappingUtils.asDbEntry(datasource));
log.info("DS saved, " + datasource.getId());
}
@PostMapping("/ds/addWithApis")
public void saveDsWithApis(@Valid @RequestBody final DatasourceDetailsWithApis d) throws DsmException {
if (d.getDatasource() == null) { throw new DsmException("Datasource field is null"); }
if (dsmService.existDs(d.getDatasource().getId())) { // TODO further check that the DS doesn't have any API
throw new DsmException(String.format("cannot register, datasource already defined '%s'", d.getDatasource().getId()));
}
dsmService.addDsAndApis(DsmMappingUtils.asDbEntry(d.getDatasource()), d.getApis());
}
@PostMapping("/ds/update")
public void updateDatasource(@RequestBody final DatasourceDetailsUpdate d) throws DsmException, DsmNotFoundException {
// initialize with current values from DB
final Datasource ds = dsmService.findDs(d.getId());
if (ds == null) { throw new DsmNotFoundException(String.format("ds '%s' does not exist", d.getId())); }
final Datasource update = DsmMappingUtils.asDbEntry(d);
if (ds.getIdentities() != null) {
final Set<Identity> identities = new HashSet<>(
Stream.of(update.getIdentities(), ds.getIdentities())
.flatMap(Collection::stream)
.collect(Collectors.toMap(i -> i.getIssuertype() + i.getPid(), Function.identity(), (i1, i2) -> i1))
.values());
DsmMappingUtils.copyNonNullProperties(update, ds);
ds.setIdentities(identities);
} else {
DsmMappingUtils.copyNonNullProperties(update, ds);
}
dsmService.saveDs(ds);
}
@PostMapping("/ds/api/baseurl")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "500", description = "unexpected error")
})
public void updateBaseUrl(
@RequestParam final String dsId,
@RequestParam final String apiId,
@RequestParam final String baseUrl) throws DsmException {
log.info(String.format("updated api '%s' baseurl with '%s'", apiId, baseUrl));
dsmService.updateApiBaseUrl(apiId, baseUrl);
}
@PostMapping("/ds/api/compliance")
public void updateCompliance(
@RequestParam final String dsId,
@RequestParam final String apiId,
@RequestParam final String compliance,
@RequestParam(required = false, defaultValue = "false") final boolean override) throws DsmException {
log.info(String.format("updated api '%s' compliance with '%s'", apiId, compliance));
dsmService.updateCompliance(null, apiId, compliance, override);
}
@PostMapping("/ds/api/oaiset")
public void updateOaiSetl(
@RequestParam final String dsId,
@RequestParam final String apiId,
@RequestParam final String oaiSet) throws DsmException, DsmNotFoundException {
dsmService.upsertApiOaiSet(apiId, oaiSet);
}
@PostMapping("/ds/api/add")
public void addApi(@RequestBody final ApiDetails api) throws DsmException {
if (StringUtils.isBlank(api.getDatasource())) { throw new DsmException("missing datasource id"); }
if (StringUtils.isBlank(api.getId())) {
api.setId(DsmMappingUtils.createId(api));
log.info(String.format("missing api id, created '%s'", api.getId()));
}
dsmService.addApi(DsmMappingUtils.asDbEntry(api));
log.info("API saved, id: " + api.getId());
}
}

View File

@ -0,0 +1,52 @@
package eu.dnetlib.services.dsm.controller;
import java.util.List;
import org.apache.commons.lang3.time.StopWatch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.services.dsm.domain.SimpleDatasourceInfo;
import eu.dnetlib.services.dsm.domain.SimpleResponse;
import eu.dnetlib.services.dsm.service.DsmService;
import eu.dnetlib.services.dsm.utils.ResponseUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@RequestMapping("/api/dsm/2.0")
@ConditionalOnProperty(value = "openaire.api.enable.dsm", havingValue = "true")
@Tag(name = "OpenAIRE DSM API (version 2.0)", description = "the OpenAIRE Datasource Manager API 2.0")
public class DsmApiControllerV2 extends AbstractDsmController {
@Autowired
private DsmService dsmService;
@GetMapping("/recentregistered/{size}")
public SimpleResponse<SimpleDatasourceInfo> recentRegisteredV2(@PathVariable final int size) throws Throwable {
final StopWatch stop = StopWatch.createStarted();
final SimpleResponse<SimpleDatasourceInfo> rsp = dsmService.searchRecentRegisteredV2(size);
return prepareResponse(1, size, stop, rsp);
}
@GetMapping("/countfirstcollect")
public Long countFirstCollectAfter(@RequestParam final String fromDate,
@RequestParam(required = false) final String typologyFilter) throws Throwable {
return dsmService.countFirstCollect(fromDate, typologyFilter);
}
@GetMapping("/firstCollected")
public SimpleResponse<SimpleDatasourceInfo> firstCollectedAfter(@RequestParam final String fromDate,
@RequestParam(required = false) final String typologyFilter) throws Throwable {
final StopWatch stop = StopWatch.createStarted();
final List<SimpleDatasourceInfo> list = dsmService.findFirstCollectedAfter(fromDate, typologyFilter);
final SimpleResponse<SimpleDatasourceInfo> rsp = ResponseUtils.simpleResponse(list);
return prepareResponse(1, list.size(), stop, rsp);
}
}

View File

@ -0,0 +1,24 @@
package eu.dnetlib.services.dsm.domain;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public class AggregationHistoryResponse extends Response {
private List<AggregationInfo> aggregationInfo;
public AggregationHistoryResponse(final List<AggregationInfo> aggregationInfo) {
super();
this.aggregationInfo = aggregationInfo;
}
public List<AggregationInfo> getAggregationInfo() {
return aggregationInfo;
}
public void setAggregationInfo(final List<AggregationInfo> aggregationInfo) {
this.aggregationInfo = aggregationInfo;
}
}

View File

@ -0,0 +1,56 @@
package eu.dnetlib.services.dsm.domain;
public abstract class AggregationInfo {
private int numberOfRecords;
private String date;
private AggregationStage aggregationStage;
private boolean indexedVersion = false;
private boolean completedSuccessfully = true;
public AggregationInfo() {}
public int getNumberOfRecords() {
return numberOfRecords;
}
public void setNumberOfRecords(final int numberOfRecords) {
this.numberOfRecords = numberOfRecords;
}
public String getDate() {
return date;
}
public void setDate(final String date) {
this.date = date;
}
public AggregationStage getAggregationStage() {
return aggregationStage;
}
public void setAggregationStage(final AggregationStage aggregationStage) {
this.aggregationStage = aggregationStage;
}
public boolean isIndexedVersion() {
return indexedVersion;
}
public void setIndexedVersion(final boolean indexedVersion) {
this.indexedVersion = indexedVersion;
}
public boolean isCompletedSuccessfully() {
return completedSuccessfully;
}
public void setCompletedSuccessfully(final boolean completedSuccessfully) {
this.completedSuccessfully = completedSuccessfully;
}
}

View File

@ -0,0 +1,25 @@
package eu.dnetlib.services.dsm.domain;
public enum AggregationStage {
COLLECT,
TRANSFORM;
public static AggregationStage parse(final String s) {
switch (s) {
case "collect":
case "collection":
case "COLLECT":
case "COLLECTION":
return AggregationStage.COLLECT;
case "transform":
case "transformation":
case "TRANSFORM":
case "TRANSFORMATION":
case "transformDatasets":
case "transformPublications":
return AggregationStage.TRANSFORM;
}
throw new IllegalArgumentException("invalid AggregationStage: " + s);
}
}

View File

@ -0,0 +1,210 @@
package eu.dnetlib.services.dsm.domain;
import java.time.LocalDateTime;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@Schema(name = "Api model", description = "provides information about the datasource API")
public class ApiDetails extends ApiIgnoredProperties {
private String id = null;
private String protocol = null;
private String datasource = null;
private String contentdescription = null;
private String eoscDatasourceType = null;
private String compatibility;
private String compatibilityOverride;
private Integer lastCollectionTotal;
private LocalDateTime lastCollectionDate;
private Integer lastAggregationTotal;
private LocalDateTime lastAggregationDate;
private Integer lastDownloadTotal;
private LocalDateTime lastDownloadDate;
private String baseurl;
protected Boolean removable = false;
private Set<ApiParamDetails> apiParams;
private String metadataIdentifierPath = "";
private String typology = null;
public String getId() {
return id;
}
public String getProtocol() {
return protocol;
}
public String getDatasource() {
return datasource;
}
public String getContentdescription() {
return contentdescription;
}
public String getCompatibility() {
return compatibility;
}
public Integer getLastCollectionTotal() {
return lastCollectionTotal;
}
public LocalDateTime getLastCollectionDate() {
return lastCollectionDate;
}
public Integer getLastAggregationTotal() {
return lastAggregationTotal;
}
public LocalDateTime getLastAggregationDate() {
return lastAggregationDate;
}
public Integer getLastDownloadTotal() {
return lastDownloadTotal;
}
public LocalDateTime getLastDownloadDate() {
return lastDownloadDate;
}
public String getBaseurl() {
return baseurl;
}
public ApiDetails setId(final String id) {
this.id = id;
return this;
}
public ApiDetails setProtocol(final String protocol) {
this.protocol = protocol;
return this;
}
public ApiDetails setDatasource(final String datasource) {
this.datasource = datasource;
return this;
}
public ApiDetails setContentdescription(final String contentdescription) {
this.contentdescription = contentdescription;
return this;
}
public ApiDetails setCompatibility(final String compatibility) {
this.compatibility = compatibility;
return this;
}
public ApiDetails setLastCollectionTotal(final Integer lastCollectionTotal) {
this.lastCollectionTotal = lastCollectionTotal;
return this;
}
public ApiDetails setLastCollectionDate(final LocalDateTime lastCollectionDate) {
this.lastCollectionDate = lastCollectionDate;
return this;
}
public ApiDetails setLastAggregationTotal(final Integer lastAggregationTotal) {
this.lastAggregationTotal = lastAggregationTotal;
return this;
}
public ApiDetails setLastAggregationDate(final LocalDateTime lastAggregationDate) {
this.lastAggregationDate = lastAggregationDate;
return this;
}
public ApiDetails setLastDownloadTotal(final Integer lastDownloadTotal) {
this.lastDownloadTotal = lastDownloadTotal;
return this;
}
public ApiDetails setLastDownloadDate(final LocalDateTime lastDownloadDate) {
this.lastDownloadDate = lastDownloadDate;
return this;
}
public ApiDetails setBaseurl(final String baseurl) {
this.baseurl = baseurl;
return this;
}
public Set<ApiParamDetails> getApiParams() {
return apiParams;
}
public void setApiParams(final Set<ApiParamDetails> apiParams) {
this.apiParams = apiParams;
}
public String getCompatibilityOverride() {
return compatibilityOverride;
}
public ApiDetails setCompatibilityOverride(final String compatibilityOverride) {
this.compatibilityOverride = compatibilityOverride;
return this;
}
public Boolean getRemovable() {
return removable;
}
public ApiDetails setRemovable(final Boolean removable) {
this.removable = removable;
return this;
}
public String getMetadataIdentifierPath() {
return metadataIdentifierPath;
}
public ApiDetails setMetadataIdentifierPath(final String metadataIdentifierPath) {
this.metadataIdentifierPath = metadataIdentifierPath;
return this;
}
public String getEoscDatasourceType() {
return eoscDatasourceType;
}
public ApiDetails setEoscDatasourceType(final String eoscDatasourceType) {
this.eoscDatasourceType = eoscDatasourceType;
return this;
}
public String getTypology() {
return typology;
}
public ApiDetails setTypology(final String typology) {
this.typology = typology;
return this;
}
}

View File

@ -0,0 +1,20 @@
package eu.dnetlib.services.dsm.domain;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public class ApiDetailsResponse extends Response {
private List<ApiDetails> api;
public List<ApiDetails> getApi() {
return api;
}
public ApiDetailsResponse setApi(final List<ApiDetails> api) {
this.api = api;
return this;
}
}

View File

@ -0,0 +1,72 @@
package eu.dnetlib.services.dsm.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
public abstract class ApiIgnoredProperties {
@JsonIgnore
protected Boolean active = false;
@JsonIgnore
protected String lastCollectionMdid;
@JsonIgnore
protected String lastAggregationMdid;
@JsonIgnore
protected String lastDownloadObjid;
@JsonIgnore
protected String lastValidationJob;
@JsonIgnore
protected boolean compatibilityOverrided;
public Boolean getActive() {
return active;
}
public void setActive(final Boolean active) {
this.active = active;
}
public String getLastCollectionMdid() {
return lastCollectionMdid;
}
public void setLastCollectionMdid(final String lastCollectionMdid) {
this.lastCollectionMdid = lastCollectionMdid;
}
public String getLastAggregationMdid() {
return lastAggregationMdid;
}
public void setLastAggregationMdid(final String lastAggregationMdid) {
this.lastAggregationMdid = lastAggregationMdid;
}
public String getLastDownloadObjid() {
return lastDownloadObjid;
}
public void setLastDownloadObjid(final String lastDownloadObjid) {
this.lastDownloadObjid = lastDownloadObjid;
}
public String getLastValidationJob() {
return lastValidationJob;
}
public void setLastValidationJob(final String lastValidationJob) {
this.lastValidationJob = lastValidationJob;
}
public boolean isCompatibilityOverrided() {
return compatibilityOverrided;
}
public void setCompatibilityOverrided(final boolean compatibilityOverrided) {
this.compatibilityOverrided = compatibilityOverrided;
}
}

View File

@ -0,0 +1,24 @@
package eu.dnetlib.services.dsm.domain;
public class ApiParamDetails {
protected String param;
protected String value;
public String getParam() {
return param;
}
public void setParam(final String param) {
this.param = param;
}
public String getValue() {
return value;
}
public void setValue(final String value) {
this.value = value;
}
}

View File

@ -0,0 +1,21 @@
package eu.dnetlib.services.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
/**
* Created by claudio on 29/11/2016.
*/
@JsonAutoDetect
public class CollectionInfo extends AggregationInfo {
private CollectionMode collectionMode;
public CollectionMode getCollectionMode() {
return collectionMode;
}
public void setCollectionMode(final CollectionMode collectionMode) {
this.collectionMode = collectionMode;
}
}

View File

@ -0,0 +1,12 @@
package eu.dnetlib.services.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
/**
* Created by claudio on 12/09/16.
*/
@JsonAutoDetect
public enum CollectionMode {
REFRESH,
INCREMENTAL
}

View File

@ -0,0 +1,31 @@
package eu.dnetlib.services.dsm.domain;
public class Country {
private String code;
private String name;
public Country() {}
public Country(final String code, final String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(final String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
}

View File

@ -0,0 +1,24 @@
package eu.dnetlib.services.dsm.domain;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public class DatasourceDetailResponse extends Response {
private List<DatasourceDetails> datasourceInfo;
public DatasourceDetailResponse(final List<DatasourceDetails> datasourceInfo) {
super();
this.datasourceInfo = datasourceInfo;
}
public List<DatasourceDetails> getDatasourceInfo() {
return datasourceInfo;
}
public void setDatasourceInfo(final List<DatasourceDetails> datasourceInfo) {
this.datasourceInfo = datasourceInfo;
}
}

View File

@ -0,0 +1,417 @@
package eu.dnetlib.services.dsm.domain;
import java.time.LocalDate;
import java.util.Set;
import org.springframework.data.annotation.Transient;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
/**
* Created by claudio on 12/09/16.
*/
@JsonAutoDetect
@Schema(name = "Datasource model", description = "provides information about the datasource")
public class DatasourceDetails extends DatasourceIgnoredProperties {
@NotBlank
private String id;
@Transient
private String openaireId;
@NotBlank
private String officialname;
@NotBlank
private String englishname;
private String websiteurl;
private String logourl;
@Email
private String contactemail;
private Double latitude;
private Double longitude;
private String timezone;
@NotBlank
private String namespaceprefix;
private String languages;
private LocalDate dateofvalidation;
@NotBlank
private String eoscDatasourceType;
private LocalDate dateofcollection;
private String platform;
private String activationId;
private String description;
private String issn;
private String eissn;
private String lissn;
@Email
private String registeredby;
private String subjects;
protected String aggregator = "OPENAIRE";
protected String collectedfrom;
private Boolean managed;
private Boolean consentTermsOfUse;
private Boolean fullTextDownload;
private LocalDate consentTermsOfUseDate;
private LocalDate lastConsentTermsOfUseDate;
private Set<OrganizationDetails> organizations;
private Set<IdentitiesDetails> identities;
private String status;
@Deprecated
private String typology;
private LocalDate registrationdate;
public String getId() {
return id;
}
public String getOpenaireId() {
return openaireId;
}
public String getOfficialname() {
return officialname;
}
public String getEnglishname() {
return englishname;
}
public String getWebsiteurl() {
return websiteurl;
}
public String getLogourl() {
return logourl;
}
public String getContactemail() {
return contactemail;
}
public Double getLatitude() {
return latitude;
}
public Double getLongitude() {
return longitude;
}
public String getTimezone() {
return timezone;
}
public String getLanguages() {
return languages;
}
public String getNamespaceprefix() {
return namespaceprefix;
}
public LocalDate getDateofvalidation() {
return dateofvalidation;
}
public String getEoscDatasourceType() {
return eoscDatasourceType;
}
public LocalDate getDateofcollection() {
return dateofcollection;
}
public String getPlatform() {
return platform;
}
public String getActivationId() {
return activationId;
}
public String getDescription() {
return description;
}
public String getIssn() {
return issn;
}
public String getEissn() {
return eissn;
}
public String getLissn() {
return lissn;
}
public String getRegisteredby() {
return registeredby;
}
public String getSubjects() {
return subjects;
}
public String getAggregator() {
return aggregator;
}
public String getCollectedfrom() {
return collectedfrom;
}
public Boolean getManaged() {
return managed;
}
public Boolean getConsentTermsOfUse() {
return consentTermsOfUse;
}
public Boolean getFullTextDownload() {
return fullTextDownload;
}
public Set<OrganizationDetails> getOrganizations() {
return organizations;
}
public Set<IdentitiesDetails> getIdentities() {
return identities;
}
public DatasourceDetails setId(final String id) {
this.id = id;
return this;
}
public DatasourceDetails setOpenaireId(final String openaireId) {
this.openaireId = openaireId;
return this;
}
public DatasourceDetails setOfficialname(final String officialname) {
this.officialname = officialname;
return this;
}
public DatasourceDetails setEnglishname(final String englishname) {
this.englishname = englishname;
return this;
}
public DatasourceDetails setWebsiteurl(final String websiteurl) {
this.websiteurl = websiteurl;
return this;
}
public DatasourceDetails setLogourl(final String logourl) {
this.logourl = logourl;
return this;
}
public DatasourceDetails setContactemail(final String contactemail) {
this.contactemail = contactemail;
return this;
}
public DatasourceDetails setLatitude(final Double latitude) {
this.latitude = latitude;
return this;
}
public DatasourceDetails setLongitude(final Double longitude) {
this.longitude = longitude;
return this;
}
public DatasourceDetails setTimezone(final String timezone) {
this.timezone = timezone;
return this;
}
public DatasourceDetails setLanguages(final String languages) {
this.languages = languages;
return this;
}
public DatasourceDetails setNamespaceprefix(final String namespaceprefix) {
this.namespaceprefix = namespaceprefix;
return this;
}
public DatasourceDetails setDateofvalidation(final LocalDate dateofvalidation) {
this.dateofvalidation = dateofvalidation;
return this;
}
public DatasourceDetails setEoscDatasourceType(final String eoscDatasourceType) {
this.eoscDatasourceType = eoscDatasourceType;
return this;
}
public DatasourceDetails setDateofcollection(final LocalDate dateofcollection) {
this.dateofcollection = dateofcollection;
return this;
}
public DatasourceDetails setPlatform(final String platform) {
this.platform = platform;
return this;
}
public DatasourceDetails setActivationId(final String activationId) {
this.activationId = activationId;
return this;
}
public DatasourceDetails setDescription(final String description) {
this.description = description;
return this;
}
public DatasourceDetails setIssn(final String issn) {
this.issn = issn;
return this;
}
public DatasourceDetails setEissn(final String eissn) {
this.eissn = eissn;
return this;
}
public DatasourceDetails setLissn(final String lissn) {
this.lissn = lissn;
return this;
}
public DatasourceDetails setRegisteredby(final String registeredby) {
this.registeredby = registeredby;
return this;
}
public DatasourceDetails setSubjects(final String subjects) {
this.subjects = subjects;
return this;
}
public DatasourceDetails setAggregator(final String aggregator) {
this.aggregator = aggregator;
return this;
}
public DatasourceDetails setCollectedfrom(final String collectedfrom) {
this.collectedfrom = collectedfrom;
return this;
}
public DatasourceDetails setManaged(final Boolean managed) {
this.managed = managed;
return this;
}
public DatasourceDetails setOrganizations(final Set<OrganizationDetails> organizations) {
this.organizations = organizations;
return this;
}
public DatasourceDetails setIdentities(final Set<IdentitiesDetails> identities) {
this.identities = identities;
return this;
}
public DatasourceDetails setConsentTermsOfUse(final Boolean consentTermsOfUse) {
this.consentTermsOfUse = consentTermsOfUse;
return this;
}
public DatasourceDetails setFullTextDownload(final Boolean fullTextDownload) {
this.fullTextDownload = fullTextDownload;
return this;
}
public LocalDate getConsentTermsOfUseDate() {
return consentTermsOfUseDate;
}
public DatasourceDetails setConsentTermsOfUseDate(final LocalDate consentTermsOfUseDate) {
this.consentTermsOfUseDate = consentTermsOfUseDate;
return this;
}
public String getStatus() {
return status;
}
public DatasourceDetails setStatus(final String status) {
this.status = status;
return this;
}
@Deprecated
public String getTypology() {
return typology;
}
@Deprecated
public DatasourceDetails setTypology(final String typology) {
this.typology = typology;
return this;
}
public LocalDate getLastConsentTermsOfUseDate() {
return lastConsentTermsOfUseDate;
}
public DatasourceDetails setLastConsentTermsOfUseDate(final LocalDate lastConsentTermsOfUseDate) {
this.lastConsentTermsOfUseDate = lastConsentTermsOfUseDate;
return this;
}
public LocalDate getRegistrationdate() {
return registrationdate;
}
public DatasourceDetails setRegistrationdate(final LocalDate registrationdate) {
this.registrationdate = registrationdate;
return this;
}
}

View File

@ -0,0 +1,247 @@
package eu.dnetlib.services.dsm.domain;
import java.time.LocalDate;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
/**
* Created by claudio on 12/09/16.
*/
@JsonAutoDetect
@Schema(name = "Datasource updatable fields model", description = "provides information about the datasource field that can be updated")
public class DatasourceDetailsUpdate {
@NotBlank
private String id;
@NotBlank
private String officialname;
@NotBlank
private String englishname;
private String websiteurl;
private String logourl;
@Email
private String contactemail;
private Double latitude;
private Double longitude;
private String timezone;
@Deprecated
private String typology;
private String eoscDatasourceType;
private String platform;
private String description;
@Email
private String registeredby;
private Boolean managed;
private Set<IdentitiesDetails> identities;
private Boolean consentTermsOfUse;
private LocalDate consentTermsOfUseDate;
private LocalDate lastConsentTermsOfUseDate;
private Boolean fullTextDownload;
public String getId() {
return id;
}
public String getOfficialname() {
return officialname;
}
public String getEnglishname() {
return englishname;
}
public String getWebsiteurl() {
return websiteurl;
}
public String getLogourl() {
return logourl;
}
public String getContactemail() {
return contactemail;
}
public Double getLatitude() {
return latitude;
}
public Double getLongitude() {
return longitude;
}
public String getTimezone() {
return timezone;
}
public String getEoscDatasourceType() {
return eoscDatasourceType;
}
public String getPlatform() {
return platform;
}
public String getDescription() {
return description;
}
public String getRegisteredby() {
return registeredby;
}
public Boolean getManaged() {
return managed;
}
public Set<IdentitiesDetails> getIdentities() {
return identities;
}
public DatasourceDetailsUpdate setId(final String id) {
this.id = id;
return this;
}
public DatasourceDetailsUpdate setOfficialname(final String officialname) {
this.officialname = officialname;
return this;
}
public DatasourceDetailsUpdate setEnglishname(final String englishname) {
this.englishname = englishname;
return this;
}
public DatasourceDetailsUpdate setWebsiteurl(final String websiteurl) {
this.websiteurl = websiteurl;
return this;
}
public DatasourceDetailsUpdate setLogourl(final String logourl) {
this.logourl = logourl;
return this;
}
public DatasourceDetailsUpdate setContactemail(final String contactemail) {
this.contactemail = contactemail;
return this;
}
public DatasourceDetailsUpdate setLatitude(final Double latitude) {
this.latitude = latitude;
return this;
}
public DatasourceDetailsUpdate setLongitude(final Double longitude) {
this.longitude = longitude;
return this;
}
public DatasourceDetailsUpdate setTimezone(final String timezone) {
this.timezone = timezone;
return this;
}
public DatasourceDetailsUpdate setEoscDatasourceType(final String eoscDatasourceType) {
this.eoscDatasourceType = eoscDatasourceType;
return this;
}
public DatasourceDetailsUpdate setPlatform(final String platform) {
this.platform = platform;
return this;
}
public DatasourceDetailsUpdate setDescription(final String description) {
this.description = description;
return this;
}
public DatasourceDetailsUpdate setRegisteredby(final String registeredby) {
this.registeredby = registeredby;
return this;
}
public DatasourceDetailsUpdate setManaged(final Boolean managed) {
this.managed = managed;
return this;
}
public DatasourceDetailsUpdate setIdentities(final Set<IdentitiesDetails> identities) {
this.identities = identities;
return this;
}
public Boolean getConsentTermsOfUse() {
return consentTermsOfUse;
}
public DatasourceDetailsUpdate setConsentTermsOfUse(final Boolean consentTermsOfUse) {
this.consentTermsOfUse = consentTermsOfUse;
return this;
}
public LocalDate getConsentTermsOfUseDate() {
return consentTermsOfUseDate;
}
public DatasourceDetailsUpdate setConsentTermsOfUseDate(final LocalDate consentTermsOfUseDate) {
this.consentTermsOfUseDate = consentTermsOfUseDate;
return this;
}
public Boolean getFullTextDownload() {
return fullTextDownload;
}
public DatasourceDetailsUpdate setFullTextDownload(final Boolean fullTextDownload) {
this.fullTextDownload = fullTextDownload;
return this;
}
public LocalDate getLastConsentTermsOfUseDate() {
return lastConsentTermsOfUseDate;
}
public DatasourceDetailsUpdate setLastConsentTermsOfUseDate(final LocalDate lastConsentTermsOfUseDate) {
this.lastConsentTermsOfUseDate = lastConsentTermsOfUseDate;
return this;
}
@Deprecated
public String getTypology() {
return typology;
}
@Deprecated
public DatasourceDetailsUpdate setTypology(final String typology) {
this.typology = typology;
return this;
}
}

View File

@ -0,0 +1,37 @@
package eu.dnetlib.services.dsm.domain;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* Created by claudio on 12/09/16.
*/
@JsonAutoDetect
@Schema(name = "Datasource model with apis", description = "provides information about the datasource and its apis")
public class DatasourceDetailsWithApis {
private DatasourceDetails datasource;
private List<ApiDetails> apis = new ArrayList<>();
public DatasourceDetails getDatasource() {
return datasource;
}
public void setDatasource(final DatasourceDetails datasource) {
this.datasource = datasource;
}
public List<ApiDetails> getApis() {
return apis;
}
public void setApis(final List<ApiDetails> apis) {
this.apis = apis;
}
}

View File

@ -0,0 +1,207 @@
package eu.dnetlib.services.dsm.domain;
import java.time.LocalDate;
import com.fasterxml.jackson.annotation.JsonIgnore;
public abstract class DatasourceIgnoredProperties {
@JsonIgnore
protected String od_contenttypes;
@JsonIgnore
protected String provenanceaction;
@JsonIgnore
protected LocalDate releasestartdate;
@JsonIgnore
protected LocalDate releaseenddate;
@JsonIgnore
protected String missionstatementurl;
@JsonIgnore
protected Boolean dataprovider;
@JsonIgnore
protected Boolean serviceprovider;
@JsonIgnore
protected String databaseaccesstype;
@JsonIgnore
protected String datauploadtype;
@JsonIgnore
protected String databaseaccessrestriction;
@JsonIgnore
protected String datauploadrestriction;
@JsonIgnore
protected Boolean versioning;
@JsonIgnore
protected String citationguidelineurl;
@JsonIgnore
protected String qualitymanagementkind;
@JsonIgnore
protected String pidsystems;
@JsonIgnore
protected String certificates;
@JsonIgnore
protected String eoscType;
@JsonIgnore
protected Boolean dedupMainService;
public String getOd_contenttypes() {
return od_contenttypes;
}
public void setOd_contenttypes(final String od_contenttypes) {
this.od_contenttypes = od_contenttypes;
}
public String getProvenanceaction() {
return provenanceaction;
}
public void setProvenanceaction(final String provenanceaction) {
this.provenanceaction = provenanceaction;
}
public LocalDate getReleasestartdate() {
return releasestartdate;
}
public void setReleasestartdate(final LocalDate releasestartdate) {
this.releasestartdate = releasestartdate;
}
public LocalDate getReleaseenddate() {
return releaseenddate;
}
public void setReleaseenddate(final LocalDate releaseenddate) {
this.releaseenddate = releaseenddate;
}
public String getMissionstatementurl() {
return missionstatementurl;
}
public void setMissionstatementurl(final String missionstatementurl) {
this.missionstatementurl = missionstatementurl;
}
public Boolean getDataprovider() {
return dataprovider;
}
public void setDataprovider(final Boolean dataprovider) {
this.dataprovider = dataprovider;
}
public Boolean getServiceprovider() {
return serviceprovider;
}
public void setServiceprovider(final Boolean serviceprovider) {
this.serviceprovider = serviceprovider;
}
public String getDatabaseaccesstype() {
return databaseaccesstype;
}
public void setDatabaseaccesstype(final String databaseaccesstype) {
this.databaseaccesstype = databaseaccesstype;
}
public String getDatauploadtype() {
return datauploadtype;
}
public void setDatauploadtype(final String datauploadtype) {
this.datauploadtype = datauploadtype;
}
public String getDatabaseaccessrestriction() {
return databaseaccessrestriction;
}
public void setDatabaseaccessrestriction(final String databaseaccessrestriction) {
this.databaseaccessrestriction = databaseaccessrestriction;
}
public String getDatauploadrestriction() {
return datauploadrestriction;
}
public void setDatauploadrestriction(final String datauploadrestriction) {
this.datauploadrestriction = datauploadrestriction;
}
public Boolean getVersioning() {
return versioning;
}
public void setVersioning(final Boolean versioning) {
this.versioning = versioning;
}
public String getCitationguidelineurl() {
return citationguidelineurl;
}
public void setCitationguidelineurl(final String citationguidelineurl) {
this.citationguidelineurl = citationguidelineurl;
}
public String getQualitymanagementkind() {
return qualitymanagementkind;
}
public void setQualitymanagementkind(final String qualitymanagementkind) {
this.qualitymanagementkind = qualitymanagementkind;
}
public String getPidsystems() {
return pidsystems;
}
public void setPidsystems(final String pidsystems) {
this.pidsystems = pidsystems;
}
public String getCertificates() {
return certificates;
}
public void setCertificates(final String certificates) {
this.certificates = certificates;
}
public String getEoscType() {
return eoscType;
}
public void setEoscType(final String eoscType) {
this.eoscType = eoscType;
}
public Boolean getDedupMainService() {
return dedupMainService;
}
public void setDedupMainService(final Boolean dedupMainService) {
this.dedupMainService = dedupMainService;
}
}

View File

@ -0,0 +1,114 @@
package eu.dnetlib.services.dsm.domain;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@Schema(name = "Datasource info model", description = "provides information about the datasource and its aggregation status")
public class DatasourceInfo {
private long indexRecords;
private long fundedContent;
private long fulltexts;
private String lastIndexingDate;
private String firstHarvestDate;
private DatasourceDetails datasource;
private AggregationInfo lastCollection;
private AggregationInfo lastTransformation;
private List<AggregationInfo> aggregationHistory;
public DatasourceInfo() {
super();
}
public DatasourceInfo setIndexRecords(final long indexRecords) {
this.indexRecords = indexRecords;
return this;
}
public DatasourceInfo setFundedContent(final long fundedContent) {
this.fundedContent = fundedContent;
return this;
}
public DatasourceInfo setFulltexts(final long fulltexts) {
this.fulltexts = fulltexts;
return this;
}
public DatasourceInfo setLastIndexingDate(final String lastIndexingDate) {
this.lastIndexingDate = lastIndexingDate;
return this;
}
public DatasourceInfo setAggregationHistory(final List<AggregationInfo> aggregationHistory) {
this.aggregationHistory = aggregationHistory;
return this;
}
public DatasourceInfo setLastCollection(final AggregationInfo lastCollection) {
this.lastCollection = lastCollection;
return this;
}
public DatasourceInfo setLastTransformation(final AggregationInfo lastTransformation) {
this.lastTransformation = lastTransformation;
return this;
}
public long getIndexRecords() {
return indexRecords;
}
public long getFundedContent() {
return fundedContent;
}
public long getFulltexts() {
return fulltexts;
}
public String getLastIndexingDate() {
return lastIndexingDate;
}
public List<AggregationInfo> getAggregationHistory() {
return aggregationHistory;
}
public AggregationInfo getLastCollection() {
return lastCollection;
}
public AggregationInfo getLastTransformation() {
return lastTransformation;
}
public DatasourceDetails getDatasource() {
return datasource;
}
public DatasourceInfo setDatasource(final DatasourceDetails datasource) {
this.datasource = datasource;
return this;
}
public String getFirstHarvestDate() {
return firstHarvestDate;
}
public void setFirstHarvestDate(final String firstHarvestDate) {
this.firstHarvestDate = firstHarvestDate;
}
}

View File

@ -0,0 +1,27 @@
package eu.dnetlib.services.dsm.domain;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public class DatasourceResponse<T> extends Response {
private List<T> datasourceInfo = new ArrayList<>();
public DatasourceResponse<T> addDatasourceInfo(final T datasourceInfo) {
getDatasourceInfo().add(datasourceInfo);
return this;
}
public List<T> getDatasourceInfo() {
return datasourceInfo;
}
public DatasourceResponse<T> setDatasourceInfo(final List<T> datasourceInfo) {
this.datasourceInfo = datasourceInfo;
return this;
}
}

View File

@ -0,0 +1,24 @@
package eu.dnetlib.services.dsm.domain;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public class DatasourceSearchResponse extends Response {
private List<DatasourceInfo> datasourceInfo;
public DatasourceSearchResponse(final List<DatasourceInfo> datasourceInfo) {
super();
this.datasourceInfo = datasourceInfo;
}
public List<DatasourceInfo> getDatasourceInfo() {
return datasourceInfo;
}
public void setDatasourceInfo(final List<DatasourceInfo> datasourceInfo) {
this.datasourceInfo = datasourceInfo;
}
}

View File

@ -0,0 +1,45 @@
package eu.dnetlib.services.dsm.domain;
import jakarta.validation.constraints.NotBlank;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@Schema(name = "Datasource model", description = "provides information about the datasource")
public class DatasourceSnippet {
@NotBlank
private String id;
@NotBlank
private String officialname;
@NotBlank
private String englishname;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getOfficialname() {
return officialname;
}
public void setOfficialname(final String officialname) {
this.officialname = officialname;
}
public String getEnglishname() {
return englishname;
}
public void setEnglishname(final String englishname) {
this.englishname = englishname;
}
}

View File

@ -0,0 +1,182 @@
package eu.dnetlib.services.dsm.domain;
import java.time.LocalDateTime;
import java.util.Set;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@Schema(name = "Datasource model", description = "provides extended information about the datasource")
public class DatasourceSnippetExtended {
@NotBlank
private String id;
@NotBlank
private String officialname;
@NotBlank
private String englishname;
private String websiteurl;
@Email
private String registeredby;
private LocalDateTime registrationdate;
private String eoscDatasourceType;
private String logoUrl;
private String description;
private Boolean consentTermsOfUse;
private LocalDateTime consentTermsOfUseDate;
private LocalDateTime lastConsentTermsOfUseDate;
private Boolean fullTextDownload;
private Set<OrganizationDetails> organizations;
@Deprecated
private String typology;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getOfficialname() {
return officialname;
}
public void setOfficialname(final String officialname) {
this.officialname = officialname;
}
public String getEnglishname() {
return englishname;
}
public void setEnglishname(final String englishname) {
this.englishname = englishname;
}
public String getWebsiteurl() {
return websiteurl;
}
public void setWebsiteurl(final String websiteurl) {
this.websiteurl = websiteurl;
}
public String getRegisteredby() {
return registeredby;
}
public void setRegisteredby(final String registeredby) {
this.registeredby = registeredby;
}
public LocalDateTime getRegistrationdate() {
return registrationdate;
}
public void setRegistrationdate(final LocalDateTime registrationdate) {
this.registrationdate = registrationdate;
}
public String getEoscDatasourceType() {
return eoscDatasourceType;
}
public void setEoscDatasourceType(final String eoscDatasourceType) {
this.eoscDatasourceType = eoscDatasourceType;
}
public String getLogoUrl() {
return logoUrl;
}
public Boolean getConsentTermsOfUse() {
return consentTermsOfUse;
}
public DatasourceSnippetExtended setConsentTermsOfUse(final Boolean consentTermsOfUse) {
this.consentTermsOfUse = consentTermsOfUse;
return this;
}
public LocalDateTime getConsentTermsOfUseDate() {
return consentTermsOfUseDate;
}
public DatasourceSnippetExtended setConsentTermsOfUseDate(final LocalDateTime consentTermsOfUseDate) {
this.consentTermsOfUseDate = consentTermsOfUseDate;
return this;
}
public Boolean getFullTextDownload() {
return fullTextDownload;
}
public DatasourceSnippetExtended setFullTextDownload(final Boolean fullTextDownload) {
this.fullTextDownload = fullTextDownload;
return this;
}
public DatasourceSnippetExtended setLogoUrl(final String logoUrl) {
this.logoUrl = logoUrl;
return this;
}
public String getDescription() {
return description;
}
public DatasourceSnippetExtended setDescription(final String description) {
this.description = description;
return this;
}
public Set<OrganizationDetails> getOrganizations() {
return organizations;
}
public DatasourceSnippetExtended setOrganizations(final Set<OrganizationDetails> organizations) {
this.organizations = organizations;
return this;
}
@Deprecated
public String getTypology() {
return typology;
}
@Deprecated
public DatasourceSnippetExtended setTypology(final String typology) {
this.typology = typology;
return this;
}
public LocalDateTime getLastConsentTermsOfUseDate() {
return lastConsentTermsOfUseDate;
}
public DatasourceSnippetExtended setLastConsentTermsOfUseDate(final LocalDateTime lastConsentTermsOfUseDate) {
this.lastConsentTermsOfUseDate = lastConsentTermsOfUseDate;
return this;
}
}

View File

@ -0,0 +1,24 @@
package eu.dnetlib.services.dsm.domain;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public class DatasourceSnippetResponse extends Response {
private List<DatasourceSnippetExtended> datasourceInfo;
public DatasourceSnippetResponse(final List<DatasourceSnippetExtended> datasourceInfo) {
super();
this.datasourceInfo = datasourceInfo;
}
public List<DatasourceSnippetExtended> getDatasourceInfo() {
return datasourceInfo;
}
public void setDatasourceInfo(final List<DatasourceSnippetExtended> datasourceInfo) {
this.datasourceInfo = datasourceInfo;
}
}

View File

@ -0,0 +1,47 @@
package eu.dnetlib.services.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@Schema(name = "Filter name", description = "List of the field names used to filter datasources")
public enum FilterName {
id,
managed,
collectedfrom, // exact match
officialname,
englishname,
websiteurl,
contactemail,
registeredby,
typology,
eoscDatasourceType,
platform, // like match
country; // exact match on related organization
public static FilterType type(final FilterName filterName) {
switch (filterName) {
case id:
case managed:
case collectedfrom:
return FilterType.exact;
case officialname:
case englishname:
case websiteurl:
case contactemail:
case registeredby:
case typology:
case platform:
return FilterType.search;
case eoscDatasourceType:
return FilterType.multiSearch;
case country:
return FilterType.searchOrgs;
default:
throw new IllegalStateException("unmapped filter type for: " + filterName);
}
}
}

View File

@ -0,0 +1,8 @@
package eu.dnetlib.services.dsm.domain;
public enum FilterType {
exact,
search,
searchOrgs,
multiSearch
}

View File

@ -0,0 +1,111 @@
package eu.dnetlib.services.dsm.domain;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@JsonAutoDetect
public class Header {
private long total;
private int page;
private int size;
private long time;
private int statusCode;
private List<String> errors = new ArrayList<>();
@JsonIgnore
private Queue<Throwable> exceptions = new LinkedList<>();
public static Header newInsance() {
return new Header();
}
public Header() {}
public long getTime() {
return time;
}
public Header setTime(final long time) {
this.time = time;
return this;
}
public int getStatusCode() {
return statusCode;
}
public Header setStatusCode(final int statusCode) {
this.statusCode = statusCode;
return this;
}
public long getTotal() {
return total;
}
public int getPage() {
return page;
}
public int getSize() {
return size;
}
public Header setPage(final int page) {
this.page = page;
return this;
}
public Header setSize(final int size) {
this.size = size;
return this;
}
public Header setTotal(final long total) {
this.total = total;
return this;
}
public Queue<Throwable> getExceptions() {
return exceptions;
}
public Header setExceptions(final Queue<Throwable> exceptions) {
this.exceptions = exceptions;
return this;
}
public List<String> getErrors() {
return getExceptions().stream()
.map(Throwable::getMessage)
.collect(Collectors.toList());
}
public Header setErrors(final List<String> errors) {
this.errors = errors;
return this;
}
public String toJson() {
try {
return new ObjectMapper().writeValueAsString(this);
} catch (final JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,30 @@
package eu.dnetlib.services.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public class IdentitiesDetails {
private String pid;
private String issuertype;
public String getPid() {
return pid;
}
public String getIssuertype() {
return issuertype;
}
public IdentitiesDetails setPid(final String pid) {
this.pid = pid;
return this;
}
public IdentitiesDetails setIssuertype(final String issuertype) {
this.issuertype = issuertype;
return this;
}
}

View File

@ -0,0 +1,70 @@
package eu.dnetlib.services.dsm.domain;
import jakarta.validation.constraints.NotBlank;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@Schema(name = "Organization info model", description = "provides information about the organization")
public class OrganizationDetails extends OrganizationIgnoredProperties {
private String legalshortname;
@NotBlank
private String legalname;
private String websiteurl;
private String logourl;
@NotBlank
private String country;
public String getLegalshortname() {
return legalshortname;
}
public String getLegalname() {
return legalname;
}
public String getWebsiteurl() {
return websiteurl;
}
public String getLogourl() {
return logourl;
}
public String getCountry() {
return country;
}
public OrganizationDetails setLegalshortname(final String legalshortname) {
this.legalshortname = legalshortname;
return this;
}
public OrganizationDetails setLegalname(final String legalname) {
this.legalname = legalname;
return this;
}
public OrganizationDetails setWebsiteurl(final String websiteurl) {
this.websiteurl = websiteurl;
return this;
}
public OrganizationDetails setLogourl(final String logourl) {
this.logourl = logourl;
return this;
}
public OrganizationDetails setCountry(final String country) {
this.country = country;
return this;
}
}

View File

@ -0,0 +1,64 @@
package eu.dnetlib.services.dsm.domain;
import java.time.LocalDateTime;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class OrganizationIgnoredProperties {
@JsonIgnore
protected String id;
@JsonIgnore
protected String collectedfrom;
@JsonIgnore
protected LocalDateTime dateofcollection;
@JsonIgnore
protected String provenanceaction;
@JsonIgnore
protected Set<?> datasources;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getCollectedfrom() {
return collectedfrom;
}
public void setCollectedfrom(final String collectedfrom) {
this.collectedfrom = collectedfrom;
}
public LocalDateTime getDateofcollection() {
return dateofcollection;
}
public void setDateofcollection(final LocalDateTime dateofcollection) {
this.dateofcollection = dateofcollection;
}
public String getProvenanceaction() {
return provenanceaction;
}
public void setProvenanceaction(final String provenanceaction) {
this.provenanceaction = provenanceaction;
}
public Set<?> getDatasources() {
return datasources;
}
public void setDatasources(final Set<?> datasources) {
this.datasources = datasources;
}
}

View File

@ -0,0 +1,96 @@
package eu.dnetlib.services.dsm.domain;
public class RegisteredDatasourceInfo {
private String id;
private String officialName;
private String englishName;
private String organization;
private String eoscDatasourceType;
private String registeredBy;
private String registrationDate;
private String compatibility;
private String lastCollectionDate;
private long lastCollectionTotal;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getOfficialName() {
return officialName;
}
public void setOfficialName(final String officialName) {
this.officialName = officialName;
}
public String getEnglishName() {
return englishName;
}
public void setEnglishName(final String englishName) {
this.englishName = englishName;
}
public String getOrganization() {
return organization;
}
public void setOrganization(final String organization) {
this.organization = organization;
}
public String getEoscDatasourceType() {
return eoscDatasourceType;
}
public void setEoscDatasourceType(final String eoscDatasourceType) {
this.eoscDatasourceType = eoscDatasourceType;
}
public String getRegisteredBy() {
return registeredBy;
}
public void setRegisteredBy(final String registeredBy) {
this.registeredBy = registeredBy;
}
public String getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(final String registrationDate) {
this.registrationDate = registrationDate;
}
public String getCompatibility() {
return compatibility;
}
public void setCompatibility(final String compatibility) {
this.compatibility = compatibility;
}
public String getLastCollectionDate() {
return lastCollectionDate;
}
public void setLastCollectionDate(final String lastCollectionDate) {
this.lastCollectionDate = lastCollectionDate;
}
public long getLastCollectionTotal() {
return lastCollectionTotal;
}
public void setLastCollectionTotal(final long lastCollectionTotal) {
this.lastCollectionTotal = lastCollectionTotal;
}
}

View File

@ -0,0 +1,20 @@
package eu.dnetlib.services.dsm.domain;
import java.util.HashMap;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@Schema(name = "Request filter", description = "field name and value pairs")
public class RequestFilter extends HashMap<FilterName, Object> {
/**
*
*/
private static final long serialVersionUID = 5501969842482508379L;
public RequestFilter() {}
}

View File

@ -0,0 +1,8 @@
package eu.dnetlib.services.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public enum RequestSort {
id, officialname, dateofvalidation, registrationdate
}

View File

@ -0,0 +1,8 @@
package eu.dnetlib.services.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public enum RequestSortOrder {
ASCENDING, DESCENDING
}

View File

@ -0,0 +1,26 @@
package eu.dnetlib.services.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import io.swagger.v3.oas.annotations.media.Schema;
@JsonAutoDetect
@Schema(name = "Api response model", description = "Api response model, provides a response header")
public class Response {
private Header header;
public Response() {
this.header = new Header();
}
public Header getHeader() {
return header;
}
public Response setHeader(final Header header) {
this.header = header;
return this;
}
}

View File

@ -0,0 +1,129 @@
package eu.dnetlib.services.dsm.domain;
import java.util.LinkedHashMap;
import java.util.Map;
public class SimpleDatasourceInfo {
private String id;
private String officialName;
private String englishName;
private Map<String, String> organizations = new LinkedHashMap<>();
@Deprecated
private String typology;
private String eoscType;
private String eoscDatasourceType;
private String registeredBy;
private String registrationDate;
private String compatibility;
private String firstCollectionDate;
private String lastCollectionDate;
private long lastCollectionTotal;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getOfficialName() {
return officialName;
}
public void setOfficialName(final String officialName) {
this.officialName = officialName;
}
public String getEnglishName() {
return englishName;
}
public void setEnglishName(final String englishName) {
this.englishName = englishName;
}
public Map<String, String> getOrganizations() {
return organizations;
}
public void setOrganizations(final Map<String, String> organizations) {
this.organizations = organizations;
}
@Deprecated
public String getTypology() {
return typology;
}
@Deprecated
public void setTypology(final String typology) {
this.typology = typology;
}
public String getEoscType() {
return eoscType;
}
public void setEoscType(final String eoscType) {
this.eoscType = eoscType;
}
public String getEoscDatasourceType() {
return eoscDatasourceType;
}
public void setEoscDatasourceType(final String eoscDatasourceType) {
this.eoscDatasourceType = eoscDatasourceType;
}
public String getRegisteredBy() {
return registeredBy;
}
public void setRegisteredBy(final String registeredBy) {
this.registeredBy = registeredBy;
}
public String getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(final String registrationDate) {
this.registrationDate = registrationDate;
}
public String getCompatibility() {
return compatibility;
}
public void setCompatibility(final String compatibility) {
this.compatibility = compatibility;
}
public String getFirstCollectionDate() {
return firstCollectionDate;
}
public void setFirstCollectionDate(final String firstCollectionDate) {
this.firstCollectionDate = firstCollectionDate;
}
public String getLastCollectionDate() {
return lastCollectionDate;
}
public void setLastCollectionDate(final String lastCollectionDate) {
this.lastCollectionDate = lastCollectionDate;
}
public long getLastCollectionTotal() {
return lastCollectionTotal;
}
public void setLastCollectionTotal(final long lastCollectionTotal) {
this.lastCollectionTotal = lastCollectionTotal;
}
}

View File

@ -0,0 +1,20 @@
package eu.dnetlib.services.dsm.domain;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect
public class SimpleResponse<T> extends Response {
private List<T> response;
public List<T> getResponse() {
return response;
}
public SimpleResponse<T> setResponse(final List<T> response) {
this.response = response;
return this;
}
}

View File

@ -0,0 +1,11 @@
package eu.dnetlib.services.dsm.domain;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
/**
* Created by claudio on 29/11/2016.
*/
@JsonAutoDetect
public class TransformationInfo extends AggregationInfo {
}

View File

@ -0,0 +1,72 @@
package eu.dnetlib.services.dsm.repository;
import java.sql.Timestamp;
import java.util.List;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import eu.dnetlib.data.model.dsm.Api;
import jakarta.transaction.Transactional;
@Repository
@ConditionalOnProperty(value = "openaire.api.enable.dsm", havingValue = "true")
public interface ApiRepository extends JpaRepository<Api, String> {
@Query("select a from #{#entityName} a where a.datasource = ?1")
List<Api> findByDatasource(String dsId);
@Modifying
@Transactional
@Query("update #{#entityName} a set a.baseurl = ?2 where a.id = ?1")
void setBaseurl(String id, String baseurl);
@Modifying
@Transactional
@Query("update #{#entityName} a set a.compatibility = ?2 where a.id = ?1")
void updateCompatibility(String apiId, String compatibility);
@Modifying
@Transactional
@Query("update #{#entityName} a set a.compatibilityOverride = ?2 where a.id = ?1")
void updateCompatibilityOverride(String apiId, String compatibility);
@Modifying
@Transactional
@Query(value = "update dsm_apiparams ap set value = ?2 where ap.param = 'set' and ap.api = ?1", nativeQuery = true)
void updateOaiSet(String apiId, String oaiSet);
@Modifying
@Transactional
@Query(value = "insert into dsm_apiparams(api, param, value, _dnet_resource_identifier_) values (?1, ?2, ?3, ?1||'@@'||?2)", nativeQuery = true)
void addApiParam(String apiId, String param, String value);
@Modifying
@Transactional
@Query("update #{#entityName} d set d.removable = ?2 where d.datasource = ?1")
void setAllApiRemovableForDs(String id, boolean removable);
@Modifying
@Transactional
@Query("update #{#entityName} set lastCollectionMdid = ?2, lastCollectionDate = ?3, lastCollectionTotal = ?4 where id = ?1")
void updateLastCollectionInfo(String apiId, String mdId, Timestamp date, long total);
@Modifying
@Transactional
@Query("update #{#entityName} set lastAggregationMdid = ?2, lastAggregationDate = ?3, lastAggregationTotal = ?4 where id = ?1")
void updateLastAggregationInfo(String apiId, String mdId, Timestamp date, long total);
@Modifying
@Transactional
@Query("update #{#entityName} set lastDownloadMdid = ?2, lastDownloadDate = ?3, lastDownloadTotal = ?4 where id = ?1")
void updateLastDownloadInfo(String apiId, String mdId, Timestamp date, long total);
@Modifying
@Transactional
@Query("update #{#entityName} set active = ?2 where id = ?1")
void setActive(String id, boolean b);
}

View File

@ -0,0 +1,14 @@
package eu.dnetlib.services.dsm.repository;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import eu.dnetlib.data.model.dsm.readonly.ApiWithAdditionalInfo;
import eu.dnetlib.utils.ReadOnlyRepository;
@Repository
@ConditionalOnProperty(value = "openaire.api.enable.dsm", havingValue = "true")
public interface ApiWithAdditionalInfoRepository extends ReadOnlyRepository<ApiWithAdditionalInfo, String>, JpaSpecificationExecutor<ApiWithAdditionalInfo> {
}

View File

@ -0,0 +1,73 @@
package eu.dnetlib.services.dsm.repository;
import java.time.LocalDate;
import java.util.Optional;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import eu.dnetlib.data.model.dsm.Datasource;
import jakarta.transaction.Transactional;
@Repository
@ConditionalOnProperty(value = "openaire.api.enable.dsm", havingValue = "true")
public interface DatasourceRepository extends JpaRepository<Datasource, String>, JpaSpecificationExecutor<Datasource> {
Optional<Datasource> findByNamespaceprefix(String namespaceprefix);
@Query("select d.managed from #{#entityName} d where d.id = ?1")
boolean isManaged(String id);
@Modifying
@Transactional
@Query("update #{#entityName} d set d.managed = ?2 where d.id = ?1")
void setManaged(String id, boolean managed);
@Modifying
@Transactional
@Query("update #{#entityName} d set d.officialname = ?2, d.englishname = ?3 where d.id = ?1")
void setDatasourcename(String id, String officialname, String englishname);
@Modifying
@Transactional
@Query("update #{#entityName} d set d.logourl = ?2 where d.id = ?1")
void setLogoUrl(String dsId, String logourl);
@Modifying
@Transactional
@Query("update #{#entityName} d set d.latitude = ?2, d.longitude = ?3 where d.id = ?1")
void setCoordinates(String dsId, Double latitude, Double longitude);
@Modifying
@Transactional
@Query("update #{#entityName} d set d.timezone = ?2 where d.id = ?1")
void setTimezone(String dsId, String timezone);
@Modifying
@Transactional
@Query("update #{#entityName} d set d.eoscDatasourceType = ?2 where d.id = ?1")
void setEoscDatasourceType(String dsId, String type);
@Modifying
@Transactional
@Query("update #{#entityName} d set d.registeredby = ?2 where d.id = ?1")
void setRegisteringUser(String id, String registeredby);
@Query("select case when registrationdate <> null then true else false end as hasregistrationdate from #{#entityName} where id = ?1")
Boolean hasRegistrationdate(String id);
@Modifying
@Transactional
@Query("update #{#entityName} d set d.registrationdate = ?2 where d.id = ?1")
void setRegistrationDate(String id, LocalDate registrationdate);
@Modifying
@Transactional
@Query("update #{#entityName} d set d.platform = ?2 where d.id = ?1")
void setPlatform(String id, String platform);
}

View File

@ -0,0 +1,68 @@
package eu.dnetlib.services.dsm.repository;
import java.util.List;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import eu.dnetlib.data.model.dsm.BrowseTerm;
import eu.dnetlib.data.model.dsm.readonly.SimpleDsWithApis;
import eu.dnetlib.utils.ReadOnlyRepository;
@Repository
@ConditionalOnProperty(value = "openaire.api.enable.dsm", havingValue = "true")
public interface SimpleDsWithApisRepository extends ReadOnlyRepository<SimpleDsWithApis, String>, JpaSpecificationExecutor<SimpleDsWithApis> {
@Query(value = "select * from dsm_datasources_view where id = :value or name ilike %:value% or other_name ilike %:value%", nativeQuery = true)
Page<SimpleDsWithApis> search(@Param("value") String value, Pageable pageable);
Page<SimpleDsWithApis> findByType(String type, Pageable pageable);
Page<SimpleDsWithApis> findByCollectedFrom(String collectdFrom, Pageable pageable);
Page<SimpleDsWithApis> findByConsenttermsofuse(Boolean consenttermsofuse, Pageable pageable);
Page<SimpleDsWithApis> findByFulltextdownload(Boolean fulltextdownload, Pageable pageable);
@Query(value = "select * from dsm_datasources_view where ? = ANY(hidden_compliances)", nativeQuery = true)
Page<SimpleDsWithApis> findByCompliance(String compliance, Pageable pageable);
@Query(value = "select * from dsm_datasources_view where ? = ANY(hidden_countries)", nativeQuery = true)
Page<SimpleDsWithApis> findByCountry(String country, Pageable pageable);
@Query(value = "select * from dsm_datasources_view where ? = ANY(hidden_protocols)", nativeQuery = true)
Page<SimpleDsWithApis> findByProtocol(String brotocol, Pageable pageable);
@Query(value = "select * from dsm_datasources_view where ? = ANY(hidden_actives)", nativeQuery = true)
Page<SimpleDsWithApis> findByActive(Boolean active, Pageable pageable);
@Query(value = "select type as term, type as name, count(*) as total from dsm_datasources_view group by type order by total desc", nativeQuery = true)
List<BrowseTerm> browseTermsForType();
@Query(value = "select collectedfrom as term, collectedfrom as name, count(*) as total from dsm_datasources_view group by collectedfrom order by total desc", nativeQuery = true)
List<BrowseTerm> browseTermsForCollectedFrom();
@Query(value = "select c as term, c as name, count(*) as total from (select unnest(hidden_compliances) as c from dsm_datasources_view) as t group by c order by total desc", nativeQuery = true)
List<BrowseTerm> browseTermsForCompliance();
@Query(value = "select c as term, c as name, count(*) as total from (select unnest(hidden_countries) as c from dsm_datasources_view) as t group by c order by total desc", nativeQuery = true)
List<BrowseTerm> browseTermsForCountry();
@Query(value = "select c as term, c as name, count(*) as total from (select unnest(hidden_protocols) as c from dsm_datasources_view) as t group by c order by total desc", nativeQuery = true)
List<BrowseTerm> browseTermsForProtocol();
@Query(value = "select c as term, c as name, count(*) as total from (select unnest(hidden_actives) as c from dsm_datasources_view) as t group by c order by total desc", nativeQuery = true)
List<BrowseTerm> browseTermsForActive();
@Query(value = "select consenttermsofuse as term, consenttermsofuse as name, count(*) as total from dsm_datasources_view group by consenttermsofuse order by total desc", nativeQuery = true)
List<BrowseTerm> browseTermsForConsenttermsofuse();
@Query(value = "select fulltextdownload as term, fulltextdownload as name, count(*) as total from dsm_datasources_view group by fulltextdownload order by total desc", nativeQuery = true)
List<BrowseTerm> browseTermsForFulltextdownload();
}

View File

@ -0,0 +1,555 @@
package eu.dnetlib.services.dsm.service;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import eu.dnetlib.data.model.dsm.Api;
import eu.dnetlib.data.model.dsm.ApiParam;
import eu.dnetlib.data.model.dsm.BrowseTerm;
import eu.dnetlib.data.model.dsm.Datasource;
import eu.dnetlib.data.model.dsm.readonly.ApiWithAdditionalInfo;
import eu.dnetlib.data.model.dsm.readonly.SimpleDsWithApis;
import eu.dnetlib.data.model.vocabulary.Vocabulary;
import eu.dnetlib.errors.DsmException;
import eu.dnetlib.errors.DsmForbiddenException;
import eu.dnetlib.errors.DsmNotFoundException;
import eu.dnetlib.services.dsm.domain.ApiDetails;
import eu.dnetlib.services.dsm.domain.Country;
import eu.dnetlib.services.dsm.domain.DatasourceDetailResponse;
import eu.dnetlib.services.dsm.domain.DatasourceSnippetResponse;
import eu.dnetlib.services.dsm.domain.RegisteredDatasourceInfo;
import eu.dnetlib.services.dsm.domain.RequestFilter;
import eu.dnetlib.services.dsm.domain.RequestSort;
import eu.dnetlib.services.dsm.domain.RequestSortOrder;
import eu.dnetlib.services.dsm.domain.SimpleDatasourceInfo;
import eu.dnetlib.services.dsm.domain.SimpleResponse;
import eu.dnetlib.services.dsm.repository.ApiRepository;
import eu.dnetlib.services.dsm.repository.ApiWithAdditionalInfoRepository;
import eu.dnetlib.services.dsm.repository.DatasourceRepository;
import eu.dnetlib.services.dsm.repository.SimpleDsWithApisRepository;
import eu.dnetlib.services.dsm.utils.DatasourceSpecs;
import eu.dnetlib.services.dsm.utils.DsmBrowsableFields;
import eu.dnetlib.services.dsm.utils.DsmMappingUtils;
import eu.dnetlib.services.dsm.utils.ResponseUtils;
import eu.dnetlib.services.dsm.utils.VocabularyClient;
import jakarta.persistence.EntityNotFoundException;
@Service
@ConditionalOnProperty(value = "openaire.api.enable.dsm", havingValue = "true")
public class DsmService {
private static final Log log = LogFactory.getLog(DsmService.class);
public static final String OAI = "oai";
public static final String SET = "set";
@Autowired
private DatasourceRepository dsRepository;
@Autowired
private ApiRepository apiRepository;
@Autowired
private ApiWithAdditionalInfoRepository apiWithAdditionalInfoRepository;
@Autowired
private SimpleDsWithApisRepository simpleDsWithApisRepository;
@Autowired
private VocabularyClient vocabularyClient;
@Autowired
@Qualifier("openaireJdbcTemplate")
private JdbcTemplate jdbcTemplate;
public Object setApiActive;
public List<Country> listCountries() throws DsmException {
final List<Country> countries = new ArrayList<>();
// TODO Usare solo vocabolari???
final Vocabulary v = vocabularyClient.getCountries();
countries.addAll(browseTerm(DsmBrowsableFields.country)
.stream()
.filter(Objects::nonNull)
.map(t -> new Country(t.getTerm(), t.getName()))
.collect(Collectors.toList()));
return countries;
}
@Transactional
public DatasourceSnippetResponse searchSnippet(final RequestSort requestSortBy,
final RequestSortOrder order,
final RequestFilter requestFilter,
final int page,
final int size) throws DsmException {
final Page<Datasource> dsPage = search(requestSortBy, order, requestFilter, page, size);
return ResponseUtils.snippetResponse(dsPage.map(DsmMappingUtils::asSnippetExtended).getContent(), dsPage.getTotalElements());
}
public DatasourceDetailResponse searchDetails(final RequestSort requestSortBy,
final RequestSortOrder order,
final RequestFilter requestFilter,
final int page,
final int size) throws DsmException {
final Page<Datasource> dsPage = search(requestSortBy, order, requestFilter, page, size);
return ResponseUtils.detailsResponse(dsPage.map(DsmMappingUtils::asDetails).getContent(), dsPage.getTotalElements());
}
private Page<Datasource> search(final RequestSort requestSortBy,
final RequestSortOrder order,
final RequestFilter requestFilter,
final int page,
final int size)
throws DsmException {
final Specification<Datasource> spec = DatasourceSpecs.dsSpec(requestSortBy, order, requestFilter);
return dsRepository.findAll(spec, PageRequest.of(page, size));
}
public Page<Datasource> searchRegistered(final RequestSort requestSortBy,
final RequestSortOrder order,
final RequestFilter requestFilter,
final int page,
final int size)
throws DsmException {
final Specification<Datasource> spec = DatasourceSpecs.dsSpec(requestSortBy, order, requestFilter).and(DatasourceSpecs.dsRegisteredbyNotNullSpec());
return dsRepository.findAll(spec, PageRequest.of(page, size));
}
public Datasource findDs(final String dsId) throws DsmException {
return dsRepository.findById(dsId).orElseThrow(() -> new DsmException("Datasource not found. ID: " + dsId));
}
public Datasource findDsByNsPrefix(final String prefix) throws DsmException {
return dsRepository.findByNamespaceprefix(prefix).orElseThrow(() -> new DsmException("Datasource not found. NS Prefix: " + prefix));
}
public void setManaged(final Datasource ds, final boolean managed) {
setManaged(ds.getId(), managed);
}
public void setManaged(final String id, final boolean managed) {
log.info(String.format("setting managed = '%s' for ds '%s'", managed, id));
dsRepository.setManaged(id, managed);
apiRepository.setAllApiRemovableForDs(id, true);
}
public boolean isManaged(final String id) {
return dsRepository.isManaged(id);
}
public void updateCompliance(final String dsId, final String apiId, final String compliance, final boolean override) {
log.info(String.format("setting compatibility = '%s' for ds '%s'", compliance, apiId));
apiRepository.updateCompatibility(apiId, compliance);
}
public List<Api> findApis(final String dsId) {
return apiRepository.findByDatasource(dsId);
}
public void deleteApi(final String dsId, final String apiId) throws DsmForbiddenException, DsmNotFoundException {
final Api api = apiRepository.findById(apiId).orElseThrow(() -> new DsmNotFoundException("Api not found. ID: " + apiId));
try {
if (!api.getRemovable()) { throw new DsmForbiddenException("api is not removable"); }
apiRepository.deleteById(apiId);
log.info(String.format("deleted api '%s'", apiId));
} catch (final EntityNotFoundException e) {
throw new DsmNotFoundException("api not found");
}
}
public void addApi(final Api api) {
apiRepository.save(api);
}
public boolean existDs(final String dsId) throws DsmException {
return dsRepository.existsById(dsId);
}
public void saveDs(final Datasource d) {
log.info(String.format("saving datasource '%s'", d.getId()));
final Datasource datasource = dsRepository.save(d);
log.info(String.format("saved datasource '%s'", datasource.getId()));
ensureRegistrationDate(d.getId());
}
public void deleteDs(final String dsId) {
dsRepository.deleteById(dsId);
log.info(String.format("deleted datasource '%s'", dsId));
}
public void updateName(final String dsId, final String officialname, final String englishname) {
// TODO what if one of the two names is null or empty?
dsRepository.setDatasourcename(dsId, officialname, englishname);
}
public void updateLogoUrl(final String dsId, final String logourl) throws DsmException {
dsRepository.setLogoUrl(dsId, logourl);
}
public void updateCoordinates(final String dsId, final Double latitude, final Double longitude) {
dsRepository.setCoordinates(dsId, latitude, longitude);
}
public void updateApiBaseUrl(final String apiId, final String baseurl) {
apiRepository.setBaseurl(apiId, baseurl);
}
@Transactional
public boolean upsertApiOaiSet(final String apiId, final String oaiSet) throws DsmException, DsmNotFoundException {
final Api api = apiRepository.findById(apiId).orElseThrow(() -> new DsmNotFoundException("Api not found. ID: " + apiId));
if (OAI.equalsIgnoreCase(api.getProtocol())) {
final Set<ApiParam> apiParams = api.getApiParams();
if (!apiParams.stream().anyMatch(ap -> SET.equals(ap.getParam()))) {
apiRepository.addApiParam(apiId, SET, oaiSet);
log.info(String.format("added api '%s' oai set with '%s'", apiId, oaiSet));
return true;
} else {
apiRepository.updateOaiSet(apiId, oaiSet);
log.info(String.format("updated api '%s' oai set with '%s'", apiId, oaiSet));
return false;
}
} else {
throw new DsmException(String.format("won't add OAI set to a non OAI interface: '%s' has protocol '%s'", apiId, api.getProtocol()));
}
}
public List<String> findApiBaseURLs(final RequestFilter requestFilter, final int page, final int size) throws DsmException {
final PageRequest pageable = PageRequest.of(page, size);
final Specification<ApiWithAdditionalInfo> spec = DatasourceSpecs.apiSpec(requestFilter);
final Set<String> set = apiWithAdditionalInfoRepository.findAll(spec, pageable)
.getContent()
.stream()
.map(ApiWithAdditionalInfo::getBaseurl)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toCollection(HashSet::new));
return new ArrayList<>(set);
}
public void updateTimezone(final String dsId, final String timezone) {
dsRepository.setTimezone(dsId, timezone);
}
public void updateEoscDatasourceType(final String dsId, final String type) throws DsmException {
if (vocabularyClient.isValidTerm("eosc_datasource_types", type)) {
throw new DsmException(String.format("invalid datasource type '%s', provide one according to vocabulary eosc_datasource_types"));
}
dsRepository.setEoscDatasourceType(dsId, type);
}
public void updateRegisteringUser(final String dsId, final String registeredBy) throws DsmException {
ensureRegistrationDate(dsId);
dsRepository.setRegisteringUser(dsId, registeredBy);
}
public void updatePlatform(final String dsId, final String platform) throws DsmException {
dsRepository.setPlatform(dsId, platform);
}
public SimpleResponse<RegisteredDatasourceInfo> searchRecentRegistered(final int size) throws DsmException {
try {
final List<RegisteredDatasourceInfo> list =
querySql("recent_registered_datasources.sql.st", BeanPropertyRowMapper.newInstance(RegisteredDatasourceInfo.class), size);
return ResponseUtils.simpleResponse(list);
} catch (final Throwable e) {
log.error("error searching recent datasources", e);
throw new DsmException("error searching recent datasources", e);
}
}
public Long countRegisteredAfter(final String fromDate, final String typeFilter) throws DsmException {
try {
if (StringUtils.isNotBlank(typeFilter)) {
final String sql =
IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/openaire/sql/recent_registered_datasources_fromDate_typology.st.sql"), Charset
.defaultCharset());
return jdbcTemplate.queryForObject(sql, Long.class, fromDate, typeFilter + "%");
} else {
final String sql =
IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/openaire/sql/recent_registered_datasources_fromDate.st.sql"), Charset
.defaultCharset());
return jdbcTemplate.queryForObject(sql, Long.class, fromDate);
}
} catch (final Throwable e) {
log.error("error searching recent datasources", e);
throw new DsmException("error searching recent datasources", e);
}
}
public SimpleResponse<SimpleDatasourceInfo> searchRecentRegisteredV2(final int size) throws DsmException {
try {
final List<SimpleDatasourceInfo> list = querySql("recent_registered_datasources_v2.sql.st", rowMapperForSimpleDatasourceInfo(), size);
return ResponseUtils.simpleResponse(list);
} catch (final Throwable e) {
log.error("error searching recent datasources", e);
throw new DsmException("error searching recent datasources", e);
}
}
public Long countFirstCollect(final String fromDate, final String typeFilter) throws DsmException {
try {
if (StringUtils.isNotBlank(typeFilter)) {
return querySql("count_first_collected_datasources_fromDate_typology.st.sql", Long.class, typeFilter + "%", fromDate);
} else {
return querySql("count_first_collected_datasources_fromDate.st.sql", Long.class, fromDate);
}
} catch (final Throwable e) {
log.error("error searching datasources using the first collection date", e);
throw new DsmException("error searching datasources using the first collection date", e);
}
}
public List<SimpleDatasourceInfo> findFirstCollectedAfter(final String fromDate, final String typeFilter) throws DsmException {
try {
if (StringUtils.isNotBlank(typeFilter)) {
return querySql("first_collected_datasources_fromDate_typology.st.sql", rowMapperForSimpleDatasourceInfo(), typeFilter + "%", fromDate);
} else {
return querySql("first_collected_datasources_fromDate.st.sql", rowMapperForSimpleDatasourceInfo(), fromDate);
}
} catch (final Throwable e) {
log.error("error searching datasources using the first collection date", e);
throw new DsmException("error searching datasources using the first collection date", e);
}
}
private <T> List<T> querySql(final String sqlFile, final RowMapper<T> rowMapper, final Object... params) throws IOException {
final String sql = IOUtils.toString(getClass().getResourceAsStream("/sql/dsm/" + sqlFile), StandardCharsets.UTF_8);
return jdbcTemplate.query(sql, rowMapper, params);
}
private <T> T querySql(final String sqlFile, final Class<T> clazz, final Object... params) throws IOException {
final String sql = IOUtils.toString(getClass().getResourceAsStream("/sql/dsm/" + sqlFile), StandardCharsets.UTF_8);
return jdbcTemplate.queryForObject(sql, clazz, params);
}
// HELPER
private void ensureRegistrationDate(final String dsId) {
if (!dsRepository.hasRegistrationdate(dsId)) {
log.info("setting registration date for datasource: " + dsId);
dsRepository.setRegistrationDate(dsId, LocalDate.now());
}
}
private RowMapper<SimpleDatasourceInfo> rowMapperForSimpleDatasourceInfo() {
return (rs, rowNum) -> {
final SimpleDatasourceInfo info = new SimpleDatasourceInfo();
info.setId(rs.getString("id"));
info.setOfficialName(rs.getString("officialName"));
info.setEnglishName(rs.getString("englishName"));
info.setTypology(rs.getString("typology"));
info.setEoscType(rs.getString("eoscType"));
info.setEoscDatasourceType(rs.getString("eoscDatasourceType"));
info.setRegisteredBy(rs.getString("registeredBy"));
info.setRegistrationDate(rs.getString("registrationDate"));
info.setFirstCollectionDate(rs.getString("firstCollectionDate"));
info.setLastCollectionDate(rs.getString("lastCollectionDate"));
info.setLastCollectionTotal(rs.getLong("lastCollectionTotal"));
final Set<String> compatibilities = new HashSet<>();
for (final String s : (String[]) rs.getArray("compatibilities").getArray()) {
compatibilities.add(s);
}
// The order of the condition is important
if (compatibilities.contains("openaire-cris_1.1")) {
info.setCompatibility("openaire-cris_1.1");
} else if (compatibilities.contains("openaire4.0")) {
info.setCompatibility("openaire4.0");
} else if (compatibilities.contains("driver") && compatibilities.contains("openaire2.0")) {
info.setCompatibility("driver-openaire2.0");
} else if (compatibilities.contains("driver")) {
info.setCompatibility("driver");
} else if (compatibilities.contains("openaire2.0")) {
info.setCompatibility("openaire2.0");
} else if (compatibilities.contains("openaire3.0")) {
info.setCompatibility("openaire3.0");
} else if (compatibilities.contains("openaire2.0_data")) {
info.setCompatibility("openaire2.0_data");
} else if (compatibilities.contains("native")) {
info.setCompatibility("native");
} else if (compatibilities.contains("hostedBy")) {
info.setCompatibility("hostedBy");
} else if (compatibilities.contains("notCompatible")) {
info.setCompatibility("notCompatible");
} else {
info.setCompatibility("UNKNOWN");
}
for (final String s : (String[]) rs.getArray("organizations").getArray()) {
info.getOrganizations().put(StringUtils.substringBefore(s, "@@@").trim(), StringUtils.substringAfter(s, "@@@").trim());
}
return info;
};
}
@Transactional
public void addDsAndApis(final Datasource ds, final List<ApiDetails> apis) throws DsmException {
try {
saveDs(ds);
if (apis != null) {
for (final ApiDetails api : apis) {
api.setDatasource(ds.getId());
if (StringUtils.isBlank(api.getId())) {
api.setId(DsmMappingUtils.createId(api));
log.info(String.format("missing api id, created '%s'", api.getId()));
}
addApi(DsmMappingUtils.asDbEntry(api));
log.info("API saved, id: " + api.getId());
}
}
} catch (final Throwable e) {
log.error("Error saving ds and/or api", e);
throw new DsmException("Error saving ds and/or api", e);
}
}
@Transactional
@Cacheable("brosable_terms")
public List<BrowseTerm> browseTerm(final DsmBrowsableFields f) {
switch (f) {
case type:
return simpleDsWithApisRepository.browseTermsForType();
case collectedfrom:
return simpleDsWithApisRepository.browseTermsForCollectedFrom();
case compliance:
return simpleDsWithApisRepository.browseTermsForCompliance();
case country:
return simpleDsWithApisRepository.browseTermsForCountry();
case protocol:
return simpleDsWithApisRepository.browseTermsForProtocol();
case active:
return simpleDsWithApisRepository.browseTermsForActive();
case consenttermsofuse:
return simpleDsWithApisRepository.browseTermsForConsenttermsofuse();
case fulltextdownload:
return simpleDsWithApisRepository.browseTermsForFulltextdownload();
default:
throw new RuntimeException("not implemeted");
}
}
public Page<SimpleDsWithApis> searchByField(final DsmBrowsableFields f, final String value, final int page, final int size) {
switch (f) {
case type:
return simpleDsWithApisRepository.findByType(value, PageRequest.of(page, size));
case collectedfrom:
return simpleDsWithApisRepository.findByCollectedFrom(value, PageRequest.of(page, size));
case compliance:
return simpleDsWithApisRepository.findByCompliance(value, PageRequest.of(page, size));
case country:
return simpleDsWithApisRepository.findByCountry(value, PageRequest.of(page, size));
case protocol:
return simpleDsWithApisRepository.findByProtocol(value, PageRequest.of(page, size));
case active:
return simpleDsWithApisRepository.findByActive(Boolean.valueOf(value), PageRequest.of(page, size));
case consenttermsofuse:
return simpleDsWithApisRepository.findByConsenttermsofuse(Boolean.valueOf(value), PageRequest.of(page, size));
case fulltextdownload:
return simpleDsWithApisRepository.findByFulltextdownload(Boolean.valueOf(value), PageRequest.of(page, size));
default:
throw new RuntimeException("not implemeted");
}
}
public Page<SimpleDsWithApis> search(final String value, final int page, final int size) {
return simpleDsWithApisRepository.search(value, PageRequest.of(page, size));
}
public Api findApi(final String id) throws DsmException {
return apiRepository.findById(id).orElseThrow(() -> new DsmException("Api not found. ID: " + id));
}
public Api updateUpdateApiCollectionInfo(final String apiId, final String mdId, final long total) throws DsmException {
if (StringUtils.isNotBlank(mdId)) {
apiRepository.updateLastCollectionInfo(apiId, mdId, new Timestamp(System.currentTimeMillis()), total);
} else {
apiRepository.updateLastCollectionInfo(apiId, null, null, 0);
}
return findApi(apiId);
}
public Api updateUpdateApiAggregationInfo(final String apiId, final String mdId, final long total) throws DsmException {
if (StringUtils.isNotBlank(mdId)) {
apiRepository.updateLastAggregationInfo(apiId, mdId, new Timestamp(System.currentTimeMillis()), total);
} else {
apiRepository.updateLastAggregationInfo(apiId, null, null, 0);
}
return findApi(apiId);
}
public Api updateUpdateApiDownloadInfo(final String apiId, final String mdId, final long total) throws DsmException {
if (StringUtils.isNotBlank(mdId)) {
apiRepository.updateLastDownloadInfo(apiId, mdId, new Timestamp(System.currentTimeMillis()), total);
} else {
apiRepository.updateLastDownloadInfo(apiId, null, null, 0);
}
return findApi(apiId);
}
public void setApiActive(final Api api, final boolean b) {
apiRepository.setActive(api.getId(), b);
}
}

View File

@ -0,0 +1,10 @@
package eu.dnetlib.services.dsm.utils;
public class CollectorClient {
public Iterable<?> listProtocols() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -0,0 +1,164 @@
package eu.dnetlib.services.dsm.utils;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.data.jpa.domain.Specification;
import eu.dnetlib.data.model.dsm.Datasource;
import eu.dnetlib.data.model.dsm.readonly.ApiWithAdditionalInfo;
import eu.dnetlib.services.dsm.domain.FilterName;
import eu.dnetlib.services.dsm.domain.RequestFilter;
import eu.dnetlib.services.dsm.domain.RequestSort;
import eu.dnetlib.services.dsm.domain.RequestSortOrder;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
public class DatasourceSpecs {
private static final Log log = LogFactory.getLog(DatasourceSpecs.class);
public static final String WILDCARD = "%";
public static Specification<Datasource> dsRegisteredbyNotNullSpec() {
return (ds, query, cb) -> cb.and(cb.isNull(ds.get(FilterName.registeredby.name())).not(), cb.isNull(ds.get("registrationdate")).not());
}
public static Specification<Datasource> dsSpec(final RequestSort requestSortBy, final RequestSortOrder order, final RequestFilter requestFilter) {
log.debug(String.format("RequestFilter:'%s', RequestSort:'%s', RequestSortOrder:'%s'", requestFilter, requestSortBy, order));
return (ds, query, cb) -> {
final Predicate p = cb.conjunction();
final List<Expression<Boolean>> expressions = p.getExpressions();
expressions.add(cb.equal(ds.get("eoscType"), "Data Source"));
expressions.add(cb.equal(ds.get("dedupMainService"), true));
if (requestFilter != null) {
requestFilter.entrySet()
.stream()
.forEach(e -> {
switch (FilterName.type(e.getKey())) {
case exact:
expressions.add(exactSearch(ds, cb, e));
break;
case search:
expressions.add(likeSearch(ds, cb, e));
break;
case multiSearch:
expressions.add(likeSearchList(ds, cb, e));
break;
case searchOrgs:
// search by case insensitive organization's country
expressions.add(cb.equal(cb.lower(ds.join("organizations").get(FilterName.country.name())), getValue(e)));
break;
}
});
}
if (requestSortBy != null) {
if (order != null) {
final Path<Object> orderField = ds.get(requestSortBy.name());
switch (order) {
case ASCENDING:
query.orderBy(cb.asc(orderField));
break;
case DESCENDING:
query.orderBy(cb.desc(orderField));
break;
}
}
}
query.distinct(true);
return p;
};
}
public static Specification<ApiWithAdditionalInfo> apiSpec(final RequestFilter requestFilter) {
log.debug(String.format("RequestFilter:'%s'", requestFilter));
return (api, query, cb) -> {
final Predicate p = cb.conjunction();
if (requestFilter != null) {
final List<Expression<Boolean>> expressions = p.getExpressions();
requestFilter.entrySet()
.stream()
.forEach(e -> {
switch (FilterName.type(e.getKey())) {
case exact:
expressions.add(exactSearch(api, cb, e));
break;
case search:
expressions.add(likeSearch(api, cb, e));
break;
case multiSearch:
expressions.add(likeSearchList(api, cb, e));
break;
case searchOrgs:
throw new RuntimeException("not implemented");
}
});
}
query.distinct(true);
return p;
};
}
// HELPERS
// substring, case insensitive, like based search
private static Predicate likeSearch(final Root<?> r, final CriteriaBuilder cb, final Entry<FilterName, Object> e) {
return cb.like(cb.lower(r.get(e.getKey().name())), WILDCARD + getValue(e) + WILDCARD);
}
// substring, case insensitive, like based search
private static Predicate likeSearchList(final Root<?> r, final CriteriaBuilder cb, final Entry<FilterName, Object> e) {
final String key = e.getKey().name();
final Predicate[] arr =
Arrays.stream(e.getValue().toString().split(","))
.map(String::trim)
.map(String::toLowerCase)
.filter(StringUtils::isNotBlank)
.map(s -> cb.like(cb.lower(r.get(key)), WILDCARD + s + WILDCARD))
.toArray(size -> new Predicate[size]);
return cb.or(arr);
}
// search by ID, managed. exact match
private static Predicate exactSearch(final Root<?> r, final CriteriaBuilder cb, final Entry<FilterName, Object> e) {
return cb.equal(r.get(e.getKey().name()), getValue(e));
}
private static Object getValue(final Entry<FilterName, Object> e) {
if (e.getValue() instanceof String) {
final String s = (String) e.getValue();
if (!e.getKey().equals(FilterName.country)) {
final Boolean b = BooleanUtils.toBooleanObject(s);
if (b != null) { return b; }
}
return e.getKey().equals(FilterName.id) ? s : StringUtils.lowerCase(s);
}
if (e.getValue() instanceof Boolean) { return e.getValue(); }
return e.getValue();
}
}

View File

@ -0,0 +1,19 @@
package eu.dnetlib.services.dsm.utils;
public enum DsmBrowsableFields {
type("Datasource typologies"),
collectedfrom("Collected From"),
country("Countries"),
compliance("Compatibility levels"),
protocol("API protocols"),
active("API activation"),
consenttermsofuse("Consent terms of use"),
fulltextdownload("Fulltext download");
public final String desc;
private DsmBrowsableFields(final String desc) {
this.desc = desc;
}
}

View File

@ -0,0 +1,190 @@
package eu.dnetlib.services.dsm.utils;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.dnetlib.data.model.dsm.Api;
import eu.dnetlib.data.model.dsm.Datasource;
import eu.dnetlib.data.model.dsm.Organization;
import eu.dnetlib.services.dsm.domain.ApiDetails;
import eu.dnetlib.services.dsm.domain.DatasourceDetails;
import eu.dnetlib.services.dsm.domain.DatasourceDetailsUpdate;
import eu.dnetlib.services.dsm.domain.DatasourceSnippetExtended;
import eu.dnetlib.services.dsm.domain.OrganizationDetails;
public class DsmMappingUtils {
public static final String DATE_FORMAT = "yyyy-MM-dd";
public static final String ID_SEPARATOR = "::";
public static final String ID_PREFIX = "api_________" + ID_SEPARATOR;
public static String createId(final ApiDetails api) {
return ID_PREFIX + api.getDatasource() + ID_SEPARATOR + RandomStringUtils.randomAlphanumeric(8);
}
public static DatasourceDetails asDetails(final Datasource d) {
final DatasourceDetails details = _convert(d, DatasourceDetails.class);
return details.setOpenaireId(asOpenaireId(details.getId()));
}
public static DatasourceSnippetExtended asSnippetExtended(final Datasource d) {
final DatasourceSnippetExtended ds = new DatasourceSnippetExtended();
ds.setId(d.getId());
ds.setOfficialname(d.getOfficialname());
ds.setEnglishname(d.getEnglishname());
ds.setRegisteredby(d.getRegisteredby());
ds.setWebsiteurl(d.getWebsiteurl());
ds.setEoscDatasourceType(d.getEoscDatasourceType());
ds.setRegistrationdate(d.getRegistrationdate());
ds.setLogoUrl(d.getLogourl());
ds.setDescription(d.getDescription());
ds.setConsentTermsOfUse(d.getConsentTermsOfUse());
ds.setConsentTermsOfUseDate(d.getConsentTermsOfUseDate());
ds.setLastConsentTermsOfUseDate(d.getLastConsentTermsOfUseDate());
ds.setFullTextDownload(d.getFullTextDownload());
if (d.getOrganizations() != null) {
ds.setOrganizations(d.getOrganizations().stream().map(DsmMappingUtils::asOrganizationDetail).collect(Collectors.toSet()));
}
ds.setTypology(d.getTypology());
return ds;
}
private static OrganizationDetails asOrganizationDetail(final Organization o) {
return new OrganizationDetails()
.setCountry(o.getCountry())
.setLegalname(o.getLegalname())
.setLegalshortname(o.getLegalshortname())
.setWebsiteurl(o.getWebsiteurl())
.setLogourl(o.getLogourl());
}
public static ApiDetails asDetails(final Api d) {
return _convert(d, ApiDetails.class);
}
public static Api asDbEntry(final ApiDetails d) {
final Api apiDbEntry = new Api();
apiDbEntry.setId(d.getId());
apiDbEntry.setBaseurl(d.getBaseurl());
apiDbEntry.setProtocol(d.getProtocol());
apiDbEntry.setDatasource(d.getDatasource());
apiDbEntry.setContentdescription(d.getContentdescription());
apiDbEntry.setCompatibility(d.getCompatibility());
apiDbEntry.setCompatibilityOverride(d.getCompatibilityOverride());
apiDbEntry.setRemovable(d.getRemovable());
apiDbEntry.setMetadataIdentifierPath(d.getMetadataIdentifierPath());
return apiDbEntry;
}
public static Datasource asDbEntry(final DatasourceDetails d) {
final Datasource dbe = _convert(d, Datasource.class);
if (dbe.getOrganizations() != null) {
dbe.getOrganizations().forEach(o -> {
final String prefix = StringUtils.isNotBlank(dbe.getNamespaceprefix()) ? dbe.getNamespaceprefix() : dbe.getId();
o.setId(prefix + ID_SEPARATOR + o.getLegalname());
if (o.getDateofcollection() == null) {
o.setDateofcollection(LocalDateTime.now());
}
o.setCollectedfrom(dbe.getCollectedfrom());
});
}
_fix_typology(dbe, d.getTypology(), d.getEoscDatasourceType());
return dbe;
}
@Deprecated
private static void _fix_typology(final Datasource dbe, final String oldTypology, final String eoscTypology) {
if (StringUtils.isNotBlank(oldTypology) && StringUtils.isBlank(eoscTypology)) {
// THE ORDER IS IMPORTANT: DO NOT CHANGE IT
if (oldTypology.startsWith("crissystem")) {
dbe.setEoscDatasourceType("CRIS system");
} else if (oldTypology.startsWith("entityregistry")) {
dbe.setEoscDatasourceType("Registry");
} else if (oldTypology.startsWith("pubscatalogue") || oldTypology.equals("websource")) {
dbe.setEoscDatasourceType("Catalogue");
} else if (oldTypology.contains("journal")) {
dbe.setEoscDatasourceType("Journal archive");
} else if (oldTypology.startsWith("aggregator")) {
dbe.setEoscDatasourceType("Aggregator");
} else if (oldTypology.contains("repository")) {
dbe.setEoscDatasourceType("Repository");
} else {
dbe.setEoscDatasourceType("Aggregator");
}
} else if (StringUtils.isBlank(oldTypology) && StringUtils.isNotBlank(eoscTypology)) {
if (dbe.getEoscDatasourceType().equals("CRIS system")) {
dbe.setTypology("crissystem");
} else if (dbe.getEoscDatasourceType().equals("Registry")) {
dbe.setTypology("entityregistry");
} else if (dbe.getEoscDatasourceType().equals("Catalogue")) {
dbe.setTypology("pubscatalogue::unknown");
} else if (dbe.getEoscDatasourceType().equals("Journal archive")) {
dbe.setTypology("pubsrepository::journal");
} else if (dbe.getEoscDatasourceType().equals("Aggregator")) {
dbe.setTypology("aggregator");
} else if (dbe.getEoscDatasourceType().equals("Repository")) {
dbe.setTypology("pubsrepository::unknown");
} else {
dbe.setTypology("aggregator");
}
}
}
public static Datasource asDbEntry(final DatasourceDetailsUpdate d) {
final Datasource dbe = _convert(d, Datasource.class);
_fix_typology(dbe, d.getTypology(), d.getEoscDatasourceType());
return dbe;
}
// HELPERS
private static <T> T _convert(final Object o, final Class<T> clazz) {
final ObjectMapper mapper = new ObjectMapper();
return mapper.convertValue(o, clazz);
}
private static String asOpenaireId(final String id) {
final String prefix = StringUtils.substringBefore(id, ID_SEPARATOR);
final String md5 = StringUtils.substringAfter(id, ID_SEPARATOR);
return prefix + ID_SEPARATOR + DigestUtils.md5Hex(md5);
}
public static void copyNonNullProperties(final Object src, final Object target) {
BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
}
public static String[] getNullPropertyNames(final Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
final java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
final Set<String> emptyNames = new HashSet<>();
for (final java.beans.PropertyDescriptor pd : pds) {
final Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) {
emptyNames.add(pd.getName());
}
}
final String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
}

View File

@ -0,0 +1,60 @@
package eu.dnetlib.services.dsm.utils;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import eu.dnetlib.services.dsm.domain.ApiDetails;
import eu.dnetlib.services.dsm.domain.ApiDetailsResponse;
import eu.dnetlib.services.dsm.domain.DatasourceDetailResponse;
import eu.dnetlib.services.dsm.domain.DatasourceDetails;
import eu.dnetlib.services.dsm.domain.DatasourceInfo;
import eu.dnetlib.services.dsm.domain.DatasourceSearchResponse;
import eu.dnetlib.services.dsm.domain.DatasourceSnippetExtended;
import eu.dnetlib.services.dsm.domain.DatasourceSnippetResponse;
import eu.dnetlib.services.dsm.domain.Header;
import eu.dnetlib.services.dsm.domain.SimpleResponse;
public class ResponseUtils {
public static ApiDetailsResponse apiResponse(final List<ApiDetails> api, final long total) {
final ApiDetailsResponse rsp = new ApiDetailsResponse().setApi(api);
rsp.setHeader(header(total));
return rsp;
}
public static DatasourceSnippetResponse snippetResponse(final List<DatasourceSnippetExtended> snippets, final long total) {
final DatasourceSnippetResponse rsp = new DatasourceSnippetResponse(snippets);
rsp.setHeader(header(total));
return rsp;
}
public static DatasourceDetailResponse detailsResponse(final List<DatasourceDetails> details, final long total) {
final DatasourceDetailResponse rsp = new DatasourceDetailResponse(details);
rsp.setHeader(header(total));
return rsp;
}
public static DatasourceSearchResponse searchResponse(final List<DatasourceInfo> infos, final long total) {
final DatasourceSearchResponse rsp = new DatasourceSearchResponse(infos);
rsp.setHeader(header(total));
return rsp;
}
public static Header header(final Queue<Throwable> errors, final long total) {
return Header.newInsance()
.setExceptions(errors)
.setTotal(total);
}
public static Header header(final long total) {
return header(new LinkedList<>(), total);
}
public static <T> SimpleResponse<T> simpleResponse(final List<T> list) {
final SimpleResponse<T> rsp = new SimpleResponse<T>().setResponse(list);;
rsp.setHeader(header(new LinkedList<>(), list.size()));
return rsp;
}
}

View File

@ -0,0 +1,35 @@
package eu.dnetlib.services.dsm.utils;
import org.springframework.stereotype.Component;
import eu.dnetlib.data.model.vocabulary.Vocabulary;
@Component
public class VocabularyClient {
public void dropCache() {
// TODO Auto-generated method stub
}
public Vocabulary getCountries() {
// TODO Auto-generated method stub
return null;
}
public Vocabulary getDatasourceTypologies() {
// TODO Auto-generated method stub
return null;
}
public boolean isValidTerm(final String string, final String type) {
// TODO Auto-generated method stub
return false;
}
public Iterable<?> findTermsByVocabulary(final String vocabulary) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -0,0 +1,33 @@
package eu.dnetlib.services.dsm.utils;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import eu.dnetlib.errors.DsmException;
import eu.dnetlib.services.dsm.domain.AggregationInfo;
/**
* Created by claudio on 20/10/2016.
*/
@Component
@ConditionalOnProperty(value = "openaire.api.enable.dsm", havingValue = "true")
public class WfLoggerClient {
private static final Log log = LogFactory.getLog(WfLoggerClient.class);
private final static String LOADTIME = "loadtime";
public List<AggregationInfo> getAggregationHistory(final String dsId) throws DsmException {
// TODO Auto-generated method stub
return null;
}
public void dropCache() {
// TODO Auto-generated method stub
}
}

View File

@ -13,6 +13,12 @@
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>dnet-db-common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Mail -->
<dependency>
<groupId>javax.mail</groupId>

View File

@ -6,10 +6,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import eu.dnetlib.base.AbstractDnetApp;
@SpringBootApplication
public class EmailSenderApplication extends AbstractDnetApp {
public class EmailApplication extends AbstractDnetApp {
public static void main(final String[] args) {
SpringApplication.run(EmailSenderApplication.class, args);
SpringApplication.run(EmailApplication.class, args);
}
}

View File

@ -11,6 +11,9 @@ public class EmailConfiguration {
private int smtpPort;
private String smtpUser;
private String smtpPassword;
private String defaultFromEmail;
private String defaultFromName;
private String defaultCc;
public String getSmtpHost() {
return smtpHost;
@ -44,4 +47,28 @@ public class EmailConfiguration {
this.smtpPassword = smtpPassword;
}
public String getDefaultFromEmail() {
return defaultFromEmail;
}
public void setDefaultFromEmail(final String defaultFromEmail) {
this.defaultFromEmail = defaultFromEmail;
}
public String getDefaultFromName() {
return defaultFromName;
}
public void setDefaultFromName(final String defaultFromName) {
this.defaultFromName = defaultFromName;
}
public String getDefaultCc() {
return defaultCc;
}
public void setDefaultCc(final String defaultCc) {
this.defaultCc = defaultCc;
}
}

View File

@ -1,102 +0,0 @@
package eu.dnetlib.utils.mail;
import java.util.Arrays;
import java.util.Date;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import eu.dnetlib.errors.DnetException;
import eu.dnetlib.errors.DnetRuntimeException;
import eu.dnetlib.params.EmailMessage;
@Component
public class EmailService {
private static final Log log = LogFactory.getLog(EmailService.class);
@Autowired
private EmailConfiguration conf;
public void sendMail(final EmailMessage email, final boolean async) throws DnetException {
try {
final Session session = Session.getInstance(obtainProperties(), obtainAuthenticator());
final MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setFrom(new InternetAddress(email.getFromMail(), email.getFromName()));
mimeMessage.setSubject(email.getSubject());
mimeMessage.setContent(email.getContent(), "text/html; charset=utf-8");
mimeMessage.setSentDate(new Date());
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(email.getTo()));
if (email.getCcs() != null) {
for (final String cc : email.getCcs()) {
mimeMessage.addRecipient(Message.RecipientType.CC, new InternetAddress(cc));
}
}
if (async) {
final Thread t = new Thread(() -> {
try {
sendMail(mimeMessage);
} catch (final MessagingException e) {
log.error("Error sending mail", e);
throw new DnetRuntimeException("Error sending mail", e);
}
});
t.start();
} else {
sendMail(mimeMessage);
}
} catch (final Exception e) {
log.error("Error sending mail", e);
throw new DnetRuntimeException("Error sending mail", e);
}
}
public void sendMail(final MimeMessage mimeMessage) throws MessagingException {
log.info("Sending mail to " + Arrays.toString(mimeMessage.getAllRecipients()) + "...");
Transport.send(mimeMessage);
log.info("...sent");
}
private Properties obtainProperties() {
final Properties p = new Properties();
p.put("mail.transport.protocol", "smtp");
p.put("mail.smtp.host", conf.getSmtpHost());
p.put("mail.smtp.port", conf.getSmtpPort());
p.put("mail.smtp.auth", Boolean.toString(StringUtils.isNotBlank(conf.getSmtpUser())));
return p;
}
private Authenticator obtainAuthenticator() {
if (StringUtils.isBlank(conf.getSmtpUser())) { return null; }
return new Authenticator() {
private final PasswordAuthentication authentication =
new PasswordAuthentication(conf.getSmtpUser(), conf.getSmtpPassword());
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return authentication;
}
};
}
}

View File

@ -0,0 +1,41 @@
package eu.dnetlib.utils.mail.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.base.AbstractDnetController;
import eu.dnetlib.data.model.email.EmailTemplate;
import eu.dnetlib.utils.mail.service.EmailService;
@RestController
@RequestMapping("/ajax")
public class EmailAjaxController extends AbstractDnetController {
@Autowired
protected EmailService emailService;
@GetMapping("/")
public List<EmailTemplate> listEmailTemplates() {
return emailService.listEmailTemplates();
}
@PostMapping("/")
public List<EmailTemplate> saveEmailTemplate(@RequestBody final EmailTemplate email) {
emailService.saveEmailTemplate(email);
return emailService.listEmailTemplates();
}
@DeleteMapping("/{id}")
public List<EmailTemplate> deleteEmailTemplate(@PathVariable final String id) {
emailService.deleteEmailTemplate(id);
return emailService.listEmailTemplates();
}
}

View File

@ -1,4 +1,4 @@
package eu.dnetlib.utils.mail;
package eu.dnetlib.utils.mail.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
@ -9,17 +9,18 @@ import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.base.AbstractDnetController;
import eu.dnetlib.errors.DnetException;
import eu.dnetlib.params.EmailMessage;
import eu.dnetlib.utils.mail.service.EmailService;
@RestController
@RequestMapping("/api")
public class EmailSenderController extends AbstractDnetController {
public class EmailApiController extends AbstractDnetController {
@Autowired
private EmailService emailService;
@PostMapping("/send")
public String sendMail(@RequestBody final EmailMessage email) throws DnetException {
emailService.sendMail(email, true);
emailService.sendMail(email);
return "Sending mail to " + email.getTo();
}

View File

@ -1,4 +1,4 @@
package eu.dnetlib.utils.mail;
package eu.dnetlib.utils.mail.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

View File

@ -0,0 +1,9 @@
package eu.dnetlib.utils.mail.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import eu.dnetlib.data.model.email.EmailTemplate;
public interface EmailTemplateRepository extends JpaRepository<EmailTemplate, String> {
}

View File

@ -0,0 +1,181 @@
package eu.dnetlib.utils.mail.service;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import javax.annotation.PostConstruct;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import eu.dnetlib.data.model.email.EmailTemplate;
import eu.dnetlib.errors.DnetException;
import eu.dnetlib.errors.DnetRuntimeException;
import eu.dnetlib.params.EmailMessage;
import eu.dnetlib.utils.mail.EmailConfiguration;
import eu.dnetlib.utils.mail.repository.EmailTemplateRepository;
@Service
public class EmailService {
private static final Log log = LogFactory.getLog(EmailService.class);
private final BlockingQueue<Message> queue = new LinkedBlockingQueue<>();
@Autowired
private EmailTemplateRepository emailTemplateRepository;
@Autowired
private EmailConfiguration conf;
@PostConstruct
private void init() {
new Thread(() -> {
while (true) {
try {
final Message message = this.queue.take();
if (message != null) {
try {
log.info("Sending mail...");
Transport.send(message);
log.info("...sent");
} catch (final MessagingException e) {
log.error("Error sending email", e);
this.queue.add(message);
}
}
} catch (final InterruptedException e1) {
throw new RuntimeException(e1);
}
}
}).start();
}
public List<EmailTemplate> listEmailTemplates() {
return emailTemplateRepository.findAll();
}
public void saveEmailTemplate(final EmailTemplate email) {
if (StringUtils.isBlank(email.getId()) || email.getId().length() < 10) {
email.setId("email-" + UUID.randomUUID());
log.info("Saving new email with id: " + email.getId());
}
emailTemplateRepository.save(email);
}
public void deleteEmailTemplate(final String id) {
emailTemplateRepository.deleteById(id);
}
public void sendMail(final EmailMessage email) throws DnetException {
try {
final Session session = Session.getInstance(obtainProperties(), obtainAuthenticator());
final MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setFrom(new InternetAddress(email.getFromMail(), email.getFromName()));
mimeMessage.setSubject(email.getSubject());
mimeMessage.setContent(email.getContent(), "text/html; charset=utf-8");
mimeMessage.setSentDate(new Date());
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(email.getTo()));
if (email.getCcs() != null) {
for (final String cc : email.getCcs()) {
mimeMessage.addRecipient(Message.RecipientType.CC, new InternetAddress(cc));
}
}
this.queue.add(mimeMessage);
log.info("Mail to " + email.getTo() + " in queue");
} catch (final Exception e) {
log.error("Error sending mail", e);
throw new DnetRuntimeException("Error sending mail", e);
}
}
public void sendMail(final String to, final String subject, final String message) {
try {
final Session session = Session.getInstance(obtainProperties(), obtainAuthenticator());
final MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setFrom(new InternetAddress(conf.getDefaultFromEmail(), conf.getDefaultFromName()));
mimeMessage.setSubject(subject);
mimeMessage.setContent(message, "text/html; charset=utf-8");
mimeMessage.setSentDate(new Date());
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
if (conf.getDefaultCc() != null) {
for (final String cc : StringUtils.split(conf.getDefaultCc(), ",")) {
mimeMessage.addRecipient(Message.RecipientType.CC, new InternetAddress(cc.trim()));
}
}
this.queue.add(mimeMessage);
log.info("Mail to " + to + " in queue");
} catch (final Exception e) {
log.error("Error sending mail", e);
}
}
public void sendStoredMail(final String to, final String emailId, final Map<String, Object> params) {
// TODO use a real template library
emailTemplateRepository.findById(emailId).ifPresent(tmpl -> {
String msg = tmpl.getMessage();
String subject = tmpl.getSubject();
for (final Entry<String, Object> e : params.entrySet()) {
msg = msg.replaceAll("{" + e.getKey() + "}", e.getValue().toString());
subject = subject.replaceAll("{" + e.getKey() + "}", e.getValue().toString());
}
sendMail(to, subject, msg);
});
}
private Properties obtainProperties() {
final Properties p = new Properties();
p.put("mail.transport.protocol", "smtp");
p.put("mail.smtp.host", conf.getSmtpHost());
p.put("mail.smtp.port", conf.getSmtpPort());
p.put("mail.smtp.auth", Boolean.toString(StringUtils.isNotBlank(conf.getSmtpUser())));
return p;
}
private Authenticator obtainAuthenticator() {
if (StringUtils.isBlank(conf.getSmtpUser())) { return null; }
return new Authenticator() {
private final PasswordAuthentication authentication =
new PasswordAuthentication(conf.getSmtpUser(), conf.getSmtpPassword());
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return authentication;
}
};
}
}

View File

@ -9,4 +9,7 @@ mail.smtpHost = localhost
mail.smtpPort = 587
mail.smtpUser =
mail.smtpPassword =
mail.defaultFromEmail = noreply@openaire.eu
mail.defaultFromName = D-NET UI
mail.defaultCc = D-NET UI

View File

@ -8,11 +8,17 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dnet-apis</artifactId>
<artifactId>dnet-is</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>dnet-db-common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- hot swapping, disable cache for template, enable live reload -->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -0,0 +1,29 @@
package eu.dnetlib;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.data.model.resource.ResourceType;
@RestController
public class MainAjaxController {
@Autowired
private ResourceTypeRepository resourceTypeRepository;
@GetMapping("/ajax/resourceTypes")
public Iterable<ResourceType> resourceTypes() {
return resourceTypeRepository.findAll();
}
@GetMapping("/ajax/resourceTypes/{id}")
public ResourceType resourceTypes(@PathVariable final String id) {
return resourceTypeRepository
.findById(id)
.orElse(new ResourceType("not_present", "???", MediaType.TEXT_PLAIN_VALUE, 0));
}
}

View File

@ -0,0 +1,36 @@
package eu.dnetlib;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import eu.dnetlib.common.app.AbstractDnetApp;
@SpringBootApplication
@EnableCaching
@EnableScheduling
@ComponentScan(basePackages = "eu.dnetlib")
public class MainApplication extends AbstractDnetApp {
public static void main(final String[] args) {
SpringApplication.run(MainApplication.class, args);
}
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("D-Net Information Service API")
.pathsToMatch("/api/**")
.build();
}
@Override
protected String swaggerTitle() {
return "D-Net Information Service APIs";
}
}

View File

@ -0,0 +1,63 @@
package eu.dnetlib;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "mainEntityManagerFactory", transactionManagerRef = "mainTransactionManager", basePackages = {
"eu.dnetlib.is",
"eu.dnetlib.common",
"eu.dnetlib.manager.history",
"eu.dnetlib.manager.wf",
"eu.dnetlib.data.mdstore"
})
public class MainDBConfig {
@Primary
@Bean(name = "mainDataSource")
@ConfigurationProperties(prefix = "is.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "mainEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
final EntityManagerFactoryBuilder builder,
@Qualifier("mainDataSource") final DataSource ds) {
return builder
.dataSource(ds)
.packages("eu.dnetlib.is.model", "eu.dnetlib.manager.history.model", "eu.dnetlib.common.model", "eu.dnetlib.manager.wf.model", "eu.dnetlib.data.mdstore.model")
.persistenceUnit("is")
.build();
}
@Primary
@Bean(name = "mainTransactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("mainEntityManagerFactory") final EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}
@Primary
@Bean(name = "mainJdbcTemplate")
public JdbcTemplate jdbcTemplate1(@Qualifier("mainDataSource") final DataSource ds) {
return new JdbcTemplate(ds);
}
}

View File

@ -0,0 +1,53 @@
package eu.dnetlib;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "openaireEntityManagerFactory", transactionManagerRef = "openaireTransactionManager", basePackages = {
"eu.dnetlib.dsm"
})
public class OpenaireDBConfig {
@Bean(name = "openaireDataSource")
@ConfigurationProperties(prefix = "openaire.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "openaireEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean openaireEntityManagerFactory(
final EntityManagerFactoryBuilder builder,
@Qualifier("openaireDataSource") final DataSource ds) {
return builder
.dataSource(ds)
.packages("eu.dnetlib.dsm.model")
.persistenceUnit("openaire")
.build();
}
@Bean(name = "openaireTransactionManager")
public PlatformTransactionManager opeanaireTransactionManager(
@Qualifier("openaireEntityManagerFactory") final EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}
@Bean(name = "openaireJdbcTemplate")
public JdbcTemplate jdbcTemplate1(@Qualifier("openaireDataSource") final DataSource ds) {
return new JdbcTemplate(ds);
}
}

View File

@ -0,0 +1,16 @@
package eu.dnetlib;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class SwaggerController {
@RequestMapping(value = {
"/", "/docs", "swagger-ui.html", "swagger-ui/"
})
public String apiDoc() {
return "redirect:swagger-ui/index.html";
}
}

View File

@ -0,0 +1,124 @@
package eu.dnetlib.data.mdstore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import eu.dnetlib.common.controller.AbstractDnetController;
import eu.dnetlib.data.mdstore.model.MDStoreType;
import eu.dnetlib.data.mdstore.model.MDStoreVersion;
import eu.dnetlib.data.mdstore.model.MDStoreWithInfo;
import eu.dnetlib.errors.MDStoreManagerException;
import io.swagger.v3.oas.annotations.Operation;
public class AbstractMDStoreController extends AbstractDnetController {
@Autowired
protected MDStoreService service;
@Operation(summary = "Return all the mdstores")
@GetMapping("/")
public Iterable<MDStoreWithInfo> find() {
return service.listMdStores();
}
@Operation(summary = "Return a mdstores by id")
@GetMapping("/mdstore/{mdId}")
public MDStoreWithInfo getMdStore(@PathVariable final String mdId) throws MDStoreManagerException {
return service.findMdStore(mdId);
}
@Operation(summary = "Create a new mdstore")
@PostMapping("/new/{format}/{layout}/{interpretation}/{type}")
public MDStoreWithInfo createMDStore(
@PathVariable final String format,
@PathVariable final String layout,
@PathVariable final String interpretation,
@PathVariable final String type,
@RequestParam(required = true) final String dsName,
@RequestParam(required = true) final String dsId,
@RequestParam(required = true) final String apiId) throws MDStoreManagerException {
final String id = service.createMDStore(format, layout, interpretation, MDStoreType.valueOf(type), dsName, dsId, apiId);
return service.findMdStore(id);
}
@Operation(summary = "Delete a mdstore by id")
@DeleteMapping("/mdstore/{mdId}")
public StatusResponse delete(@PathVariable final String mdId)
throws MDStoreManagerException {
service.deleteMdStore(mdId);
return StatusResponse.DELETED;
}
@Operation(summary = "Return all the versions of a mdstore")
@GetMapping("/mdstore/{mdId}/versions")
public Iterable<MDStoreVersion> listVersions(@PathVariable final String mdId) throws MDStoreManagerException {
return service.listVersions(mdId);
}
@Operation(summary = "Create a new preliminary version of a mdstore")
@GetMapping("/mdstore/{mdId}/newVersion")
public MDStoreVersion prepareNewVersion(
@PathVariable final String mdId) throws MDStoreManagerException {
return service.prepareMdStoreVersion(mdId);
}
@Operation(summary = "Promote a preliminary version to current")
@GetMapping("/version/{versionId}/commit/{size}")
public MDStoreVersion commitVersion(
@PathVariable final String versionId,
@PathVariable final long size) throws MDStoreManagerException {
try {
return service.commitMdStoreVersion(versionId, size);
} finally {
service.deleteExpiredVersions();
}
}
@Operation(summary = "Abort a preliminary version")
@GetMapping("/version/{versionId}/abort")
public StatusResponse commitVersion(@PathVariable final String versionId)
throws MDStoreManagerException {
service.deleteMdStoreVersion(versionId, true);
return StatusResponse.ABORTED;
}
@Operation(summary = "Return an existing mdstore version")
@GetMapping("/version/{versionId}")
public MDStoreVersion getVersion(@PathVariable final String versionId)
throws MDStoreManagerException {
return service.findVersion(versionId);
}
@Operation(summary = "Delete a mdstore version")
@DeleteMapping("/version/{versionId}")
public StatusResponse deleteVersion(@PathVariable final String versionId,
@RequestParam(required = false, defaultValue = "false") final boolean force)
throws MDStoreManagerException {
service.deleteMdStoreVersion(versionId, force);
return StatusResponse.DELETED;
}
@Operation(summary = "Decrease the read count of a mdstore version")
@GetMapping("/version/{versionId}/endReading")
public MDStoreVersion endReading(@PathVariable final String versionId) throws MDStoreManagerException {
return service.endReading(versionId);
}
@Operation(summary = "Reset the read count of a mdstore version")
@GetMapping("/version/{versionId}/resetReading")
public MDStoreVersion resetReading(@PathVariable final String versionId) throws MDStoreManagerException {
return service.resetReading(versionId);
}
}

View File

@ -0,0 +1,56 @@
package eu.dnetlib.data.mdstore;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.data.mdstore.model.records.MetadataRecord;
import eu.dnetlib.errors.MDStoreManagerException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@RequestMapping("/ajax/mdstores")
@Tag(name = "Metadata Stores")
public class MDStoreAjaxController extends AbstractMDStoreController {
@Value("${dhp.mdstore-manager.hadoop.cluster}")
private String hadoopCluster;
@Value("${dhp.mdstore-manager.hadoop.user}")
private String hadoopUser;
@Value("${dhp.mdstore-manager.hdfs.base-path}")
private String hdfsBasePath;
@Operation(summary = "Show informations")
@GetMapping("/info")
public Map<String, Object> info() {
final Map<String, Object> info = new LinkedHashMap<>();
info.put("number_of_mdstores", service.countMdStores());
info.put("hadoop_user", hadoopUser);
info.put("hadoop_cluster", hadoopCluster);
info.put("hdfs_base_path", hdfsBasePath);
info.put("expired_versions", service.listExpiredVersions());
return info;
}
@Operation(summary = "read the parquet file of a mdstore version")
@GetMapping("/version/{versionId}/content/{limit}")
public List<? extends MetadataRecord> listVersionRecords(@PathVariable final String versionId, @PathVariable final long limit)
throws MDStoreManagerException {
return service.listVersionRecords(versionId, limit);
}
@Operation(summary = "read the parquet file of a mdstore (current version)")
@GetMapping("/mdstore/{mdId}/content/{limit}")
public List<? extends MetadataRecord> listMdstoreRecords(@PathVariable final String mdId, @PathVariable final long limit) throws MDStoreManagerException {
return service.listVersionRecords(service.findMdStore(mdId).getCurrentVersion(), limit);
}
}

View File

@ -0,0 +1,59 @@
package eu.dnetlib.data.mdstore;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.data.mdstore.model.MDStoreType;
import eu.dnetlib.data.mdstore.model.MDStoreVersion;
import eu.dnetlib.errors.MDStoreManagerException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
@RequestMapping("/api/mdstores")
@Tag(name = "Metadata Stores")
public class MDStoreApiController extends AbstractMDStoreController {
@Operation(summary = "Return all the mdstore identifiers")
@GetMapping("/ids")
public List<String> findIdentifiers() {
return service.listMdStoreIDs();
}
@Operation(summary = "Increase the read count of the current mdstore")
@GetMapping("/mdstore/{mdId}/startReading")
public MDStoreVersion startReading(@PathVariable final String mdId) throws MDStoreManagerException {
return service.startReading(mdId);
}
@Operation(summary = "Fix the inconsistencies on HDFS")
@GetMapping("/hdfs/inconsistencies")
public Map<MDStoreType, Set<String>> fixHdfsInconsistencies(
@RequestParam(required = false, defaultValue = "false") final boolean forceDelete)
throws MDStoreManagerException {
return service.fixInconsistencies(forceDelete);
}
@Operation(summary = "Delete expired versions")
@DeleteMapping("/versions/expired")
public StatusResponse deleteExpiredVersions() {
new Thread(service::deleteExpiredVersions).start();
return StatusResponse.DELETING;
}
@Operation(summary = "list the file inside the path of a mdstore version")
@GetMapping("/version/{versionId}/files")
public Set<String> listVersionFiles(@PathVariable final String versionId) throws MDStoreManagerException {
return service.listVersionInternalFiles(versionId);
}
}

View File

@ -0,0 +1,25 @@
package eu.dnetlib.data.mdstore;
public class StatusResponse {
public static final StatusResponse DELETED = new StatusResponse("DELETED");
public static final StatusResponse DELETING = new StatusResponse("DELETING...");
public static final StatusResponse ABORTED = new StatusResponse("ABORTED");;
private String status;
public StatusResponse() {}
public StatusResponse(final String status) {
this.status = status;
}
public String getStatus() {
return status;
}
public void setStatus(final String status) {
this.status = status;
}
}

View File

@ -0,0 +1,30 @@
package eu.dnetlib.data.mdstore;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.common.controller.AbstractDnetController;
import eu.dnetlib.data.mdstore.hadoop.ZeppelinClient;
import eu.dnetlib.errors.MDStoreManagerException;
@RestController
@RequestMapping("/zeppelin")
public class ZeppelinAjaxController extends AbstractDnetController {
@Autowired
private ZeppelinClient zeppelinClient;
@GetMapping("/templates")
public List<String> getTemplates() throws MDStoreManagerException {
try {
return zeppelinClient.listTemplates();
} catch (final Throwable e) {
throw new MDStoreManagerException("Zeppelin is unreachable", e);
}
}
}

View File

@ -0,0 +1,37 @@
package eu.dnetlib.data.mdstore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import eu.dnetlib.data.mdstore.hadoop.ZeppelinClient;
import eu.dnetlib.data.mdstore.model.MDStoreType;
import eu.dnetlib.data.mdstore.model.MDStoreVersion;
import eu.dnetlib.data.mdstore.model.MDStoreWithInfo;
import eu.dnetlib.errors.MDStoreManagerException;
@Controller
public class ZeppelinController {
@Autowired
private ZeppelinClient zeppelinClient;
@Autowired
private MDStoreService service;
@RequestMapping("/zeppelin/{mdId}/{note}")
public String goToZeppelin(@PathVariable final String mdId, final @PathVariable String note) throws MDStoreManagerException {
final MDStoreWithInfo mdstore = service.findMdStore(mdId);
if (mdstore.getType() == MDStoreType.HDFS) {
final String currentVersion = mdstore.getCurrentVersion();
final MDStoreVersion version = service.findVersion(currentVersion);
if (version.getParams().containsKey("hdfs_path")) {
final String path = version.getParams().get("hdfs_path") + "/store";
return "redirect:" + zeppelinClient.zeppelinNote(note, mdstore, path);
}
}
throw new MDStoreManagerException();
}
}

View File

@ -0,0 +1,21 @@
package eu.dnetlib.is.context;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import eu.dnetlib.common.controller.AbstractDnetController;
import eu.dnetlib.is.model.context.Context;
public class AbstractContextController extends AbstractDnetController {
@Autowired
protected ContextService contextService;
@GetMapping("/")
public List<Context> listContexts() {
return contextService.listContexts();
}
}

View File

@ -0,0 +1,33 @@
package eu.dnetlib.is.context;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.errors.InformationServiceException;
import eu.dnetlib.is.model.context.Category;
import eu.dnetlib.is.model.context.Context;
import eu.dnetlib.is.model.context.CtxChildInfo;
@RestController
@RequestMapping("/ajax/contexts")
public class ContextAjaxController extends AbstractContextController {
@GetMapping("/{ctxId}")
public Context getContext(@PathVariable final String ctxId) throws InformationServiceException {
return contextService.getContext(ctxId);
}
@GetMapping("/{parent}/categories")
public Iterable<Category> listCategories(@PathVariable final String parent) {
return contextService.listCategories(parent);
}
@GetMapping("/{level}/{parent}/concepts")
public Iterable<? extends CtxChildInfo> listCategories(@PathVariable final int level, @PathVariable final String parent)
throws InformationServiceException {
return contextService.listConcepts(level, parent);
}
}

View File

@ -0,0 +1,21 @@
package eu.dnetlib.is.context;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.node.ObjectNode;
import eu.dnetlib.errors.InformationServiceException;
@RestController
@RequestMapping("/api/contexts")
public class ContextApiController extends AbstractContextController {
@GetMapping("/{ctxId}")
public ObjectNode getContextFull(@PathVariable final String ctxId) throws InformationServiceException {
return contextService.getContextFull(ctxId);
}
}

View File

@ -0,0 +1,113 @@
package eu.dnetlib.is.importer;
import java.io.IOException;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import eu.dnetlib.is.context.repository.CategoryRepository;
import eu.dnetlib.is.context.repository.ConceptLevel0Repository;
import eu.dnetlib.is.context.repository.ConceptLevel1Repository;
import eu.dnetlib.is.context.repository.ConceptLevel2Repository;
import eu.dnetlib.is.context.repository.ContextRepository;
import eu.dnetlib.is.model.context.Category;
import eu.dnetlib.is.model.context.ConceptLevel0;
import eu.dnetlib.is.model.context.ConceptLevel1;
import eu.dnetlib.is.model.context.ConceptLevel2;
import eu.dnetlib.is.model.context.Context;
import eu.dnetlib.is.model.context.CtxChildInfo;
import eu.dnetlib.is.model.context.CtxInfo;
import eu.dnetlib.is.model.context.Parameter;
@Service
public class ContextImporter {
@Autowired
private ContextRepository contextRepository;
@Autowired
private CategoryRepository categoryRepository;
@Autowired
private ConceptLevel0Repository conceptLevel0Repository;
@Autowired
private ConceptLevel1Repository conceptLevel1Repository;
@Autowired
private ConceptLevel2Repository conceptLevel2Repository;
private static final Log log = LogFactory.getLog(ContextImporter.class);
public void loadFromOldProfile(final String xml) throws DocumentException, IOException {
DocumentHelper.parseText(xml)
.selectNodes("//context")
.forEach(this::saveContext);
}
private void saveContext(final Node node) {
final Context ctx = new Context();
setCommonInfo(ctx, null, node);
ctx.setType(node.valueOf("@type"));
contextRepository.save(ctx);
log.info("Saved context: " + ctx.getId());
node.selectNodes("./category").forEach(n -> saveCategory(n, ctx.getId()));
}
private void saveCategory(final Node node, final String ctxId) {
final Category cat = new Category();
setCommonInfo(cat, ctxId, node);
categoryRepository.save(cat);
log.info("- Saved category: " + cat.getId());
node.selectNodes("./concept").forEach(n -> saveConceptLvl0(n, cat.getId()));
}
private void saveConceptLvl0(final Node node, final String parent) {
final ConceptLevel0 c0 = new ConceptLevel0();
setCommonInfo(c0, parent, node);
conceptLevel0Repository.save(c0);
log.info("-- Saved concept 0: " + c0.getId());
node.selectNodes("./concept").forEach(n -> saveConceptLvl1(n, c0.getId()));
}
private void saveConceptLvl1(final Node node, final String parent) {
final ConceptLevel1 c1 = new ConceptLevel1();
setCommonInfo(c1, parent, node);
conceptLevel1Repository.save(c1);
log.info("--- Saved concept 1: " + c1.getId());
node.selectNodes("./concept").forEach(n -> saveConceptLvl2(n, c1.getId()));
}
private void saveConceptLvl2(final Node node, final String parent) {
final ConceptLevel2 c2 = new ConceptLevel2();
setCommonInfo(c2, parent, node);
conceptLevel2Repository.save(c2);
log.info("---- Saved concept 2: " + c2.getId());
}
private void setCommonInfo(final CtxInfo o, final String parent, final Node n) {
o.setId(n.valueOf("@id"));
o.setLabel(n.valueOf("@label"));
if (o instanceof CtxChildInfo) {
((CtxChildInfo) o).setParent(parent);
((CtxChildInfo) o).setClaim(BooleanUtils.toBoolean(n.valueOf("@claim")));
}
o.setParameters(n.selectNodes("./param")
.stream()
.map(np -> new Parameter(np.valueOf("@name"), np.getText()))
.sorted()
.toArray(Parameter[]::new));
}
}

View File

@ -0,0 +1,80 @@
package eu.dnetlib.is.importer;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;
import org.dom4j.DocumentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.common.controller.AbstractDnetController;
import eu.dnetlib.is.model.vocabulary.Vocabulary;
@RestController
@RequestMapping("/api/import")
public class ImporterController extends AbstractDnetController {
// EXAMPLE:
// find ./VocabularyDSResourceType/ -name "*.xml" -exec curl -X POST "http://localhost:8280/api/import/vocabulary" -H "accept: */*" -H
// "Content-Type: text/plain" --data-binary @{} \;
// find ./DedupConfigurationDSResources/ -name "*.xml" -exec curl -X POST "http://localhost:8280/api/import/resource" -H "accept: */*"
// -H "Content-Type: text/plain" --data-binary @{} \;
@Autowired
private ContextImporter contextImporter;
@Autowired
private OldProfilesImporter oldProfilesImporter;
@Autowired
private WfHistoryImporter wfHistoryImporter;
@PostMapping(value = "/context", consumes = {
MediaType.TEXT_PLAIN_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE
})
public List<String> importContext(final HttpServletRequest request) throws DocumentException, IOException {
final String xml = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
contextImporter.loadFromOldProfile(xml);
return Arrays.asList("Done.");
}
@PostMapping(value = "/resource", consumes = {
MediaType.TEXT_PLAIN_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE
})
public String importResource(final HttpServletRequest request) throws Exception {
final String xml = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
return oldProfilesImporter.importSimpleResource(xml);
}
@PostMapping(value = "/vocabulary", consumes = {
MediaType.TEXT_PLAIN_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE
})
public Vocabulary importVocabulary(final HttpServletRequest request) throws Exception, IOException {
final String xml = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
return oldProfilesImporter.importVocabulary(xml);
}
@GetMapping(value = "/wf_logs")
public List<String> importWfLogs(@RequestParam final String path) throws Exception {
// mongoexport -d dnet_logs -c wf_logs --jsonArray -o /tmp/mongodump.json
wfHistoryImporter.load(path);
return Arrays.asList("Done.");
}
}

View File

@ -0,0 +1,156 @@
package eu.dnetlib.is.importer;
import java.time.LocalDateTime;
import javax.transaction.Transactional;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import eu.dnetlib.errors.InformationServiceException;
import eu.dnetlib.is.model.resource.SimpleResource;
import eu.dnetlib.is.model.vocabulary.Synonym;
import eu.dnetlib.is.model.vocabulary.Vocabulary;
import eu.dnetlib.is.model.vocabulary.VocabularyTerm;
import eu.dnetlib.is.resource.ResourceValidator;
import eu.dnetlib.is.resource.repository.SimpleResourceRepository;
import eu.dnetlib.is.vocabulary.repository.VocabularyRepository;
import eu.dnetlib.is.vocabulary.repository.VocabularyTermRepository;
import eu.dnetlib.utils.XmlIndenter;
@Service
public class OldProfilesImporter {
@Autowired
private SimpleResourceRepository simpleResourceRepository;
@Autowired
private VocabularyRepository vocabularyRepository;
@Autowired
private VocabularyTermRepository vocabularyTermRepository;
@Autowired
private ResourceValidator resourceValidator;
@Transactional
public String importSimpleResource(final String xml) throws InformationServiceException {
try {
final Document doc = DocumentHelper.parseText(xml);
final String id = StringUtils.substringBefore(doc.valueOf("//RESOURCE_IDENTIFIER/@value"), "_");
final LocalDateTime now = LocalDateTime.now();
final SimpleResource res = new SimpleResource();
res.setId(id);
res.setCreationDate(now);
res.setModificationDate(now);
String resContent;
switch (doc.valueOf("//RESOURCE_TYPE/@value")) {
case "CleanerDSResourceType":
res.setType("cleaning_rule");
res.setName(doc.valueOf("//CLEANER_NAME"));
res.setDescription(doc.valueOf("//CLEANER_DESCRIPTION"));
for (final Node n : doc.selectNodes("//RULE")) {
final Element e = (Element) n;
e.addAttribute("vocabulary", e.valueOf("@vocabularies"));
for (final Attribute attr : e.attributes()) {
if (attr.getName() == "vocabularies" || attr.getName() == "groovy") {
attr.detach();
}
}
}
resContent = XmlIndenter.indent(doc.selectSingleNode("//CLEANER_RULES"));
break;
case "TransformationRuleDSResourceType":
res.setName(doc.valueOf("//SCRIPT/TITLE"));
res.setDescription("");
if (doc.selectNodes("//*[local-name() = 'stylesheet']").size() > 0) {
res.setType("transformation_rule_xslt");
resContent = XmlIndenter.indent(doc.selectSingleNode("//*[local-name() = 'stylesheet']"));
} else {
final String code = doc.valueOf("//SCRIPT/CODE").trim();
try {
final Document xsltDoc = DocumentHelper.parseText(code);
res.setType("transformation_rule_xslt");
resContent = XmlIndenter.indent(xsltDoc);
} catch (final DocumentException e) {
res.setType("transformation_rule_legacy");
resContent = code;
}
}
break;
case "HadoopJobConfigurationDSResourceType":
res.setType("hadoop_job_configuration");
res.setName(doc.valueOf("//HADOOP_JOB/@name"));
res.setDescription(doc.valueOf("//HADOOP_JOB/DESCRIPTION"));
resContent = XmlIndenter.indent(doc.selectSingleNode("//HADOOP_JOB"));
break;
case "DedupConfigurationDSResourceType":
res.setType("dedup_configuration");
res.setName(doc.valueOf("//DESCRIPTION"));
res.setDescription(doc.valueOf("//DESCRIPTION"));
resContent = doc.valueOf("//DEDUPLICATION");
break;
default:
throw new InformationServiceException("Invalid resource type: " + doc.valueOf("//RESOURCE_TYPE/@value"));
}
resourceValidator.validate(res.getType(), resContent.trim());
simpleResourceRepository.save(res);
simpleResourceRepository.setContentById(id, resContent.trim());
return res.getId();
} catch (final Exception e) {
throw new InformationServiceException("Error parsing file", e);
}
}
@Transactional
public Vocabulary importVocabulary(final String xml) throws Exception {
final Document doc = DocumentHelper.parseText(xml);
final Vocabulary voc = new Vocabulary();
final String vocId = doc.valueOf("//VOCABULARY_NAME/@code");
final String vocName = doc.valueOf("//VOCABULARY_NAME");
final String vocDesc = doc.valueOf("//VOCABULARY_DESCRIPTION");
voc.setId(vocId);
voc.setName(vocName);
voc.setDescription(vocDesc);
vocabularyRepository.save(voc);
for (final Node n : doc.selectNodes("//TERM")) {
final VocabularyTerm term = new VocabularyTerm();
term.setVocabulary(vocId);
term.setCode(n.valueOf("@code"));
term.setName(n.valueOf("@english_name"));
term.setEncoding(n.valueOf("@encoding"));
term.setSynonyms(n.selectNodes(".//SYNONYM")
.stream()
.map(ns -> new Synonym(ns.valueOf("@term"), ns.valueOf("@encoding")))
.sorted()
.distinct()
.toArray(Synonym[]::new));
vocabularyTermRepository.save(term);
}
return voc;
}
}

View File

@ -0,0 +1,85 @@
package eu.dnetlib.is.importer;
import java.io.File;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.dnetlib.manager.history.model.WfHistoryEntry;
import eu.dnetlib.manager.history.repository.WfHistoryEntryRepository;
@Service
public class WfHistoryImporter {
private static final Log log = LogFactory.getLog(WfHistoryImporter.class);
@Autowired
private WfHistoryEntryRepository wfHistoryEntryRepository;
public void load(final String path) throws Exception {
final ObjectMapper mapper = new ObjectMapper();
final JsonNode rootNode = mapper.readTree(new File(path));
rootNode.forEach(wf -> saveWf(wf));
}
private void saveWf(final JsonNode node) {
final WfHistoryEntry wf = new WfHistoryEntry();
wf.setProcessId(node.get("system:processId").asText());
wf.setName(node.get("system:wfName").asText());
wf.setFamily(node.get("system:profileFamily").asText());
if (node.has("dataprovider:id")) {
wf.setDsId(node.get("dataprovider:id").asText());
}
if (node.has("dataprovider:name")) {
wf.setDsName(node.get("dataprovider:name").asText());
}
if (node.has("dataprovider:interface")) {
wf.setDsApi(node.get("dataprovider:interface").asText());
}
wf.setStartDate(LocalDateTime
.ofInstant(Instant.ofEpochMilli(NumberUtils.toLong(node.get("system:startDate").asText())), TimeZone.getDefault().toZoneId()));
wf.setEndDate(LocalDateTime.ofInstant(Instant.ofEpochMilli(NumberUtils.toLong(node.get("system:endDate").asText())), TimeZone.getDefault().toZoneId()));
if (BooleanUtils.toBoolean(node.get("system:isCompletedSuccessfully").asText())) {
wf.setStatus("success");
} else {
wf.setStatus("failure");
}
final Map<String, String> details = new LinkedHashMap<>();
final Iterator<Entry<String, JsonNode>> fields = node.fields();
while (fields.hasNext()) {
final Entry<String, JsonNode> f = fields.next();
if (f.getValue().isValueNode()) {
details.put(f.getKey(), f.getValue().asText());
}
}
wf.setDetails(details);
wfHistoryEntryRepository.save(wf);
log.info("Wf saved with id: " + wf.getProcessId());
}
}

View File

@ -0,0 +1,146 @@
package eu.dnetlib.is.info;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.common.controller.AbstractDnetController;
@RestController
@RequestMapping("/ajax/info")
public class InfoAjaxController extends AbstractDnetController {
@Autowired
private ConfigurableEnvironment configurableEnvironment;
@Autowired
private ResourceLoader resourceLoader;
private final RuntimeMXBean mxbean = ManagementFactory.getRuntimeMXBean();
private static final Log log = LogFactory.getLog(InfoAjaxController.class);
@GetMapping("/")
public List<InfoSection<?>> info() throws Exception {
final List<InfoSection<?>> res = new ArrayList<>();
res.add(jvm());
res.add(args());
res.addAll(props());
res.add(modules());
return res;
}
private InfoSection<KeyValue<String>> jvm() {
final InfoSection<KeyValue<String>> jvm = new InfoSection<>("JVM");
jvm.getData().add(new KeyValue<>("JVM Name", mxbean.getVmName()));
jvm.getData().add(new KeyValue<>("JVM Vendor", mxbean.getVmVendor()));
jvm.getData().add(new KeyValue<>("JVM Version", mxbean.getVmVersion()));
jvm.getData().add(new KeyValue<>("JVM Spec Name", mxbean.getSpecName()));
jvm.getData().add(new KeyValue<>("JVM Spec Vendor", mxbean.getSpecVendor()));
jvm.getData().add(new KeyValue<>("JVM Spec Version", mxbean.getSpecVersion()));
jvm.getData().add(new KeyValue<>("Running JVM Name", mxbean.getName()));
jvm.getData().add(new KeyValue<>("Management Spec Version", mxbean.getManagementSpecVersion()));
return jvm;
}
private InfoSection<KeyValue<String>> args() {
final InfoSection<KeyValue<String>> libs = new InfoSection<>("Arguments");
libs.getData().add(new KeyValue<>("Input arguments", StringUtils.join(mxbean.getInputArguments(), " ")));
return libs;
}
private List<InfoSection<KeyValue<?>>> props() {
final List<InfoSection<KeyValue<?>>> res = new ArrayList<>();
configurableEnvironment.getPropertySources().forEach(ps -> {
final InfoSection<KeyValue<?>> section = new InfoSection<>("Properties: " + ps.getName());
addAllProperties(section, ps);
res.add(section);
});
return res;
}
private void addAllProperties(final InfoSection<KeyValue<?>> res, final PropertySource<?> ps) {
if (ps instanceof CompositePropertySource) {
final CompositePropertySource cps = (CompositePropertySource) ps;
cps.getPropertySources().forEach(x -> addAllProperties(res, x));
} else if (ps instanceof EnumerablePropertySource<?>) {
final EnumerablePropertySource<?> eps = (EnumerablePropertySource<?>) ps;
Arrays.asList(eps.getPropertyNames()).forEach(k -> res.getData().add(new KeyValue<>(k, eps.getProperty(k))));
} else {}
}
public InfoSection<JavaModule> modules() throws IOException {
final Map<String, Map<String, JavaModule>> modules = new LinkedHashMap<>();
final MavenXpp3Reader reader = new MavenXpp3Reader();
for (final Resource res : ResourcePatternUtils.getResourcePatternResolver(resourceLoader).getResources("classpath*:/META-INF/**/pom.xml")) {
try {
final Model model = reader.read(res.getInputStream());
final String name = model.getArtifactId();
String groupId = model.getGroupId();
for (Parent parent = model.getParent(); groupId == null && model.getParent() != null; parent = model.getParent()) {
groupId = parent.getGroupId();
}
String version = model.getVersion();
for (Parent parent = model.getParent(); version == null && model.getParent() != null; parent = model.getParent()) {
version = parent.getVersion();
}
if (!modules.containsKey(groupId)) {
modules.put(groupId, new HashMap<String, JavaModule>());
}
if (!modules.get(groupId).containsKey(name)) {
modules.get(groupId).put(name, new JavaModule(groupId, name));
}
modules.get(groupId).get(name).addFileAndVersion(res.getURI().toString(), version);
} catch (final Exception e) {
log.error("Error evaluating pom: " + res.getURI());
log.debug("-- ERROR --", e);
}
}
final InfoSection<JavaModule> res = new InfoSection<>("Modules");
for (final Entry<String, Map<String, JavaModule>> e : modules.entrySet()) {
for (final Entry<String, JavaModule> e1 : e.getValue().entrySet()) {
res.getData().add(e1.getValue());
}
}
Collections.sort(res.getData());
return res;
}
}

View File

@ -0,0 +1,24 @@
package eu.dnetlib.is.info;
import java.util.ArrayList;
import java.util.List;
public class InfoSection<T> {
private final String name;
private final List<T> data;
public InfoSection(final String name) {
this.name = name;
this.data = new ArrayList<>();
}
public String getName() {
return name;
}
public List<T> getData() {
return data;
}
}

View File

@ -0,0 +1,50 @@
package eu.dnetlib.is.info;
import java.util.LinkedHashSet;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
public class JavaModule implements Comparable<JavaModule> {
private final String group;
private final String name;
private final Set<String> versions = new LinkedHashSet<>();
private final Set<String> files = new LinkedHashSet<>();
public JavaModule(final String group, final String name) {
this.group = group;
this.name = name;
}
public String getGroup() {
return group;
}
public String getName() {
return name;
}
public Set<String> getVersions() {
return versions;
}
public Set<String> getFiles() {
return files;
}
public void addFileAndVersion(final String file, final String version) {
files.add(file);
versions.add(version);
}
@Override
public int compareTo(final JavaModule o) {
if (getGroup().equals(o.getGroup())) {
return StringUtils.compare(getName(), o.getName());
} else {
return StringUtils.compare(getGroup(), o.getGroup());
}
}
}

View File

@ -0,0 +1,21 @@
package eu.dnetlib.is.info;
public class KeyValue<T> {
private final String k;
private final T v;
public KeyValue(final String k, final T v) {
this.k = k;
this.v = v;
}
public String getK() {
return k;
}
public T getV() {
return v;
}
}

View File

@ -0,0 +1,52 @@
package eu.dnetlib.is.resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import eu.dnetlib.common.controller.AbstractDnetController;
import eu.dnetlib.errors.InformationServiceException;
import eu.dnetlib.is.model.resource.SimpleResource;
import eu.dnetlib.utils.XmlIndenter;
public class AbstractResourceController extends AbstractDnetController {
@Autowired
protected SimpleResourceService service;
@GetMapping("/{typeId}")
public List<SimpleResource> listResources(@PathVariable final String typeId) {
return service.listResources(typeId);
}
@GetMapping("/{resId}/metadata")
public SimpleResource getMetadata(@PathVariable final String resId) throws InformationServiceException {
return service.getMetadata(resId);
}
@GetMapping("/{resId}/content")
public void getContent(@PathVariable final String resId, final HttpServletResponse res) throws InformationServiceException {
final String ctype = service.getContentType(resId);
res.setCharacterEncoding(StandardCharsets.UTF_8.name());
res.setContentType(ctype);
final String content =
ctype.equals(MediaType.APPLICATION_XML_VALUE) ? XmlIndenter.indent(service.getContent(resId)) : service.getContent(resId);
try {
IOUtils.write(content, res.getOutputStream(), StandardCharsets.UTF_8.name());
} catch (final IOException e) {
throw new InformationServiceException("Error retrieving content", e);
}
}
}

View File

@ -0,0 +1,63 @@
package eu.dnetlib.is.resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.errors.InformationServiceException;
import eu.dnetlib.is.model.resource.SimpleResource;
@RestController
@RequestMapping("/ajax/resources")
public class ResourceAjaxController extends AbstractResourceController {
@PostMapping("/")
public SimpleResource newResource(@RequestParam final String name,
@RequestParam final String type,
@RequestParam(required = false, defaultValue = "") final String subtype,
@RequestParam(required = false, defaultValue = "") final String description,
@RequestParam final String content)
throws InformationServiceException {
return service.saveNewResource(name, type, subtype, description, content);
}
@DeleteMapping("/{resId}")
public void deleteResource(@PathVariable final String resId) {
service.deleteResource(resId);
}
@PostMapping("/{resId}/metadata")
public void saveMetadata(@PathVariable final String resId, @RequestBody final SimpleResource r) throws InformationServiceException {
service.saveMetadata(resId, r);
}
@PostMapping("/{resId}/content")
public void saveContent(@PathVariable final String resId, @RequestParam final String content) throws InformationServiceException {
service.saveContent(resId, content);
}
@PostMapping(value = "/{resId}/file", consumes = {
MediaType.TEXT_PLAIN_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE
})
public void uploadContent(@PathVariable final String resId, final HttpServletRequest request) throws InformationServiceException {
try {
final String content = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
service.saveContent(resId, content);
} catch (final IOException e) {
throw new InformationServiceException("Error processing input file", e);
}
}
}

View File

@ -0,0 +1,65 @@
package eu.dnetlib.is.resource;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.is.model.resource.ResourceType;
import eu.dnetlib.is.resource.repository.ResourceTypeRepository;
@RestController
@RequestMapping("/api/resources")
public class ResourceApiController extends AbstractResourceController {
@Autowired
private ResourceTypeRepository resourceTypeRepository;
@GetMapping("/")
private List<SimpleResourceType> types() {
return StreamSupport.stream(resourceTypeRepository.findAll().spliterator(), false)
.filter(rt -> rt.isSimple())
.map(rt -> new SimpleResourceType(rt))
.collect(Collectors.toList());
}
class SimpleResourceType {
private final String typeId;
private final String typeName;
private final String contentType;
private final long count;
public SimpleResourceType(final ResourceType rt) {
this.typeId = rt.getId();
this.typeName = rt.getName();
this.contentType = rt.getContentType();
this.count = rt.getCount();
}
public String getTypeId() {
return typeId;
}
public String getTypeName() {
return typeName;
}
public String getContentType() {
return contentType;
}
public long getCount() {
return count;
}
}
}

View File

@ -0,0 +1,6 @@
package eu.dnetlib.is.resource;
public class ResourceTypeRepository {
}

View File

@ -15,11 +15,11 @@
<module>collector</module>
<module>dsm</module>
<module>oaiExporter</module>
<module>publicApi</module>
<module>solrIndexer</module>
<module>wfManager</module>
<module>xsltTransformer</module>
<module>email</module>
<module>transformer</module>
<module>is</module>
</modules>
<dependencies>

View File

@ -8,11 +8,17 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dnet-xslt-transformer</artifactId>
<artifactId>dnet-transformer</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>dnet-db-common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- hot swapping, disable cache for template, enable live reload -->
<dependency>
<groupId>org.springframework.boot</groupId>

Some files were not shown because too many files have changed in this diff Show More