2019-06-19 16:21:13 +02:00
package eu.dnetlib.functionality.modular.ui.repositories ;
import java.io.StringReader ;
import java.util.Date ;
import java.util.List ;
import java.util.Map ;
import javax.annotation.Resource ;
import javax.servlet.http.HttpServletRequest ;
import javax.servlet.http.HttpServletResponse ;
import org.apache.commons.io.IOUtils ;
import org.apache.commons.lang.StringUtils ;
import org.apache.commons.lang.exception.ExceptionUtils ;
import org.apache.commons.logging.Log ;
import org.apache.commons.logging.LogFactory ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.cache.annotation.CacheEvict ;
import org.springframework.cache.annotation.Cacheable ;
import org.springframework.http.HttpStatus ;
import org.springframework.stereotype.Controller ;
import org.springframework.ui.ModelMap ;
import org.springframework.web.bind.annotation.ExceptionHandler ;
import org.springframework.web.bind.annotation.RequestMapping ;
import org.springframework.web.bind.annotation.RequestParam ;
import org.springframework.web.bind.annotation.ResponseBody ;
import org.springframework.web.bind.annotation.ResponseStatus ;
import com.google.common.collect.Maps ;
import com.google.gson.Gson ;
import com.google.gson.reflect.TypeToken ;
import eu.dnetlib.data.collector.rmi.CollectorService ;
import eu.dnetlib.data.collector.rmi.CollectorServiceException ;
import eu.dnetlib.data.collector.rmi.ProtocolParameterValue ;
import eu.dnetlib.enabling.datasources.common.Api ;
import eu.dnetlib.enabling.datasources.common.ApiParam ;
import eu.dnetlib.enabling.datasources.common.ApiParamImpl ;
import eu.dnetlib.enabling.datasources.common.BrowseTerm ;
import eu.dnetlib.enabling.datasources.common.Datasource ;
import eu.dnetlib.enabling.datasources.common.DsmException ;
import eu.dnetlib.enabling.datasources.common.Identity ;
import eu.dnetlib.enabling.datasources.common.LocalDatasourceManager ;
import eu.dnetlib.enabling.datasources.common.Organization ;
import eu.dnetlib.enabling.datasources.common.SearchApisEntry ;
import eu.dnetlib.enabling.datasources.common.SimpleDatasource ;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException ;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService ;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService ;
import eu.dnetlib.enabling.locators.UniqueServiceLocator ;
import eu.dnetlib.functionality.modular.ui.error.ErrorMessage ;
import eu.dnetlib.functionality.modular.ui.repositories.objects.RepoInterfaceEntry ;
import eu.dnetlib.functionality.modular.ui.workflows.objects.sections.WorkflowSectionGrouper ;
import eu.dnetlib.miscutils.functional.xml.ApplyXslt ;
import eu.dnetlib.msro.workflows.sarasvati.loader.WorkflowExecutor ;
import eu.dnetlib.msro.workflows.util.WorkflowsConstants ;
@Controller
public class RepoInternalController {
@Autowired
private LocalDatasourceManager < Datasource < ? , ? > , Api < ? > > dsManager ;
@Resource
private UniqueServiceLocator serviceLocator ;
@Resource
private WorkflowSectionGrouper workflowSectionGrouper ;
@Resource
private WorkflowExecutor workflowExecutor ;
@Resource
private RepoUIUtils repoUIUtils ;
private static final Log log = LogFactory . getLog ( RepoInternalController . class ) ;
@RequestMapping ( value = " /ui/browseRepoField.do " )
2019-10-02 17:32:21 +02:00
public @ResponseBody List < BrowseTerm > browseRepoField ( @RequestParam ( value = " field " , required = true ) final String field ) throws Exception {
2019-06-19 16:21:13 +02:00
return dsManager . browseField ( field ) ;
}
@Cacheable ( cacheNames = " repoUIJsonCache " , key = " #param, #value " , condition = " #refresh == false " )
@RequestMapping ( value = " /ui/listApis.do " )
public @ResponseBody List < ? extends SearchApisEntry > listApis (
@RequestParam ( value = " param " , required = true ) final String param ,
@RequestParam ( value = " value " , required = true ) final String value ,
@RequestParam ( value = " refresh " , required = false ) final String refresh ) throws Exception {
return dsManager . searchApis ( param , value ) ;
}
@RequestMapping ( value = " /ui/listRepositories.json " )
public @ResponseBody List < SimpleDatasource > listRepositories ( @RequestParam ( value = " type " , required = true ) final String type ) throws Exception {
return dsManager . searchDatasourcesByType ( type ) ;
}
@CacheEvict ( " repoUIJsonCache " )
@RequestMapping ( value = " /ui/validateRepo.do " )
public @ResponseBody String listRepositories ( @RequestParam ( value = " id " , required = true ) final String id ,
@RequestParam ( value = " b " , required = true ) final boolean b ) throws Exception {
final String query = " count(/*[.//RESOURCE_TYPE/@value='MetaWorkflowDSResourceType' and .//DATAPROVIDER/@id=' " + id + " ']) " ;
if ( ! b & & Integer . parseInt ( serviceLocator . getService ( ISLookUpService . class ) . getResourceProfileByQuery ( query ) ) > 0 ) { throw new Exception ( " Repo " + id
+ " can be invalidated: it is related to some metawfs " ) ; }
final String newId = b ? serviceLocator . getService ( ISRegistryService . class ) . validateProfile ( id )
: serviceLocator . getService ( ISRegistryService . class ) . invalidateProfile ( id ) ;
return newId ;
}
@RequestMapping ( value = " /ui/getRepoDetails.do " )
public void getRepoDetails ( final HttpServletResponse response , @RequestParam ( value = " id " , required = true ) final String id ) throws Exception {
String profile ;
try {
profile = serviceLocator . getService ( ISLookUpService . class ) . getResourceProfile ( id ) ;
} catch ( final ISLookUpDocumentNotFoundException e ) {
profile = serviceLocator . getService ( ISLookUpService . class ) . getResourceProfileByQuery (
" collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType')/*[.//DATASOURCE_ORIGINAL_ID=' " + id + " '] " ) ;
}
final ApplyXslt xslt = new ApplyXslt ( IOUtils . toString ( getClass ( ) . getResourceAsStream (
" /eu/dnetlib/functionality/modular/ui/repositories/xslt/repoDetails.xslt " ) ) ) ;
IOUtils . copy ( new StringReader ( xslt . evaluate ( profile ) ) , response . getOutputStream ( ) ) ;
}
@RequestMapping ( " /ui/repoMetaWf.new " )
public @ResponseBody String newDataProviderWorkflow ( @RequestParam ( value = " id " , required = true ) final String repoId ,
@RequestParam ( value = " name " , required = true ) final String repoName ,
@RequestParam ( value = " iface " , required = true ) final String ifaceId ,
@RequestParam ( value = " wf " , required = true ) final String wfId ) throws Exception {
final Map < String , Object > params = Maps . newHashMap ( ) ;
params . put ( WorkflowsConstants . DATAPROVIDER_ID , repoId ) ;
params . put ( WorkflowsConstants . DATAPROVIDER_NAME , repoName ) ;
params . put ( WorkflowsConstants . DATAPROVIDER_INTERFACE , ifaceId ) ;
return workflowExecutor . startProcess ( wfId , params ) ;
}
@RequestMapping ( " /ui/repoMetaWf.destroy " )
public @ResponseBody String destroyDataProviderWorkflow ( @RequestParam ( value = " destroyWf " , required = true ) final String destroyWfId )
throws Exception {
return workflowExecutor . startProcess ( destroyWfId , null ) ;
}
@RequestMapping ( " /ui/repoApi.get " )
public @ResponseBody RepoInterfaceEntry getRepoApi ( @RequestParam ( value = " repoId " , required = true ) final String repoId ,
@RequestParam ( value = " ifaceId " , required = true ) final String ifaceId ) throws Exception {
try {
return repoUIUtils . getApi ( repoId , ifaceId ) ;
} catch ( ISLookUpDocumentNotFoundException e ) {
log . warn ( String . format ( " the Interface '%s' is not available for repository '%s', try to sync DB and profiles via the DatasourceManager " , ifaceId , repoId ) ) ;
dsManager . setActive ( repoId , ifaceId , dsManager . isActive ( repoId , ifaceId ) ) ;
return repoUIUtils . getApi ( repoId , ifaceId ) ;
}
}
@RequestMapping ( " /ui/repoApi.update " )
public @ResponseBody boolean updateRepoApi (
@RequestParam ( value = " id " , required = true ) final String repoId ,
@RequestParam ( value = " iface " , required = true ) final String ifaceId ,
@RequestParam ( value = " accessParams " , required = false ) final String accessParamsJson ,
@RequestParam ( value = " mdIdPath " , required = false ) final String mdIdPath ) throws Exception {
if ( ! StringUtils . isEmpty ( accessParamsJson ) ) {
final Map < String , String > params = new Gson ( ) . fromJson ( accessParamsJson , new TypeToken < Map < String , String > > ( ) { } . getType ( ) ) ;
final String baseUrl = params . remove ( " baseUrl " ) ;
dsManager . updateApiDetails ( repoId , ifaceId , mdIdPath , baseUrl , params ) ;
}
return true ;
}
@RequestMapping ( " /ui/repoApi.delete " )
public @ResponseBody boolean updateRepoApi (
@RequestParam ( value = " repo " , required = true ) final String repoId ,
@RequestParam ( value = " iface " , required = true ) final String ifaceId ) throws Exception {
dsManager . deleteApi ( repoId , ifaceId ) ;
return true ;
}
@CacheEvict ( " repoUIJsonCache " )
@RequestMapping ( " /ui/repoApiCompliance.update " )
public @ResponseBody boolean updateRepoApiCompliance ( @RequestParam ( value = " id " , required = true ) final String repoId ,
@RequestParam ( value = " iface " , required = true ) final String ifaceId ,
@RequestParam ( value = " compliance " , required = true ) final String compliance ) throws Exception {
log . debug ( " SET COMPLIANCE TO " + compliance ) ;
dsManager . updateCompliance ( repoId , ifaceId , compliance , true ) ;
return true ;
}
@CacheEvict ( " repoUIJsonCache " )
@RequestMapping ( " /ui/repoApiCompliance.reset " )
public @ResponseBody boolean resetRepoApiCompliance ( @RequestParam ( value = " id " , required = true ) final String repoId ,
@RequestParam ( value = " iface " , required = true ) final String ifaceId ) throws Exception {
log . debug ( " RESET COMPLIANCE " ) ;
dsManager . updateCompliance ( repoId , ifaceId , null , true ) ;
return true ;
}
@RequestMapping ( " /ui/repos/repoApi.html " )
public void resetRepoApiCompliance ( final ModelMap map ) throws Exception { }
@RequestMapping ( " /ui/repoApi.new " )
public @ResponseBody boolean addRepoApi ( @RequestParam ( value = " repoId " , required = true ) final String repoId ,
@RequestParam ( value = " iface " , required = true ) final String ifaceJson ) throws DsmException {
final Api < ApiParam > iface = new Gson ( ) . fromJson ( ifaceJson , new TypeToken < Api < ApiParamImpl > > ( ) { } . getType ( ) ) ;
iface . setDatasource ( repoId ) ;
log . info ( " Adding api " + iface . getId ( ) + " to repository " + repoId ) ;
dsManager . addApi ( iface ) ;
return true ;
}
@RequestMapping ( " /ui/repo.new " )
public @ResponseBody boolean addRepoApi ( @RequestParam ( value = " repo " , required = true ) final String repoJson ) throws DsmException {
final Datasource < Organization < ? > , Identity > ds = new Gson ( ) . fromJson ( repoJson , new TypeToken < Datasource < Organization < ? > , Identity > > ( ) { } . getType ( ) ) ;
final Date now = new Date ( ) ;
ds . setDateofcollection ( new java . sql . Date ( now . getTime ( ) ) ) ;
if ( StringUtils . isBlank ( ds . getEnglishname ( ) ) ) {
ds . setEnglishname ( ds . getOfficialname ( ) ) ;
}
log . info ( " Adding datasource " + ds . getId ( ) + " - name " + ds . getOfficialname ( ) ) ;
dsManager . saveDs ( ds ) ;
return true ;
}
@RequestMapping ( " /ui/listValidValuesForParam.do " )
public @ResponseBody List < ProtocolParameterValue > listValidValuesForParam (
@RequestParam ( value = " protocol " , required = true ) final String protocol ,
@RequestParam ( value = " param " , required = true ) final String param ,
@RequestParam ( value = " baseUrl " , required = true ) final String baseUrl ) throws CollectorServiceException {
return serviceLocator . getService ( CollectorService . class ) . listValidValuesForParam ( protocol , baseUrl , param , null ) ;
}
@ExceptionHandler ( Exception . class )
@ResponseStatus ( value = HttpStatus . INTERNAL_SERVER_ERROR )
public @ResponseBody ErrorMessage handleException ( final HttpServletRequest req , final Exception e ) {
log . error ( " Error processing " + req . getRequestURI ( ) , e ) ;
return new ErrorMessage ( e . getMessage ( ) , ExceptionUtils . getStackTrace ( e ) ) ;
}
}