package eu.eudat.depositinterface.dataverserepository.interfaces; import com.fasterxml.jackson.databind.ObjectMapper; import com.researchspace.dataverse.api.v1.DataverseAPI; import com.researchspace.dataverse.api.v1.DataverseConfig; import com.researchspace.dataverse.entities.DataverseContacts; import com.researchspace.dataverse.entities.DataversePost; import com.researchspace.dataverse.entities.DataverseResponse; import com.researchspace.dataverse.entities.Identifier; import com.researchspace.dataverse.entities.facade.DatasetAuthor; import com.researchspace.dataverse.entities.facade.DatasetContact; import com.researchspace.dataverse.entities.facade.DatasetDescription; import com.researchspace.dataverse.entities.facade.DatasetFacade; import com.researchspace.dataverse.http.DataverseAPIImpl; import eu.eudat.depositinterface.models.DMPDepositModel; import eu.eudat.depositinterface.repository.RepositoryDeposit; import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.http.*; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Files; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.Objects; import java.util.stream.Collectors; import static eu.eudat.depositinterface.repository.RepositoryDepositConfiguration.DepositAccountStatus.SystemDeposit; @Component public class DataverseDeposit implements RepositoryDeposit { private static final Logger logger = LoggerFactory.getLogger(DataverseDeposit.class); private static final ObjectMapper objectMapper = new ObjectMapper(); private static final String API_TOKEN = ""; private static final String SYSTEM_PARENT_DATAVERSE_ALIAS = ""; private static final String SERVER = ""; private static final String SYSTEM_EMAIL = ""; private DataverseAPI api; private boolean isApiSet; private Environment environment; @Autowired public DataverseDeposit(Environment environment){ this.environment = environment; this.isApiSet = false; } private void setDataverseApi() throws MalformedURLException { if(!this.isApiSet) { this.api = new DataverseAPIImpl(); DataverseConfig config = new DataverseConfig(new URL(SERVER), API_TOKEN, SYSTEM_PARENT_DATAVERSE_ALIAS); api.configure(config); this.isApiSet = true; } } @Override public String deposit(DMPDepositModel dmpDepositModel, boolean update, String repositoryAccessToken) throws Exception { if(!this.isApiSet) this.setDataverseApi(); DataversePost entity = new DataversePost(); entity.setName(dmpDepositModel.getLabel()); entity.setAlias(dmpDepositModel.getLabel().replace(" ", "_")); entity.setDescription(dmpDepositModel.getDescription()); entity.setCreationDate(new Date()); entity.setDataverseContacts(Collections.singletonList(new DataverseContacts(SYSTEM_EMAIL))); DataverseResponse response = this.api.getDataverseOperations().createNewDataverse(SYSTEM_PARENT_DATAVERSE_ALIAS, entity); DatasetFacade dataset = DatasetFacade.builder() .title(dmpDepositModel.getLabel()) .authors(dmpDepositModel.getUsers().stream().map(x -> DatasetAuthor.builder().authorName(x.getUser().getName()).build()).collect(Collectors.toList())) .contacts(dmpDepositModel.getUsers().stream().map(x -> DatasetContact.builder().datasetContactEmail(x.getUser().getEmail()).build()).collect(Collectors.toList())) .subject("Other") .description(DatasetDescription.builder().description(dmpDepositModel.getDescription()).build()) .languages(new ArrayList<>()) .depositor("") .build(); Identifier id = this.api.getDataverseOperations().createDataset(dataset, entity.getAlias()); String doi = this.api.getDatasetOperations().getDataset(id).getDoiId().orElse(null); this.uploadFile(dmpDepositModel.getPdfFileName(), dmpDepositModel.getPdfFile(), doi); String contentDisposition = dmpDepositModel.getRdaJson().getHeaders().get("Content-Disposition").get(0); String jsonFileName = contentDisposition.substring(contentDisposition.lastIndexOf('=') + 1); File rdaJson = new File(this.environment.getProperty("storage.temp") + jsonFileName); OutputStream output = new FileOutputStream(rdaJson); try { output.write(Objects.requireNonNull(dmpDepositModel.getRdaJson().getBody())); output.flush(); output.close(); } catch (IOException e) { logger.error(e.getMessage(), e); } this.uploadFile(jsonFileName, rdaJson, doi); Files.deleteIfExists(rdaJson.toPath()); return doi; } private void uploadFile(String filename, File file, String doi) throws IOException { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); headers.set("X-Dataverse-key", API_TOKEN); MultiValueMap fileMap = new LinkedMultiValueMap<>(); ContentDisposition contentDisposition = ContentDisposition .builder("form-data") .name("file") .filename(filename) .build(); fileMap.add(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString()); HttpEntity fileEntity = new HttpEntity<>(Files.readAllBytes(file.toPath()), fileMap); MultiValueMap body = new LinkedMultiValueMap<>(); body.add("file", fileEntity); body.add("jsonData", "{\"restrict\":\"true\", \"tabIngest\":\"false\"}"); HttpEntity> requestEntity = new HttpEntity<>(body, headers); String serverUrl = SERVER + "/api/datasets/:persistentId/add?persistentId=doi:" + doi; RestTemplate restTemplate = new RestTemplate(); ResponseEntity resp = restTemplate.postForEntity(serverUrl, requestEntity, Object.class); } @Override public RepositoryDepositConfiguration getConfiguration() { RepositoryDepositConfiguration conf = new RepositoryDepositConfiguration(); conf.setRepositoryId("Dataverse"); conf.setDepositAccountStatus(SystemDeposit.getValue()); conf.setAccessToken(API_TOKEN); conf.setRepositoryUrl(SERVER + "/api/"); conf.setRepositoryRecordUrl(SERVER + "/dataverse/"); return conf; } @Override public String authenticate(String code) { return null; } }