From a5312208d7d289deb041332d228c1f079a84fce9 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Tue, 13 Feb 2018 16:20:19 -0500 Subject: [PATCH] stub out calling prov from publish, add export stub #4381 --- .../iq/dataverse/EjbDataverseEngine.java | 9 +++ .../edu/harvard/iq/dataverse/api/Prov.java | 20 +++++++ .../engine/command/CommandContext.java | 3 + .../FinalizeDatasetPublicationCommand.java | 26 +++++++++ .../provenance/ProvenanceRestServiceBean.java | 9 +++ .../edu/harvard/iq/dataverse/api/ProvIT.java | 56 ++++++++++++++++++- .../edu/harvard/iq/dataverse/api/UtilIT.java | 17 ++++++ .../dataverse/engine/TestCommandContext.java | 6 ++ 8 files changed, 144 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/EjbDataverseEngine.java b/src/main/java/edu/harvard/iq/dataverse/EjbDataverseEngine.java index e36f7feaec3..0018437b698 100644 --- a/src/main/java/edu/harvard/iq/dataverse/EjbDataverseEngine.java +++ b/src/main/java/edu/harvard/iq/dataverse/EjbDataverseEngine.java @@ -15,6 +15,7 @@ import edu.harvard.iq.dataverse.engine.command.exception.PermissionException; import edu.harvard.iq.dataverse.ingest.IngestServiceBean; import edu.harvard.iq.dataverse.privateurl.PrivateUrlServiceBean; +import edu.harvard.iq.dataverse.provenance.ProvenanceRestServiceBean; import edu.harvard.iq.dataverse.search.IndexServiceBean; import edu.harvard.iq.dataverse.search.SearchServiceBean; import java.util.Map; @@ -150,6 +151,9 @@ public class EjbDataverseEngine { @EJB DataCaptureModuleServiceBean dataCaptureModule; + @EJB + ProvenanceRestServiceBean provenanceRestService; + @PersistenceContext(unitName = "VDCNet-ejbPU") private EntityManager em; @@ -437,6 +441,11 @@ public DataCaptureModuleServiceBean dataCaptureModule() { return dataCaptureModule; } + @Override + public ProvenanceRestServiceBean provenanceRestService() { + return provenanceRestService; + } + }; } diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Prov.java b/src/main/java/edu/harvard/iq/dataverse/api/Prov.java index d15dbda1104..7e51bd996cc 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Prov.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Prov.java @@ -5,14 +5,17 @@ import edu.harvard.iq.dataverse.engine.command.impl.DeleteProvJsonProvCommand; import edu.harvard.iq.dataverse.engine.command.impl.PersistProvFreeFormCommand; import edu.harvard.iq.dataverse.engine.command.impl.PersistProvJsonProvCommand; +import edu.harvard.iq.dataverse.provenance.ProvenanceRestServiceBean; import java.io.StringReader; import java.util.logging.Logger; +import javax.ejb.EJB; import javax.json.Json; import javax.json.JsonException; import javax.json.JsonObject; import javax.json.JsonObjectBuilder; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; +import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @@ -24,6 +27,9 @@ public class Prov extends AbstractApiBean { private static final Logger logger = Logger.getLogger(Prov.class.getCanonicalName()); + @EJB + ProvenanceRestServiceBean provenanceRestSvc; + /** Provenance JSON methods **/ @POST @Path("{id}/prov-json") @@ -88,6 +94,20 @@ public Response removeProvFreeForm(String body, @PathParam("id") String idSuppli } } + @GET + @Path("{id}/prov") + public Response exportProv(@PathParam("id") String idSupplied) { + try { + // FIXME: Don't hard code this as 94, obviously. Look up the bundleId based on the file id/PID. + long bundleId = 94; + JsonObject jsonObject = provenanceRestSvc.getBundleJson(bundleId); + // FIXME: How should this JSON look? + return ok(Json.createObjectBuilder().add("exportProv", jsonObject)); + } catch (Exception ex) { + return error(BAD_REQUEST, "error!"); + } + } + /** Helper Methods */ // FIXME: Delete this and switch to the version in AbstractApiBean.java once this is merged: https://github.com/IQSS/dataverse/pull/4350 private DataFile findDataFileOrDie(String idSupplied) throws WrappedResponse { diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/CommandContext.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/CommandContext.java index 3e340827ae3..9bd422046f7 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/CommandContext.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/CommandContext.java @@ -30,6 +30,7 @@ import edu.harvard.iq.dataverse.engine.DataverseEngine; import edu.harvard.iq.dataverse.ingest.IngestServiceBean; import edu.harvard.iq.dataverse.privateurl.PrivateUrlServiceBean; +import edu.harvard.iq.dataverse.provenance.ProvenanceRestServiceBean; import edu.harvard.iq.dataverse.search.SolrIndexServiceBean; import edu.harvard.iq.dataverse.search.savedsearch.SavedSearchServiceBean; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; @@ -123,4 +124,6 @@ public interface CommandContext { public MapLayerMetadataServiceBean mapLayerMetadata(); public DataCaptureModuleServiceBean dataCaptureModule(); + + public ProvenanceRestServiceBean provenanceRestService(); } diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/FinalizeDatasetPublicationCommand.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/FinalizeDatasetPublicationCommand.java index faa7d3885f9..e155fb01f53 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/FinalizeDatasetPublicationCommand.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/FinalizeDatasetPublicationCommand.java @@ -1,5 +1,6 @@ package edu.harvard.iq.dataverse.engine.command.impl; +import com.mashape.unirest.http.exceptions.UnirestException; import edu.harvard.iq.dataverse.DataFile; import edu.harvard.iq.dataverse.Dataset; import edu.harvard.iq.dataverse.DatasetField; @@ -29,6 +30,9 @@ import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; /** * @@ -177,6 +181,7 @@ private void publicizeExternalIdentifier(Dataset dataset, CommandContext ctxt) t } private void updateFiles(Timestamp updateTime, CommandContext ctxt) throws CommandException { + boolean provEnabled = ctxt.systemConfig().getProvServiceUrl() != null; for (DataFile dataFile : theDataset.getFiles()) { if (dataFile.getPublicationDate() == null) { // this is a new, previously unpublished file, so publish by setting date @@ -238,6 +243,27 @@ private void updateFiles(Timestamp updateTime, CommandContext ctxt) throws Comma theDataset.setThumbnailFile(null); } } + if (provEnabled) { + logger.info("let's do prov stuff of file id " + dataFile.getId()); + try { + // FIXME: It's bizarre to have to call setProvBaseUrl like this. Fix it. + ctxt.provenanceRestService().setProvBaseUrl(ctxt.systemConfig().getProvServiceUrl()); + // FIXME: What should the bundle id be? + Long bundleId = ctxt.provenanceRestService().createEmptyBundleFromName("FIXME"); + JsonObjectBuilder innerJson = Json.createObjectBuilder(); + // FIXME: What JSON should we send to the prov service? + innerJson.add("foo", "bar"); + JsonObject provJson = innerJson.build(); + // FIXME: What should this bundleName be? + String bundleName = bundleId + "-uploadJson"; + JsonObject returnFromUpload = ctxt.provenanceRestService().uploadProvJsonForBundle(provJson, bundleName); + logger.info("return from upload: " + returnFromUpload); + } catch (UnirestException ex) { + logger.info("Problem calling into prov service: " + ex); + } + } else { + logger.info("on file id " + dataFile.getId() + " but prov is not enabled"); + } } } diff --git a/src/main/java/edu/harvard/iq/dataverse/provenance/ProvenanceRestServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/provenance/ProvenanceRestServiceBean.java index 6c0b42ae2da..9db7183d250 100644 --- a/src/main/java/edu/harvard/iq/dataverse/provenance/ProvenanceRestServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/provenance/ProvenanceRestServiceBean.java @@ -285,6 +285,15 @@ public JsonObject uploadProvJsonForBundle(JsonObject provJson, String bundleName //{ // 'id': Long //} + /** + * Need IRI per Dataverse-installation. + * + * @param prefix Short, three characters + */ + public static void createObject(String prefix, String name, String type, String bundleId) { + // FIXME: Implement me. Add function for addBundlePrefix too. + } + // //POST /provapi/lookup/object //looks up an object diff --git a/src/test/java/edu/harvard/iq/dataverse/api/ProvIT.java b/src/test/java/edu/harvard/iq/dataverse/api/ProvIT.java index 62d8480b6f2..48f2dcdb785 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/ProvIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/ProvIT.java @@ -19,6 +19,58 @@ public static void setUpClass() { RestAssured.baseURI = UtilIT.getRestAssuredBaseUri(); } + @Test + public void testPublish() { + + Response createDepositor = UtilIT.createRandomUser(); + createDepositor.prettyPrint(); + createDepositor.then().assertThat() + .statusCode(OK.getStatusCode()); + String usernameForDepositor = UtilIT.getUsernameFromResponse(createDepositor); + String apiTokenForDepositor = UtilIT.getApiTokenFromResponse(createDepositor); + + Response createDataverseResponse = UtilIT.createRandomDataverse(apiTokenForDepositor); + createDataverseResponse.prettyPrint(); + createDataverseResponse.then().assertThat() + .statusCode(CREATED.getStatusCode()); + + String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse); + + Response createDataset = UtilIT.createRandomDatasetViaNativeApi(dataverseAlias, apiTokenForDepositor); + createDataset.prettyPrint(); + createDataset.then().assertThat() + .statusCode(CREATED.getStatusCode()); + + Integer datasetId = UtilIT.getDatasetIdFromResponse(createDataset); + + String pathToFile = "src/main/webapp/resources/images/dataverseproject.png"; + Response authorAddsFile = UtilIT.uploadFileViaNative(datasetId.toString(), pathToFile, apiTokenForDepositor); + authorAddsFile.prettyPrint(); + authorAddsFile.then().assertThat() + .body("status", equalTo("OK")) + .body("data.files[0].label", equalTo("dataverseproject.png")) + .statusCode(OK.getStatusCode()); + + Long dataFileId = JsonPath.from(authorAddsFile.getBody().asString()).getLong("data.files[0].dataFile.id"); + System.out.println("datafile id: " + dataFileId); + + Response publishDataverse = UtilIT.publishDataverseViaNativeApi(dataverseAlias, apiTokenForDepositor); + publishDataverse.then().assertThat() + .statusCode(OK.getStatusCode()); + + Response publishDataset = UtilIT.publishDatasetViaNativeApi(datasetId.toString(), "major", apiTokenForDepositor); + publishDataset.prettyPrint(); + publishDataset.then().assertThat() + .statusCode(OK.getStatusCode()); + + String apiToken = apiTokenForDepositor; + Response exportProv = UtilIT.exportProv(dataFileId.toString(), apiToken); + exportProv.prettyPrint(); + exportProv.then().assertThat() + // FIXME: assert what to expect in the body + .statusCode(OK.getStatusCode()); + } + @Test public void testAddProvFile() { @@ -67,7 +119,7 @@ public void testAddProvFile() { uploadProvJson.then().assertThat() .body("data.message", equalTo("PROV-JSON provenance data saved: {\"prov\":true,\"foo\":\"bar\"}")) .statusCode(OK.getStatusCode()); - + Response deleteProvJson = UtilIT.deleteProvJson(dataFileId.toString(), apiTokenForDepositor); deleteProvJson.prettyPrint(); deleteProvJson.then().assertThat() @@ -82,7 +134,7 @@ public void testAddProvFile() { uploadProvFreeForm.then().assertThat() .body("data.message", equalTo("Free-form provenance data saved: I inherited this file from my grandfather.")) .statusCode(OK.getStatusCode()); - + Response deleteProvFreeForm = UtilIT.deleteProvFreeForm(dataFileId.toString(), apiTokenForDepositor); deleteProvFreeForm.prettyPrint(); deleteProvFreeForm.then().assertThat() diff --git a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java index 56802a4614c..024eb2cae54 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java @@ -990,6 +990,23 @@ static Response deleteProvFreeForm(String idOrPersistentId, String apiToken) { return requestSpecification.delete("/api/files/" + idInPath + "/prov-freeform" + optionalQueryParam); } + static Response exportProv(String idOrPersistentId, String apiToken) { + logger.info("Exporting Provenance"); + //TODO: Repeated code, refactor + String idInPath = idOrPersistentId; // Assume it's a number. + String optionalQueryParam = ""; // If idOrPersistentId is a number we'll just put it in the path. + if (!NumberUtils.isNumber(idOrPersistentId)) { + idInPath = ":persistentId"; + optionalQueryParam = "?persistentId=" + idOrPersistentId; + } + RequestSpecification requestSpecification = given(); + if (apiToken != null) { + requestSpecification = given() + .header(UtilIT.API_TOKEN_HTTP_HEADER, apiToken); + } + return requestSpecification.get("/api/files/" + idInPath + "/prov" + optionalQueryParam); + } + static Response exportDataset(String datasetPersistentId, String exporter, String apiToken) { // http://localhost:8080/api/datasets/export?exporter=dataverse_json&persistentId=doi%3A10.5072/FK2/W6WIMQ return given() diff --git a/src/test/java/edu/harvard/iq/dataverse/engine/TestCommandContext.java b/src/test/java/edu/harvard/iq/dataverse/engine/TestCommandContext.java index 908cf087e41..aa1f7c254a0 100644 --- a/src/test/java/edu/harvard/iq/dataverse/engine/TestCommandContext.java +++ b/src/test/java/edu/harvard/iq/dataverse/engine/TestCommandContext.java @@ -8,6 +8,7 @@ import edu.harvard.iq.dataverse.engine.command.CommandContext; import edu.harvard.iq.dataverse.ingest.IngestServiceBean; import edu.harvard.iq.dataverse.privateurl.PrivateUrlServiceBean; +import edu.harvard.iq.dataverse.provenance.ProvenanceRestServiceBean; import edu.harvard.iq.dataverse.search.IndexServiceBean; import edu.harvard.iq.dataverse.search.SearchServiceBean; import edu.harvard.iq.dataverse.search.SolrIndexServiceBean; @@ -203,4 +204,9 @@ public MapLayerMetadataServiceBean mapLayerMetadata() { public DataCaptureModuleServiceBean dataCaptureModule() { return null; } + + @Override + public ProvenanceRestServiceBean provenanceRestService() { + return null; + } }