dnet-applications/apps/dnet-is-application/src/main/java/eu/dnetlib/dsm/DsmApiControllerV1.java

282 lines
11 KiB
Java
Executable File

package eu.dnetlib.dsm;
import static eu.dnetlib.dsm.utils.DsmMappingUtils.asDbEntry;
import static eu.dnetlib.dsm.utils.DsmMappingUtils.copyNonNullProperties;
import static eu.dnetlib.dsm.utils.DsmMappingUtils.createId;
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 javax.validation.Valid;
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.dsm.domain.AggregationHistoryResponse;
import eu.dnetlib.dsm.domain.AggregationInfo;
import eu.dnetlib.dsm.domain.ApiDetails;
import eu.dnetlib.dsm.domain.ApiDetailsResponse;
import eu.dnetlib.dsm.domain.Country;
import eu.dnetlib.dsm.domain.DatasourceDetailResponse;
import eu.dnetlib.dsm.domain.DatasourceDetails;
import eu.dnetlib.dsm.domain.DatasourceDetailsUpdate;
import eu.dnetlib.dsm.domain.DatasourceDetailsWithApis;
import eu.dnetlib.dsm.domain.DatasourceSnippetResponse;
import eu.dnetlib.dsm.domain.RegisteredDatasourceInfo;
import eu.dnetlib.dsm.domain.RequestFilter;
import eu.dnetlib.dsm.domain.RequestSort;
import eu.dnetlib.dsm.domain.RequestSortOrder;
import eu.dnetlib.dsm.domain.SimpleResponse;
import eu.dnetlib.dsm.model.Api;
import eu.dnetlib.dsm.model.Datasource;
import eu.dnetlib.dsm.model.Identity;
import eu.dnetlib.dsm.utils.DsmMappingUtils;
import eu.dnetlib.dsm.utils.ResponseUtils;
import eu.dnetlib.dsm.utils.WfLoggerClient;
import eu.dnetlib.errors.DsmException;
import eu.dnetlib.errors.DsmForbiddenException;
import eu.dnetlib.errors.DsmNotFoundException;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
@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(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(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 = 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());
copyNonNullProperties(update, ds);
ds.setIdentities(identities);
} else {
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(createId(api));
log.info(String.format("missing api id, created '%s'", api.getId()));
}
dsmService.addApi(asDbEntry(api));
log.info("API saved, id: " + api.getId());
}
}