Action Tracking Service work (replication task 79)

New concrete data transfer classes for holding the basic details on executing actions, and basic support (but no unit tests yet) for storing and retrieving these


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21281 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Nick Burch
2010-07-19 16:56:34 +00:00
parent a18efbbb6f
commit a2b793c21e
5 changed files with 173 additions and 47 deletions

View File

@@ -245,7 +245,7 @@ public class ActionServiceImplTransactionalTest extends TestCase
// Wait for the post-rollback update to complete // Wait for the post-rollback update to complete
// (The stored one gets updated asynchronously) // (The stored one gets updated asynchronously)
txn.rollback(); txn.rollback();
Thread.sleep(100); Thread.sleep(150);
txn = transactionService.getUserTransaction(); txn = transactionService.getUserTransaction();
txn.begin(); txn.begin();
@@ -283,7 +283,7 @@ public class ActionServiceImplTransactionalTest extends TestCase
// End the transaction. Should allow the async action // End the transaction. Should allow the async action
// to be executed // to be executed
txn.commit(); txn.commit();
Thread.sleep(100); Thread.sleep(150);
assertNotNull(action.getExecutionStartDate()); assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate()); assertNotNull(action.getExecutionEndDate());
@@ -315,7 +315,7 @@ public class ActionServiceImplTransactionalTest extends TestCase
// End the transaction. Should allow the async action // End the transaction. Should allow the async action
// to be executed // to be executed
txn.commit(); txn.commit();
Thread.sleep(100); Thread.sleep(150);
assertNotNull(action.getExecutionStartDate()); assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate()); assertNotNull(action.getExecutionEndDate());
@@ -351,7 +351,7 @@ public class ActionServiceImplTransactionalTest extends TestCase
// End the transaction. Should allow the async action // End the transaction. Should allow the async action
// to be executed // to be executed
txn.commit(); txn.commit();
Thread.sleep(100); Thread.sleep(150);
txn = transactionService.getUserTransaction(); txn = transactionService.getUserTransaction();
txn.begin(); txn.begin();

View File

@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.StringTokenizer;
import org.alfresco.repo.cache.EhCacheAdapter; import org.alfresco.repo.cache.EhCacheAdapter;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
@@ -33,6 +34,8 @@ import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionStatus; import org.alfresco.service.cmr.action.ActionStatus;
import org.alfresco.service.cmr.action.ActionTrackingService; import org.alfresco.service.cmr.action.ActionTrackingService;
import org.alfresco.service.cmr.action.CancellableAction; import org.alfresco.service.cmr.action.CancellableAction;
import org.alfresco.service.cmr.action.ExecutionDetails;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@@ -50,8 +53,7 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
*/ */
private static Log logger = LogFactory.getLog(ActionTrackingServiceImpl.class); private static Log logger = LogFactory.getLog(ActionTrackingServiceImpl.class);
// TODO - Fix types private EhCacheAdapter<String, ExecutionDetails> executingActionsCache;
private EhCacheAdapter<String, Void> executingActionsCache;
private TransactionService transactionService; private TransactionService transactionService;
private RuntimeActionService runtimeActionService; private RuntimeActionService runtimeActionService;
@@ -86,9 +88,8 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
/** /**
* Sets the cache used to store details of * Sets the cache used to store details of
* currently executing actions, cluster wide. * currently executing actions, cluster wide.
* TODO Fix types
*/ */
public void setExecutingActionsCache(EhCacheAdapter<String, Void> executingActionsCache) public void setExecutingActionsCache(EhCacheAdapter<String, ExecutionDetails> executingActionsCache)
{ {
this.executingActionsCache = executingActionsCache; this.executingActionsCache = executingActionsCache;
} }
@@ -110,6 +111,8 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
{ {
runtimeActionService.saveActionImpl(action.getNodeRef(), action); runtimeActionService.saveActionImpl(action.getNodeRef(), action);
} }
// TODO Remove it from the cache
} }
public void recordActionExecuting(Action action) public void recordActionExecuting(Action action)
@@ -117,6 +120,8 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
// Mark the action as starting // Mark the action as starting
((ActionImpl)action).setExecutionStartDate(new Date()); ((ActionImpl)action).setExecutionStartDate(new Date());
((ActionImpl)action).setExecutionStatus(ActionStatus.Running); ((ActionImpl)action).setExecutionStatus(ActionStatus.Running);
// TODO Put it into the cache
} }
/** /**
@@ -134,6 +139,8 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
((ActionImpl)action).setExecutionStatus(ActionStatus.Failed); ((ActionImpl)action).setExecutionStatus(ActionStatus.Failed);
((ActionImpl)action).setExecutionFailureMessage(exception.getMessage()); ((ActionImpl)action).setExecutionFailureMessage(exception.getMessage());
// TODO Take it out of the cache
if(action.getNodeRef() != null) if(action.getNodeRef() != null)
{ {
// Take a local copy of the details // Take a local copy of the details
@@ -206,55 +213,70 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
public void requestActionCancellation(CancellableAction action) public void requestActionCancellation(CancellableAction action)
{ {
// See if the action is in the cache requestActionCancellation(
// If it isn't, nothing to do generateCacheKey(action)
// If it is, update the cancelled flag on it );
// TODO
} }
public List<Void> getAllExecutingActions() { public void requestActionCancellation(ExecutionSummary executionSummary)
{
requestActionCancellation(
generateCacheKey(executionSummary)
);
}
private void requestActionCancellation(String actionKey)
{
// See if the action is in the cache
ExecutionDetails details = executingActionsCache.get(actionKey);
if(details == null) {
// It isn't in the cache, so nothing to do
return;
}
// Since it is, update the cancelled flag on it
// TODO
executingActionsCache.put(actionKey, details);
}
public List<ExecutionSummary> getAllExecutingActions() {
Collection<String> actions = executingActionsCache.getKeys(); Collection<String> actions = executingActionsCache.getKeys();
// TODO fix types List<ExecutionSummary> details = new ArrayList<ExecutionSummary>(actions.size());
List<Void> details = new ArrayList<Void>(actions.size());
for(String key : actions) { for(String key : actions) {
//details.add( buildExecutionSummary(key) ); details.add( buildExecutionSummary(key) );
} }
return details; return details;
} }
public List<Void> getExecutingActions(Action action) { public List<ExecutionSummary> getExecutingActions(Action action) {
Collection<String> actions = executingActionsCache.getKeys(); Collection<String> actions = executingActionsCache.getKeys();
// TODO fix types List<ExecutionSummary> details = new ArrayList<ExecutionSummary>();
List<Void> details = new ArrayList<Void>();
String match = action.getActionDefinitionName() + "-" + action.getId(); String match = action.getActionDefinitionName() + "-" + action.getId();
for(String key : actions) { for(String key : actions) {
if(key.startsWith(match)) { if(key.startsWith(match)) {
//details.add( buildExecutionSummary(key) ); details.add( buildExecutionSummary(key) );
} }
} }
return details; return details;
} }
public List<Void> getExecutingActions(String type) { public List<ExecutionSummary> getExecutingActions(String type) {
Collection<String> actions = executingActionsCache.getKeys(); Collection<String> actions = executingActionsCache.getKeys();
// TODO fix types List<ExecutionSummary> details = new ArrayList<ExecutionSummary>();
List<Void> details = new ArrayList<Void>();
for(String key : actions) { for(String key : actions) {
if(key.startsWith(type)) { if(key.startsWith(type)) {
//details.add( buildExecutionSummary(key) ); details.add( buildExecutionSummary(key) );
} }
} }
return details; return details;
} }
public void getExecutionDetails(Void executionSummary) { public ExecutionDetails getExecutionDetails(ExecutionSummary executionSummary) {
// TODO Auto-generated method stub return executingActionsCache.get(
generateCacheKey(executionSummary)
} );
public void requestActionCancellation(Void executionSummary) {
// TODO Auto-generated method stub
} }
/** /**
@@ -262,18 +284,33 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
*/ */
protected String generateCacheKey(Action action) protected String generateCacheKey(Action action)
{ {
// TODO return
return null; action.getActionDefinitionName() + "-" +
action.getId() + "-" +
""//action.getExecutionInstance // TODO
;
}
protected String generateCacheKey(ExecutionSummary summary)
{
return
summary.getActionType() + "-" +
summary.getActionId() + "-" +
summary.getExecutionInstance()
;
} }
/** /**
* Turns a cache key back into its constituent * Turns a cache key back into its constituent
* parts, for easier access. * parts, for easier access.
* TODO Fix types
*/ */
protected void buildExecutionSummary(String key) protected ExecutionSummary buildExecutionSummary(String key)
{ {
StringTokenizer st = new StringTokenizer(key, "-");
String actionType = st.nextToken();
String actionId = st.nextToken();
int executionInstance = Integer.parseInt(st.nextToken());
return new ExecutionSummary(actionType, actionId, executionInstance);
} }
} }

View File

@@ -82,10 +82,9 @@ public interface ActionTrackingService
* If the specified action is not a cancellable * If the specified action is not a cancellable
* action, nothing will happen. * action, nothing will happen.
* *
* TODO Correct param type - is key based data only.
* @param action The action to request the cancel of * @param action The action to request the cancel of
*/ */
void requestActionCancellation(Void executionSummary); void requestActionCancellation(ExecutionSummary executionSummary);
/** /**
* Has cancellation been requested for the given * Has cancellation been requested for the given
@@ -104,30 +103,25 @@ public interface ActionTrackingService
* Retrieves the execution details on the given * Retrieves the execution details on the given
* executing action, such as when it started, * executing action, such as when it started,
* and what machine it is executing on. * and what machine it is executing on.
* TODO Correct param type - is key based data only.
* TODO Correct return type - is all cache data
*/ */
void getExecutionDetails(Void executionSummary); ExecutionDetails getExecutionDetails(ExecutionSummary executionSummary);
/** /**
* Retrieve summary details of all the actions * Retrieve summary details of all the actions
* currently executing. * currently executing.
* TODO Correct return type - is key based data only.
*/ */
List<Void> getAllExecutingActions(); List<ExecutionSummary> getAllExecutingActions();
/** /**
* Retrieve summary details of all the actions * Retrieve summary details of all the actions
* of the given type that are currently executing. * of the given type that are currently executing.
* TODO Correct return type - is key based data only.
*/ */
List<Void> getExecutingActions(String type);//or is it qname? List<ExecutionSummary> getExecutingActions(String type);
/** /**
* Retrieve summary details of all instances of * Retrieve summary details of all instances of
* the specified action that are currently * the specified action that are currently
* executing. * executing.
* TODO Correct return type - is key based data only.
*/ */
List<Void> getExecutingActions(Action action); List<ExecutionSummary> getExecutingActions(Action action);
} }

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2005-2010 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.service.cmr.action;
import java.util.Date;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Holds all the details available to the
* {@link ActionTrackingService} on a currently
* executing Action.
*
* @author Nick Burch
*/
public class ExecutionDetails {
/*
* Transient as all the info is held in the key,
* we don't need to also hold a 2nd copy of it
*/
private transient ExecutionSummary executionSummary;
private NodeRef persistedActionRef;
private String runningOn;
private Date startedAt;
private boolean cancelRequested;
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2005-2010 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.service.cmr.action;
/**
* Holds core key details of an Action that is
* currently executing.
* This information is normally the limit
* of what the {@link ActionTrackingService}
* can use when filtering lists of actions.
*
* @author Nick Burch
*/
public class ExecutionSummary {
private String actionType;
private String actionId;
private int executionInstance;
public ExecutionSummary(String actionType, String actionId,
int executionInstance) {
this.actionType = actionType;
this.actionId = actionId;
this.executionInstance = executionInstance;
}
public String getActionType() {
return actionType;
}
public String getActionId() {
return actionId;
}
public int getExecutionInstance() {
return executionInstance;
}
}