Merged HEAD-BUG-FIX (5.0/Cloud) to HEAD (4.3/Cloud)

71594: Merged V4.2-BUG-FIX (4.2.3) to HEAD-BUG-FIX (4.3/Cloud)
      70332: Merged V4.1-BUG-FIX (4.1.9) to V4.2-BUG-FIX (4.2.3)
         70292: Merged DEV to V4.1-BUG-FIX (4.1.9)
            60077: Created branch for MNT-10067 work.
            60101: MNT-10067: first commit of a generic SQL script runner.
            Very rough and ready extraction of SchemaBootstrap SQL script execution functionality. Will serve as the basis for the implementation of MNT-10067.
            60147: MNT-10067: added tests for "dialect" placeholder resolution, including overriding of dialects.
            60180: MNT-10067: exception thrown when unable to find SQL script to execute
            60187: MNT-10067: renamed ScriptExecutor to ScriptExecutorImpl to make way for an interface definition.
            60188: MNT-10067: introduced a ScriptExecutor interface.
            60189: MNT-10067: renamed ScriptExecutorTest
            60190: MNT-10067: added ScriptExecutorImplIntegrationTest to repo test suite.
            60194: MNT-10067: a very simple initial implementation of a SQL script runner capable of running multiple scripts in a given
            directory.
            60195: MNT-10067: added integration test for ScriptBundleExecutorImpl.
            60196: MNT-10067: moved ScriptBundleExecutorImplTest to correct source tree.
            60197: MNT-10067: added ScriptBundleExecutorImplIntegrationTest to repo test suite.
            60263: MNT-10067: ScriptBundleExecutor(Impl) now stops executing the main batch of scripts upon failure and runs a post-script.
            60459: MNT-10067: minor change to test data to avoid implying that ScriptBundleExecutor.exec(String, String...) has an always-run
            final script.
            60482: MNT-10067: added integration test for ScriptBundleExecutor.execWithPostScript()
            60483: MNT-10067: committed missing files from r60482
            60488: MNT-10067: set appropriate log levels for log4j
            60620: MNT-10067: added alf_props_xxx clean-up script.
            60623: MNT-10067: minor tidy up of ScriptExecutorImpl (tidy imports, group fields at top of class)
            60625: MNT-10067: further tidy up ScriptExecutorImpl (removed redundant constants, made externally unused public constant private)
            60629: MNT-10067: fix tests broken by introduction of scriptExecutor bean in production code.
            60662: MNT-10067: added tests to check deletion of doubles, serializables and dates.
            61378: MNT-10067 : Cleanup alf_prop_XXX data
            Added MySQL, Oracle DB, MS SQL Server and IBM DB2 scripts.
            63371: MNT-10067: removed the vacuum and analyze statements from the postgresql script.
            63372: MNT-10067: replaced begin and commit statements (PostgreSQL script only) with --BEGIN TXN and --END TXN, handled by the
            script executor.
            63568: MNT-10067 : Cleanup alf_prop_XXX data
            Added start and end transaction marks to the scripts.
            64115: MNT-10067: added Quartz job that by default doesn't fire until 2099 and can be manually invoked over JMX.
            64223: MNT-10067: improved testing for AuditDAOTest and added PropertyValueDAOTest
            64685: MNT-10067: added AttributeServiceTest
            65796: MNT-10067 : Cleanup alf_prop_XXX data
            Implemented a performance test.
            65983: MNT-10067 : Cleanup alf_prop_XXX data
            Reworked the MySQL script.
            Added time measurements for entry creation.
            66116: MNT-10067 : Cleanup alf_prop_XXX data
            For MySQL:
            1) Renamed temp tables.
            2) Split the script into execution and cleanup of temp tables parts.
            67023: MNT-10067 : Cleanup alf_prop_XXX data
            Modified MySQL script to skip null values from alf_prop_unique_ctx.prop1_id.
            67199: MNT-10067 : Cleanup alf_prop_XXX data
            Implemented the latest changes of the script for other DB flavors.
            Removed the MS SQL Server transaction marks.
            67763: MNT-10067 : Cleanup alf_prop_XXX data
            Removed unnecessary temporary index dropping.
            Added additional cleanup before main script execution.
            68710: MNT-10067 : Cleanup alf_prop_XXX data
            Added batch logging.
            Moved clearCaches() statement in PropertyValueDAOImpl.cleanupUnusedValues() to finally block.
            68711: MNT-10067 : Cleanup alf_prop_XXX data
            Added batching for MySQL script.
            69602: MNT-10067 : Cleanup alf_prop_XXX data
            Updated scripts for all DB flavors with batching.
            69768: MNT-10067 : Cleanup alf_prop_XXX data
            Fixed failing ScriptBundleExecutorImplIntegrationTest and ScriptExecutorImplIntegrationTest.
            70058: Sync with latest changes in V4.1-BUG-FIX.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@74691 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Will Abson
2014-06-25 15:26:31 +00:00
parent b703c1de1f
commit 04cead57a6
39 changed files with 2139 additions and 2 deletions

View File

@@ -20,13 +20,18 @@ package org.alfresco.repo.attributes;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import junit.framework.TestCase;
import org.alfresco.repo.domain.propval.PropValGenerator;
import org.alfresco.repo.domain.propval.PropertyValueDAO;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.attributes.AttributeService;
import org.alfresco.service.cmr.attributes.AttributeService.AttributeQueryCallback;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.Pair;
import org.apache.commons.lang.mutable.MutableInt;
import org.springframework.context.ApplicationContext;
@@ -47,12 +52,14 @@ public class AttributeServiceTest extends TestCase
private ApplicationContext ctx;
private AttributeService attributeService;
private PropertyValueDAO propertyValueDAO;
@Override
protected void setUp() throws Exception
{
ctx = ApplicationContextHelper.getApplicationContext();
attributeService = (AttributeService) ctx.getBean("AttributeService");
propertyValueDAO = (PropertyValueDAO) ctx.getBean("propertyValueDAO");
}
@Override
@@ -132,4 +139,57 @@ public class AttributeServiceTest extends TestCase
assertEquals(2, results.size());
assertEquals(2, counter.getValue());
}
public void testRemoveOrphanedProps()
{
final Serializable[] stringKey = new String[] { "z", "q", "string" };
final Serializable[] doubleKey = new String[] { "z", "q", "double" };
final Serializable[] dateKey = new String[] { "z", "q", "date" };
// Make sure there's nothing left from previous failed test runs etc.
attributeService.removeAttributes(stringKey);
attributeService.removeAttributes(doubleKey);
attributeService.removeAttributes(dateKey);
final PropValGenerator valueGen = new PropValGenerator(propertyValueDAO);
// Create some values
final String stringValue = valueGen.createUniqueString();
attributeService.createAttribute(stringValue, stringKey);
final Double doubleValue = valueGen.createUniqueDouble();
attributeService.createAttribute(doubleValue, doubleKey);
final Date dateValue = valueGen.createUniqueDate();
attributeService.createAttribute(dateValue, dateKey);
// Remove the properties, potentially leaving oprhaned prop values.
attributeService.removeAttributes(stringKey);
attributeService.removeAttributes(doubleKey);
attributeService.removeAttributes(dateKey);
// Check there are some persisted values to delete, otherwise there is no
// need to run the cleanup script in the first place.
assertEquals(stringValue, propertyValueDAO.getPropertyValue(stringValue).getSecond());
assertEquals(doubleValue, propertyValueDAO.getPropertyValue(doubleValue).getSecond());
assertEquals(dateValue, propertyValueDAO.getPropertyValue(dateValue).getSecond());
// Run the cleanup script - should remove the orphaned values.
propertyValueDAO.cleanupUnusedValues();
// Check that the cleanup script removed the orphaned values.
assertPropDeleted(propertyValueDAO.getPropertyValue(stringValue));
assertPropDeleted(propertyValueDAO.getPropertyValue(doubleValue));
assertPropDeleted(propertyValueDAO.getPropertyValue(dateValue));
}
private void assertPropDeleted(Pair<Long, ?> value)
{
if (value != null)
{
String msg = String.format("Property value [%s=%s] should have been deleted by cleanup script.",
value.getSecond().getClass().getSimpleName(), value.getSecond());
fail(msg);
}
}
}

View File

@@ -0,0 +1,79 @@
/*
* 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.attributes;
import static org.junit.Assert.*;
import java.util.Date;
import org.alfresco.repo.domain.propval.PropertyValueDAO;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.CronTriggerBean;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.quartz.JobDetail;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationContext;
import com.ibm.icu.util.Calendar;
/**
* Integration tests for the {@link PropTablesCleanupJob} class.
*
* @author Matt Ward
*/
public class PropTablesCleanupJobIntegrationTest
{
private static ApplicationContext ctx;
private CronTriggerBean jobTrigger;
@BeforeClass
public static void setUpClass()
{
ctx = ApplicationContextHelper.getApplicationContext();
}
@Before
public void setUp() throws Exception
{
jobTrigger = ctx.getBean("propTablesCleanupTrigger", CronTriggerBean.class);
}
@Test
public void checkJobWillNeverRunByDefault() throws Exception
{
Date fireTime = jobTrigger.getTrigger().getFireTimeAfter(new Date());
Calendar calendar = Calendar.getInstance();
// Far into the future, we count this as never.
calendar.setTime(fireTime);
assertEquals(2099, calendar.get(Calendar.YEAR));
}
@Test
public void checkJobDetails()
{
JobDetail jobDetail = jobTrigger.getJobDetail();
assertEquals(PropTablesCleanupJob.class, jobDetail.getJobClass());
assertTrue("JobDetail did not contain PropertyValueDAO reference",
jobDetail.getJobDataMap().get("propertyValueDAO") instanceof PropertyValueDAO);
}
}

View File

@@ -0,0 +1,63 @@
package org.alfresco.repo.attributes;
import static org.junit.Assert.*;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.alfresco.repo.domain.propval.PropertyValueDAO;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* Tests for the {@link PropTablesCleanupJob} class.
*
* @author Matt Ward
*/
@RunWith(MockitoJUnitRunner.class)
public class PropTablesCleanupJobTest
{
private PropTablesCleanupJob cleanupJob;
private @Mock JobExecutionContext jobCtx;
private @Mock PropertyValueDAO propValueDAO;
private JobDetail jobDetail;
@Before
public void setUp() throws Exception
{
jobDetail = new JobDetail("propTablesCleanupJob", PropTablesCleanupJob.class);
jobDetail.getJobDataMap().put(PropTablesCleanupJob.PROPERTY_VALUE_DAO_KEY, propValueDAO);
cleanupJob = new PropTablesCleanupJob();
when(jobCtx.getJobDetail()).thenReturn(jobDetail);
}
@Test
public void testExecute() throws JobExecutionException
{
cleanupJob.execute(jobCtx);
verify(propValueDAO).cleanupUnusedValues();
}
@Test(expected=IllegalArgumentException.class)
public void testMissingPropertyValueDAO() throws JobExecutionException
{
jobDetail.getJobDataMap().put(PropTablesCleanupJob.PROPERTY_VALUE_DAO_KEY, null);
cleanupJob.execute(jobCtx);
}
@Test(expected=ClassCastException.class)
public void testWrongTypeForPropertyValueDAO() throws JobExecutionException
{
jobDetail.getJobDataMap().put(PropTablesCleanupJob.PROPERTY_VALUE_DAO_KEY, "This is not a PropertyValueDAO");
cleanupJob.execute(jobCtx);
}
}