mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-17 06:53:09 +00:00
[DS-2058] Move workflow curation testing to dspace-api since it has no essential connection with REST.
This patch duplicates the Spring/JUnit initializer classes from dspace-server-webapp. We should share a single set. Possibly they should live in dspace-services where the fundamental Spring support is found.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
#---------------------------------------------------------------#
|
||||
#--------------CURATION SYSTEM CONFIGURATIONS-------------------#
|
||||
#---------------------------------------------------------------#
|
||||
# Configuration properties used solely by the Curation system #
|
||||
#---------------------------------------------------------------#
|
||||
|
||||
### Task Class implementations
|
||||
|
||||
# NOTE: Other configurations can append to this list of default tasks by simply
|
||||
# adding their own additional values of "plugin.named.org.dspace.curate.CurationTask"
|
||||
plugin.named.org.dspace.curate.CurationTask = org.dspace.ctask.general.NoOpCurationTask = noop
|
||||
plugin.named.org.dspace.curate.CurationTask = org.dspace.ctask.general.ProfileFormats = profileformats
|
||||
plugin.named.org.dspace.curate.CurationTask = org.dspace.ctask.general.RequiredMetadata = requiredmetadata
|
||||
#plugin.named.org.dspace.curate.CurationTask = org.dspace.ctask.general.ClamScan = vscan
|
||||
#plugin.named.org.dspace.curate.CurationTask = org.dspace.ctask.general.MicrosoftTranslator = translate
|
||||
plugin.named.org.dspace.curate.CurationTask = org.dspace.ctask.general.MetadataValueLinkChecker = checklinks
|
||||
# add new tasks here (or in additional config files)
|
||||
|
||||
# Testing tasks
|
||||
plugin.named.org.dspace.curate.CurationTask = org.dspace.ctask.testing.MarkerTask = marker
|
||||
|
||||
## task queue implementation
|
||||
plugin.single.org.dspace.curate.TaskQueue = org.dspace.curate.FileTaskQueue
|
||||
|
||||
# directory location of curation task queues
|
||||
curate.taskqueue.dir = ${dspace.dir}/ctqueues
|
||||
|
||||
# (optional) directory location of scripted (non-java) tasks
|
||||
# curate.script.dir = ${dspace.dir}/ctscripts
|
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.util;
|
||||
|
||||
import org.apache.commons.configuration2.Configuration;
|
||||
import org.apache.commons.configuration2.spring.ConfigurationPropertySource;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
/**
|
||||
* Utility class that will initialize the DSpace Configuration on Spring startup.
|
||||
* Adapted from the class of the same name in {@code dspace-server-webapp}.
|
||||
* <P>
|
||||
* NOTE: MUST be loaded after DSpaceKernelInitializer, as it requires the kernel
|
||||
* is already initialized.
|
||||
* <P>
|
||||
* This initializer ensures that our DSpace Configuration is loaded into Spring's
|
||||
* list of {@code PropertySource}s very early in the Spring startup process.
|
||||
* That is important as it allows us to use DSpace configurations within
|
||||
* {@code @ConditionalOnProperty} annotations on beans, as well as {@code @Value}
|
||||
* annotations and XML bean definitions.
|
||||
*/
|
||||
public class DSpaceConfigurationInitializer
|
||||
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
|
||||
|
||||
private static final Logger log = LogManager.getLogger();
|
||||
|
||||
@Override
|
||||
public void initialize(final ConfigurableApplicationContext applicationContext) {
|
||||
// Load DSpace Configuration service (requires kernel already initialized)
|
||||
ConfigurationService configurationService
|
||||
= DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||
Configuration configuration = configurationService.getConfiguration();
|
||||
|
||||
// Create an Apache Commons Configuration Property Source from our configuration
|
||||
ConfigurationPropertySource apacheCommonsConfigPropertySource =
|
||||
new ConfigurationPropertySource(configuration.getClass().getName(), configuration);
|
||||
|
||||
// Prepend it to the Environment's list of PropertySources
|
||||
// NOTE: This is added *first* in the list so that settings in DSpace's
|
||||
// ConfigurationService *override* any default values in Spring's
|
||||
// application.properties (or similar).
|
||||
applicationContext.getEnvironment()
|
||||
.getPropertySources()
|
||||
.addFirst(apacheCommonsConfigPropertySource);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.util;
|
||||
|
||||
import java.io.File;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.kernel.DSpaceKernel;
|
||||
import org.dspace.kernel.DSpaceKernelManager;
|
||||
import org.dspace.servicemanager.DSpaceKernelImpl;
|
||||
import org.dspace.servicemanager.DSpaceKernelInit;
|
||||
import org.dspace.servicemanager.config.DSpaceConfigurationService;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.event.ContextClosedEvent;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
||||
/**
|
||||
* Utility class that will initialize the DSpace Kernel on Spring startup.
|
||||
* Adapted from the class of the same name in {@code dspace-server-webapp}.
|
||||
*/
|
||||
public class DSpaceKernelInitializer
|
||||
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
|
||||
|
||||
private static final Logger log = LogManager.getLogger();
|
||||
|
||||
private transient DSpaceKernel dspaceKernel;
|
||||
|
||||
@Override
|
||||
public void initialize(final ConfigurableApplicationContext applicationContext) {
|
||||
// Check if the kernel is already started
|
||||
this.dspaceKernel = DSpaceKernelManager.getDefaultKernel();
|
||||
if (this.dspaceKernel == null) {
|
||||
DSpaceKernelImpl kernelImpl = null;
|
||||
try {
|
||||
// Load the kernel with default settings
|
||||
kernelImpl = DSpaceKernelInit.getKernel(null);
|
||||
if (!kernelImpl.isRunning()) {
|
||||
// Determine configured DSpace home & init the Kernel
|
||||
kernelImpl.start(getDSpaceHome(applicationContext.getEnvironment()));
|
||||
}
|
||||
this.dspaceKernel = kernelImpl;
|
||||
|
||||
} catch (Exception e) {
|
||||
// failed to start so destroy it and log and throw an exception
|
||||
try {
|
||||
if (kernelImpl != null) {
|
||||
kernelImpl.destroy();
|
||||
}
|
||||
this.dspaceKernel = null;
|
||||
} catch (Exception e1) {
|
||||
// nothing
|
||||
}
|
||||
String message = "Failure during ServletContext initialisation: " + e.getMessage();
|
||||
log.error("Failure during ServletContext initialisation: ", e);
|
||||
throw new RuntimeException(message, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (applicationContext.getParent() == null) {
|
||||
// Set the DSpace Kernel Application context as a parent of the
|
||||
// Spring context so that we can auto-wire all DSpace Kernel services.
|
||||
applicationContext.setParent(dspaceKernel.getServiceManager().getApplicationContext());
|
||||
|
||||
// Add a listener for Spring application shutdown so that we can
|
||||
// nicely cleanup the DSpace kernel.
|
||||
applicationContext.addApplicationListener(new DSpaceKernelDestroyer(dspaceKernel));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find DSpace's "home" directory (from current environment)
|
||||
* Initially look for JNDI Resource called "java:/comp/env/dspace.dir".
|
||||
* If not found, use value provided in "dspace.dir" in Spring Environment
|
||||
*/
|
||||
private String getDSpaceHome(ConfigurableEnvironment environment) {
|
||||
// Load the "dspace.dir" property from Spring's configuration.
|
||||
// This gives us the location of our DSpace configuration, which is
|
||||
// necessary to start the kernel.
|
||||
String providedHome = environment.getProperty(DSpaceConfigurationService.DSPACE_HOME);
|
||||
|
||||
String dspaceHome = null;
|
||||
try {
|
||||
// Allow ability to override home directory via JNDI
|
||||
Context ctx = new InitialContext();
|
||||
dspaceHome = (String) ctx.lookup("java:/comp/env/" + DSpaceConfigurationService.DSPACE_HOME);
|
||||
} catch (Exception e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
// Otherwise, verify the 'providedHome' value is non-empty, exists and includes DSpace configs
|
||||
if (dspaceHome == null) {
|
||||
if (StringUtils.isNotBlank(providedHome) &&
|
||||
!providedHome.equals("${" + DSpaceConfigurationService.DSPACE_HOME + "}")) {
|
||||
File test = new File(providedHome);
|
||||
if (test.exists() && new File(test, DSpaceConfigurationService.DSPACE_CONFIG_PATH).exists()) {
|
||||
dspaceHome = providedHome;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dspaceHome;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Utility class that will destroy the DSpace Kernel on Spring shutdown.
|
||||
*/
|
||||
private class DSpaceKernelDestroyer
|
||||
implements ApplicationListener<ContextClosedEvent> {
|
||||
private DSpaceKernel kernel;
|
||||
|
||||
public DSpaceKernelDestroyer(DSpaceKernel kernel) {
|
||||
this.kernel = kernel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(final ContextClosedEvent event) {
|
||||
if (this.kernel != null) {
|
||||
this.kernel.destroy();
|
||||
this.kernel = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.workflow;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.dspace.AbstractIntegrationTestWithDatabase;
|
||||
import org.dspace.builder.CollectionBuilder;
|
||||
import org.dspace.builder.CommunityBuilder;
|
||||
import org.dspace.builder.EPersonBuilder;
|
||||
import org.dspace.builder.WorkflowItemBuilder;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.MetadataValue;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.ctask.testing.MarkerTask;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.util.DSpaceConfigurationInitializer;
|
||||
import org.dspace.util.DSpaceKernelInitializer;
|
||||
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Test the attachment of curation tasks to workflows.
|
||||
*
|
||||
* @author mwood
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(
|
||||
initializers = { DSpaceKernelInitializer.class, DSpaceConfigurationInitializer.class },
|
||||
locations = { "classpath:spring/*.xml" }
|
||||
)
|
||||
public class WorkflowCurationIT
|
||||
extends AbstractIntegrationTestWithDatabase {
|
||||
@Inject
|
||||
private ConfigurationService configurationService;
|
||||
|
||||
@Inject
|
||||
private ItemService itemService;
|
||||
|
||||
/**
|
||||
* Basic smoke test of a curation task attached to a workflow step.
|
||||
* See {@link MarkerTask}.
|
||||
* @throws java.lang.Exception passed through.
|
||||
*/
|
||||
@Test
|
||||
public void curationTest()
|
||||
throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
//** GIVEN **
|
||||
|
||||
// A submitter;
|
||||
EPerson submitter = EPersonBuilder.createEPerson(context)
|
||||
.withEmail("submitter@example.com")
|
||||
.withPassword(password)
|
||||
.withLanguage("en")
|
||||
.build();
|
||||
|
||||
// A containment hierarchy;
|
||||
Community community = CommunityBuilder.createCommunity(context)
|
||||
.withName("Community")
|
||||
.build();
|
||||
final String CURATION_COLLECTION_HANDLE = "123456789/curation-test-1";
|
||||
Collection collection = CollectionBuilder
|
||||
.createCollection(context, community, CURATION_COLLECTION_HANDLE)
|
||||
.withName("Collection")
|
||||
.build();
|
||||
|
||||
// A workflow configuration for the test Collection;
|
||||
// See test/dspaceFolder/config/spring/api/workflow.xml
|
||||
|
||||
// A curation task attached to the workflow;
|
||||
// See test/dspaceFolder/config/workflow-curation.xml for the attachment.
|
||||
// This should include MarkerTask.
|
||||
|
||||
// A workflow item;
|
||||
context.setCurrentUser(submitter);
|
||||
XmlWorkflowItem wfi = WorkflowItemBuilder.createWorkflowItem(context, collection)
|
||||
.withTitle("Test of workflow curation")
|
||||
.withIssueDate("2021-05-14")
|
||||
.withSubject("Testing")
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
//** THEN **
|
||||
|
||||
// Search the Item's provenance for MarkerTask's name.
|
||||
List<MetadataValue> provenance = itemService.getMetadata(wfi.getItem(),
|
||||
MarkerTask.SCHEMA, MarkerTask.ELEMENT, MarkerTask.QUALIFIER, MarkerTask.LANGUAGE);
|
||||
Pattern markerPattern = Pattern.compile(MarkerTask.class.getCanonicalName());
|
||||
boolean found = false;
|
||||
for (MetadataValue record : provenance) {
|
||||
if (markerPattern.matcher(record.getValue()).find()) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertThat("Item should have been curated", found);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user