Skip to content

Commit

Permalink
This is a combination of 5 commits.
Browse files Browse the repository at this point in the history
add overloaded method to add input stream

fix tests

Update src/main/java/com/researchspace/dataverse/entities/ObjectOrStringMessageDeserializer.java

docs: javadocs

Update src/main/java/com/researchspace/dataverse/http/DataverseOperationsImplV1.java

remove obsolete comment
  • Loading branch information
otter606 committed Nov 27, 2022
1 parent 865b981 commit 22da346
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 38 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
Significant changes since 0.1.0

1.1.0 In progress

- feature: Support upload of files to a dataset using native API. #16
- feature: After creating a Dataset, the persistent ID is stored in the Identifier object. #22

1.0.0 2022-11-21

Increasing major version due to major updates to dependencies. However, there are no
Expand All @@ -8,7 +13,7 @@ breaking API changes in this library.
- dependencies: Major dependency updates to Spring 5.3, Lombok 18.24.
- build: fix integration tests
- build: enable integration test running through Github actions
- build: test build and test on Java 8, 11, and 17
- build: test build and test on Java 8, 11, and 17.

0.2.0 2022-11-20

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
import org.junit.Ignore;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -63,17 +65,51 @@ public void testPostSampleDataset() throws IOException, InterruptedException, UR
}

@Test
public void uploadFileToDataSetWithNativeApi() throws IOException, URISyntaxException {
DatasetFacade facade = createFacade();
Identifier datasetId = dataverseOps.createDataset(facade, dataverseAlias);
public void uploadFileToDataSetWithNativeApiBytes() throws IOException, URISyntaxException {
//arrange
Identifier datasetId = createADataset();
assertNotNull(datasetId.getId());
FileUploadMetadata meta = FileUploadMetadata.builder().description("My description.").categories(Arrays.asList(new String[]{"Data"}))
.directoryLabel("test/x").build();
DatasetFileList datasetFileList = datasetOps.uploadNativeFile(meta, datasetId, new byte[]{1, 2, 3, 4, 5}, "myFileName.dat");
FileUploadMetadata meta = getUploadMetadata();

//act
DatasetFileList datasetFileList = datasetOps.uploadNativeFile(new byte[]{1, 2, 3, 4, 5}, meta, datasetId, "myFileName.dat");

//assert
assertNotNull(datasetFileList);
assertEquals(1, datasetFileList.getFiles().size());
assertTrue(datasetFileList.getFiles().get(0).getCategories().contains("Data"));
assertTrue(datasetFileList.getFiles().get(0).getDescription().equals(("My description.")));
assertEquals(5 ,datasetFileList.getFiles().get(0).getDataFile().getFilesize());
}

@Test
public void uploadFileToDataSetWithNativeApiInputStream() throws IOException, URISyntaxException {
// arrange
Identifier datasetId = createADataset();
assertNotNull(datasetId.getId());
FileUploadMetadata meta = getUploadMetadata();

//act
DatasetFileList datasetFileList = datasetOps.uploadNativeFile(new ByteArrayInputStream(new byte[]{1, 2, 3, 4, 5,6}), 6, meta, datasetId, "myFileName.dat");

//assert
assertNotNull(datasetFileList);
assertEquals(1, datasetFileList.getFiles().size());
DatasetFile uploadedFile = datasetFileList.getFiles().get(0);
assertTrue(uploadedFile.getCategories().contains("Data"));
assertTrue(uploadedFile.getDescription().equals(("My description.")));
assertEquals(6 ,uploadedFile.getDataFile().getFilesize());
}

private Identifier createADataset() throws MalformedURLException, URISyntaxException {
DatasetFacade facade = createFacade();
Identifier datasetId = dataverseOps.createDataset(facade, dataverseAlias);
return datasetId;
}

private FileUploadMetadata getUploadMetadata() {
return FileUploadMetadata.builder().description("My description.").categories(Arrays.asList(new String[]{"Data"}))
.directoryLabel("test/x").build();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ public interface DatasetOperations {
*/
DatasetVersion updateDataset(DatasetFacade facade, Identifier id);


/**
* Retrieves a {@link Dataset} based on its Id.
* @param dsIdentifier
Expand All @@ -57,7 +56,27 @@ public interface DatasetOperations {
*/
List<DatasetVersion> getDatasetVersions(Identifier dsIdentifier);

DatasetFileList uploadNativeFile(FileUploadMetadata metadata, Identifier dsIdentifier, byte[] data, String fileName);
/**
* Upload a file to a dataset using Dataverse's native API (not Sword)
* @param metadata Metadata to attach to the file upload
* @param dsIdentifier The persistent identifier of the dataset
* @param data bytes of data to upload
* @param fileName The name of the file to be created on Dataverse
* @return DatasetFileList information about the uploaded file.
*/
DatasetFileList uploadNativeFile( byte[] data, FileUploadMetadata metadata, Identifier dsIdentifier, String fileName);

/**
* Upload a file to a dataset using Dataverse's native API (not Sword).
* @param metadata Metadata to attach to the file upload
* @param contentLength The length of the stream
* @param dsIdentifier The persistent identifier of the dataset
* @param data bytes of data to upload
* @param fileName The name of the file to be created on Dataverse
* @return DatasetFileList information about the uploaded file.
*/
DatasetFileList uploadNativeFile(InputStream data, long contentLength, FileUploadMetadata metadata,
Identifier dsIdentifier, String fileName);

/**
* Uploads a file to a dataset
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.researchspace.dataverse.entities;

import com.researchspace.dataverse.http.FileUploadMetadata;
import lombok.Data;

/**
* Checksum is part of the response from
* {@link com.researchspace.dataverse.api.v1.DatasetOperations#uploadNativeFile(byte[], FileUploadMetadata, Identifier, String)}
*/
@Data
public class Checksum {
private String type;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package com.researchspace.dataverse.entities;

import com.researchspace.dataverse.http.FileUploadMetadata;
import lombok.Data;

import java.util.List;

/**
* DatasetFile is part of the response from
* {@link com.researchspace.dataverse.api.v1.DatasetOperations#uploadNativeFile(byte[], FileUploadMetadata, Identifier, String)}
*/
@Data
public class DatasetFile {
private String description;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package com.researchspace.dataverse.entities;

import com.researchspace.dataverse.http.FileUploadMetadata;
import lombok.Data;

import java.util.Date;

/**
* DatasetFileDetails is a subsection of the response from
* {@link com.researchspace.dataverse.api.v1.DatasetOperations#uploadNativeFile(byte[], FileUploadMetadata, Identifier, String)}
*/
@Data
public class DatasetFileDetails {
private int id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import lombok.Data;

import java.util.List;

/**
* DatasetFileList is the response from uploading a file using the native API
*/
@Data
public class DatasetFileList {
List<DatasetFile> files;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public String deserialize(JsonParser jp, DeserializationContext ctxt)
} else if (node.isObject()){
return node.get("message").toString();
} else{
throw new IllegalArgumentException("expect a string or an object with a string property");
throw new IllegalArgumentException("expect a string or an object with a string property 'message'");
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.AbstractResource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
Expand Down Expand Up @@ -192,17 +195,43 @@ public List<DatasetVersion> getDatasetVersions (Identifier dsIdentifier) {
}

@Override
public DatasetFileList uploadNativeFile( FileUploadMetadata metadata, Identifier dsIdentifier, byte[] data, String fileName){
public DatasetFileList uploadNativeFile( byte[] data, FileUploadMetadata metadata, Identifier dsIdentifier, String fileName){
ByteArrayResource resource = new ByteArrayResource(data){
@Override
public String getFilename(){
return fileName;
}
};
return getDatasetFileList(metadata, dsIdentifier, resource);
}
@Override
public DatasetFileList uploadNativeFile(InputStream data, long contentLength, FileUploadMetadata metadata, Identifier dsIdentifier, String fileName) {
InputStreamResource resource = new InputStreamResource(data) {
@Override
public String getFilename(){
return fileName;
}

@Override
public long contentLength() throws IOException {
return contentLength;
}
};
return getDatasetFileList(metadata, dsIdentifier, resource);

}

private DatasetFileList getDatasetFileList(FileUploadMetadata metadata, Identifier dsIdentifier, AbstractResource resource) {
String url = createV1Url("datasets", ":persistentId", "add") + "?persistentId=" + dsIdentifier.getPersistentId();
ParameterizedTypeReference<DataverseResponse<DatasetFileList>> type =
new ParameterizedTypeReference<DataverseResponse<DatasetFileList>>() {};
HttpEntity<MultiValueMap<String, Object>> entity = new NativeFileUploader().uploadFile(metadata, apiKey, data, fileName);
HttpEntity<MultiValueMap<String, Object>> entity = new NativeFileUploader().createFileUploadEntity(metadata, apiKey, resource);
ResponseEntity<DataverseResponse<DatasetFileList>> resp = template.exchange(url, HttpMethod.POST, entity, type);
log.debug("{}", resp.getBody());
handleError(resp);
return resp.getBody().getData();
}

/* (non-Javadoc)
* @see com.researchspace.dataverse.http.DataverseAPI#uploadFile(java.lang.String, java.io.File)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
*/
@Data
@Builder

public class FileUploadMetadata {
private String description;
private String directoryLabel;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
package com.researchspace.dataverse.http;

import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.core.io.AbstractResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

/**
* NativeFileUploader is helper class that performs upload of files using native API
*/
public class NativeFileUploader {

public HttpEntity<MultiValueMap<String, Object>> uploadFile(FileUploadMetadata metadata, String apiKey, byte[] data, String fName){
RestTemplate restTemplate = new RestTemplate();
public HttpEntity<MultiValueMap<String, Object>> createFileUploadEntity(FileUploadMetadata metadata, String apiKey, AbstractResource resource){

MultiValueMap<String,Object> multipartRequest = new LinkedMultiValueMap<>();

HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add(AbstractOpsImplV1.apiHeader, apiKey);
requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);//Main request's headers

HttpHeaders requestHeadersAttachment = new HttpHeaders();
//requestHeadersAttachment.setContentType(MediaType.APPLICATION_OCTET_STREAM);// extract mediatype from file extensionHttpEntity<ByteArrayResource> attachmentPart;
ByteArrayResource fileAsResource = new ByteArrayResource(data){
@Override
public String getFilename(){
return fName;
}
};
HttpEntity attachmentPart = new HttpEntity<>(fileAsResource,requestHeadersAttachment);

HttpEntity attachmentPart = new HttpEntity<>(resource,requestHeadersAttachment);
multipartRequest.set("file",attachmentPart);

HttpHeaders requestHeadersJSON = new HttpHeaders();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import com.researchspace.dataverse.entities.Identifier;
import com.researchspace.dataverse.search.entities.SearchConfig;
import com.researchspace.dataverse.testutils.TestFileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.http.HttpMethod;
import org.springframework.test.web.client.ExpectedCount;
Expand Down Expand Up @@ -43,27 +41,22 @@
</pre>
*/
public class DatasetFilePostMockServerTest {

@Before
public void setUp() throws Exception {
}

@After
public void tearDown() throws Exception {
}

@Test
public void testNativeFilePost() throws MalformedURLException {
RestTemplate template = new RestTemplate();
DataverseOperationsImplV1 tss = setupDataverseOps(template);
setUpServerResponse(template, "http://anyDataverse.com/api/v1/datasets/:persistentId/add?persistentId=1234",
final String persistentid = "doi://dsfh.dsdsd.sds";
setUpServerResponse(template, "http://anyDataverse.com/api/v1/datasets/:persistentId/add?persistentId="+persistentid,
getDataSetFileUploadResults() );

DataverseConfig cfg = new DataverseConfig(new URL("http://anyDataverse.com"), "any", "alias");
tss.configure(cfg);
Identifier id = new Identifier();
id.setId(1234L);
DatasetFileList resp = tss.uploadNativeFile( FileUploadMetadata.builder().build(), id, null, null);
id.setPersistentId(persistentid);
DatasetFileList resp = tss.uploadNativeFile(new byte []{}, FileUploadMetadata.builder().build(), id, "any");
assertNotNull(resp.getFiles());
assertEquals(1, resp.getFiles().size());
}
Expand Down

0 comments on commit 22da346

Please sign in to comment.