mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.2 to HEAD
16652: Fix ETHREEOH-1052 - usage is not displayed (for admin & guest - after initial bootstrap, before restart) 16778: Fix ETHREEOH-3009 - Patch required for UserUsageTrackingComponent so that new queries work on upgraded repository git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@16922 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -53,6 +53,7 @@
|
|||||||
<cm:organizationId></cm:organizationId>
|
<cm:organizationId></cm:organizationId>
|
||||||
<cm:homeFolder>/${spaces.company_home.childname}</cm:homeFolder>
|
<cm:homeFolder>/${spaces.company_home.childname}</cm:homeFolder>
|
||||||
<cm:homeFolderProvider>bootstrapHomeFolderProvider</cm:homeFolderProvider>
|
<cm:homeFolderProvider>bootstrapHomeFolderProvider</cm:homeFolderProvider>
|
||||||
|
<cm:sizeCurrent>0</cm:sizeCurrent>
|
||||||
</cm:person>
|
</cm:person>
|
||||||
<!-- Guest needs to read their own person information -->
|
<!-- Guest needs to read their own person information -->
|
||||||
<cm:person view:childName="cm:${alfresco_user_store.guestusername}">
|
<cm:person view:childName="cm:${alfresco_user_store.guestusername}">
|
||||||
@@ -69,6 +70,7 @@
|
|||||||
<cm:organizationId></cm:organizationId>
|
<cm:organizationId></cm:organizationId>
|
||||||
<cm:homeFolder>/${spaces.company_home.childname}/${spaces.guest_home.childname}</cm:homeFolder>
|
<cm:homeFolder>/${spaces.company_home.childname}/${spaces.guest_home.childname}</cm:homeFolder>
|
||||||
<cm:homeFolderProvider>bootstrapHomeFolderProvider</cm:homeFolderProvider>
|
<cm:homeFolderProvider>bootstrapHomeFolderProvider</cm:homeFolderProvider>
|
||||||
|
<cm:sizeCurrent>0</cm:sizeCurrent>
|
||||||
</cm:person>
|
</cm:person>
|
||||||
</sys:children>
|
</sys:children>
|
||||||
</sys:container>
|
</sys:container>
|
||||||
|
@@ -280,3 +280,7 @@ patch.fixNameCrcValues.description=Fixes name CRC32 values to match UTF-8 encodi
|
|||||||
patch.fixNameCrcValues.result=Fixed {0} name CRC32 values for UTF-8 encoding. See file {1} for details.
|
patch.fixNameCrcValues.result=Fixed {0} name CRC32 values for UTF-8 encoding. See file {1} for details.
|
||||||
patch.fixNameCrcValues.fixed=Updated CRC32 value for node ID {0}, name ''{1}'': {2} -> {3}.
|
patch.fixNameCrcValues.fixed=Updated CRC32 value for node ID {0}, name ''{1}'': {2} -> {3}.
|
||||||
patch.fixNameCrcValues.unableToChange=Failed to update the CRC32 value for node ID {0}: \n Node name: {1} \n CRC old: {2} \n CRC new: {3} \n Error: {4}
|
patch.fixNameCrcValues.unableToChange=Failed to update the CRC32 value for node ID {0}: \n Node name: {1} \n CRC old: {2} \n CRC new: {3} \n Error: {4}
|
||||||
|
|
||||||
|
patch.personUsagePatch.description=Add person 'cm:sizeCurrent' property (if missing).
|
||||||
|
patch.personUsagePatch.result1=Added 'cm:sizeCurrent' property to {0} people that were missing this property.
|
||||||
|
patch.personUsagePatch.result2=No people were missing the 'cm:sizeCurrent' property.
|
||||||
|
@@ -250,6 +250,7 @@
|
|||||||
<property name="cm:sizeCurrent">
|
<property name="cm:sizeCurrent">
|
||||||
<type>d:long</type>
|
<type>d:long</type>
|
||||||
<protected>true</protected>
|
<protected>true</protected>
|
||||||
|
<mandatory enforced="true">true</mandatory>
|
||||||
</property>
|
</property>
|
||||||
<property name="cm:sizeQuota">
|
<property name="cm:sizeQuota">
|
||||||
<type>d:long</type>
|
<type>d:long</type>
|
||||||
|
@@ -1933,4 +1933,22 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="patch.personUsagePatch" class="org.alfresco.repo.admin.patch.impl.PersonUsagePatch" parent="basePatch" >
|
||||||
|
<property name="id"><value>patch.personUsagePatch</value></property>
|
||||||
|
<property name="description"><value>patch.personUsagePatch.description</value></property>
|
||||||
|
<property name="fixesFromSchema"><value>0</value></property>
|
||||||
|
<property name="fixesToSchema"><value>3004</value></property>
|
||||||
|
<property name="targetSchema"><value>3005</value></property>
|
||||||
|
<!-- helper beans -->
|
||||||
|
<property name="nodeDaoService">
|
||||||
|
<ref bean="nodeDaoService"/>
|
||||||
|
</property>
|
||||||
|
<property name="personStoreUrl">
|
||||||
|
<value>${spaces.store}</value>
|
||||||
|
</property>
|
||||||
|
<property name="tenantService">
|
||||||
|
<ref bean="tenantService"/>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
@@ -19,4 +19,4 @@ version.build=@build-number@
|
|||||||
|
|
||||||
# Schema number
|
# Schema number
|
||||||
|
|
||||||
version.schema=3004
|
version.schema=3005
|
||||||
|
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have received a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.admin.patch.impl;
|
||||||
|
|
||||||
|
import org.alfresco.i18n.I18NUtil;
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||||
|
import org.alfresco.repo.node.db.NodeDaoService;
|
||||||
|
import org.alfresco.repo.node.db.NodeDaoService.ObjectArrayQueryCallback;
|
||||||
|
import org.alfresco.repo.tenant.TenantService;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch to add person usage ('cm:sizeCurrent') property to person (if missing)
|
||||||
|
*
|
||||||
|
* @author janv
|
||||||
|
*/
|
||||||
|
public class PersonUsagePatch extends AbstractPatch
|
||||||
|
{
|
||||||
|
private static Log logger = LogFactory.getLog(PersonUsagePatch.class);
|
||||||
|
|
||||||
|
/** Success messages. */
|
||||||
|
private static final String MSG_SUCCESS1 = "patch.personUsagePatch.result1";
|
||||||
|
private static final String MSG_SUCCESS2 = "patch.personUsagePatch.result2";
|
||||||
|
|
||||||
|
private NodeDaoService nodeDaoService;
|
||||||
|
private StoreRef personStoreRef;
|
||||||
|
private TenantService tenantService;
|
||||||
|
|
||||||
|
|
||||||
|
public void setNodeDaoService(NodeDaoService nodeDaoService)
|
||||||
|
{
|
||||||
|
this.nodeDaoService = nodeDaoService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPersonStoreUrl(String storeUrl)
|
||||||
|
{
|
||||||
|
this.personStoreRef = new StoreRef(storeUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTenantService(TenantService tenantService)
|
||||||
|
{
|
||||||
|
this.tenantService = tenantService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String applyInternal() throws Exception
|
||||||
|
{
|
||||||
|
logger.info("Checking for people with missing 'cm:sizeCurrent' property ...");
|
||||||
|
|
||||||
|
int count = addPersonSizeCurrentProperty();
|
||||||
|
|
||||||
|
String msg = null;
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
logger.info("... missing 'cm:sizeCurrent' property added to "+count+" people");
|
||||||
|
msg = I18NUtil.getMessage(MSG_SUCCESS1, count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.info("... no people were missing the 'cm:sizeCurrent' property");
|
||||||
|
msg = I18NUtil.getMessage(MSG_SUCCESS2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int addPersonSizeCurrentProperty()
|
||||||
|
{
|
||||||
|
// get people (users) with missing 'cm:sizeCurrent' property
|
||||||
|
|
||||||
|
CountObjectArrayQueryCallback userHandler = new CountObjectArrayQueryCallback();
|
||||||
|
|
||||||
|
nodeDaoService.getUsersWithoutUsageProp(tenantService.getName(personStoreRef), userHandler);
|
||||||
|
|
||||||
|
return userHandler.getCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CountObjectArrayQueryCallback implements ObjectArrayQueryCallback
|
||||||
|
{
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
public CountObjectArrayQueryCallback()
|
||||||
|
{
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean handle(Object[] arr)
|
||||||
|
{
|
||||||
|
String uuid = (String)arr[0];
|
||||||
|
|
||||||
|
nodeService.setProperty(new NodeRef(personStoreRef, uuid), ContentModel.PROP_SIZE_CURRENT, null);
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
return true; // continue to next node (more required)
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount()
|
||||||
|
{
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@@ -716,6 +716,22 @@
|
|||||||
(p1.string_value != 'System' OR (p1.string_value IS NULL AND n.audit_creator != 'System'))
|
(p1.string_value != 'System' OR (p1.string_value IS NULL AND n.audit_creator != 'System'))
|
||||||
</sql-query>
|
</sql-query>
|
||||||
|
|
||||||
|
<!-- note: for PersonUsagePatch only -->
|
||||||
|
<sql-query name="node.GetUsersWithoutUsageProp">
|
||||||
|
<return-scalar column="uuid" type="string"/>
|
||||||
|
SELECT
|
||||||
|
n.uuid AS uuid
|
||||||
|
FROM
|
||||||
|
alf_node n
|
||||||
|
JOIN alf_store s ON (s.id = n.store_id AND n.type_qname_id = :personTypeQNameID)
|
||||||
|
LEFT JOIN alf_node_properties p1 ON (p1.node_id = n.id AND p1.qname_id = :sizeCurrentPropQNameID)
|
||||||
|
WHERE
|
||||||
|
s.protocol = :storeProtocol AND
|
||||||
|
s.identifier = :storeIdentifier AND
|
||||||
|
n.node_deleted = :isDeleted AND
|
||||||
|
p1.persisted_type_n IS NULL
|
||||||
|
</sql-query>
|
||||||
|
|
||||||
<sql-query name="node.GetUsersWithoutUsage">
|
<sql-query name="node.GetUsersWithoutUsage">
|
||||||
<return-scalar column="username" type="string"/>
|
<return-scalar column="username" type="string"/>
|
||||||
<return-scalar column="uuid" type="string"/>
|
<return-scalar column="uuid" type="string"/>
|
||||||
|
@@ -503,6 +503,19 @@ public interface NodeDaoService
|
|||||||
StoreRef storeRef,
|
StoreRef storeRef,
|
||||||
ObjectArrayQueryCallback resultsCallback);
|
ObjectArrayQueryCallback resultsCallback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate over all person nodes with missing usage property (for one-off patch)
|
||||||
|
*
|
||||||
|
* @param storeRef the store to search in
|
||||||
|
* @param handler the callback to use while iterating over the people
|
||||||
|
* @return Returns the values for person node uuid
|
||||||
|
*/
|
||||||
|
@DirtySessionAnnotation(markDirty=true)
|
||||||
|
public void getUsersWithoutUsageProp(
|
||||||
|
StoreRef storeRef,
|
||||||
|
ObjectArrayQueryCallback resultsCallback);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterate over all person nodes to get users without a calculated usage
|
* Iterate over all person nodes to get users without a calculated usage
|
||||||
*
|
*
|
||||||
|
@@ -163,6 +163,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
|
|||||||
private static final String QUERY_GET_NODES_WITH_PROPERTY_VALUES_BY_STRING_AND_STORE = "node.GetNodesWithPropertyValuesByStringAndStore";
|
private static final String QUERY_GET_NODES_WITH_PROPERTY_VALUES_BY_STRING_AND_STORE = "node.GetNodesWithPropertyValuesByStringAndStore";
|
||||||
private static final String QUERY_GET_CONTENT_URLS_FOR_STORE_OLD = "node.GetContentUrlsForStoreOld";
|
private static final String QUERY_GET_CONTENT_URLS_FOR_STORE_OLD = "node.GetContentUrlsForStoreOld";
|
||||||
private static final String QUERY_GET_CONTENT_URLS_FOR_STORE_NEW = "node.GetContentUrlsForStoreNew";
|
private static final String QUERY_GET_CONTENT_URLS_FOR_STORE_NEW = "node.GetContentUrlsForStoreNew";
|
||||||
|
private static final String QUERY_GET_USERS_WITHOUT_USAGE_PROP = "node.GetUsersWithoutUsageProp";
|
||||||
private static final String QUERY_GET_USERS_WITHOUT_USAGE = "node.GetUsersWithoutUsage";
|
private static final String QUERY_GET_USERS_WITHOUT_USAGE = "node.GetUsersWithoutUsage";
|
||||||
private static final String QUERY_GET_USERS_WITH_USAGE = "node.GetUsersWithUsage";
|
private static final String QUERY_GET_USERS_WITH_USAGE = "node.GetUsersWithUsage";
|
||||||
private static final String QUERY_GET_NODES_WITH_PROPERTY_VALUES_BY_ACTUAL_TYPE = "node.GetNodesWithPropertyValuesByActualType";
|
private static final String QUERY_GET_NODES_WITH_PROPERTY_VALUES_BY_ACTUAL_TYPE = "node.GetNodesWithPropertyValuesByActualType";
|
||||||
@@ -3649,6 +3650,59 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
|
|||||||
// Done
|
// Done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getUsersWithoutUsageProp(
|
||||||
|
final StoreRef storeRef,
|
||||||
|
final ObjectArrayQueryCallback resultsCallback)
|
||||||
|
{
|
||||||
|
final Pair<Long, QName> sizeCurrentPropQNamePair = qnameDAO.getQName(ContentModel.PROP_SIZE_CURRENT);
|
||||||
|
final Pair<Long, QName> personTypeQNamePair = qnameDAO.getQName(ContentModel.TYPE_PERSON);
|
||||||
|
|
||||||
|
// Shortcut the query if the QNames don't exist
|
||||||
|
if (sizeCurrentPropQNamePair == null || personTypeQNamePair == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HibernateCallback callback = new HibernateCallback()
|
||||||
|
{
|
||||||
|
public Object doInHibernate(Session session)
|
||||||
|
{
|
||||||
|
Query query = session
|
||||||
|
.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_USERS_WITHOUT_USAGE_PROP)
|
||||||
|
.setString("storeProtocol", storeRef.getProtocol())
|
||||||
|
.setString("storeIdentifier", storeRef.getIdentifier())
|
||||||
|
.setParameter("sizeCurrentPropQNameID", sizeCurrentPropQNamePair.getFirst()) // cm:sizeCurrent
|
||||||
|
.setParameter("personTypeQNameID", personTypeQNamePair.getFirst()) // cm:person
|
||||||
|
.setParameter("isDeleted", false);
|
||||||
|
;
|
||||||
|
DirtySessionMethodInterceptor.setQueryFlushMode(session, query);
|
||||||
|
return query.scroll(ScrollMode.FORWARD_ONLY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ScrollableResults results = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
results = (ScrollableResults) getHibernateTemplate().execute(callback);
|
||||||
|
// Callback with the results
|
||||||
|
Session session = getSession();
|
||||||
|
while (results.next())
|
||||||
|
{
|
||||||
|
Object[] arr = new Object[1];
|
||||||
|
arr[0] = (String)results.get(0); // node uuid
|
||||||
|
resultsCallback.handle(arr);
|
||||||
|
// Flush if required
|
||||||
|
DirtySessionMethodInterceptor.flushSession(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (results != null)
|
||||||
|
{
|
||||||
|
results.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void getUsersWithoutUsage(
|
public void getUsersWithoutUsage(
|
||||||
final StoreRef storeRef,
|
final StoreRef storeRef,
|
||||||
final ObjectArrayQueryCallback resultsCallback)
|
final ObjectArrayQueryCallback resultsCallback)
|
||||||
|
@@ -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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -508,6 +508,7 @@ public class AuthenticationUtil implements InitializingBean
|
|||||||
}
|
}
|
||||||
AuthenticationUtil.setRunAsUser(uid);
|
AuthenticationUtil.setRunAsUser(uid);
|
||||||
}
|
}
|
||||||
|
logNDC(uid);
|
||||||
result = runAsWork.doWork();
|
result = runAsWork.doWork();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -528,11 +529,14 @@ public class AuthenticationUtil implements InitializingBean
|
|||||||
if (originalFullAuthentication == null)
|
if (originalFullAuthentication == null)
|
||||||
{
|
{
|
||||||
AuthenticationUtil.clearCurrentSecurityContext();
|
AuthenticationUtil.clearCurrentSecurityContext();
|
||||||
|
logNDC(null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AuthenticationUtil.setFullAuthentication(originalFullAuthentication);
|
AuthenticationUtil.setFullAuthentication(originalFullAuthentication);
|
||||||
AuthenticationUtil.setRunAsAuthentication(originalRunAsAuthentication);
|
AuthenticationUtil.setRunAsAuthentication(originalRunAsAuthentication);
|
||||||
|
|
||||||
|
logNDC(getUserName(originalFullAuthentication));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -599,6 +603,8 @@ public class AuthenticationUtil implements InitializingBean
|
|||||||
{
|
{
|
||||||
NDC.remove();
|
NDC.remove();
|
||||||
|
|
||||||
|
if (userName != null)
|
||||||
|
{
|
||||||
if (isMtEnabled())
|
if (isMtEnabled())
|
||||||
{
|
{
|
||||||
String[] parts = splitUserTenant(userName);
|
String[] parts = splitUserTenant(userName);
|
||||||
@@ -616,6 +622,7 @@ public class AuthenticationUtil implements InitializingBean
|
|||||||
NDC.push("User:" + userName);
|
NDC.push("User:" + userName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static String[] splitUserTenant(String userName)
|
private static String[] splitUserTenant(String userName)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user