/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE file at the root of the source * tree and available online at * * https://github.com/keeps/roda */ package org.roda.core.plugins; import java.io.IOException; import java.net.URL; import java.nio.file.FileAlreadyExistsException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.io.IOUtils; import org.apache.solr.client.solrj.SolrServerException; import org.roda.core.CorporaConstants; import org.roda.core.RodaCoreFactory; import org.roda.core.TestsHelper; import org.roda.core.common.iterables.CloseableIterable; import org.roda.core.common.monitor.TransferredResourcesScanner; import org.roda.core.data.common.RodaConstants; import org.roda.core.data.exceptions.AlreadyExistsException; import org.roda.core.data.exceptions.AuthorizationDeniedException; import org.roda.core.data.exceptions.GenericException; import org.roda.core.data.exceptions.InvalidParameterException; import org.roda.core.data.exceptions.IsStillUpdatingException; import org.roda.core.data.exceptions.NotFoundException; import org.roda.core.data.exceptions.RODAException; import org.roda.core.data.exceptions.RequestNotValidException; import org.roda.core.data.v2.common.OptionalWithCause; import org.roda.core.data.v2.index.IndexResult; import org.roda.core.data.v2.index.filter.Filter; import org.roda.core.data.v2.index.filter.SimpleFilterParameter; import org.roda.core.data.v2.index.select.SelectedItemsAll; import org.roda.core.data.v2.index.select.SelectedItemsList; import org.roda.core.data.v2.index.sort.Sorter; import org.roda.core.data.v2.index.sublist.Sublist; import org.roda.core.data.v2.ip.AIP; import org.roda.core.data.v2.ip.DIP; import org.roda.core.data.v2.ip.DIPFile; import org.roda.core.data.v2.ip.File; import org.roda.core.data.v2.ip.IndexedAIP; import org.roda.core.data.v2.ip.IndexedDIP; import org.roda.core.data.v2.ip.Permissions; import org.roda.core.data.v2.ip.Representation; import org.roda.core.data.v2.ip.StoragePath; import org.roda.core.data.v2.ip.TransferredResource; import org.roda.core.data.v2.jobs.Job; import org.roda.core.data.v2.jobs.PluginType; import org.roda.core.data.v2.jobs.Report; import org.roda.core.index.IndexService; import org.roda.core.model.ModelService; import org.roda.core.model.utils.ModelUtils; import org.roda.core.plugins.plugins.characterization.DigitalSignatureDIPPlugin; import org.roda.core.plugins.plugins.characterization.DigitalSignatureDIPPluginUtils; import org.roda.core.plugins.plugins.characterization.PDFSignatureUtils; import org.roda.core.plugins.plugins.ingest.TransferredResourceToAIPPlugin; import org.roda.core.storage.DirectResourceAccess; import org.roda.core.storage.fs.FSUtils; import org.roda.core.util.IdUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.AssertJUnit; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @Test(groups = {"all"}) public class DigitalSignatureDIPTest { private static final Logger LOGGER = LoggerFactory.getLogger(DigitalSignatureDIPTest.class); private static Path basePath; private static ModelService model; private static IndexService index; private static Path corporaPath; @BeforeMethod public void setUp() throws Exception { basePath = TestsHelper.createBaseTempDir(this.getClass(), true); boolean deploySolr = true; boolean deployLdap = false; boolean deployFolderMonitor = true; boolean deployOrchestrator = true; boolean deployPluginManager = true; boolean deployDefaultResources = false; RodaCoreFactory.instantiateTest(deploySolr, deployLdap, deployFolderMonitor, deployOrchestrator, deployPluginManager, deployDefaultResources); model = RodaCoreFactory.getModelService(); index = RodaCoreFactory.getIndexService(); URL corporaURL = getClass().getResource("/corpora"); corporaPath = Paths.get(corporaURL.toURI()); LOGGER.info("Running internal convert plugins tests under storage {}", basePath); } @AfterMethod public void tearDown() throws Exception { RodaCoreFactory.shutdown(); FSUtils.deletePath(basePath); } public List<TransferredResource> createCorpora() throws InterruptedException, IOException, FileAlreadyExistsException, NotFoundException, GenericException, AlreadyExistsException, SolrServerException, IsStillUpdatingException { TransferredResourcesScanner f = RodaCoreFactory.getTransferredResourcesScanner(); List<TransferredResource> resources = new ArrayList<TransferredResource>(); Path corpora = corporaPath.resolve(RodaConstants.STORAGE_CONTAINER_AIP) .resolve(CorporaConstants.SOURCE_AIP_CONVERTER_3).resolve(RodaConstants.STORAGE_DIRECTORY_REPRESENTATIONS) .resolve(CorporaConstants.REPRESENTATION_CONVERTER_ID_3).resolve(RodaConstants.STORAGE_DIRECTORY_DATA); String transferredResourceId = "testt"; FSUtils.copy(corpora, f.getBasePath().resolve(transferredResourceId), true); f.updateTransferredResources(Optional.empty(), true); index.commit(TransferredResource.class); resources .add(index.retrieve(TransferredResource.class, IdUtils.createUUID(transferredResourceId), new ArrayList<>())); return resources; } public AIP ingestCorpora() throws RequestNotValidException, NotFoundException, GenericException, AlreadyExistsException, AuthorizationDeniedException, InvalidParameterException, InterruptedException, IOException, FileAlreadyExistsException, SolrServerException, IsStillUpdatingException { String parentId = null; String aipType = RodaConstants.AIP_TYPE_MIXED; AIP root = model.createAIP(parentId, aipType, new Permissions(), RodaConstants.ADMIN); Map<String, String> parameters = new HashMap<>(); parameters.put(RodaConstants.PLUGIN_PARAMS_PARENT_ID, root.getId()); List<TransferredResource> transferredResources = new ArrayList<TransferredResource>(); transferredResources = createCorpora(); AssertJUnit.assertEquals(1, transferredResources.size()); Job job = TestsHelper.executeJob(TransferredResourceToAIPPlugin.class, parameters, PluginType.SIP_TO_AIP, SelectedItemsList.create(TransferredResource.class, transferredResources.stream().map(tr -> tr.getUUID()).collect(Collectors.toList()))); TestsHelper.getJobReports(index, job, true); index.commitAIPs(); IndexResult<IndexedAIP> find = index.find(IndexedAIP.class, new Filter(new SimpleFilterParameter(RodaConstants.AIP_PARENT_ID, root.getId())), null, new Sublist(0, 10), new ArrayList<>()); AssertJUnit.assertEquals(1L, find.getTotalCount()); IndexedAIP indexedAIP = find.getResults().get(0); return model.retrieveAIP(indexedAIP.getId()); } @SuppressWarnings("unchecked") @Test public void testDigitalSignatureDIPPlugin() throws RODAException, FileAlreadyExistsException, InterruptedException, IOException, SolrServerException, IsStillUpdatingException { AIP aip = ingestCorpora(); Representation rep = aip.getRepresentations().get(0); CloseableIterable<OptionalWithCause<File>> allFiles = model.listFilesUnder(aip.getId(), rep.getId(), true); OptionalWithCause<File> file = allFiles.iterator().next(); StoragePath fileStoragePath = ModelUtils.getFileStoragePath(file.get()); DirectResourceAccess directAccess = model.getStorage().getDirectAccess(fileStoragePath); AssertJUnit.assertEquals(0, PDFSignatureUtils.countSignaturesPDF(directAccess.getPath())); IOUtils.closeQuietly(directAccess); Map<String, String> parameters = new HashMap<>(); DigitalSignatureDIPPluginUtils.setKeystorePath(corporaPath.toString() + "/Certification/keystore.jks"); Job job = TestsHelper.executeJob(DigitalSignatureDIPPlugin.class, parameters, PluginType.AIP_TO_AIP, SelectedItemsAll.create(Representation.class)); List<Report> jobReports = TestsHelper.getJobReports(index, job, true); index.commit(IndexedDIP.class); for (Report report : jobReports) { if (report.getSourceObjectId().equals(aip.getRepresentations().get(0))) { String repUUID = IdUtils.getRepresentationId(rep); IndexResult<IndexedDIP> dips = index.find(IndexedDIP.class, new Filter(new SimpleFilterParameter(RodaConstants.DIP_REPRESENTATION_UUIDS, repUUID)), Sorter.NONE, new Sublist(0, 1), new ArrayList<>()); DIP dip = dips.getResults().get(0); IndexResult<DIPFile> files = index.find(DIPFile.class, new Filter(new SimpleFilterParameter(RodaConstants.DIPFILE_DIP_ID, dip.getId())), Sorter.NONE, new Sublist(0, 1), new ArrayList<>()); DIPFile dipfile = files.getResults().get(0); StoragePath newFileStoragePath = ModelUtils.getDIPFileStoragePath(dipfile); DirectResourceAccess newDirectAccess = model.getStorage().getDirectAccess(newFileStoragePath); AssertJUnit.assertEquals(1, PDFSignatureUtils.countSignaturesPDF(newDirectAccess.getPath())); IOUtils.closeQuietly(newDirectAccess); } } } }