diff --git a/config/alfresco/usage-services-context.xml b/config/alfresco/usage-services-context.xml
index 0a49f83089..0f4f1940b5 100644
--- a/config/alfresco/usage-services-context.xml
+++ b/config/alfresco/usage-services-context.xml
@@ -52,7 +52,6 @@
-
@@ -61,6 +60,7 @@
+
diff --git a/source/java/org/alfresco/repo/usage/RepoUsageComponent.java b/source/java/org/alfresco/repo/usage/RepoUsageComponent.java
index 98af5b6d92..d7de1d0185 100644
--- a/source/java/org/alfresco/repo/usage/RepoUsageComponent.java
+++ b/source/java/org/alfresco/repo/usage/RepoUsageComponent.java
@@ -1,28 +1,28 @@
-/*
- * #%L
- * Alfresco Repository
- * %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
- * %%
- * This file is part of the Alfresco software.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * 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 .
- * #L%
- */
+/*
+ * #%L
+ * Alfresco Repository
+ * %%
+ * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * 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 .
+ * #L%
+ */
package org.alfresco.repo.usage;
import org.alfresco.service.cmr.admin.RepoUsage;
@@ -39,11 +39,6 @@ import org.alfresco.service.namespace.QName;
*/
public interface RepoUsageComponent
{
- public static final Long LOCK_TTL = 60000L;
- public static final QName LOCK_USAGE = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "RepoUsageComponent");
- public static final QName LOCK_USAGE_USERS = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "RepoUsageComponent.Users");
- public static final QName LOCK_USAGE_DOCUMENTS = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "RepoUsageComponent.Documents");
-
public static final String KEY_USAGE_ROOT = ".repoUsages";
public static final String KEY_USAGE_CURRENT = "current";
public static final String KEY_USAGE_LAST_UPDATE_USERS = "lastUpdateUsers";
diff --git a/source/java/org/alfresco/repo/usage/RepoUsageComponentImpl.java b/source/java/org/alfresco/repo/usage/RepoUsageComponentImpl.java
index f61befd6a3..8f5acfeec0 100644
--- a/source/java/org/alfresco/repo/usage/RepoUsageComponentImpl.java
+++ b/source/java/org/alfresco/repo/usage/RepoUsageComponentImpl.java
@@ -1,28 +1,28 @@
-/*
- * #%L
- * Alfresco Repository
- * %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
- * %%
- * This file is part of the Alfresco software.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * 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 .
- * #L%
- */
+/*
+ * #%L
+ * Alfresco Repository
+ * %%
+ * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * 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 .
+ * #L%
+ */
package org.alfresco.repo.usage;
import java.util.ArrayList;
@@ -39,8 +39,6 @@ import org.alfresco.ibatis.IdsEntity;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.qname.QNameDAO;
import org.alfresco.repo.domain.query.CannedQueryDAO;
-import org.alfresco.repo.lock.JobLockService;
-import org.alfresco.repo.lock.LockAcquisitionException;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
import org.alfresco.service.cmr.admin.RepoUsage;
@@ -52,7 +50,7 @@ import org.alfresco.service.cmr.attributes.AttributeService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.namespace.QName;
-import org.alfresco.service.transaction.TransactionService;
+import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.DateUtil;
import org.alfresco.util.PropertyCheck;
import org.apache.commons.logging.Log;
@@ -77,7 +75,6 @@ public class RepoUsageComponentImpl implements RepoUsageComponent
private AuthorityService authorityService;
private AttributeService attributeService;
private DictionaryService dictionaryService;
- private JobLockService jobLockService;
private CannedQueryDAO cannedQueryDAO;
private QNameDAO qnameDAO;
@@ -130,14 +127,6 @@ public class RepoUsageComponentImpl implements RepoUsageComponent
this.dictionaryService = dictionaryService;
}
- /**
- * @param jobLockService service to prevent duplicate work when updating usages
- */
- public void setJobLockService(JobLockService jobLockService)
- {
- this.jobLockService = jobLockService;
- }
-
/**
* @param cannedQueryDAO DAO for executing queries
*/
@@ -169,7 +158,6 @@ public class RepoUsageComponentImpl implements RepoUsageComponent
PropertyCheck.mandatory(this, "authorityService", authorityService);
PropertyCheck.mandatory(this, "attributeService", attributeService);
PropertyCheck.mandatory(this, "dictionaryService", dictionaryService);
- PropertyCheck.mandatory(this, "jobLockService", jobLockService);
PropertyCheck.mandatory(this, "cannedQueryDAO", cannedQueryDAO);
PropertyCheck.mandatory(this, "qnameDAO", qnameDAO);
}
@@ -287,48 +275,28 @@ public class RepoUsageComponentImpl implements RepoUsageComponent
*/
private boolean updateUsers(boolean reset)
{
- String lockToken = null;
- try
- {
- // Lock to prevent concurrent queries
- lockToken = jobLockService.getLock(LOCK_USAGE_USERS, LOCK_TTL);
- Long userCount = 0L;
-
- if (!reset)
- {
- // Count users
- IdsEntity idsParam = new IdsEntity();
- idsParam.setIdOne(qnameDAO.getOrCreateQName(ContentModel.ASPECT_PERSON_DISABLED).getFirst());
- idsParam.setIdTwo(qnameDAO.getOrCreateQName(ContentModel.TYPE_PERSON).getFirst());
- userCount = cannedQueryDAO.executeCountQuery(QUERY_NS, QUERY_SELECT_COUNT_PERSONS_NOT_DISABLED, idsParam);
-
- // We subtract one to cater for 'guest', which is implicit
- userCount = userCount > 0L ? userCount - 1L : 0L;
+ Long userCount = 0L;
- // Lock again to be sure we still have the right to update
- jobLockService.refreshLock(lockToken, LOCK_USAGE_USERS, LOCK_TTL);
- }
- attributeService.setAttribute(
- new Long(System.currentTimeMillis()),
- KEY_USAGE_ROOT, KEY_USAGE_CURRENT, KEY_USAGE_LAST_UPDATE_USERS);
- attributeService.setAttribute(
- userCount,
- KEY_USAGE_ROOT, KEY_USAGE_CURRENT, KEY_USAGE_USERS);
- // Success
- return true;
- }
- catch (LockAcquisitionException e)
+ if (!reset)
{
- logger.debug("Failed to get lock for user counts: " + e.getMessage());
- return false;
- }
- finally
- {
- if (lockToken != null)
- {
- jobLockService.releaseLock(lockToken, LOCK_USAGE_USERS);
- }
+ // Count users
+ IdsEntity idsParam = new IdsEntity();
+ idsParam.setIdOne(qnameDAO.getOrCreateQName(ContentModel.ASPECT_PERSON_DISABLED).getFirst());
+ idsParam.setIdTwo(qnameDAO.getOrCreateQName(ContentModel.TYPE_PERSON).getFirst());
+ userCount = cannedQueryDAO.executeCountQuery(QUERY_NS, QUERY_SELECT_COUNT_PERSONS_NOT_DISABLED, idsParam);
+
+ // We subtract one to cater for 'guest', which is implicit
+ userCount = userCount > 0L ? userCount - 1L : 0L;
+
}
+ attributeService.setAttribute(
+ new Long(System.currentTimeMillis()),
+ KEY_USAGE_ROOT, KEY_USAGE_CURRENT, KEY_USAGE_LAST_UPDATE_USERS);
+ attributeService.setAttribute(
+ userCount,
+ KEY_USAGE_ROOT, KEY_USAGE_CURRENT, KEY_USAGE_USERS);
+ // Success
+ return true;
}
/**
@@ -336,52 +304,31 @@ public class RepoUsageComponentImpl implements RepoUsageComponent
*/
private boolean updateDocuments(boolean reset)
{
- String lockToken = null;
- try
- {
- // Lock to prevent concurrent queries
- lockToken = jobLockService.getLock(LOCK_USAGE_DOCUMENTS, LOCK_TTL);
- Long documentCount = 0L;
+ Long documentCount = 0L;
- if (!reset)
- {
- // Count documents
- Set searchTypeQNames = new HashSet(11);
- Collection qnames = dictionaryService.getSubTypes(ContentModel.TYPE_CONTENT, true);
- searchTypeQNames.addAll(qnames);
- searchTypeQNames.add(ContentModel.TYPE_CONTENT);
- qnames = dictionaryService.getSubTypes(ContentModel.TYPE_LINK, true);
- searchTypeQNames.addAll(qnames);
- searchTypeQNames.add(ContentModel.TYPE_LINK);
- Set searchTypeQNameIds = qnameDAO.convertQNamesToIds(searchTypeQNames, false);
- IdsEntity idsParam = new IdsEntity();
- idsParam.setIds(new ArrayList(searchTypeQNameIds));
- documentCount = cannedQueryDAO.executeCountQuery(QUERY_NS, QUERY_SELECT_COUNT_DOCUMENTS, idsParam);
-
- // Lock again to be sure we still have the right to update
- jobLockService.refreshLock(lockToken, LOCK_USAGE_DOCUMENTS, LOCK_TTL);
- }
- attributeService.setAttribute(
- new Long(System.currentTimeMillis()),
- KEY_USAGE_ROOT, KEY_USAGE_CURRENT, KEY_USAGE_LAST_UPDATE_DOCUMENTS);
- attributeService.setAttribute(
- documentCount,
- KEY_USAGE_ROOT, KEY_USAGE_CURRENT, KEY_USAGE_DOCUMENTS);
- // Success
- return true;
- }
- catch (LockAcquisitionException e)
+ if (!reset)
{
- logger.debug("Failed to get lock for document counts: " + e.getMessage());
- return false;
- }
- finally
- {
- if (lockToken != null)
- {
- jobLockService.releaseLock(lockToken, LOCK_USAGE_DOCUMENTS);
- }
+ // Count documents
+ Set searchTypeQNames = new HashSet(11);
+ Collection qnames = dictionaryService.getSubTypes(ContentModel.TYPE_CONTENT, true);
+ searchTypeQNames.addAll(qnames);
+ searchTypeQNames.add(ContentModel.TYPE_CONTENT);
+ qnames = dictionaryService.getSubTypes(ContentModel.TYPE_LINK, true);
+ searchTypeQNames.addAll(qnames);
+ searchTypeQNames.add(ContentModel.TYPE_LINK);
+ Set searchTypeQNameIds = qnameDAO.convertQNamesToIds(searchTypeQNames, false);
+ IdsEntity idsParam = new IdsEntity();
+ idsParam.setIds(new ArrayList(searchTypeQNameIds));
+ documentCount = cannedQueryDAO.executeCountQuery(QUERY_NS, QUERY_SELECT_COUNT_DOCUMENTS, idsParam);
}
+ attributeService.setAttribute(
+ new Long(System.currentTimeMillis()),
+ KEY_USAGE_ROOT, KEY_USAGE_CURRENT, KEY_USAGE_LAST_UPDATE_DOCUMENTS);
+ attributeService.setAttribute(
+ documentCount,
+ KEY_USAGE_ROOT, KEY_USAGE_CURRENT, KEY_USAGE_DOCUMENTS);
+ // Success
+ return true;
}
/**
diff --git a/source/java/org/alfresco/repo/usage/RepoUsageMonitor.java b/source/java/org/alfresco/repo/usage/RepoUsageMonitor.java
index 09e690a428..6f9531db00 100644
--- a/source/java/org/alfresco/repo/usage/RepoUsageMonitor.java
+++ b/source/java/org/alfresco/repo/usage/RepoUsageMonitor.java
@@ -1,33 +1,35 @@
-/*
- * #%L
- * Alfresco Repository
- * %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
- * %%
- * This file is part of the Alfresco software.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * 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 .
- * #L%
- */
+/*
+ * #%L
+ * Alfresco Repository
+ * %%
+ * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * 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 .
+ * #L%
+ */
package org.alfresco.repo.usage;
import java.util.Date;
import org.alfresco.error.AlfrescoRuntimeException;
+import org.alfresco.repo.lock.JobLockService;
+import org.alfresco.repo.lock.LockAcquisitionException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
@@ -62,10 +64,14 @@ import org.quartz.TriggerUtils;
public class RepoUsageMonitor implements RepoUsageComponent.RestrictionObserver
{
private static Log logger = LogFactory.getLog(RepoUsageMonitor.class);
-
+
+ public static final Long LOCK_TTL = 60000L;
+ public static final QName LOCK_USAGE = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "RepoUsageMonitor");
+
private Scheduler scheduler;
private TransactionServiceImpl transactionService;
private RepoUsageComponent repoUsageComponent;
+ private JobLockService jobLockService;
private final QName vetoName = QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "RepoUsageMonitor");
/**
@@ -99,6 +105,14 @@ public class RepoUsageMonitor implements RepoUsageComponent.RestrictionObserver
this.repoUsageComponent = repoUsageComponent;
}
+ /**
+ * @param jobLockService service to prevent duplicate work when updating usages
+ */
+ public void setJobLockService(JobLockService jobLockService)
+ {
+ this.jobLockService = jobLockService;
+ }
+
/**
* Check that all properties are properly set
*/
@@ -107,7 +121,8 @@ public class RepoUsageMonitor implements RepoUsageComponent.RestrictionObserver
PropertyCheck.mandatory(this, "scheduler", scheduler);
PropertyCheck.mandatory(this, "transactionService", transactionService);
PropertyCheck.mandatory(this, "repoUsageComponent", repoUsageComponent);
-
+ PropertyCheck.mandatory(this, "jobLockService", jobLockService);
+
// Trigger the scheduled updates
final JobDetail jobDetail = new JobDetail("rmj", Scheduler.DEFAULT_GROUP, RepoUsageMonitorJob.class);
jobDetail.getJobDataMap().put("RepoUsageMonitor", this);
@@ -167,7 +182,34 @@ public class RepoUsageMonitor implements RepoUsageComponent.RestrictionObserver
return null;
}
};
- AuthenticationUtil.runAs(runAs, AuthenticationUtil.getSystemUserName());
+ String lockToken = null;
+ TrackerJobLockRefreshCallback callback = new TrackerJobLockRefreshCallback();
+ try
+ {
+ // Lock to prevent concurrent queries
+ lockToken = jobLockService.getLock(LOCK_USAGE, LOCK_TTL);
+ jobLockService.refreshLock(lockToken, LOCK_USAGE, LOCK_TTL / 2, callback);
+ AuthenticationUtil.runAs(runAs, AuthenticationUtil.getSystemUserName());
+ }
+ catch (LockAcquisitionException e)
+ {
+ logger.debug("Failed to get lock for usage monitor: " + e.getMessage());
+ }
+ finally
+ {
+ if (lockToken != null)
+ {
+ try
+ {
+ callback.isActive = false;
+ jobLockService.releaseLock(lockToken, LOCK_USAGE);
+ }
+ catch (LockAcquisitionException e)
+ {
+ logger.debug("Failed to release lock for usage monitor: " + e.getMessage());
+ }
+ }
+ }
}
/**
@@ -209,4 +251,24 @@ public class RepoUsageMonitor implements RepoUsageComponent.RestrictionObserver
repoUsageMonitor.checkUsages();
}
}
+
+ private class TrackerJobLockRefreshCallback implements JobLockService.JobLockRefreshCallback
+ {
+ public boolean isActive = true;
+
+ @Override
+ public boolean isActive()
+ {
+ return isActive;
+ }
+
+ @Override
+ public void lockReleased()
+ {
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("lock released");
+ }
+ }
+ }
}
diff --git a/source/test-java/org/alfresco/repo/usage/RepoUsageComponentTest.java b/source/test-java/org/alfresco/repo/usage/RepoUsageComponentTest.java
index 2638fa5335..fd41d62b71 100644
--- a/source/test-java/org/alfresco/repo/usage/RepoUsageComponentTest.java
+++ b/source/test-java/org/alfresco/repo/usage/RepoUsageComponentTest.java
@@ -1,28 +1,28 @@
-/*
- * #%L
- * Alfresco Repository
- * %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
- * %%
- * This file is part of the Alfresco software.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * 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 .
- * #L%
- */
+/*
+ * #%L
+ * Alfresco Repository
+ * %%
+ * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * 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 .
+ * #L%
+ */
package org.alfresco.repo.usage;
import javax.transaction.UserTransaction;
@@ -236,7 +236,10 @@ public class RepoUsageComponentTest extends TestCase
/**
* Check that concurrent updates are prevented
+ *
+ * The test is disabled as the Component is not using JobLocks any more
*/
+/*
public void test6ConcurrentUpdates() throws Exception
{
// Firstly check that we can get an update
@@ -286,4 +289,5 @@ public class RepoUsageComponentTest extends TestCase
jobLockService.releaseLock(lockToken, RepoUsageComponent.LOCK_USAGE_USERS);
}
}
+*/
}