Skip to content

Commit

Permalink
assert current /bag-info.txt behavior #8760
Browse files Browse the repository at this point in the history
Also, add a superuser-only API for downloading files
(such as bags) from the file system so we can make
assertions about them in our tests.
  • Loading branch information
pdurbin committed Nov 17, 2023
1 parent 9186b06 commit 2500bcc
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@
import edu.harvard.iq.dataverse.search.savedsearch.SavedSearchServiceBean;
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
import edu.harvard.iq.dataverse.util.BundleUtil;
import edu.harvard.iq.dataverse.util.FileUtil;
import edu.harvard.iq.dataverse.util.SystemConfig;
import edu.harvard.iq.dataverse.util.json.JsonParser;
import edu.harvard.iq.dataverse.util.json.JsonUtil;
import edu.harvard.iq.dataverse.util.json.NullSafeJsonBuilder;
import edu.harvard.iq.dataverse.validation.PasswordValidatorServiceBean;
import java.io.InputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -726,6 +728,11 @@ protected Response ok(String data, MediaType mediaType, String downloadFilename)
return res.build();
}

protected Response ok(InputStream inputStream) {
ResponseBuilder res = Response.ok().entity(inputStream).type(MediaType.valueOf(FileUtil.MIME_TYPE_UNDETERMINED_DEFAULT));
return res.build();
}

protected Response created( String uri, JsonObjectBuilder bld ) {
return Response.created( URI.create(uri) )
.entity( Json.createObjectBuilder()
Expand Down
25 changes: 24 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/api/Admin.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
import edu.harvard.iq.dataverse.util.SystemConfig;
import edu.harvard.iq.dataverse.util.UrlSignerUtil;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

Expand Down Expand Up @@ -2425,5 +2426,27 @@ public Response getSignedUrl(@Context ContainerRequestContext crc, JsonObject ur

return ok(Json.createObjectBuilder().add(ExternalToolHandler.SIGNED_URL, signedUrl));
}


/**
* For testing only. Download a file from the file system.
*/
@GET
@AuthRequired
@Path("/localfile")
public Response getLocalFile(@Context ContainerRequestContext crc, @QueryParam("pathToFile") String pathToFile) {
try {
AuthenticatedUser user = getRequestAuthenticatedUserOrDie(crc);
if (!user.isSuperuser()) {
return error(Response.Status.FORBIDDEN, "Superusers only.");
}
} catch (WrappedResponse wr) {
return wr.getResponse();
}
try {
return ok(new FileInputStream(pathToFile));
} catch (IOException ex) {
return error(Status.BAD_REQUEST, ex.toString());
}
}

}
101 changes: 97 additions & 4 deletions src/test/java/edu/harvard/iq/dataverse/api/BagIT.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
package edu.harvard.iq.dataverse.api;

import io.restassured.RestAssured;
import io.restassured.response.Response;
import edu.harvard.iq.dataverse.engine.command.impl.LocalSubmitToArchiveCommand;
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
import io.restassured.RestAssured;
import static io.restassured.RestAssured.given;
import io.restassured.response.Response;
import static jakarta.ws.rs.core.Response.Status.CREATED;
import static jakarta.ws.rs.core.Response.Status.OK;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Enumeration;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.junit.jupiter.api.AfterAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

public class BagIT {

static String bagitExportDir = "/tmp";

@BeforeAll
public static void setUpClass() {

Expand All @@ -25,14 +40,14 @@ public static void setUpClass() {
setArchiverSettings.then().assertThat()
.statusCode(OK.getStatusCode());

Response setBagItLocalPath = UtilIT.setSetting(":BagItLocalPath", "/tmp");
Response setBagItLocalPath = UtilIT.setSetting(":BagItLocalPath", bagitExportDir);
setBagItLocalPath.then().assertThat()
.statusCode(OK.getStatusCode());

}

@Test
public void testBagItExport() {
public void testBagItExport() throws IOException {

Response createUser = UtilIT.createRandomUser();
createUser.then().assertThat().statusCode(OK.getStatusCode());
Expand Down Expand Up @@ -63,6 +78,78 @@ public void testBagItExport() {
archiveDataset.prettyPrint();
archiveDataset.then().assertThat().statusCode(OK.getStatusCode());

// spaceName comes from LocalSubmitToArchiveCommand
String spaceName = datasetPid.replace(':', '-').replace('/', '-')
.replace('.', '-').toLowerCase();
// spacename: doi-10-5072-fk2-fosg5q

String pathToZip = bagitExportDir + "/" + spaceName + "v1.0" + ".zip";

try {
// give the bag time to generate
Thread.sleep(3000);
} catch (InterruptedException ex) {
}

// A bag could look like this:
//doi-10-5072-FK2-DKUTDUv-1-0/data/
//doi-10-5072-FK2-DKUTDUv-1-0/data/Darwin's Finches/
//doi-10-5072-FK2-DKUTDUv-1-0/metadata/
//doi-10-5072-FK2-DKUTDUv-1-0/metadata/pid-mapping.txt
//doi-10-5072-FK2-DKUTDUv-1-0/manifest-md5.txt
//doi-10-5072-FK2-DKUTDUv-1-0/bagit.txt
//doi-10-5072-FK2-DKUTDUv-1-0/metadata/oai-ore.jsonld
//doi-10-5072-FK2-DKUTDUv-1-0/metadata/datacite.xml
//doi-10-5072-FK2-DKUTDUv-1-0/bag-info.txt
// ---
// bag-info.txt could look like this:
//Contact-Name: Finch, Fiona
//Contact-Email: finch@mailinator.com
//Source-Organization: Dataverse Installation (<Site Url>)
//Organization-Address: <Full address>
//Organization-Email: <Email address>
//External-Description: Darwin's finches (also known as the Galápagos finches) are a group of about
// fifteen species of passerine birds.
//Bagging-Date: 2023-11-14
//External-Identifier: https://doi.org/10.5072/FK2/LZIGBC
//Bag-Size: 0 bytes
//Payload-Oxum: 0.0
//Internal-Sender-Identifier: Root:Darwin's Finches
Response downloadBag = downloadLocalFile(pathToZip, apiToken);
downloadBag.then().assertThat().statusCode(OK.getStatusCode());
Path outputPath = Paths.get("/tmp/foo.zip");
java.nio.file.Files.copy(downloadBag.getBody().asInputStream(), outputPath, StandardCopyOption.REPLACE_EXISTING);

ZipFile zipFile = new ZipFile(outputPath.toString());
Enumeration<? extends ZipEntry> entries = zipFile.entries();
String sourceOrg = null;
String orgAddress = null;
String orgEmail = null;
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String name = entry.getName();
System.out.println("name: " + name);
if (name.endsWith("bag-info.txt")) {
InputStream stream = zipFile.getInputStream(entry);
Scanner s = new Scanner(stream).useDelimiter("\\A");
String result = s.hasNext() ? s.next() : "";
System.out.println("result: " + result);
String[] lines = result.split("\n");
for (String line : lines) {
if (line.startsWith("Source-Organization")) {
sourceOrg = line;
} else if (line.startsWith("Organization-Address")) {
orgAddress = line;
} else if (line.startsWith("Organization-Email")) {
orgEmail = line;
} else {
}
}
}
}
assertEquals("Source-Organization: Dataverse Installation (<Site Url>)", sourceOrg.trim());
assertEquals("Organization-Address: <Full address>", orgAddress.trim());
assertEquals("Organization-Email: <Email address>", orgEmail.trim());
}

@AfterAll
Expand All @@ -75,4 +162,10 @@ public static void tearDownClass() {

}

static Response downloadLocalFile(String pathToFile, String apiToken) {
return given()
.header("X-Dataverse-key", apiToken)
.get("/api/admin/localfile?pathToFile=" + pathToFile);
}

}

0 comments on commit 2500bcc

Please sign in to comment.