package eu.dnetlib.openaire.dsm.dao; import com.google.common.collect.Lists; import eu.dnetlib.OpenaireExporterConfig; 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.dsm.domain.RequestFilter; import eu.dnetlib.openaire.dsm.domain.RequestSort; import eu.dnetlib.openaire.dsm.domain.RequestSortOrder; import eu.dnetlib.openaire.dsm.domain.db.ApiDbEntry; import eu.dnetlib.openaire.dsm.domain.db.ApiParamDbEntry; import eu.dnetlib.openaire.dsm.domain.db.DatasourceApiDbEntry; import eu.dnetlib.openaire.dsm.domain.db.DatasourceDbEntry; import eu.dnetlib.openaire.vocabularies.Country; import eu.dnetlib.openaire.vocabularies.Vocabulary; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpStatus; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityNotFoundException; import java.sql.Date; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import static eu.dnetlib.openaire.common.ExporterConstants.OAI; import static eu.dnetlib.openaire.common.ExporterConstants.SET; import static eu.dnetlib.openaire.dsm.dao.DatasourceSpecs.apiSpec; import static eu.dnetlib.openaire.dsm.dao.DatasourceSpecs.dsSpec; import static eu.dnetlib.openaire.dsm.dao.DatasourceSpecs.dsRegisteredbyNotNullSpec; /** * Created by claudio on 20/10/2016. */ @Component @ConditionalOnProperty(value = "openaire.exporter.enable.dsm", havingValue = "true") public class DatasourceDaoImpl implements DatasourceDao { private static final Log log = LogFactory.getLog(DatasourceDao.class); @Autowired private OpenaireExporterConfig config; @Autowired private CountryTermRepository countryTermRepository; @Autowired private DatasourceDbEntryRepository dsRepository; @Autowired private ApiDbEntryRepository apiRepository; @Autowired private DatasourceApiDbEntryRepository dsApiRepository; @Autowired private VocabularyClient vocabularyClient; @Override public List listCountries() throws DsmException { final List countries = Lists.newArrayList(); final Vocabulary v = vocabularyClient.getCountries(); countries.addAll(countryTermRepository.findAll().stream() .filter(Objects::nonNull) .map(t -> new Country(t.getTerm(), v.getEnglishName(t.getTerm()))) .collect(Collectors.toList())); return countries; } @Override public Page search(final RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, final int page, final int size) throws DsmException { final Specification spec = dsSpec(requestSortBy, order, requestFilter); return dsRepository.findAll(spec, PageRequest.of(page, size)); } @Override public Page searchRegistered(final RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, final int page, final int size) throws DsmException { final Specification spec = dsSpec(requestSortBy, order, requestFilter).and(dsRegisteredbyNotNullSpec()); return dsRepository.findAll(spec, PageRequest.of(page, size)); } @Override public DatasourceDbEntry getDs(final String dsId) throws DsmException { return dsRepository.getOne(dsId); } @Override 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.setRemovable(id, true); } @Override public boolean isManaged(final String id) { return dsRepository.isManaged(id); } @Override public void updateCompliance(String dsId, String apiId, String compliance, boolean override) { log.info(String.format("setting compatibility = '%s' for ds '%s'", compliance, apiId)); apiRepository.updateCompatibility(apiId, compliance); } @Override public List getApis(final String dsId) { return apiRepository.findByDatasource(dsId); } @Override public void deleteApi(final String dsId, final String apiId) throws DsmForbiddenException, DsmNotFoundException { final ApiDbEntry api = apiRepository.getOne(apiId); try { if (!api.getRemovable()) { throw new DsmForbiddenException(HttpStatus.SC_UNAUTHORIZED, "api is not removable"); } apiRepository.deleteById(apiId); log.info(String.format("deleted api '%s'", apiId)); } catch (EntityNotFoundException e) { throw new DsmNotFoundException(HttpStatus.SC_NOT_FOUND, "api not found"); } } @Override public void addApi(final ApiDbEntry api) { apiRepository.save(api); } @Override public boolean existDs(final String dsId) throws DsmException { return dsRepository.existsById(dsId); } @Override public void saveDs(final DatasourceDbEntry d) { log.info(String.format("saving datasource '%s'", d.getId())); final DatasourceDbEntry datasource = dsRepository.save(d); log.info(String.format("saved datasource '%s'", datasource.getId())); ensureRegistrationDate(d.getId()); } @Override public void deleteDs(final String dsId) { dsRepository.deleteById(dsId); log.info(String.format("deleted datasource '%s'", dsId)); } @Override 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); } @Override public void updateLogoUrl(final String dsId, final String logourl) throws DsmException { dsRepository.setLogoUrl(dsId, logourl); } @Override public void updateCoordinates(final String dsId, final Double latitude, final Double longitude) { dsRepository.setCoordinates(dsId, latitude, longitude); } @Override public void updateApiBaseUrl(final String apiId, final String baseurl) { apiRepository.setBaseurl(apiId, baseurl); } @Override @Transactional public boolean upsertApiOaiSet(final String apiId, final String oaiSet) throws DsmException { final ApiDbEntry api = apiRepository.getOne(apiId); if (OAI.equalsIgnoreCase(api.getProtocol())) { final Set 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())); } } @Override public List findApiBaseURLs(final RequestFilter requestFilter, final int page, final int size) throws DsmException { final PageRequest pageable = PageRequest.of(page, size); final Specification spec = apiSpec(requestFilter); final Set set = dsApiRepository.findAll(spec, pageable).getContent().stream() .map(DatasourceApiDbEntry::getBaseurl) .filter(StringUtils::isNotBlank) .collect(Collectors.toCollection(HashSet::new)); return Lists.newArrayList(set); } @Override public void updateTimezone(final String dsId, final String timezone) { dsRepository.setTimezone(dsId, timezone); } @Override public void updateTypology(final String dsId, final String typology) throws DsmException { final Vocabulary typologies = vocabularyClient.getDatasourceTypologies(); if (!typologies.hasCode(typology)) { throw new DsmException( HttpStatus.SC_BAD_REQUEST, String.format( "invalid datasource typology '%s', provide one according to vocabulary %s", typology, config.getVocabularies().getDatasourceTypologiesEndpoint())); } dsRepository.setTypology(dsId, typology); } @Override public void updateRegisteringUser(final String dsId, final String registeredBy) throws DsmException { ensureRegistrationDate(dsId); dsRepository.setRegisteringUser(dsId, registeredBy); } @Override public void updatePlatform(final String dsId, final String platform) throws DsmException { dsRepository.setPlatform(dsId, platform); } //HELPER private void ensureRegistrationDate(String dsId) { if (!dsRepository.hasRegistrationdate(dsId)) { log.info("setting registration date for datasource: " + dsId); dsRepository.setRegistrationDate(dsId, new Date(System.currentTimeMillis())); } } }