From 70d66c0f8c46b12d42ed9af5e2812a9e0aff6ca1 Mon Sep 17 00:00:00 2001 From: Jan Vonka Date: Wed, 6 May 2009 11:40:13 +0000 Subject: [PATCH] Merged V3.1 to HEAD 13902: Merged V2.2 to V3.1 13900: Fixed ETHREEOH-1846: NullPointerException in ADMLuceneIndexerImpl if localized string is null 14167: MT - fix ETHREEOH-2015 14198: MT - fix ETHREEOH-210 and add unit tests (will also fix ALFCOM-2823 when merged forward to HEAD) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14204 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/scheduled-jobs-context.xml | 3 + .../impl/lucene/ADMLuceneIndexerImpl.java | 44 ++- .../alfresco/repo/tenant/MultiTDemoTest.java | 321 ++++++++++++------ .../usage/UserUsageTrackingComponent.java | 68 ++-- 4 files changed, 300 insertions(+), 136 deletions(-) diff --git a/config/alfresco/scheduled-jobs-context.xml b/config/alfresco/scheduled-jobs-context.xml index 8090725384..24acf2a340 100644 --- a/config/alfresco/scheduled-jobs-context.xml +++ b/config/alfresco/scheduled-jobs-context.xml @@ -300,6 +300,9 @@ + + + 50 diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java index 7a813cb9a1..96bd58a8d4 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java @@ -597,6 +597,9 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp for (QName propertyName : properties.keySet()) { Serializable value = properties.get(propertyName); + + value = convertForMT(propertyName, value); + if (indexAllProperties) { indexProperty(nodeRef, propertyName, value, xdoc, false); @@ -616,7 +619,7 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp Pair pair = it.next(); // Lucene flags in order are: Stored, indexed, tokenised - qNameRef = getLastRefOrNull(pair.getFirst()); + qNameRef = tenantService.getName(getLastRefOrNull(pair.getFirst())); String pathString = pair.getFirst().toString(); if ((pathString.length() > 0) && (pathString.charAt(0) == '/')) @@ -648,7 +651,7 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp qNameBuffer.append(";/"); } qNameBuffer.append(ISO9075.getXPathName(qNameRef.getQName())); - xdoc.add(new Field("PARENT", tenantService.getName(qNameRef.getParentRef()).toString(), Field.Store.YES, Field.Index.NO_NORMS, Field.TermVector.NO)); + xdoc.add(new Field("PARENT", qNameRef.getParentRef().toString(), Field.Store.YES, Field.Index.NO_NORMS, Field.TermVector.NO)); xdoc.add(new Field("ASSOCTYPEQNAME", ISO9075.getXPathName(qNameRef.getTypeQName()), Field.Store.YES, Field.Index.NO, Field.TermVector.NO)); xdoc.add(new Field("LINKASPECT", (pair.getSecond() == null) ? "" : ISO9075.getXPathName(pair.getSecond()), Field.Store.YES, Field.Index.NO_NORMS, Field.TermVector.NO)); @@ -745,7 +748,37 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp return docs; } - + + private Serializable convertForMT(QName propertyName, Serializable inboundValue) + { + if (! tenantService.isEnabled()) + { + // no conversion + return inboundValue; + } + + PropertyDefinition propertyDef = getDictionaryService().getProperty(propertyName); + if ((propertyDef != null) && ((propertyDef.getDataType().getName().equals(DataTypeDefinition.NODE_REF)) || (propertyDef.getDataType().getName().equals(DataTypeDefinition.CATEGORY)))) + { + if (inboundValue instanceof Collection) + { + Collection in = (Collection)inboundValue; + ArrayList out = new ArrayList(in.size()); + for (NodeRef o : in) + { + out.add(tenantService.getName(o)); + } + return out; + } + else + { + return tenantService.getName((NodeRef)inboundValue); + } + } + + return inboundValue; + } + /** * @param indexAtomicPropertiesOnly * true to ignore all properties that must be indexed non-atomically @@ -979,6 +1012,11 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp for (Locale locale : mlText.getLocales()) { String localeString = mlText.getValue(locale); + if (localeString == null) + { + // No text for that locale + continue; + } StringBuilder builder; MLAnalysisMode analysisMode; VerbatimAnalyser vba; diff --git a/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java b/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java index 6801dbd847..3b01d1fb4f 100644 --- a/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java +++ b/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java @@ -29,7 +29,7 @@ import java.io.PrintWriter; import java.io.Serializable; import java.io.StringWriter; import java.util.ArrayList; -import java.util.Date; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -63,6 +63,7 @@ import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.cmr.usage.UsageService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.util.ApplicationContextHelper; @@ -74,7 +75,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; public class MultiTDemoTest extends TestCase { private static Log logger = LogFactory.getLog(MultiTDemoTest.class); - + private static ApplicationContext ctx =new ClassPathXmlApplicationContext( new String[] {ApplicationContextHelper.CONFIG_LOCATIONS[0], "classpath:tenant/mt-*context.xml"} ); @@ -93,10 +94,12 @@ public class MultiTDemoTest extends TestCase private CheckOutCheckInService cociService; private RepoAdminService repoAdminService; private DictionaryService dictionaryService; + private UsageService usageService; public static int NUM_TENANTS = 2; - public static final String TEST_TENANT_DOMAIN = "my.test"; + public static final String TEST_RUN = System.currentTimeMillis()+""; + public static final String TEST_TENANT_DOMAIN = TEST_RUN+".my.test"; public static final String TEST_TENANT_DOMAIN2 = TEST_TENANT_DOMAIN+"2"; public static List tenants; @@ -111,7 +114,7 @@ public class MultiTDemoTest extends TestCase } public static final String ROOT_DIR = "./tenantstores"; - + public static final String DEFAULT_ADMIN_PW = "admin"; public static final String DEFAULT_GUEST_UN = "guest"; @@ -125,13 +128,13 @@ public class MultiTDemoTest extends TestCase private static final int DEFAULT_STORE_COUNT = 7; // including siteStore public static StoreRef SPACES_STORE = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"); - + public MultiTDemoTest() { } - - + + @Override protected void setUp() throws Exception { @@ -151,14 +154,49 @@ public class MultiTDemoTest extends TestCase cociService = (CheckOutCheckInService) ctx.getBean("CheckoutCheckinService"); repoAdminService = (RepoAdminService) ctx.getBean("RepoAdminService"); dictionaryService = (DictionaryService) ctx.getBean("DictionaryService"); + usageService = (UsageService) ctx.getBean("usageService"); } - + @Override protected void tearDown() throws Exception { super.tearDown(); } - + + + public void test_ETHREEOH_2015() + { + final String tenantDomain1 = TEST_RUN+".one.ethreeoh2015"; + final String tenantDomain2 = TEST_RUN+".two.ethreeoh2015"; + + clearUsage(AuthenticationUtil.getAdminUserName()); + + createTenant(tenantDomain1); + + String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain1); + AuthenticationUtil.runAs(new RunAsWork() + { + public Object doWork() throws Exception + { + createUser(TEST_USER1, tenantDomain1, TEST_USER1+" "+tenantDomain1); + + return null; + } + }, tenantAdminName); + + createTenant(tenantDomain2); + } + + private void clearUsage(String userName) + { + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); // authenticate as super-admin + + // find person + NodeRef personNodeRef = personService.getPerson(userName); + // clear user usage + nodeService.setProperty(personNodeRef, ContentModel.PROP_SIZE_CURRENT, null); + usageService.deleteDeltas(personNodeRef); + } public void testCreateTenants() throws Throwable { @@ -172,7 +210,7 @@ public class MultiTDemoTest extends TestCase { String userName = (String)nodeService.getProperty(personRef, ContentModel.PROP_USERNAME); for (final String tenantDomain : tenants) - { + { assertFalse("Unexpected (tenant) user: "+userName, userName.endsWith(tenantDomain)); } } @@ -180,23 +218,8 @@ public class MultiTDemoTest extends TestCase try { for (final String tenantDomain : tenants) - { - // create tenants (if not already created) - AuthenticationUtil.runAs(new RunAsWork() - { - public Object doWork() throws Exception - { - if (! tenantAdminService.existsTenant(tenantDomain)) - { - //tenantAdminService.createTenant(tenantDomain, DEFAULT_ADMIN_PW.toCharArray(), ROOT_DIR + "/" + tenantDomain); - tenantAdminService.createTenant(tenantDomain, (DEFAULT_ADMIN_PW+" "+tenantDomain).toCharArray(), null); // use default root dir - - logger.info("Created tenant " + tenantDomain); - } - - return null; - } - }, AuthenticationUtil.getSystemUserName()); + { + createTenant(tenantDomain); } } catch (Throwable t) @@ -205,7 +228,27 @@ public class MultiTDemoTest extends TestCase t.printStackTrace(new PrintWriter(stackTrace)); System.err.println(stackTrace.toString()); throw t; - } + } + } + + private void createTenant(final String tenantDomain) + { + // create tenants (if not already created) + AuthenticationUtil.runAs(new RunAsWork() + { + public Object doWork() throws Exception + { + if (! tenantAdminService.existsTenant(tenantDomain)) + { + //tenantAdminService.createTenant(tenantDomain, DEFAULT_ADMIN_PW.toCharArray(), ROOT_DIR + "/" + tenantDomain); + tenantAdminService.createTenant(tenantDomain, (DEFAULT_ADMIN_PW+" "+tenantDomain).toCharArray(), null); // use default root dir + + logger.info("Created tenant " + tenantDomain); + } + + return null; + } + }, AuthenticationUtil.getSystemUserName()); } public void testCreateUsers() throws Throwable @@ -218,7 +261,7 @@ public class MultiTDemoTest extends TestCase { String userName = (String)nodeService.getProperty(personRef, ContentModel.PROP_USERNAME); for (final String tenantDomain : tenants) - { + { assertFalse("Unexpected (tenant) user: "+userName, userName.endsWith(tenantDomain)); } } @@ -226,7 +269,7 @@ public class MultiTDemoTest extends TestCase try { for (final String tenantDomain : tenants) - { + { String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); AuthenticationUtil.runAs(new RunAsWork() @@ -241,13 +284,13 @@ public class MultiTDemoTest extends TestCase createUser(TEST_USER3, tenantDomain, TEST_USER3+" "+tenantDomain); } - return null; + return null; } }, tenantAdminName); } for (final String tenantDomain : tenants) - { + { String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); AuthenticationUtil.runAs(new RunAsWork() @@ -276,9 +319,7 @@ public class MultiTDemoTest extends TestCase assertEquals(4, personRefs.size()); // admin@tenant, guest@tenant, alice@tenant, bob@tenant } - - - return null; + return null; } }, tenantAdminName); } @@ -368,9 +409,9 @@ public class MultiTDemoTest extends TestCase public void testCreateGroups() { logger.info("Create demo groups"); - + for (final String tenantDomain : tenants) - { + { String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); AuthenticationUtil.runAs(new RunAsWork() @@ -389,9 +430,9 @@ public class MultiTDemoTest extends TestCase createGroup("SubGrpC-"+tenantDomain, "GrpC-"+tenantDomain); } - return null; + return null; } - }, tenantAdminName); + }, tenantAdminName); } } @@ -400,33 +441,109 @@ public class MultiTDemoTest extends TestCase { logger.info("Create demo categories"); + // super admin + AuthenticationUtil.runAs(new RunAsWork() + { + public Object doWork() throws Exception + { + logger.info("Create demo categories - super tenant"); + createCategoriesImpl(""); + + return null; + } + }, AuthenticationUtil.getAdminUserName()); + for (final String tenantDomain : tenants) - { + { String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); AuthenticationUtil.runAs(new RunAsWork() - { - public Object doWork() throws Exception - { - NodeRef catRef = createCategory(SPACES_STORE, null, "CatA", "CatA-"+tenantDomain); - createCategory(SPACES_STORE, catRef, "SubCatA", "SubCatA-"+tenantDomain); // ignore return - - catRef = createCategory(SPACES_STORE, null, "CatB", "CatB-"+tenantDomain); - createCategory(SPACES_STORE, catRef, "SubCatB", "SubCatB-"+tenantDomain); // ignore return - - if (tenantDomain.equals(TEST_TENANT_DOMAIN2)) - { - catRef = createCategory(SPACES_STORE, null, "CatC", "CatC-"+tenantDomain); - createCategory(SPACES_STORE, catRef, "SubCatC", "SubCatC-"+tenantDomain); // ignore return - } - - return null; - } - }, tenantAdminName); + { + public Object doWork() throws Exception + { + logger.info("Create demo categories - "+tenantDomain); + + createCategoriesImpl(tenantDomain); + + return null; + } + }, tenantAdminName); } } + @SuppressWarnings("unchecked") + private void createCategoriesImpl(String tenantDomain) + { + if (tenantDomain.equals(TenantService.DEFAULT_DOMAIN)) + { + Collection childAssocs = categoryService.getRootCategories(SPACES_STORE, ContentModel.ASPECT_GEN_CLASSIFIABLE); + + for (ChildAssociationRef childAssoc : childAssocs) + { + if (nodeService.getProperty(childAssoc.getChildRef(), ContentModel.PROP_NAME).equals("CatA")) + { + return; // re-runnable, else we need to delete the created categories + } + } + } + + // Find all root categories + String query = "PATH:\"/cm:generalclassifiable/*\""; + ResultSet resultSet = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, query); + int cnt = resultSet.length(); + + NodeRef catA = createCategory(SPACES_STORE, null, "CatA", "CatA-"+tenantDomain); + createCategory(SPACES_STORE, catA, "SubCatA", "SubCatA-"+tenantDomain); // ignore return + + NodeRef catB = createCategory(SPACES_STORE, null, "CatB", "CatB-"+tenantDomain); + createCategory(SPACES_STORE, catB, "SubCatB", "SubCatB-"+tenantDomain); // ignore return + + cnt = cnt + 2; + + if (tenantDomain.equals(TEST_TENANT_DOMAIN2)) + { + NodeRef catC = createCategory(SPACES_STORE, null, "CatC", "CatC-"+tenantDomain); + createCategory(SPACES_STORE, catC, "SubCatC", "SubCatC-"+tenantDomain); // ignore return + + cnt = cnt + 1; + } + + // Find all root categories + resultSet = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, query); + assertEquals(cnt, resultSet.length()); + + String queryMembers = "PATH:\"/cm:generalclassifiable//cm:catA/member\""; + resultSet = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, queryMembers); + assertEquals(0, resultSet.length()); + + NodeRef homeSpaceRef = getHomeSpaceFolderNode(AuthenticationUtil.getRunAsUser()); + NodeRef contentRef = addContent(homeSpaceRef, "tqbfjotld.txt", "The quick brown fox jumps over the lazy dog (tenant " + tenantDomain + ")", MimetypeMap.MIMETYPE_TEXT_PLAIN); + + assertFalse(nodeService.hasAspect(contentRef, ContentModel.ASPECT_GEN_CLASSIFIABLE)); + + List categories = (List)nodeService.getProperty(contentRef, ContentModel.PROP_CATEGORIES); + assertNull(categories); + + // Classify the node (ie. assign node to a particular category in a classification) + categories = new ArrayList(1); + categories.add(catA); + + HashMap catProps = new HashMap(); + catProps.put(ContentModel.PROP_CATEGORIES, (Serializable)categories); + nodeService.addAspect(contentRef, ContentModel.ASPECT_GEN_CLASSIFIABLE, catProps); + + assertTrue(nodeService.hasAspect(contentRef, ContentModel.ASPECT_GEN_CLASSIFIABLE)); + + categories = (List)nodeService.getProperty(contentRef, ContentModel.PROP_CATEGORIES); + assertEquals(1, categories.size()); + + // test ETHREEOH-210 + queryMembers = "PATH:\"/cm:generalclassifiable//cm:CatA/member\""; + resultSet = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, queryMembers); + assertEquals(1, resultSet.length()); + } + public void testCreateFolders() { logger.info("Create demo folders"); @@ -437,7 +554,7 @@ public class MultiTDemoTest extends TestCase users.add(TEST_USER3); for (final String tenantDomain : tenants) - { + { for (String baseUserName : users) { if ((! baseUserName.equals(TEST_USER3)) || (tenantDomain.equals(TEST_TENANT_DOMAIN2))) @@ -450,7 +567,7 @@ public class MultiTDemoTest extends TestCase { NodeRef homeSpaceRef = getHomeSpaceFolderNode(tenantUserName); - NodeRef folderRef = createFolderNode(homeSpaceRef, "myfolder1"); + NodeRef folderRef = createFolderNode(homeSpaceRef, "myfolder1"); createFolderNode(folderRef, "mysubfolder1"); // ignore return folderRef = createFolderNode(homeSpaceRef, "myfolder2"); @@ -462,9 +579,9 @@ public class MultiTDemoTest extends TestCase createFolderNode(folderRef, "mysubfolder3"); // ignore return } - return null; + return null; } - }, tenantUserName); + }, tenantUserName); } } } @@ -480,7 +597,7 @@ public class MultiTDemoTest extends TestCase users.add(TEST_USER3); for (final String tenantDomain : tenants) - { + { for (String baseUserName : users) { if ((! baseUserName.equals(TEST_USER3)) || (tenantDomain.equals(TEST_TENANT_DOMAIN2))) @@ -499,18 +616,17 @@ public class MultiTDemoTest extends TestCase if (tenantDomain.equals(TEST_TENANT_DOMAIN2)) { contentRef = addContent(homeSpaceRef, tenantUserName+" quick brown fox ANO.txt", "The quick brown fox jumps over the lazy dog ANO (tenant " + tenantDomain + ")", MimetypeMap.MIMETYPE_TEXT_PLAIN); - nodeService.addAspect(contentRef, ContentModel.ASPECT_VERSIONABLE, null); } - return null; + return null; } - }, tenantUserName); + }, tenantUserName); } } } } - + public void testGetStores() { logger.info("Get tenant stores"); @@ -526,7 +642,7 @@ public class MultiTDemoTest extends TestCase } assertTrue("System: "+nodeService.getStores().size()+", "+(tenants.size()+1), (nodeService.getStores().size() >= (DEFAULT_STORE_COUNT * (tenants.size()+1)))); - return null; + return null; } }, AuthenticationUtil.getSystemUserName()); @@ -536,12 +652,12 @@ public class MultiTDemoTest extends TestCase public Object doWork() throws Exception { assertTrue("Super admin: "+nodeService.getStores().size(), (nodeService.getStores().size() >= DEFAULT_STORE_COUNT)); - return null; + return null; } }, AuthenticationUtil.getAdminUserName()); for (final String tenantDomain : tenants) - { + { String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); AuthenticationUtil.runAs(new RunAsWork() @@ -550,7 +666,7 @@ public class MultiTDemoTest extends TestCase { assertEquals("Tenant: "+tenantDomain, DEFAULT_STORE_COUNT, nodeService.getStores().size()); - return null; + return null; } }, tenantAdminName); } @@ -583,7 +699,7 @@ public class MultiTDemoTest extends TestCase assertFalse(props.get(ContentModel.PROP_STORE_IDENTIFIER).toString().contains(tenantDomain)); - return null; + return null; } }, tenantAdminName); } @@ -614,7 +730,7 @@ public class MultiTDemoTest extends TestCase NodeRef workingCopyNodeRef = cociService.checkout(nodeRef); ContentWriter writer = contentService.getWriter(workingCopyNodeRef, ContentModel.PROP_CONTENT, true); - + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.setEncoding("UTF-8"); @@ -631,7 +747,7 @@ public class MultiTDemoTest extends TestCase resultSet = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, query); assertEquals(1, resultSet.length()); - return null; + return null; } }, tenantAdminName); } @@ -642,7 +758,7 @@ public class MultiTDemoTest extends TestCase logger.info("test delete/archive & restore content"); for (final String tenantDomain : tenants) - { + { final String tenantUserName = tenantService.getDomainUser(TEST_USER1, tenantDomain); AuthenticationUtil.runAs(new RunAsWork() @@ -662,7 +778,7 @@ public class MultiTDemoTest extends TestCase nodeService.restoreNode(archivedContentRef, null, null, null); - return null; + return null; } }, tenantUserName); } @@ -673,9 +789,9 @@ public class MultiTDemoTest extends TestCase logger.info("test custom models"); final int defaultModelCnt = dictionaryService.getAllModels().size(); - + for (final String tenantDomain : tenants) - { + { final String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); AuthenticationUtil.runAs(new RunAsWork() @@ -763,17 +879,17 @@ public class MultiTDemoTest extends TestCase logger.warn("Parent group does not exist: " + parentShortName); return; } - } + } this.authorityService.createAuthority(AuthorityType.GROUP, parentGroupName, shortName); - + } else { logger.warn("Group already exists: " + shortName); } } - + private NodeRef createUser(String baseUserName, String tenantDomain, String password) { @@ -784,7 +900,7 @@ public class MultiTDemoTest extends TestCase if (! this.authenticationService.authenticationExists(userName)) { NodeRef baseHomeFolder = getUserHomesNodeRef(SPACES_STORE); - + // Create the users home folder NodeRef homeFolder = createHomeSpaceFolderNode( baseHomeFolder, @@ -931,7 +1047,7 @@ public class MultiTDemoTest extends TestCase this.nodeService.addAspect(nodeRef, ApplicationModel.ASPECT_UIFACETS, uiFacetsProps); setupHomeSpacePermissions(nodeRef, userName); - + return nodeRef; } @@ -943,7 +1059,7 @@ public class MultiTDemoTest extends TestCase // Admin Authority has full permissions by default (automatic - set in the permission config) // give full permissions to the new user this.permissionService.setPermission(homeSpaceRef, userName, permissionService.getAllPermission(), true); - + // by default other users will only have GUEST access to the space contents String permission = "Consumer"; @@ -951,11 +1067,11 @@ public class MultiTDemoTest extends TestCase { this.permissionService.setPermission(homeSpaceRef, permissionService.getAllAuthorities(), permission, true); } - + // the new user is the OWNER of their own space and always has full permissions this.ownableService.setOwner(homeSpaceRef, userName); this.permissionService.setPermission(homeSpaceRef, permissionService.getOwnerAuthority(), permissionService.getAllPermission(), true); - + // now detach (if we did this first we could not set any permissions!) this.permissionService.setInheritParentPermissions(homeSpaceRef, false); } @@ -969,26 +1085,26 @@ public class MultiTDemoTest extends TestCase { Map contentProps = new HashMap(); contentProps.put(ContentModel.PROP_NAME, name); - + ChildAssociationRef association = nodeService.createNode(spaceRef, - ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), + ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), ContentModel.TYPE_CONTENT, contentProps); - + NodeRef content = association.getChildRef(); - + // add titled aspect (for Web Client display) Map titledProps = new HashMap(); titledProps.put(ContentModel.PROP_TITLE, name); titledProps.put(ContentModel.PROP_DESCRIPTION, name); this.nodeService.addAspect(content, ContentModel.ASPECT_TITLED, titledProps); - + ContentWriter writer = contentService.getWriter(content, ContentModel.PROP_CONTENT, true); - + writer.setMimetype(mimeType); writer.setEncoding("UTF-8"); - + writer.putContent(textData); return content; @@ -998,38 +1114,37 @@ public class MultiTDemoTest extends TestCase { Map contentProps = new HashMap(); contentProps.put(ContentModel.PROP_NAME, name); - + ChildAssociationRef association = nodeService.createNode(spaceRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), ContentModel.TYPE_CONTENT, contentProps); - + NodeRef content = association.getChildRef(); - + // add titled aspect (for Web Client display) Map titledProps = new HashMap(); titledProps.put(ContentModel.PROP_TITLE, name); titledProps.put(ContentModel.PROP_DESCRIPTION, name); this.nodeService.addAspect(content, ContentModel.ASPECT_TITLED, titledProps); - + ContentWriter writer = contentService.getWriter(content, ContentModel.PROP_CONTENT, true); - + writer.setMimetype(mimeType); writer.setEncoding("UTF-8"); - + writer.putContent(is); return content; } - - // comment-in to run from command line + /* public static void main(String args[]) { System.out.println(new Date()); junit.textui.TestRunner.run(MultiTDemoTest.class); System.out.println(new Date()); } - + */ } diff --git a/source/java/org/alfresco/repo/usage/UserUsageTrackingComponent.java b/source/java/org/alfresco/repo/usage/UserUsageTrackingComponent.java index 221144197e..2cf1edade8 100644 --- a/source/java/org/alfresco/repo/usage/UserUsageTrackingComponent.java +++ b/source/java/org/alfresco/repo/usage/UserUsageTrackingComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -39,6 +39,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.tenant.Tenant; import org.alfresco.repo.tenant.TenantAdminService; +import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.transaction.TransactionServiceImpl; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.repository.ContentData; @@ -68,6 +69,7 @@ public class UserUsageTrackingComponent private NodeDaoService nodeDaoService; private UsageService usageService; private TenantAdminService tenantAdminService; + private TenantService tenantService; private StoreRef personStoreRef; @@ -101,7 +103,7 @@ public class UserUsageTrackingComponent { this.nodeDaoService = nodeDaoService; } - + public void setUsageService(UsageService usageService) { this.usageService = usageService; @@ -112,6 +114,11 @@ public class UserUsageTrackingComponent this.tenantAdminService = tenantAdminService; } + public void setTenantService(TenantService tenantService) + { + this.tenantService = tenantService; + } + public void setClearBatchSize(int clearBatchSize) { this.clearBatchSize = clearBatchSize; @@ -126,7 +133,7 @@ public class UserUsageTrackingComponent { this.enabled = enabled; } - + public void execute() { if (enabled == false || transactionService.isReadOnly()) @@ -137,7 +144,7 @@ public class UserUsageTrackingComponent boolean locked = writeLock.tryLock(); if (locked) { - // collapse usages - note: for MT environment, will collapse for all tenants + // collapse usages - note: for MT environment, will collapse for all tenants try { collapseUsages(); @@ -146,30 +153,30 @@ public class UserUsageTrackingComponent { writeLock.unlock(); } - } - } + } + } // called once on startup public void bootstrap() { - // default domain - bootstrapInternal(); - - if (tenantAdminService.isEnabled()) - { - List tenants = tenantAdminService.getAllTenants(); + // default domain + bootstrapInternal(); + + if (tenantAdminService.isEnabled()) + { + List tenants = tenantAdminService.getAllTenants(); for (Tenant tenant : tenants) - { - AuthenticationUtil.runAs(new RunAsWork() + { + AuthenticationUtil.runAs(new RunAsWork() { - public Object doWork() throws Exception + public Object doWork() throws Exception { - bootstrapInternal(); - return null; + bootstrapInternal(); + return null; } }, tenantAdminService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenant.getTenantDomain())); } - } + } } public void bootstrapInternal() @@ -178,7 +185,7 @@ public class UserUsageTrackingComponent { return; } - + boolean locked = writeLock.tryLock(); if (locked) { @@ -235,7 +242,7 @@ public class UserUsageTrackingComponent } }; nodeDaoService.getUsersWithUsage(personStoreRef, userHandler); - + return null; } }; @@ -268,7 +275,7 @@ public class UserUsageTrackingComponent batchCount = 0; } } - + if (logger.isInfoEnabled()) { logger.info("... cleared non-missing usages for " + clearCount + " users"); @@ -332,7 +339,8 @@ public class UserUsageTrackingComponent return true; // continue to next node (more required) } }; - nodeDaoService.getUsersWithoutUsage(personStoreRef, userHandler); + + nodeDaoService.getUsersWithoutUsage(tenantService.getName(personStoreRef), userHandler); return null; } @@ -351,13 +359,13 @@ public class UserUsageTrackingComponent { updateCount = recalculateUsages(users); } - + if (logger.isInfoEnabled()) { logger.info("... calculated missing usages for " + updateCount + " users"); } } - + /* * Recalculate content usage for given users. Required if upgrading an existing Alfresco, for users that * have not had their initial usage calculated. In a future release, could also be called explicitly by @@ -375,7 +383,7 @@ public class UserUsageTrackingComponent for (String store : stores) { - final StoreRef storeRef = new StoreRef(store); + final StoreRef storeRef = tenantService.getName(new StoreRef(store)); if (logger.isTraceEnabled()) { @@ -413,7 +421,7 @@ public class UserUsageTrackingComponent }; nodeDaoService.getContentUrlsForStore(storeRef, nodeContentUrlHandler); } - + return null; } }; @@ -459,7 +467,7 @@ public class UserUsageTrackingComponent return totalCount; } - + private int updateUsages(final List> userUsages) { RetryingTransactionCallback updateCurrentUsages = new RetryingTransactionCallback() @@ -508,8 +516,8 @@ public class UserUsageTrackingComponent // execute in READ-ONLY txn Set usageNodeRefs = transactionService.getRetryingTransactionHelper().doInTransaction(getUsageNodeRefs, true); - - int collapseCount = 0; + + int collapseCount = 0; for (final NodeRef usageNodeRef : usageNodeRefs) { Boolean collapsed = AuthenticationUtil.runAs(new RunAsWork() @@ -554,7 +562,7 @@ public class UserUsageTrackingComponent if (currentUsage != -1) { // collapse the usage deltas - currentUsage = contentUsageImpl.getUserUsage(userName); + currentUsage = contentUsageImpl.getUserUsage(userName); usageService.deleteDeltas(personNodeRef); contentUsageImpl.setUserStoredUsage(personNodeRef, currentUsage);