package edu.harvard.iq.dataverse.api; import edu.harvard.iq.dataverse.api.imports.ImportServiceBean; import edu.harvard.iq.dataverse.DatasetFieldServiceBean; import edu.harvard.iq.dataverse.DatasetServiceBean; import edu.harvard.iq.dataverse.Dataverse; import edu.harvard.iq.dataverse.DataverseServiceBean; import edu.harvard.iq.dataverse.MetadataBlockServiceBean; import edu.harvard.iq.dataverse.api.imports.ImportException; import edu.harvard.iq.dataverse.api.imports.ImportUtil.ImportType; import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser; import edu.harvard.iq.dataverse.engine.command.DataverseRequest; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import java.io.IOException; import java.io.PrintWriter; import javax.ejb.EJB; import javax.ejb.Stateless; import javax.json.JsonObjectBuilder; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; @Stateless @Path("batch") public class BatchImport extends AbstractApiBean { @EJB DatasetServiceBean datasetService; @EJB DataverseServiceBean dataverseService; @EJB DatasetFieldServiceBean datasetfieldService; @EJB MetadataBlockServiceBean metadataBlockService; @EJB SettingsServiceBean settingsService; @EJB ImportServiceBean importService; @EJB BatchServiceBean batchService; /** * migrate - only needed for importing studies from old DVN installations * into Dataverse 4.0 read ddi files from the filesystem, and import them in * "migrate" mode * * @param fileDir - the full path of the parent directory where the files * are located. If there are subdirectories, then ddi's will be imported * into the dataverse matching the subdirectory name (alias) * @param parentIdtf - the dataverse that the top-level files should be * imported to - if null, then use root dataverse. * @param apiKey - users's apiKey * @return */ @GET @Path("migrate") public Response migrate(@QueryParam("path") String fileDir, @QueryParam("dv") String parentIdtf, @QueryParam("createDV") Boolean createDV, @QueryParam("key") String apiKey) throws IOException { return startBatchJob(fileDir, parentIdtf, apiKey, ImportType.MIGRATION, createDV); } @GET @Path("harvest") public Response harvest(@QueryParam("path") String fileDir, @QueryParam("dv") String parentIdtf, @QueryParam("createDV") Boolean createDV, @QueryParam("key") String apiKey) throws IOException { return startBatchJob(fileDir, parentIdtf, apiKey, ImportType.HARVEST, createDV); } /** * Import a new Dataset with DDI xml data posted in the request * * @param body the xml * @param parentIdtf the dataverse to import into (id or alias) * @param apiKey user's api key * @return import status (including id of the dataset created) */ @POST @Path("import") public Response postImport(String body, @QueryParam("dv") String parentIdtf, @QueryParam("key") String apiKey) { DataverseRequest dataverseRequest; try { dataverseRequest = createDataverseRequest(findAuthenticatedUserOrDie()); } catch (WrappedResponse wr) { return wr.getResponse(); } if (parentIdtf == null) { parentIdtf = "root"; } Dataverse owner = findDataverse(parentIdtf); if (owner == null) { return error(Response.Status.NOT_FOUND, "Can't find dataverse with identifier='" + parentIdtf + "'"); } try { PrintWriter cleanupLog = null; // Cleanup log isn't needed for ImportType == NEW. We don't do any data cleanup in this mode. String filename = null; // Since this is a single input from a POST, there is no file that we are reading from. JsonObjectBuilder status = importService.doImport(dataverseRequest, owner, body, filename, ImportType.NEW, cleanupLog); return this.ok(status); } catch (ImportException | IOException e) { return this.error(Response.Status.BAD_REQUEST, e.getMessage()); } } /** * Import single or multiple datasets that are in the local filesystem * * @param fileDir the absolute path of the file or directory (all files * within the directory will be imported * @param parentIdtf the dataverse to import into (id or alias) * @param apiKey user's api key * @return import status (including id's of the datasets created) */ @GET @Path("import") public Response getImport(@QueryParam("path") String fileDir, @QueryParam("dv") String parentIdtf, @QueryParam("createDV") Boolean createDV, @QueryParam("key") String apiKey) { return startBatchJob(fileDir, parentIdtf, apiKey, ImportType.NEW, createDV); } private Response startBatchJob(String fileDir, String parentIdtf, String apiKey, ImportType importType, Boolean createDV) { if (createDV == null) { createDV = Boolean.FALSE; } try { DataverseRequest dataverseRequest; try { dataverseRequest = createDataverseRequest(findAuthenticatedUserOrDie()); } catch (WrappedResponse wr) { return wr.getResponse(); } if (parentIdtf == null) { parentIdtf = "root"; } Dataverse owner = findDataverse(parentIdtf); if (owner == null) { if (createDV) { owner = importService.createDataverse(parentIdtf, dataverseRequest); } else { return error(Response.Status.NOT_FOUND, "Can't find dataverse with identifier='" + parentIdtf + "'"); } } batchService.processFilePath(fileDir, parentIdtf, dataverseRequest, owner, importType, createDV); } catch (ImportException e) { return this.error(Response.Status.BAD_REQUEST, "Import Exception, " + e.getMessage()); } return this.accepted(); } }