mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged HEAD-BUG-FIX (5.0/Cloud) to HEAD (5.0/Cloud)
76560: Merged V4.2-BUG-FIX (4.2.4) to HEAD-BUG-FIX (5.0/Cloud) 75816: Merged DEV V4.2-BUG-FIX to V4.2-BUG-FIX (4.2.3) 75777: MNT-11598: Escaped Freemarker query templates don't work with org.alfresco.repo.action.scheduled.CronScheduledQueryBasedTemplateActionDefinition - Workaround with unescaping Free Marker template has been applied and tested with the newly implemented test git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@77627 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This file is part of Alfresco
|
* This file is part of Alfresco
|
||||||
*
|
*
|
||||||
@@ -220,6 +220,19 @@ public class CronScheduledQueryBasedTemplateActionDefinition extends AbstractSch
|
|||||||
|
|
||||||
// Build the actual query string
|
// Build the actual query string
|
||||||
String queryTemplate = getQueryTemplate();
|
String queryTemplate = getQueryTemplate();
|
||||||
|
|
||||||
|
// MNT-11598 workaround: de-escape \$\{foo\} or \#\{foo\}
|
||||||
|
if (queryTemplate.contains("\\$\\{") || queryTemplate.contains("\\#\\{"))
|
||||||
|
{
|
||||||
|
queryTemplate = queryTemplate.replace("\\$\\{", "${");
|
||||||
|
queryTemplate = queryTemplate.replace("\\#\\{", "#{");
|
||||||
|
|
||||||
|
if (queryTemplate.contains("\\}"))
|
||||||
|
{
|
||||||
|
queryTemplate = queryTemplate.replace("\\}", "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String query = templateService.processTemplateString(getTemplateActionModelFactory().getTemplateEngine(),
|
String query = templateService.processTemplateString(getTemplateActionModelFactory().getTemplateEngine(),
|
||||||
queryTemplate, getTemplateActionModelFactory().getModel());
|
queryTemplate, getTemplateActionModelFactory().getModel());
|
||||||
|
|
||||||
|
@@ -368,6 +368,7 @@ public class Repository01TestSuite extends TestSuite
|
|||||||
suite.addTestSuite(org.alfresco.repo.transfer.TransferVersionCheckerImplTest.class);
|
suite.addTestSuite(org.alfresco.repo.transfer.TransferVersionCheckerImplTest.class);
|
||||||
suite.addTestSuite(org.alfresco.repo.transfer.manifest.ManifestIntegrationTest.class);
|
suite.addTestSuite(org.alfresco.repo.transfer.manifest.ManifestIntegrationTest.class);
|
||||||
suite.addTestSuite(org.alfresco.repo.transfer.script.ScriptTransferServiceTest.class);
|
suite.addTestSuite(org.alfresco.repo.transfer.script.ScriptTransferServiceTest.class);
|
||||||
|
suite.addTestSuite(org.alfresco.repo.action.scheduled.CronScheduledQueryBasedTemplateActionDefinitionTest.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tests58(TestSuite suite)
|
static void tests58(TestSuite suite)
|
||||||
|
@@ -0,0 +1,288 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.action.scheduled;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.transaction.Status;
|
||||||
|
import javax.transaction.UserTransaction;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.nodelocator.CompanyHomeNodeLocator;
|
||||||
|
import org.alfresco.repo.policy.BehaviourFilter;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
|
import org.alfresco.service.ServiceRegistry;
|
||||||
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
|
import org.alfresco.service.cmr.model.FileInfo;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.quartz.Scheduler;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@link CronScheduledQueryBasedTemplateActionDefinition} class. The test assumes that not all test-cases require scheduling. Hence,
|
||||||
|
* {@link CronScheduledQueryBasedTemplateActionDefinition} instance is not registered as scheduled job. But in the same time this instance is unregistered as scheduled job after
|
||||||
|
* every test-case execution. Also default query template is not set for {@link CronScheduledQueryBasedTemplateActionDefinition} instance
|
||||||
|
*
|
||||||
|
* @author Dmitry Velichkevich
|
||||||
|
* @see CronScheduledQueryBasedTemplateActionDefinitionTest#initializeScheduler(ServiceRegistry)
|
||||||
|
*/
|
||||||
|
public class CronScheduledQueryBasedTemplateActionDefinitionTest extends TestCase
|
||||||
|
{
|
||||||
|
private static final int AMOUNT_OF_DAYS_BEFORE = -1;
|
||||||
|
|
||||||
|
private static final int TEST_DOCUMENTS_AMOUNT = 5;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SimpleTemplateActionDefinition#setActionName(String)}
|
||||||
|
*/
|
||||||
|
private static final String SCRIPT_TEST_ACTION_NAME = "scriptTestActionName-" + System.currentTimeMillis();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link CronScheduledQueryBasedTemplateActionDefinition#setQueryLanguage(String)}
|
||||||
|
*/
|
||||||
|
private static final String SCHEDULER_QUERY_LANGUAGE = "lucene";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link CronScheduledQueryBasedTemplateActionDefinition#setCronExpression(String)}
|
||||||
|
*/
|
||||||
|
private static final String SCHEDULER_CRON_EXPRESSION = "0 50 * * * ?";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link CronScheduledQueryBasedTemplateActionDefinition#setCompensatingActionMode(String)}
|
||||||
|
*/
|
||||||
|
private static final String SCHEDULER_COMPENSATING_ACTION_MODE = "IGNORE";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link CronScheduledQueryBasedTemplateActionDefinition#setTransactionMode(String)}
|
||||||
|
*/
|
||||||
|
private static final String SCHEDULER_TRANSACTION_MODE = "UNTIL_FIRST_FAILURE";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link CronScheduledQueryBasedTemplateActionDefinition#setJobName(String)}
|
||||||
|
*/
|
||||||
|
private static final String SCHEDULER_JOB_NAME = "jobTestName-" + System.currentTimeMillis();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link CronScheduledQueryBasedTemplateActionDefinition#setJobGroup(String)}
|
||||||
|
*/
|
||||||
|
private static final String SCHEDULER_JOB_GROUP = "jobTestGroup-" + System.currentTimeMillis();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link CronScheduledQueryBasedTemplateActionDefinition#setTriggerName(String)}
|
||||||
|
*/
|
||||||
|
private static final String SCHEDULER_TRIGGER_NAME = "triggerTestName-" + System.currentTimeMillis();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link CronScheduledQueryBasedTemplateActionDefinition#setTriggerGroup(String)}
|
||||||
|
*/
|
||||||
|
private static final String SCHEDULER_TRIGGER_GROUP = "triggerTestGroup-" + System.currentTimeMillis();
|
||||||
|
|
||||||
|
|
||||||
|
private static final String SCHEDULER_FACTORY_BEAN_NAME = "schedulerFactory";
|
||||||
|
|
||||||
|
private static final String POLICY_BEHAVIOUR_FILTER_BEAN_NAME = "policyBehaviourFilter";
|
||||||
|
|
||||||
|
private static final String ROOT_TEST_FOLDER_NAME_TEMPLATE = "RootTestFolder-%d";
|
||||||
|
|
||||||
|
private static final String TEST_DOCUMENT_NAME_TEMPLATE = "TestDocument-%d-%d.txt";
|
||||||
|
|
||||||
|
private static final String FRESH_TEST_DOCUMENT_NAME_TEMPLATE = "Fresh" + TEST_DOCUMENT_NAME_TEMPLATE;
|
||||||
|
|
||||||
|
private static final String YESTERDAY_TEST_DOCUMENT_NAME_TEMPLATE = "Yesterday" + TEST_DOCUMENT_NAME_TEMPLATE;
|
||||||
|
|
||||||
|
|
||||||
|
private static final String MNT_11598_QUERY_TEMPLATE = "@cm\\:created:\\$\\{luceneDateRange(yesterday, \"-P10Y\")\\}";
|
||||||
|
|
||||||
|
|
||||||
|
private ApplicationContext applicationContext = ApplicationContextHelper.getApplicationContext();
|
||||||
|
|
||||||
|
|
||||||
|
private UserTransaction transaction;
|
||||||
|
|
||||||
|
|
||||||
|
private NodeRef rootTestFolder;
|
||||||
|
|
||||||
|
private List<NodeRef> freshNodes = new LinkedList<NodeRef>();
|
||||||
|
|
||||||
|
private List<NodeRef> yesterdayNodes = new LinkedList<NodeRef>();
|
||||||
|
|
||||||
|
|
||||||
|
private CronScheduledQueryBasedTemplateActionDefinition scheduler;
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception
|
||||||
|
{
|
||||||
|
ServiceRegistry registry = (ServiceRegistry) applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||||
|
|
||||||
|
initializeScheduler(registry);
|
||||||
|
|
||||||
|
AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
|
||||||
|
|
||||||
|
transaction = registry.getTransactionService().getUserTransaction(false);
|
||||||
|
transaction.begin();
|
||||||
|
|
||||||
|
createTestContent(registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes target {@link CronScheduledQueryBasedTemplateActionDefinition} instance for testing. <b>Default query template is not set!</b> It must be set in test method. No
|
||||||
|
* need to register for every test for scheduling. Hence, {@link CronScheduledQueryBasedTemplateActionDefinition#afterPropertiesSet()} is omitted here and must be invoked for
|
||||||
|
* test which requires scheduling
|
||||||
|
*
|
||||||
|
* @param registry - {@link ServiceRegistry} instance
|
||||||
|
*/
|
||||||
|
private void initializeScheduler(ServiceRegistry registry)
|
||||||
|
{
|
||||||
|
Scheduler factory = (Scheduler) applicationContext.getBean(SCHEDULER_FACTORY_BEAN_NAME);
|
||||||
|
|
||||||
|
FreeMarkerWithLuceneExtensionsModelFactory templateActionModelFactory = new FreeMarkerWithLuceneExtensionsModelFactory();
|
||||||
|
templateActionModelFactory.setServiceRegistry(registry);
|
||||||
|
|
||||||
|
SimpleTemplateActionDefinition templateActionDefinition = new SimpleTemplateActionDefinition();
|
||||||
|
templateActionDefinition.setApplicationContext(applicationContext);
|
||||||
|
templateActionDefinition.setActionService(registry.getActionService());
|
||||||
|
templateActionDefinition.setTemplateService(registry.getTemplateService());
|
||||||
|
templateActionDefinition.setDictionaryService(registry.getDictionaryService());
|
||||||
|
templateActionDefinition.setTemplateActionModelFactory(templateActionModelFactory);
|
||||||
|
|
||||||
|
templateActionDefinition.setActionName(SCRIPT_TEST_ACTION_NAME);
|
||||||
|
|
||||||
|
scheduler = new CronScheduledQueryBasedTemplateActionDefinition();
|
||||||
|
scheduler.setScheduler(factory);
|
||||||
|
scheduler.setTransactionService(registry.getTransactionService());
|
||||||
|
scheduler.setActionService(registry.getActionService());
|
||||||
|
scheduler.setSearchService(registry.getSearchService());
|
||||||
|
scheduler.setTemplateService(registry.getTemplateService());
|
||||||
|
scheduler.setRunAsUser(AuthenticationUtil.getSystemUserName());
|
||||||
|
scheduler.setTemplateActionDefinition(templateActionDefinition);
|
||||||
|
scheduler.setTemplateActionModelFactory(templateActionModelFactory);
|
||||||
|
scheduler.setStores(Collections.singletonList(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.toString()));
|
||||||
|
|
||||||
|
scheduler.setQueryLanguage(SCHEDULER_QUERY_LANGUAGE);
|
||||||
|
scheduler.setCronExpression(SCHEDULER_CRON_EXPRESSION);
|
||||||
|
scheduler.setCompensatingActionMode(SCHEDULER_COMPENSATING_ACTION_MODE);
|
||||||
|
scheduler.setTransactionMode(SCHEDULER_TRANSACTION_MODE);
|
||||||
|
scheduler.setJobName(SCHEDULER_JOB_NAME);
|
||||||
|
scheduler.setJobGroup(SCHEDULER_JOB_GROUP);
|
||||||
|
scheduler.setTriggerName(SCHEDULER_TRIGGER_NAME);
|
||||||
|
scheduler.setTriggerGroup(SCHEDULER_TRIGGER_GROUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates <code>rootTestFolder</code> test folder as start of test content hierarchy. Then it creates
|
||||||
|
* {@link CronScheduledQueryBasedTemplateActionDefinitionTest#TEST_DOCUMENTS_AMOUNT} documents in the root folder with "today" creation date and the same amount of documents
|
||||||
|
* with "yesterday" creation date
|
||||||
|
*
|
||||||
|
* @param registry - {@link ServiceRegistry} instance
|
||||||
|
*/
|
||||||
|
private void createTestContent(ServiceRegistry registry)
|
||||||
|
{
|
||||||
|
FileFolderService fileFolderService = registry.getFileFolderService();
|
||||||
|
|
||||||
|
NodeRef companyHomeNodeRef = registry.getNodeLocatorService().getNode(CompanyHomeNodeLocator.NAME, null, null);
|
||||||
|
String objectName = String.format(ROOT_TEST_FOLDER_NAME_TEMPLATE, System.currentTimeMillis());
|
||||||
|
rootTestFolder = fileFolderService.create(companyHomeNodeRef, objectName, ContentModel.TYPE_FOLDER).getNodeRef();
|
||||||
|
|
||||||
|
for (int i = 0; i < TEST_DOCUMENTS_AMOUNT; i++)
|
||||||
|
{
|
||||||
|
objectName = String.format(FRESH_TEST_DOCUMENT_NAME_TEMPLATE, i, System.currentTimeMillis());
|
||||||
|
FileInfo fileInfo = fileFolderService.create(rootTestFolder, objectName, ContentModel.TYPE_CONTENT);
|
||||||
|
freshNodes.add(fileInfo.getNodeRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
Calendar calendar = GregorianCalendar.getInstance();
|
||||||
|
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||||
|
calendar.add(Calendar.DAY_OF_YEAR, AMOUNT_OF_DAYS_BEFORE);
|
||||||
|
Date yesterdayTime = calendar.getTime();
|
||||||
|
|
||||||
|
NodeService nodeService = registry.getNodeService();
|
||||||
|
BehaviourFilter policyBehaviourFilter = (BehaviourFilter) applicationContext.getBean(POLICY_BEHAVIOUR_FILTER_BEAN_NAME);
|
||||||
|
policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_AUDITABLE);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (int i = 0; i < TEST_DOCUMENTS_AMOUNT; i++)
|
||||||
|
{
|
||||||
|
objectName = String.format(YESTERDAY_TEST_DOCUMENT_NAME_TEMPLATE, i, System.currentTimeMillis());
|
||||||
|
FileInfo fileInfo = fileFolderService.create(rootTestFolder, objectName, ContentModel.TYPE_CONTENT);
|
||||||
|
nodeService.setProperty(fileInfo.getNodeRef(), ContentModel.PROP_CREATED, yesterdayTime);
|
||||||
|
yesterdayNodes.add(fileInfo.getNodeRef());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_ANULLABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
@Override
|
||||||
|
public void tearDown() throws Exception
|
||||||
|
{
|
||||||
|
scheduler.getScheduler().unscheduleJob(scheduler.getTriggerName(), scheduler.getJobGroup());
|
||||||
|
|
||||||
|
if (Status.STATUS_ROLLEDBACK != transaction.getStatus())
|
||||||
|
{
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
freshNodes.clear();
|
||||||
|
yesterdayNodes.clear();
|
||||||
|
|
||||||
|
AuthenticationUtil.clearCurrentSecurityContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQueryTemplateFunctionsUnescapingMnt11598() throws Exception
|
||||||
|
{
|
||||||
|
scheduler.setQueryTemplate(MNT_11598_QUERY_TEMPLATE);
|
||||||
|
|
||||||
|
Set<NodeRef> actualNodes = new HashSet<NodeRef>(scheduler.getNodes());
|
||||||
|
assertNotNull("Result set must not be null!", actualNodes);
|
||||||
|
assertFalse("Result set must not be empty!", actualNodes.isEmpty());
|
||||||
|
assertTrue(("Result set must contain at least " + TEST_DOCUMENTS_AMOUNT + " nodes!"), actualNodes.size() >= yesterdayNodes.size());
|
||||||
|
|
||||||
|
for (NodeRef nodeRef : freshNodes)
|
||||||
|
{
|
||||||
|
assertFalse("No one of the nodes created \"today\" is expected in result set!", actualNodes.contains(nodeRef));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NodeRef nodeRef : yesterdayNodes)
|
||||||
|
{
|
||||||
|
assertTrue("One of the nodes created \"yesteday\" is missing in result set!", actualNodes.contains(nodeRef));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user