You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
11 KiB
Java

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")
public @ResponseBody List<BrowseTerm> browseRepoField(@RequestParam(value = "field", required = true) final String field) throws Exception {
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));
}
}