use of org.alfresco.repo.lock.LockAcquisitionException in project alfresco-repository by Alfresco.
the class LockingJobTest method testJobLocking.
@Test
public void testJobLocking() throws Exception {
HBBaseDataCollector simpleCollector = mock(HBBaseDataCollector.class);
when(simpleCollector.getCollectorId()).thenReturn("c1");
when(simpleCollector.getCronExpression()).thenReturn("0 0 0 ? * *");
// mock the job context
JobExecutionContext mockJobExecutionContext = mock(JobExecutionContext.class);
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("collector", simpleCollector);
jobDataMap.put("hbDataSenderService", mockDataSenderService);
jobDataMap.put("jobLockService", mockJobLockService);
JobDetail jobDetail = JobBuilder.newJob().setJobData(jobDataMap).ofType(LockingJob.class).build();
when(mockJobExecutionContext.getJobDetail()).thenReturn(jobDetail);
// Simulate job lock service
String lockToken = "token";
when(mockJobLockService.getLock(isA(QName.class), anyLong())).thenReturn(// first job gets the lock
lockToken).thenThrow(// second job doesn't get the lock
new LockAcquisitionException("", ""));
// Run two heart beat jobs
new LockingJob().execute(mockJobExecutionContext);
new LockingJob().execute(mockJobExecutionContext);
// Verify that the collector only collects data once, since only one job got the lock
verify(simpleCollector, Mockito.times(1)).collectData();
// Verify that data was passed to data sender
verify(mockDataSenderService, Mockito.times(1)).sendData(any(List.class));
verify(mockDataSenderService, Mockito.times(0)).sendData(any(HBData.class));
// Verify that both jobs tried to get the lock
verify(mockJobLockService, Mockito.times(2)).getLock(any(QName.class), anyLong());
// Verify that a callback was registered once
verify(mockJobLockService, Mockito.times(1)).refreshLock(eq(lockToken), any(QName.class), anyLong(), any(JobLockService.JobLockRefreshCallback.class));
}
use of org.alfresco.repo.lock.LockAcquisitionException in project alfresco-repository by Alfresco.
the class RepoTransferReceiverImpl method start.
/*
* (non-Javadoc)
*
* @see org.alfresco.repo.web.scripts.transfer.TransferReceiver#start()
*/
public String start(String fromRepositoryId, boolean transferToSelf, TransferVersion fromVersion) {
log.debug("Start transfer");
/**
* Check that transfer is allowed to this repository
*/
checkTransfer(fromRepositoryId, transferToSelf);
/**
* Check that the versions are compatible
*/
TransferVersion toVersion = getVersion();
if (!getTransferVersionChecker().checkTransferVersions(fromVersion, toVersion)) {
throw new TransferException(MSG_INCOMPATIBLE_VERSIONS, new Object[] { "None", fromVersion, toVersion });
}
/**
* First get the transfer lock for this domain
*/
String tenantDomain = tenantService.getUserDomain(AuthenticationUtil.getRunAsUser());
String lockStr = tenantDomain.isEmpty() ? "transfer.server.default" : "transfer.server.tenant." + tenantDomain;
QName lockQName = QName.createQName(TransferModel.TRANSFER_MODEL_1_0_URI, lockStr);
Lock lock = new Lock(lockQName);
try {
TransferServicePolicies.BeforeStartInboundTransferPolicy beforeStartPolicy = beforeStartInboundTransferDelegate.get(TransferModel.TYPE_TRANSFER_RECORD);
beforeStartPolicy.beforeStartInboundTransfer();
lock.makeLock();
/**
* Transfer Lock held if we get this far
*/
String transferId = null;
try {
/**
* Now create a transfer record and use its NodeRef as the transfer id
*/
RetryingTransactionHelper txHelper = transactionService.getRetryingTransactionHelper();
transferId = txHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<String>() {
public String execute() throws Throwable {
final NodeRef relatedTransferRecord = createTransferRecord();
String transferId = relatedTransferRecord.toString();
getTempFolder(transferId);
getStagingFolder(transferId);
TransferServicePolicies.OnStartInboundTransferPolicy onStartPolicy = onStartInboundTransferDelegate.get(TransferModel.TYPE_TRANSFER_RECORD);
onStartPolicy.onStartInboundTransfer(transferId);
return transferId;
}
}, false, true);
} catch (Exception e) {
log.debug("Exception while staring transfer", e);
log.debug("releasing lock - we never created the transfer id");
lock.releaseLock();
throw new TransferException(MSG_ERROR_WHILE_STARTING, e);
}
/**
* Here if we have begun a transfer and have a valid transfer id
*/
lock.transferId = transferId;
locks.put(transferId, lock);
log.info("transfer started:" + transferId);
lock.enableLockTimeout();
return transferId;
} catch (LockAcquisitionException lae) {
log.debug("transfer lock is already taken", lae);
// lock is already taken.
throw new TransferException(MSG_TRANSFER_LOCK_UNAVAILABLE);
}
}
use of org.alfresco.repo.lock.LockAcquisitionException in project alfresco-repository by Alfresco.
the class NodeStringLengthWorker method execute.
/**
* Performs the work, including logging details of progress.
*/
public NodeStringLengthWorkResult execute() {
// Build refresh callback
final NodeStringLengthWorkResult progress = new NodeStringLengthWorkResult();
JobLockRefreshCallback lockCallback = new JobLockRefreshCallback() {
@Override
public void lockReleased() {
progress.inProgress.set(false);
}
@Override
public boolean isActive() {
return progress.inProgress.get();
}
};
String lockToken = null;
try {
progress.inProgress.set(true);
// Get the lock
lockToken = jobLockService.getLock(LOCK, LOCK_TTL);
// Start the refresh timer
jobLockService.refreshLock(lockToken, LOCK, LOCK_TTL, lockCallback);
// Now we know that we'll do something
if (logger.isInfoEnabled()) {
logger.info("NodeStringLengthWorker: Starting");
}
// Do the work
doWork(progress);
// Done
if (logger.isInfoEnabled()) {
logger.info("NodeStringLengthWorker: " + progress);
}
} catch (LockAcquisitionException e) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping node string length job: " + e.getMessage());
}
} catch (Exception e) {
progress.inProgress.set(false);
logger.error("Node string length job " + progress);
logger.error("Stopping node string length job with exception.", e);
} finally {
if (lockToken != null) {
jobLockService.releaseLock(lockToken, LOCK);
}
// The background
progress.inProgress.set(false);
}
// Done
return progress;
}
use of org.alfresco.repo.lock.LockAcquisitionException in project alfresco-repository by Alfresco.
the class AbstractFeedGenerator method execute.
public void execute() throws JobExecutionException {
checkProperties();
// Avoid running when in read-only mode
if (!transactionService.getAllowWrite()) {
if (logger.isTraceEnabled()) {
logger.trace("Activities feed generator not running due to read-only server");
}
return;
}
// MNT-12145 : BM-0013 Soak test: Exception during generation of feeds org.springframework.dao.DataIntegrityViolationException.
// run one job cycle
RetryingTransactionHelper helper = transactionService.getRetryingTransactionHelper();
helper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable {
LockCallback lockCallback = new LockCallback();
String lockToken = null;
try {
lockToken = acquireLock(lockCallback);
if (logger.isTraceEnabled()) {
logger.trace("Activities feed generator started");
}
generate();
if (logger.isTraceEnabled()) {
logger.trace("Activities feed generator completed");
}
} catch (LockAcquisitionException e) {
// Job being done by another process
if (logger.isDebugEnabled()) {
logger.debug("Activities feed generator already underway: " + LOCK_QNAME);
}
} catch (Throwable e) {
// If the VM is shutting down, then ignore
if (vmShutdownListener.isVmShuttingDown()) {
// Ignore
} else {
logger.error("Exception during generation of feeds", e);
}
} finally {
releaseLock(lockCallback, lockToken);
}
return null;
}
}, false, false);
}
use of org.alfresco.repo.lock.LockAcquisitionException in project alfresco-repository by Alfresco.
the class RepoUsageMonitor method checkUsages.
/**
* Performs the physical checking of usages.
*/
public void checkUsages() {
final RetryingTransactionCallback<Void> checkWork = new RetryingTransactionCallback<Void>() {
@Override
public Void execute() throws Throwable {
RepoUsage restrictions = repoUsageComponent.getRestrictions();
// Bypass if there are no restrictions
if (restrictions.getUsers() == null && restrictions.getDocuments() == null) {
transactionService.setAllowWrite(true, vetoName);
return null;
}
// Update user count, if required
if (restrictions.getUsers() != null) {
repoUsageComponent.updateUsage(UsageType.USAGE_USERS);
}
// Update document count, if required
if (restrictions.getDocuments() != null) {
repoUsageComponent.updateUsage(UsageType.USAGE_DOCUMENTS);
}
// Same as if restrictions have been changed
onChangeRestriction(restrictions);
return null;
}
};
RunAsWork<Void> runAs = new RunAsWork<Void>() {
@Override
public Void doWork() throws Exception {
transactionService.getRetryingTransactionHelper().doInTransaction(checkWork, false);
return null;
}
};
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());
}
}
}
}
Aggregations