2022-02-04 10:12:15 +01:00
package eu.dnetlib.openaire.dsm ;
import static eu.dnetlib.openaire.common.ExporterConstants.API ;
import static eu.dnetlib.openaire.common.ExporterConstants.DS ;
import static eu.dnetlib.openaire.common.ExporterConstants.M ;
import static eu.dnetlib.openaire.common.ExporterConstants.R ;
import static eu.dnetlib.openaire.common.ExporterConstants.W ;
import java.util.List ;
import javax.validation.Valid ;
import org.apache.commons.lang3.StringUtils ;
import org.apache.commons.lang3.time.StopWatch ;
import org.apache.http.HttpStatus ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty ;
import org.springframework.web.bind.annotation.CrossOrigin ;
import org.springframework.web.bind.annotation.PathVariable ;
import org.springframework.web.bind.annotation.RequestBody ;
import org.springframework.web.bind.annotation.RequestMapping ;
import org.springframework.web.bind.annotation.RequestMethod ;
import org.springframework.web.bind.annotation.RequestParam ;
import org.springframework.web.bind.annotation.RestController ;
import eu.dnetlib.enabling.datasources.common.DsmException ;
import eu.dnetlib.enabling.datasources.common.DsmForbiddenException ;
import eu.dnetlib.enabling.datasources.common.DsmNotFoundException ;
import eu.dnetlib.openaire.common.AbstractExporterController ;
import eu.dnetlib.openaire.common.OperationManager ;
2022-02-07 09:03:36 +01:00
import eu.dnetlib.openaire.dsm.domain.AggregationHistoryResponse ;
import eu.dnetlib.openaire.dsm.domain.ApiDetails ;
import eu.dnetlib.openaire.dsm.domain.ApiDetailsResponse ;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetailResponse ;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetails ;
import eu.dnetlib.openaire.dsm.domain.DatasourceDetailsUpdate ;
import eu.dnetlib.openaire.dsm.domain.DatasourceResponse ;
import eu.dnetlib.openaire.dsm.domain.DatasourceSnippetResponse ;
import eu.dnetlib.openaire.dsm.domain.RequestFilter ;
import eu.dnetlib.openaire.dsm.domain.RequestSort ;
import eu.dnetlib.openaire.dsm.domain.RequestSortOrder ;
import eu.dnetlib.openaire.dsm.domain.Response ;
import eu.dnetlib.openaire.dsm.domain.SimpleResponse ;
2022-02-04 10:12:15 +01:00
import eu.dnetlib.openaire.vocabularies.Country ;
import io.swagger.annotations.ApiOperation ;
import io.swagger.annotations.ApiResponse ;
import io.swagger.annotations.ApiResponses ;
@RestController
2022-02-07 09:03:36 +01:00
@CrossOrigin ( origins = {
" * "
} )
2022-02-04 10:12:15 +01:00
@ConditionalOnProperty ( value = " openaire.exporter.enable.dsm " , havingValue = " true " )
@io.swagger.annotations.Api ( tags = " OpenAIRE DSM API " , description = " the OpenAIRE Datasource Manager API " )
public class DsmApiController extends AbstractExporterController {
@Autowired
private DsmCore dsmCore ;
2022-02-07 09:03:36 +01:00
@RequestMapping ( value = " /ds/countries " , produces = {
" application/json "
} , method = RequestMethod . GET )
@ApiOperation ( value = " list the datasource countries " , notes = " list the datasource countries " , tags = {
DS , R
} , response = Country [ ] . class )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " , response = Country [ ] . class ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public List < Country > listCountries ( ) throws DsmException {
return dsmCore . listCountries ( ) ;
}
2022-02-07 09:03:36 +01:00
@RequestMapping ( value = " /ds/searchdetails/{page}/{size} " , produces = {
" application/json "
} , method = RequestMethod . POST )
@ApiOperation ( value = " search datasources " , notes = " Returns list of Datasource details. " , tags = {
DS , R
} , response = DatasourceDetailResponse . class )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " , response = DatasourceDetailResponse . class ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public DatasourceDetailResponse searchDsDetails (
2022-02-07 09:03:36 +01:00
@RequestParam final RequestSort requestSortBy ,
@RequestParam final RequestSortOrder order ,
@RequestBody final RequestFilter requestFilter ,
@PathVariable final int page ,
@PathVariable final int size ) throws DsmException {
2022-02-04 10:12:15 +01:00
final StopWatch stop = StopWatch . createStarted ( ) ;
final DatasourceDetailResponse rsp = dsmCore . searchDsDetails ( requestSortBy , order , requestFilter , page , size ) ;
return prepareResponse ( page , size , stop , rsp ) ;
}
2022-02-07 09:03:36 +01:00
@RequestMapping ( value = " /ds/aggregationhistory/{dsId} " , produces = {
" application/json "
} , method = RequestMethod . GET )
@ApiOperation ( value = " search datasources " , notes = " Returns list of Datasource details. " , tags = {
DS , R
} , response = AggregationHistoryResponse . class )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " , response = AggregationHistoryResponse . class ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public AggregationHistoryResponse aggregationHistory ( @PathVariable final String dsId ) throws DsmException {
final StopWatch stop = StopWatch . createStarted ( ) ;
final AggregationHistoryResponse rsp = dsmCore . aggregationhistory ( dsId ) ;
return prepareResponse ( 0 , rsp . getAggregationInfo ( ) . size ( ) , stop , rsp ) ;
}
2022-02-07 09:03:36 +01:00
@RequestMapping ( value = " /ds/searchsnippet/{page}/{size} " , produces = {
" application/json "
} , method = RequestMethod . POST )
@ApiOperation ( value = " search datasources " , notes = " Returns list of Datasource basic info. " , tags = {
DS , R
} , response = DatasourceSnippetResponse . class )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " , response = DatasourceSnippetResponse . class ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public DatasourceSnippetResponse searchSnippet (
2022-02-07 09:03:36 +01:00
@RequestParam final RequestSort requestSortBy ,
@RequestParam final RequestSortOrder order ,
@RequestBody final RequestFilter requestFilter ,
@PathVariable final int page ,
@PathVariable final int size ) throws DsmException {
2022-02-04 10:12:15 +01:00
final StopWatch stop = StopWatch . createStarted ( ) ;
final DatasourceSnippetResponse rsp = dsmCore . searchSnippet ( requestSortBy , order , requestFilter , page , size ) ;
return prepareResponse ( page , size , stop , rsp ) ;
}
2022-02-07 09:03:36 +01:00
@RequestMapping ( value = " /ds/searchregistered/{page}/{size} " , produces = {
" application/json "
} , method = RequestMethod . POST )
@ApiOperation ( value = " search among registered datasources " , notes = " Returns list of Datasource basic info. " , tags = {
DS ,
R
} , response = DatasourceSnippetResponse . class )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " , response = DatasourceSnippetResponse . class ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public DatasourceSnippetResponse searchRegistered (
2022-02-07 09:03:36 +01:00
@RequestParam final RequestSort requestSortBy ,
@RequestParam final RequestSortOrder order ,
@RequestBody final RequestFilter requestFilter ,
@PathVariable final int page ,
@PathVariable final int size ) throws DsmException {
2022-02-04 10:12:15 +01:00
final StopWatch stop = StopWatch . createStarted ( ) ;
final DatasourceSnippetResponse rsp = dsmCore . searchRegistered ( requestSortBy , order , requestFilter , page , size ) ;
return prepareResponse ( page , size , stop , rsp ) ;
}
2022-02-07 09:03:36 +01:00
@RequestMapping ( value = " /ds/recentregistered/{size} " , produces = {
" application/json "
} , method = RequestMethod . GET )
@ApiOperation ( value = " return the latest datasources that were registered through Provide " , notes = " Returns list of Datasource basic info. " , tags = {
DS ,
R
} , response = SimpleResponse . class )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " , response = DatasourceResponse . class ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-07 10:09:18 +01:00
public SimpleResponse < ? > recentRegistered ( @PathVariable final int size ) throws Throwable {
2022-02-04 10:12:15 +01:00
final StopWatch stop = StopWatch . createStarted ( ) ;
2022-02-07 10:09:18 +01:00
final SimpleResponse < ? > rsp = dsmCore . searchRecentRegistered ( size ) ;
2022-02-04 10:12:15 +01:00
return prepareResponse ( 1 , size , stop , rsp ) ;
}
2022-02-07 09:03:36 +01:00
@RequestMapping ( value = " /ds/countregistered " , produces = {
" application/json "
} , method = RequestMethod . GET )
@ApiOperation ( value = " return the number of datasources registered after the given date " , notes = " Returns a number. " , tags = {
DS ,
R
} , response = Long . class )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " , response = Long . class ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public Long countRegistered ( @RequestParam final String fromDate ,
2022-02-07 09:03:36 +01:00
@RequestParam ( required = false ) final String typologyFilter ) throws Throwable {
2022-02-04 10:12:15 +01:00
return dsmCore . countRegisteredAfter ( fromDate , typologyFilter ) ;
}
2022-02-07 09:03:36 +01:00
@RequestMapping ( value = " /ds/api/{dsId} " , produces = {
" application/json "
} , method = RequestMethod . GET )
@ApiOperation ( value = " get the list of API for a given datasource " , notes = " Returns the list of API for a given datasource. " , tags = {
API ,
R
} , response = ApiDetailsResponse . class )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " , response = ApiDetailsResponse . class ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public ApiDetailsResponse getApi (
2022-02-07 09:03:36 +01:00
@PathVariable final String dsId ) throws DsmException {
2022-02-04 10:12:15 +01:00
final StopWatch stop = StopWatch . createStarted ( ) ;
final ApiDetailsResponse rsp = dsmCore . getApis ( dsId ) ;
return prepareResponse ( 0 , rsp . getApi ( ) . size ( ) , stop , rsp ) ;
}
2022-02-07 09:03:36 +01:00
@RequestMapping ( value = " /api/baseurl/{page}/{size} " , produces = {
" application/json "
} , method = RequestMethod . POST )
2022-02-04 10:12:15 +01:00
@ApiOperation ( value = " search for the list of base URLs of Datasource APIs managed by a user " , notes = " Returns the list of base URLs of Datasource APIs managed by a user " , tags = {
2022-02-07 09:03:36 +01:00
DS , API , R
} , response = String [ ] . class )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " , response = String [ ] . class ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public List < String > searchBaseUrls (
2022-02-07 09:03:36 +01:00
@RequestBody final RequestFilter requestFilter ,
@PathVariable final int page ,
@PathVariable final int size ) throws DsmException {
2022-02-04 10:12:15 +01:00
return dsmCore . findBaseURLs ( requestFilter , page , size ) ;
}
@RequestMapping ( value = " /ds/api/{apiId} " , method = RequestMethod . DELETE )
2022-02-07 09:03:36 +01:00
@ApiOperation ( value = " delete an API " , notes = " delete an API, if removable " , tags = {
API , W
} )
@ApiResponses ( value = {
@ApiResponse ( code = 200 , message = " OK " ) ,
@ApiResponse ( code = 400 , message = " Api not found " , response = ErrorMessage . class ) ,
@ApiResponse ( code = 403 , message = " Api not removable " , response = ErrorMessage . class ) ,
@ApiResponse ( code = 500 , message = " DSM Server error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public void deleteApi ( @PathVariable final String apiId ) throws DsmForbiddenException , DsmNotFoundException {
dsmCore . deleteApi ( apiId ) ;
}
@RequestMapping ( value = " /ds/manage " , method = RequestMethod . POST )
2022-02-07 09:03:36 +01:00
@ApiOperation ( value = " set the managed status for a given datasource " , notes = " set the managed status for a given datasource " , tags = {
DS , W
} )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public void setManaged (
2022-02-07 09:03:36 +01:00
@RequestParam final String id ,
@RequestParam final boolean managed ) throws DsmException {
2022-02-04 10:12:15 +01:00
dsmCore . setManaged ( id , managed ) ;
}
@RequestMapping ( value = " /ds/managed/{id} " , method = RequestMethod . GET )
2022-02-07 09:03:36 +01:00
@ApiOperation ( value = " get the datasource managed status " , notes = " get the datasource managed status " , tags = {
DS , R
} )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public boolean isManaged ( @PathVariable final String id ) throws DsmException {
return dsmCore . isManaged ( id ) ;
}
@RequestMapping ( value = " /ds/add " , method = RequestMethod . POST )
2022-02-07 09:03:36 +01:00
@ApiOperation ( value = " add a new Datasource " , notes = " add a new Datasource " , tags = {
DS , W
} )
@ApiResponses ( value = {
@ApiResponse ( code = 200 , message = " OK " ) ,
@ApiResponse ( code = 400 , message = " Malformed request " , response = ErrorMessage [ ] . class ) ,
@ApiResponse ( code = 500 , message = " Unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public void saveDs ( @Valid @RequestBody final DatasourceDetails datasource ) throws DsmException {
if ( dsmCore . exist ( datasource ) ) { // TODO further check that the DS doesn't have any API
throw new DsmException ( HttpStatus . SC_CONFLICT , String . format ( " cannot register, datasource already defined '%s' " , datasource . getId ( ) ) ) ;
}
dsmCore . save ( datasource ) ;
}
@RequestMapping ( value = " /ds/update " , method = RequestMethod . POST )
2022-02-07 09:03:36 +01:00
@ApiOperation ( value = " update Datasource details " , notes = " update Datasource details " , tags = {
DS , W
} )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public void updateDatasource (
2022-02-07 09:03:36 +01:00
@RequestBody final DatasourceDetailsUpdate ds ) throws DsmException , DsmNotFoundException {
2022-02-04 10:12:15 +01:00
dsmCore . updateDatasource ( ds ) ;
}
@RequestMapping ( value = " /ds/api/baseurl " , method = RequestMethod . POST )
2022-02-07 09:03:36 +01:00
@ApiOperation ( value = " update the base URL of a datasource interface " , notes = " update the base URL of a datasource interface " , tags = {
API , W
} )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public void updateBaseUrl (
2022-02-07 09:03:36 +01:00
@RequestParam final String dsId ,
@RequestParam final String apiId ,
@RequestParam final String baseUrl ) throws DsmException {
2022-02-04 10:12:15 +01:00
dsmCore . updateApiBaseurl ( dsId , apiId , baseUrl ) ;
}
@RequestMapping ( value = " /ds/api/compliance " , method = RequestMethod . POST )
2022-02-07 09:03:36 +01:00
@ApiOperation ( value = " update the compatibility of a datasource interface " , notes = " update the compatibility of a datasource interface " , tags = {
API , W
} )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public void updateCompliance (
2022-02-07 09:03:36 +01:00
@RequestParam final String dsId ,
@RequestParam final String apiId ,
@RequestParam final String compliance ,
@RequestParam ( required = false , defaultValue = " false " ) final boolean override ) throws DsmException {
2022-02-04 10:12:15 +01:00
dsmCore . updateApiCompatibility ( dsId , apiId , compliance , override ) ;
}
@RequestMapping ( value = " /ds/api/oaiset " , method = RequestMethod . POST )
2022-02-07 09:03:36 +01:00
@ApiOperation ( value = " update the OAI set of a datasource interface " , notes = " update the OAI set of a datasource interface " , tags = {
API , W
} )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public void updateOaiSetl (
2022-02-07 09:03:36 +01:00
@RequestParam final String dsId ,
@RequestParam final String apiId ,
@RequestParam final String oaiSet ) throws DsmException {
2022-02-04 10:12:15 +01:00
dsmCore . updateApiOaiSet ( dsId , apiId , oaiSet ) ;
}
@RequestMapping ( value = " /ds/api/add " , method = RequestMethod . POST )
2022-02-07 09:03:36 +01:00
@ApiOperation ( value = " adds a new Interface to one Datasource " , notes = " adds an Interface to one Datasource " , tags = {
API , W
} )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public void addApi ( @RequestBody final ApiDetails api ) throws DsmException {
if ( StringUtils . isBlank ( api . getDatasource ( ) ) ) { throw new DsmException ( HttpStatus . SC_BAD_REQUEST , " missing datasource id " ) ; }
dsmCore . addApi ( api ) ;
}
// MANAGEMENT
@Autowired
private OperationManager operationManager ;
@RequestMapping ( value = " /dsm/ops " , method = RequestMethod . GET )
2022-02-07 09:03:36 +01:00
@ApiOperation ( value = " get the number of pending operations " , notes = " get the number of pending operations " , tags = {
R , M
} )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public int getOps ( ) throws DsmException {
return operationManager . getOpSize ( ) ;
}
@RequestMapping ( value = " /dsm/killops " , method = RequestMethod . POST )
2022-02-07 09:03:36 +01:00
@ApiOperation ( value = " interrupts the pending operations " , notes = " return the number of interrupted operations " , tags = {
W , M
} )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public int killOps ( ) throws DsmException {
return operationManager . dropAll ( ) ;
}
@RequestMapping ( value = " /dsm/dropcache " , method = RequestMethod . POST )
2022-02-07 09:03:36 +01:00
@ApiOperation ( value = " drop the caches " , notes = " drop the internal caches " , tags = {
W , M
} )
2022-02-04 10:12:15 +01:00
@ApiResponses ( value = {
2022-02-07 09:03:36 +01:00
@ApiResponse ( code = 200 , message = " OK " ) ,
@ApiResponse ( code = 500 , message = " unexpected error " , response = ErrorMessage . class )
} )
2022-02-04 10:12:15 +01:00
public void dropCache ( ) throws DsmException {
dsmCore . dropCaches ( ) ;
}
// HELPERS
private < T extends Response > T prepareResponse ( final int page , final int size , final StopWatch stopWatch , final T rsp ) {
rsp . getHeader ( )
2022-02-07 09:03:36 +01:00
. setTime ( stopWatch . getTime ( ) )
. setPage ( page )
. setSize ( size ) ;
2022-02-04 10:12:15 +01:00
return rsp ;
}
}