You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ah...@apache.org on 2013/06/18 02:24:46 UTC

[1/9] git commit: updated refs/heads/vmsync to 309f8da

Updated Branches:
  refs/heads/vmsync a72ddad92 -> 309f8da6d


jobs changes


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/2b96665b
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/2b96665b
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/2b96665b

Branch: refs/heads/vmsync
Commit: 2b96665bf408486f23003f878fa1f05ec5d5b963
Parents: a72ddad
Author: Alex Huang <al...@gmail.com>
Authored: Fri Jun 14 16:27:01 2013 -0700
Committer: Alex Huang <al...@gmail.com>
Committed: Mon Jun 17 17:04:00 2013 -0700

----------------------------------------------------------------------
 .../api/response/AsyncJobResponse.java          |   4 +-
 api/src/org/apache/cloudstack/jobs/Job.java     |  67 -------
 api/src/org/apache/cloudstack/jobs/JobInfo.java |  65 +++++++
 .../com/cloud/vm/VirtualMachineManagerImpl.java |   7 +-
 .../cloud/vm/VmWorkTestApiJobDispatcher.java    |   2 +-
 .../cloud/async/AsyncJobExecutionContext.java   | 173 ------------------
 .../cloudstack/framework/jobs/AsyncJob.java     |   4 +-
 .../jobs/AsyncJobExecutionContext.java          | 178 +++++++++++++++++++
 .../jobs/JobCancellationException.java          |  48 +++++
 .../cloudstack/framework/jobs/Outcome.java      |  62 +++++++
 .../framework/jobs/impl/AsyncJobVO.java         |   4 +-
 .../framework/jobs/impl/OutcomeImpl.java        | 111 ++++++++++++
 .../com/cloud/async/AsyncJobManagerImpl.java    |  14 +-
 .../com/cloud/server/ManagementServerImpl.java  |   2 +-
 .../com/cloud/storage/VolumeManagerImpl.java    |   2 +-
 .../src/com/cloud/vm/SystemVmLoadScanner.java   |   2 +-
 .../vm/VmWorkMockVirtualMachineManagerImpl.java |   2 +-
 .../cloud/vm/VmWorkTestWorkJobDispatcher.java   |   2 +-
 utils/src/com/cloud/utils/SerialVersionUID.java |   1 +
 19 files changed, 486 insertions(+), 264 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/api/src/org/apache/cloudstack/api/response/AsyncJobResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/AsyncJobResponse.java b/api/src/org/apache/cloudstack/api/response/AsyncJobResponse.java
index 622c7c0..f5c0c1e 100644
--- a/api/src/org/apache/cloudstack/api/response/AsyncJobResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/AsyncJobResponse.java
@@ -24,11 +24,11 @@ import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseResponse;
 import org.apache.cloudstack.api.EntityReference;
 import org.apache.cloudstack.api.ResponseObject;
-import org.apache.cloudstack.jobs.Job;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.serializer.Param;
 
-@EntityReference(value = Job.class)
+@EntityReference(value = JobInfo.class)
 public class AsyncJobResponse extends BaseResponse {
 
     @SerializedName("accountid") @Param(description="the account that executed the async command")

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/api/src/org/apache/cloudstack/jobs/Job.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/jobs/Job.java b/api/src/org/apache/cloudstack/jobs/Job.java
deleted file mode 100644
index d238da3..0000000
--- a/api/src/org/apache/cloudstack/jobs/Job.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.jobs;
-
-import java.util.Date;
-
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-public interface Job extends Identity, InternalIdentity {
-
-
-
-    String getType();
-
-    String getDispatcher();
-
-    int getPendingSignals();
-
-    long getUserId();
-
-    long getAccountId();
-
-    String getCmd();
-
-    int getCmdVersion();
-
-    String getCmdInfo();
-
-    int getStatus();
-
-    int getProcessStatus();
-
-    int getResultCode();
-
-    String getResult();
-
-    Long getInitMsid();
-
-    Long getExecutingMsid();
-
-    Long getCompleteMsid();
-
-    Date getCreated();
-
-    Date getLastUpdated();
-
-    Date getLastPolled();
-
-    String getInstanceType();
-
-    Long getInstanceId();
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/api/src/org/apache/cloudstack/jobs/JobInfo.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/jobs/JobInfo.java b/api/src/org/apache/cloudstack/jobs/JobInfo.java
new file mode 100644
index 0000000..bce9627
--- /dev/null
+++ b/api/src/org/apache/cloudstack/jobs/JobInfo.java
@@ -0,0 +1,65 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.jobs;
+
+import java.util.Date;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+public interface JobInfo extends Identity, InternalIdentity {
+
+    String getType();
+
+    String getDispatcher();
+
+    int getPendingSignals();
+
+    long getUserId();
+
+    long getAccountId();
+
+    String getCmd();
+
+    int getCmdVersion();
+
+    String getCmdInfo();
+
+    int getStatus();
+
+    int getProcessStatus();
+
+    int getResultCode();
+
+    String getResult();
+
+    Long getInitMsid();
+
+    Long getExecutingMsid();
+
+    Long getCompleteMsid();
+
+    Date getCreated();
+
+    Date getLastUpdated();
+
+    Date getLastPolled();
+
+    String getInstanceType();
+
+    Long getInstanceId();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index 1f2ca57..4fee49e 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -47,6 +47,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
 import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.framework.messagebus.MessageBus;
 import org.apache.cloudstack.framework.messagebus.MessageDispatcher;
@@ -84,7 +85,6 @@ import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.agent.manager.Commands;
 import com.cloud.agent.manager.allocator.HostAllocator;
 import com.cloud.alert.AlertManager;
-import com.cloud.async.AsyncJobExecutionContext;
 import com.cloud.dao.EntityManager;
 import com.cloud.dc.ClusterDetailsDao;
 import com.cloud.dc.ClusterDetailsVO;
@@ -186,11 +186,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     protected AgentManager _agentMgr;
     @Inject
     protected VMInstanceDao _vmDao;
-/*
-    @Inject
-    protected ItWorkDao _workDao;
-*/
-    
     @Inject
     protected NicDao _nicsDao;
     @Inject

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/engine/orchestration/test/com/cloud/vm/VmWorkTestApiJobDispatcher.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/test/com/cloud/vm/VmWorkTestApiJobDispatcher.java b/engine/orchestration/test/com/cloud/vm/VmWorkTestApiJobDispatcher.java
index 926fcbb..766929a 100644
--- a/engine/orchestration/test/com/cloud/vm/VmWorkTestApiJobDispatcher.java
+++ b/engine/orchestration/test/com/cloud/vm/VmWorkTestApiJobDispatcher.java
@@ -24,10 +24,10 @@ import javax.inject.Inject;
 
 import org.apache.cloudstack.framework.jobs.AsyncJob;
 import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.vm.jobs.VmWorkJobVO;
 
-import com.cloud.async.AsyncJobExecutionContext;
 import com.cloud.utils.component.AdapterBase;
 import com.cloud.utils.db.Transaction;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/framework/jobs/src/com/cloud/async/AsyncJobExecutionContext.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/com/cloud/async/AsyncJobExecutionContext.java b/framework/jobs/src/com/cloud/async/AsyncJobExecutionContext.java
deleted file mode 100644
index 0e05a98..0000000
--- a/framework/jobs/src/com/cloud/async/AsyncJobExecutionContext.java
+++ /dev/null
@@ -1,173 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.async;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-import org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDao;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobJoinMapVO;
-import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
-import org.apache.cloudstack.framework.jobs.impl.SyncQueueItem;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.utils.component.ComponentContext;
-
-public class AsyncJobExecutionContext  {
-    private AsyncJob _job;
-	
-	@Inject private AsyncJobManager _jobMgr;
-	@Inject private AsyncJobJoinMapDao _joinMapDao;
-	
-	private static ThreadLocal<AsyncJobExecutionContext> s_currentExectionContext = new ThreadLocal<AsyncJobExecutionContext>();
-
-	public AsyncJobExecutionContext() {
-	}
-	
-    public AsyncJobExecutionContext(AsyncJob job) {
-		_job = job;
-	}
-	
-	public SyncQueueItem getSyncSource() {
-		return _job.getSyncSource();
-	}
-	
-	public void resetSyncSource() {
-		_job.setSyncSource(null);
-	}
-	
-    public AsyncJob getJob() {
-		if(_job == null) {
-			_job = _jobMgr.getPseudoJob();
-		}
-		
-		return _job;
-	}
-	
-    public void setJob(AsyncJob job) {
-		_job = job;
-	}
-	
-    public void completeAsyncJob(int jobStatus, int resultCode, Object resultObject) {
-    	assert(_job != null);
-    	_jobMgr.completeAsyncJob(_job.getId(), jobStatus, resultCode, resultObject);
-    }
-    
-    public void updateAsyncJobStatus(int processStatus, Object resultObject) {
-    	assert(_job != null);
-    	_jobMgr.updateAsyncJobStatus(_job.getId(), processStatus, resultObject);
-    }
-    
-    public void updateAsyncJobAttachment(String instanceType, Long instanceId) {
-    	assert(_job != null);
-    	_jobMgr.updateAsyncJobAttachment(_job.getId(), instanceType, instanceId);
-    }
-	
-    public void logJobJournal(AsyncJob.JournalType journalType, String journalText, String journalObjJson) {
-		assert(_job != null);
-		_jobMgr.logJobJournal(_job.getId(), journalType, journalText, journalObjJson);
-	}
-
-    public void log(Logger logger, String journalText) {
-        _jobMgr.logJobJournal(_job.getId(), AsyncJob.JournalType.SUCCESS, journalText, null);
-        logger.debug(journalText);
-    }
-
-    public void joinJob(long joinJobId) {
-    	assert(_job != null);
-    	_jobMgr.joinJob(_job.getId(), joinJobId);
-    }
-	
-    public void joinJob(long joinJobId, String wakeupHandler, String wakeupDispatcher,
-    		String[] wakeupTopcisOnMessageBus, long wakeupIntervalInMilliSeconds, long timeoutInMilliSeconds) {
-    	assert(_job != null);
-    	_jobMgr.joinJob(_job.getId(), joinJobId, wakeupHandler, wakeupDispatcher, wakeupTopcisOnMessageBus,
-    		wakeupIntervalInMilliSeconds, timeoutInMilliSeconds);
-    }
-    
-    //
-	// check failure exception before we disjoin the worker job
-	// TODO : it is ugly and this will become unnecessary after we switch to full-async mode
-	//
-    public void disjoinJob(long joinedJobId) throws InsufficientCapacityException,
-		ConcurrentOperationException, ResourceUnavailableException {
-    	assert(_job != null);
-    	
-    	AsyncJobJoinMapVO record = _joinMapDao.getJoinRecord(_job.getId(), joinedJobId);
-    	if(record.getJoinStatus() == AsyncJobConstants.STATUS_FAILED && record.getJoinResult() != null) {
-    		Object exception = JobSerializerHelper.fromObjectSerializedString(record.getJoinResult());
-    		if(exception != null && exception instanceof Exception) {
-    			if(exception instanceof InsufficientCapacityException)
-    				throw (InsufficientCapacityException)exception;
-    			else if(exception instanceof ConcurrentOperationException)
-    				throw (ConcurrentOperationException)exception;
-    			else if(exception instanceof ResourceUnavailableException)
-    				throw (ResourceUnavailableException)exception;
-    			else
-    				throw new RuntimeException((Exception)exception);
-    		}
-    	}
-    	
-    	_jobMgr.disjoinJob(_job.getId(), joinedJobId);
-    }
-    
-    public void completeJoin(int joinStatus, String joinResult) {
-    	assert(_job != null);
-    	_jobMgr.completeJoin(_job.getId(), joinStatus, joinResult);
-    }
-    
-    public void completeJobAndJoin(int joinStatus, String joinResult) {
-    	assert(_job != null);
-    	_jobMgr.completeJoin(_job.getId(), joinStatus, joinResult);
-    	_jobMgr.completeAsyncJob(_job.getId(), joinStatus, 0, null);
-    }
-
-	public static AsyncJobExecutionContext getCurrentExecutionContext() {
-		AsyncJobExecutionContext context = s_currentExectionContext.get();
-		if(context == null) {
-			context = new AsyncJobExecutionContext();
-			context = ComponentContext.inject(context);
-			context.getJob();
-			setCurrentExecutionContext(context);
-		}
-		
-		return context;
-	}
-	
-    public static AsyncJobExecutionContext registerPseudoExecutionContext() {
-        AsyncJobExecutionContext context = s_currentExectionContext.get();
-        if (context == null) {
-            context = new AsyncJobExecutionContext();
-            context = ComponentContext.inject(context);
-            context.getJob();
-            setCurrentExecutionContext(context);
-        }
-
-        return context;
-    }
-
-    // This is intended to be package level access for AsyncJobManagerImpl only.
-    static void setCurrentExecutionContext(AsyncJobExecutionContext currentContext) {
-		s_currentExectionContext.set(currentContext);
-	}
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java
index 8f52073..dfb67f8 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java
@@ -19,9 +19,9 @@ package org.apache.cloudstack.framework.jobs;
 import java.util.Date;
 
 import org.apache.cloudstack.framework.jobs.impl.SyncQueueItem;
-import org.apache.cloudstack.jobs.Job;
+import org.apache.cloudstack.jobs.JobInfo;
 
-public interface AsyncJob extends Job {
+public interface AsyncJob extends JobInfo {
 
     public enum JournalType {
         SUCCESS, FAILURE

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
new file mode 100644
index 0000000..3d5c326
--- /dev/null
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
@@ -0,0 +1,178 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.framework.jobs;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDao;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobJoinMapVO;
+import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
+import org.apache.cloudstack.framework.jobs.impl.SyncQueueItem;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.utils.component.ComponentContext;
+
+public class AsyncJobExecutionContext  {
+    private AsyncJob _job;
+	
+    static private AsyncJobManager _jobMgr;
+    static private AsyncJobJoinMapDao _joinMapDao;
+
+    public static void init(AsyncJobManager jobMgr, AsyncJobJoinMapDao joinMapDao) {
+        _jobMgr = jobMgr;
+        _joinMapDao = joinMapDao;
+    }
+	
+	private static ThreadLocal<AsyncJobExecutionContext> s_currentExectionContext = new ThreadLocal<AsyncJobExecutionContext>();
+
+	public AsyncJobExecutionContext() {
+	}
+	
+    public AsyncJobExecutionContext(AsyncJob job) {
+		_job = job;
+	}
+	
+	public SyncQueueItem getSyncSource() {
+		return _job.getSyncSource();
+	}
+	
+	public void resetSyncSource() {
+		_job.setSyncSource(null);
+	}
+	
+    public AsyncJob getJob() {
+		if(_job == null) {
+			_job = _jobMgr.getPseudoJob();
+		}
+		
+		return _job;
+	}
+	
+    public void setJob(AsyncJob job) {
+		_job = job;
+	}
+	
+    public void completeAsyncJob(int jobStatus, int resultCode, Object resultObject) {
+    	assert(_job != null);
+    	_jobMgr.completeAsyncJob(_job.getId(), jobStatus, resultCode, resultObject);
+    }
+    
+    public void updateAsyncJobStatus(int processStatus, Object resultObject) {
+    	assert(_job != null);
+    	_jobMgr.updateAsyncJobStatus(_job.getId(), processStatus, resultObject);
+    }
+    
+    public void updateAsyncJobAttachment(String instanceType, Long instanceId) {
+    	assert(_job != null);
+    	_jobMgr.updateAsyncJobAttachment(_job.getId(), instanceType, instanceId);
+    }
+	
+    public void logJobJournal(AsyncJob.JournalType journalType, String journalText, String journalObjJson) {
+		assert(_job != null);
+		_jobMgr.logJobJournal(_job.getId(), journalType, journalText, journalObjJson);
+	}
+
+    public void log(Logger logger, String journalText) {
+        _jobMgr.logJobJournal(_job.getId(), AsyncJob.JournalType.SUCCESS, journalText, null);
+        logger.debug(journalText);
+    }
+
+    public void joinJob(long joinJobId) {
+    	assert(_job != null);
+    	_jobMgr.joinJob(_job.getId(), joinJobId);
+    }
+	
+    public void joinJob(long joinJobId, String wakeupHandler, String wakeupDispatcher,
+    		String[] wakeupTopcisOnMessageBus, long wakeupIntervalInMilliSeconds, long timeoutInMilliSeconds) {
+    	assert(_job != null);
+    	_jobMgr.joinJob(_job.getId(), joinJobId, wakeupHandler, wakeupDispatcher, wakeupTopcisOnMessageBus,
+    		wakeupIntervalInMilliSeconds, timeoutInMilliSeconds);
+    }
+    
+    //
+	// check failure exception before we disjoin the worker job
+	// TODO : it is ugly and this will become unnecessary after we switch to full-async mode
+	//
+    public void disjoinJob(long joinedJobId) throws InsufficientCapacityException,
+		ConcurrentOperationException, ResourceUnavailableException {
+    	assert(_job != null);
+    	
+    	AsyncJobJoinMapVO record = _joinMapDao.getJoinRecord(_job.getId(), joinedJobId);
+    	if(record.getJoinStatus() == AsyncJobConstants.STATUS_FAILED && record.getJoinResult() != null) {
+    		Object exception = JobSerializerHelper.fromObjectSerializedString(record.getJoinResult());
+    		if(exception != null && exception instanceof Exception) {
+    			if(exception instanceof InsufficientCapacityException)
+    				throw (InsufficientCapacityException)exception;
+    			else if(exception instanceof ConcurrentOperationException)
+    				throw (ConcurrentOperationException)exception;
+    			else if(exception instanceof ResourceUnavailableException)
+    				throw (ResourceUnavailableException)exception;
+    			else
+    				throw new RuntimeException((Exception)exception);
+    		}
+    	}
+    	
+    	_jobMgr.disjoinJob(_job.getId(), joinedJobId);
+    }
+    
+    public void completeJoin(int joinStatus, String joinResult) {
+    	assert(_job != null);
+    	_jobMgr.completeJoin(_job.getId(), joinStatus, joinResult);
+    }
+    
+    public void completeJobAndJoin(int joinStatus, String joinResult) {
+    	assert(_job != null);
+    	_jobMgr.completeJoin(_job.getId(), joinStatus, joinResult);
+    	_jobMgr.completeAsyncJob(_job.getId(), joinStatus, 0, null);
+    }
+
+	public static AsyncJobExecutionContext getCurrentExecutionContext() {
+		AsyncJobExecutionContext context = s_currentExectionContext.get();
+		if(context == null) {
+			context = new AsyncJobExecutionContext();
+			context = ComponentContext.inject(context);
+			context.getJob();
+			setCurrentExecutionContext(context);
+		}
+		
+		return context;
+	}
+	
+    public static AsyncJobExecutionContext registerPseudoExecutionContext() {
+        AsyncJobExecutionContext context = s_currentExectionContext.get();
+        if (context == null) {
+            context = new AsyncJobExecutionContext();
+            context.getJob();
+            setCurrentExecutionContext(context);
+        }
+
+        return context;
+    }
+
+    public static AsyncJobExecutionContext unregister() {
+        AsyncJobExecutionContext context = s_currentExectionContext.get();
+        setCurrentExecutionContext(null);
+        return context;
+    }
+
+    // This is intended to be package level access for AsyncJobManagerImpl only.
+    public static void setCurrentExecutionContext(AsyncJobExecutionContext currentContext) {
+		s_currentExectionContext.set(currentContext);
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/framework/jobs/src/org/apache/cloudstack/framework/jobs/JobCancellationException.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/JobCancellationException.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/JobCancellationException.java
new file mode 100644
index 0000000..a433b2b
--- /dev/null
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/JobCancellationException.java
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.framework.jobs;
+
+import com.cloud.utils.SerialVersionUID;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+/**
+ * This exception is fired when the job has been cancelled
+ *
+ */
+public class JobCancellationException extends CloudRuntimeException {
+    
+    private static final long serialVersionUID = SerialVersionUID.AffinityConflictException;
+
+    public enum Reason {
+        RequestedByUser,
+        RequestedByCaller,
+        TimedOut;
+    }
+
+
+    Reason reason;
+
+    public JobCancellationException(Reason reason) {
+        super("The job was cancelled due to " + reason.toString());
+        this.reason = reason;
+    }
+
+    public Reason getReason() {
+        return reason;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/framework/jobs/src/org/apache/cloudstack/framework/jobs/Outcome.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/Outcome.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/Outcome.java
new file mode 100644
index 0000000..b400b71
--- /dev/null
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/Outcome.java
@@ -0,0 +1,62 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.framework.jobs;
+
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Outcome is returned by clients of jobs framework as a way to wait for the
+ * outcome of a job.  It fully complies with how Future interface is designed.
+ * In addition, it allows the callee to file a task to be scheduled when the
+ * job completes.
+ * 
+ * Note that the callee should schedule a job when using the Task interface.
+ * It shouldn't try to complete the job in the schedule code as that will take
+ * up threads in the jobs framework.
+ * 
+ * For the client of the jobs framework, you can either use the OutcomeImpl
+ * class to implement this interface or you can add to this interface to
+ * allow for your specific exceptions to be thrown.
+ *
+ * @param <T> Object returned to the callee when the job completes
+ */
+public interface Outcome<T> extends Future<T> {
+    AsyncJob getJob();
+
+    /**
+     * In addition to the normal Future methods, Outcome allows the ability
+     * to register a schedule task to be performed when the job is completed.
+     * 
+     * @param listener
+     */
+    void execute(Task<T> task);
+
+    void execute(Task<T> task, long wait, TimeUnit unit);
+
+    /**
+     * Listener is used by Outcome to schedule a task to run when a job
+     * completes.
+     *
+     * @param <T> T result returned
+     */
+    public interface Task<T> extends Runnable {
+        void schedule(AsyncJobExecutionContext context, T result);
+
+        void scheduleOnError(AsyncJobExecutionContext context, Throwable e);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
index 13b0d12..0e103b9 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
@@ -34,7 +34,7 @@ import javax.persistence.TemporalType;
 import javax.persistence.Transient;
 
 import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.jobs.Job;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.utils.UuidUtils;
 import com.cloud.utils.db.GenericDao;
@@ -43,7 +43,7 @@ import com.cloud.utils.db.GenericDao;
 @Table(name="async_job")
 @Inheritance(strategy=InheritanceType.JOINED)
 @DiscriminatorColumn(name="job_type", discriminatorType=DiscriminatorType.STRING, length=32)
-public class AsyncJobVO implements AsyncJob, Job {
+public class AsyncJobVO implements AsyncJob, JobInfo {
 	
 	@Id
     @GeneratedValue(strategy=GenerationType.IDENTITY)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
new file mode 100644
index 0000000..f1e4f4b
--- /dev/null
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
@@ -0,0 +1,111 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.framework.jobs.impl;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.framework.jobs.Outcome;
+
+import com.cloud.utils.Predicate;
+
+public class OutcomeImpl<T> implements Outcome<T> {
+    protected AsyncJob _job;
+    protected Class<T> _clazz;
+    protected String[] _topics;
+    protected Predicate _predicate;
+    protected long _checkIntervalInMs;
+
+    protected T _result;
+
+    private static AsyncJobManager s_jobMgr;
+
+    public static void init(AsyncJobManager jobMgr) {
+        s_jobMgr = jobMgr;
+    }
+
+    public OutcomeImpl(Class<T> clazz, AsyncJob job, long checkIntervalInMs, Predicate predicate, String... topics) {
+        _clazz = clazz;
+        _job = job;
+        _topics = topics;
+        _predicate = predicate;
+        _checkIntervalInMs = checkIntervalInMs;
+    }
+
+    @Override
+    public AsyncJob getJob() {
+        return _job;
+    }
+
+    @Override
+    public boolean cancel(boolean mayInterruptIfRunning) {
+        return false;
+    }
+
+    @Override
+    public T get() throws InterruptedException, ExecutionException {
+        s_jobMgr.waitAndCheck(_topics, _checkIntervalInMs, -1, _predicate);
+        return retrieve();
+    }
+
+    @Override
+    public T get(long timeToWait, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+        s_jobMgr.waitAndCheck(_topics, _checkIntervalInMs, unit.toMillis(timeToWait), _predicate);
+        return retrieve();
+    }
+
+    /**
+     * This method can be overridden by children classes to retrieve the
+     * actual object.
+     */
+    protected T retrieve() {
+        return _result;
+    }
+
+    protected Outcome<T> set(T result) {
+        _result = result;
+        return this;
+    }
+
+    @Override
+    public boolean isCancelled() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isDone() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void execute(Task<T> task) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void execute(Task<T> task, long wait, TimeUnit unit) {
+        // TODO Auto-generated method stub
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/server/src/com/cloud/async/AsyncJobManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/async/AsyncJobManagerImpl.java b/server/src/com/cloud/async/AsyncJobManagerImpl.java
index 084585f..332587a 100644
--- a/server/src/com/cloud/async/AsyncJobManagerImpl.java
+++ b/server/src/com/cloud/async/AsyncJobManagerImpl.java
@@ -42,6 +42,7 @@ import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
 import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.framework.jobs.dao.AsyncJobDao;
 import org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDao;
@@ -51,6 +52,7 @@ import org.apache.cloudstack.framework.jobs.impl.AsyncJobJournalVO;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobMBeanImpl;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobMonitor;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.framework.jobs.impl.OutcomeImpl;
 import org.apache.cloudstack.framework.jobs.impl.SyncQueueItem;
 import org.apache.cloudstack.framework.jobs.impl.SyncQueueItemVO;
 import org.apache.cloudstack.framework.jobs.impl.SyncQueueManager;
@@ -537,8 +539,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                     }
                     
                     _jobMonitor.registerActiveTask(runNumber, job.getId());
-                    AsyncJobExecutionContext.setCurrentExecutionContext(
-                    	(AsyncJobExecutionContext)ComponentContext.inject(new AsyncJobExecutionContext(job))
+                    AsyncJobExecutionContext.setCurrentExecutionContext((AsyncJobExecutionContext)ComponentContext.inject(new AsyncJobExecutionContext(job))
                     );
                     
                     // execute the job
@@ -847,12 +848,10 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        int expireMinutes = NumbersUtil.parseInt(
-                _configDao.getValue(Config.JobExpireMinutes.key()), 24*60);
+        int expireMinutes = NumbersUtil.parseInt(_configDao.getValue(Config.JobExpireMinutes.key()), 24 * 60);
         _jobExpireSeconds = (long)expireMinutes*60;
 
-        _jobCancelThresholdSeconds = NumbersUtil.parseInt(
-                _configDao.getValue(Config.JobCancelThresholdMinutes.key()), 60);
+        _jobCancelThresholdSeconds = NumbersUtil.parseInt(_configDao.getValue(Config.JobCancelThresholdMinutes.key()), 60);
         _jobCancelThresholdSeconds *= 60;
 
         try {
@@ -870,6 +869,9 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
             throw new ConfigurationException("Unable to load db.properties to configure AsyncJobManagerImpl");
         }
 
+        AsyncJobExecutionContext.init(this, _joinMapDao);
+        OutcomeImpl.init(this);
+
         return true;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 4ad60ea..6de8840 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -425,6 +425,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
 import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
@@ -442,7 +443,6 @@ import com.cloud.alert.AlertManager;
 import com.cloud.alert.AlertVO;
 import com.cloud.alert.dao.AlertDao;
 import com.cloud.api.ApiDBUtils;
-import com.cloud.async.AsyncJobExecutionContext;
 import com.cloud.capacity.Capacity;
 import com.cloud.capacity.CapacityVO;
 import com.cloud.capacity.dao.CapacityDao;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/server/src/com/cloud/storage/VolumeManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java
index 9d3f4df..2eeb206 100644
--- a/server/src/com/cloud/storage/VolumeManagerImpl.java
+++ b/server/src/com/cloud/storage/VolumeManagerImpl.java
@@ -67,6 +67,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
 import org.apache.cloudstack.framework.async.AsyncCallFuture;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
@@ -79,7 +80,6 @@ import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.agent.api.to.VolumeTO;
 import com.cloud.alert.AlertManager;
 import com.cloud.api.ApiDBUtils;
-import com.cloud.async.AsyncJobExecutionContext;
 import com.cloud.capacity.CapacityManager;
 import com.cloud.capacity.dao.CapacityDao;
 import com.cloud.configuration.Config;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/server/src/com/cloud/vm/SystemVmLoadScanner.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/SystemVmLoadScanner.java b/server/src/com/cloud/vm/SystemVmLoadScanner.java
index 3d7953f..704129d 100644
--- a/server/src/com/cloud/vm/SystemVmLoadScanner.java
+++ b/server/src/com/cloud/vm/SystemVmLoadScanner.java
@@ -23,8 +23,8 @@ import java.util.concurrent.TimeUnit;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 
-import com.cloud.async.AsyncJobExecutionContext;
 import com.cloud.utils.Pair;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.GlobalLock;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
index 642dfc1..2c1249e 100644
--- a/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
+++ b/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
@@ -26,11 +26,11 @@ import javax.naming.ConfigurationException;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 import org.apache.cloudstack.framework.messagebus.MessageBus;
 
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.async.AsyncJobExecutionContext;
 import com.cloud.deploy.DeployDestination;
 import com.cloud.deploy.DeploymentPlan;
 import com.cloud.exception.AgentUnavailableException;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java b/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java
index 288b793..72210b4 100644
--- a/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java
+++ b/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java
@@ -5,8 +5,8 @@ import org.apache.log4j.Logger;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
 import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 
-import com.cloud.async.AsyncJobExecutionContext;
 import com.cloud.utils.component.AdapterBase;
 
 public class VmWorkTestWorkJobDispatcher extends AdapterBase implements AsyncJobDispatcher {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b96665b/utils/src/com/cloud/utils/SerialVersionUID.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/SerialVersionUID.java b/utils/src/com/cloud/utils/SerialVersionUID.java
index 856d563..90fafdd 100755
--- a/utils/src/com/cloud/utils/SerialVersionUID.java
+++ b/utils/src/com/cloud/utils/SerialVersionUID.java
@@ -62,4 +62,5 @@ public interface SerialVersionUID {
     public static final long CallFailedException = Base | 0x28;
     public static final long UnableDeleteHostException = Base | 0x29;
     public static final long AffinityConflictException = Base | 0x2a;
+    public static final long JobCancellationException = Base | 0x2b;
 }


[5/9] git commit: updated refs/heads/vmsync to 309f8da

Posted by ah...@apache.org.
Removed a bunch of useless classes.  Move configuration into utils package


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/3a074f31
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/3a074f31
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/3a074f31

Branch: refs/heads/vmsync
Commit: 3a074f31aefe266d9dd7b077b0fc1fae913d9ac6
Parents: aad2bc7
Author: Alex Huang <al...@gmail.com>
Authored: Sat Jun 15 05:52:41 2013 -0700
Committer: Alex Huang <al...@gmail.com>
Committed: Mon Jun 17 17:04:04 2013 -0700

----------------------------------------------------------------------
 .../com/cloud/configuration/Configuration.java  |  33 ----
 .../configuration/ConfigurationService.java     |   1 +
 api/src/com/cloud/dao/EntityManager.java        | 102 ----------
 api/src/com/cloud/event/EventTypes.java         |   3 +-
 api/src/com/cloud/server/ManagementService.java |   2 +-
 api/src/org/apache/cloudstack/api/BaseCmd.java  |   2 +-
 .../cloudstack/api/ResponseGenerator.java       |   2 +-
 .../api/command/admin/config/ListCfgsByCmd.java |   2 +-
 .../api/command/admin/config/UpdateCfgCmd.java  |   2 +-
 .../org/apache/cloudstack/config/ConfigKey.java |  98 ----------
 .../apache/cloudstack/context/CallContext.java  |   2 +-
 .../api/command/test/ListCfgCmdTest.java        |   3 +-
 .../api/command/test/UpdateCfgCmdTest.java      |   3 +-
 .../com/cloud/vm/ReservationContextImpl.java    |   2 +-
 .../apache/cloudstack/config/ConfigDepot.java   |  25 ---
 .../apache/cloudstack/config/ConfigValue.java   |  72 -------
 .../com/cloud/vm/VirtualMachineManagerImpl.java |   2 +-
 .../src/com/cloud/vm/VmWorkJobDispatcher.java   |   2 +-
 .../engine/vm/VMEntityManagerImpl.java          |   2 +-
 .../cloud/vm/VirtualMachineManagerImplTest.java |   2 +-
 .../cloud/configuration/ConfigurationVO.java    |   2 +
 .../com/cloud/vm/VirtualMachineProfileImpl.java |   2 +-
 server/src/com/cloud/api/ApiDispatcher.java     |   2 +-
 server/src/com/cloud/api/ApiResponseHelper.java |   4 +-
 server/src/com/cloud/api/ApiServer.java         |   2 +-
 .../configuration/ConfigurationManagerImpl.java |   6 +-
 .../consoleproxy/ConsoleProxyManagerImpl.java   |   2 +-
 server/src/com/cloud/dao/EntityManagerImpl.java |   1 +
 .../VirtualNetworkApplianceManagerImpl.java     |   2 +-
 .../resourcelimit/ResourceLimitManagerImpl.java |   2 +-
 .../com/cloud/server/ManagementServerImpl.java  |   2 +-
 .../com/cloud/servlet/ConsoleProxyServlet.java  |   2 +-
 .../cloud/servlet/RegisterCompleteServlet.java  |   3 +-
 .../secondary/SecondaryStorageManagerImpl.java  |   2 +-
 .../cloud/async/AsyncJobTestConfiguration.java  |   2 +-
 .../com/cloud/vm/VmWorkTestConfiguration.java   |   2 +-
 .../cloud/vpc/MockConfigurationManagerImpl.java |   2 +-
 utils/src/com/cloud/utils/db/Condition.java     | 100 ----------
 utils/src/com/cloud/utils/db/EntityManager.java |  99 ++++++++++
 utils/src/com/cloud/utils/db/FirstWhere.java    |  29 ---
 .../com/cloud/utils/db/JoinQueryBuilder.java    |  31 ---
 utils/src/com/cloud/utils/db/NextWhere.java     |  27 ---
 utils/src/com/cloud/utils/db/On.java            |  21 --
 utils/src/com/cloud/utils/db/QueryBuilder.java  | 194 -------------------
 utils/src/com/cloud/utils/db/Select.java        |  52 -----
 .../com/cloud/utils/db/SelectQueryBuilder.java  |  28 ---
 .../com/cloud/utils/db/SimpleQueryBuilder.java  |  47 -----
 utils/src/com/cloud/utils/db/Where.java         |  81 --------
 .../apache/cloudstack/config/ConfigDepot.java   |  25 +++
 .../org/apache/cloudstack/config/ConfigKey.java |  98 ++++++++++
 .../apache/cloudstack/config/ConfigValue.java   |  75 +++++++
 .../apache/cloudstack/config/Configuration.java |  33 ++++
 52 files changed, 372 insertions(+), 970 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/src/com/cloud/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/configuration/Configuration.java b/api/src/com/cloud/configuration/Configuration.java
deleted file mode 100644
index f148c0b..0000000
--- a/api/src/com/cloud/configuration/Configuration.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.configuration;
-
-public interface Configuration {
-
-    public String getCategory();
-
-    public String getInstance();
-
-    public String getComponent();
-
-    public String getName();
-
-    public String getValue();
-
-    public String getDescription();
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/src/com/cloud/configuration/ConfigurationService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/configuration/ConfigurationService.java b/api/src/com/cloud/configuration/ConfigurationService.java
index 63ad7fb..881bad0 100644
--- a/api/src/com/cloud/configuration/ConfigurationService.java
+++ b/api/src/com/cloud/configuration/ConfigurationService.java
@@ -45,6 +45,7 @@ import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
 import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
 import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
 import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
+import org.apache.cloudstack.config.Configuration;
 
 import com.cloud.dc.DataCenter;
 import com.cloud.dc.Pod;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/src/com/cloud/dao/EntityManager.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/dao/EntityManager.java b/api/src/com/cloud/dao/EntityManager.java
deleted file mode 100644
index 8e6a438..0000000
--- a/api/src/com/cloud/dao/EntityManager.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.dao;
-
-import java.io.Serializable;
-import java.util.List;
-
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-/**
- * Generic Entity Manager to retrieve database objects.
- *
- */
-public interface EntityManager {
-    /**
-     * Finds an entity by its id.
-     * @param <T> class of the entity you're trying to find.
-     * @param <K> class of the id that the entity uses.
-     * @param entityType Type of the entity.
-     * @param id id value
-     * @return T if found; null if not.
-     */
-    public <T, K extends Serializable> T findById(Class<T> entityType, K id);
-
-    /**
-     * Finds an entity by its id including removed.
-     * @param <T> class of the entity you're trying to find.
-     * @param <K> class of the id that the entity uses.
-     * @param entityType Type of the entity.
-     * @param id id value
-     * @return T if found; null if not.
-     */
-    public <T, K extends Serializable> T findByIdIncludingRemoved(Class<T> entityType, K id);
-    
-    /**
-     * Finds a unique entity by uuid string
-     * @param <T> entity class
-     * @param entityType type of entity you're looking for.
-     * @param uuid the unique id
-     * @return T if found, null if not.
-     */
-    public <T> T findByUuid(Class<T> entityType, String uuid);
-
-    /**
-     * Finds a unique entity by uuid string
-     * @param <T> entity class
-     * @param entityType type of entity you're looking for.
-     * @param uuid the unique id
-     * @return T if found, null if not.
-     */
-    public <T> T findByUuidIncludingRemoved(Class<T> entityType, String uuid);
-
-    /**
-     * Finds an entity by external id which is always String
-     * @param <T> entity class
-     * @param entityType type of entity you're looking for.
-     * @param xid external id
-     * @return T if found, null if not.
-     */
-    public <T> T findByXId(Class<T> entityType, String xid);
-
-    /**
-     * Lists all entities.  Use this method at your own risk.
-     * @param <T> entity class
-     * @param entityType type of entity you're looking for.
-     * @return List<T>
-     */
-    public <T> List<? extends T> list(Class<T> entityType);
-
-    /**
-     * Persists the entity.
-     * @param <T> entity class
-     * @param t entity
-     * @return persisted entity.  Only use this after persisting.
-     */
-    public <T> T persist(T t);
-
-    public <T> SearchBuilder<T> createSearchBuilder(Class<T> entityType);
-
-    public <T, K> GenericSearchBuilder<T, K> createGenericSearchBuilder(Class<T> entityType, Class<K> resultType);
-
-    public <T, K> List<K> search(Class<T> entityType, SearchCriteria<K> sc);
-
-    public <T, K extends Serializable> void remove(Class<T> entityType, K id);
-}
-

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/src/com/cloud/event/EventTypes.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index ed4ba12..8327a16 100755
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -19,7 +19,8 @@ package com.cloud.event;
 import java.util.HashMap;
 import java.util.Map;
 
-import com.cloud.configuration.Configuration;
+import org.apache.cloudstack.config.Configuration;
+
 import com.cloud.dc.DataCenter;
 import com.cloud.dc.Pod;
 import com.cloud.dc.StorageNetworkIpRange;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/src/com/cloud/server/ManagementService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java
index 24d33d5..ca8a689 100755
--- a/api/src/com/cloud/server/ManagementService.java
+++ b/api/src/com/cloud/server/ManagementService.java
@@ -54,10 +54,10 @@ import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd;
 import org.apache.cloudstack.api.command.user.vm.GetVMPasswordCmd;
 import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd;
 import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
+import org.apache.cloudstack.config.Configuration;
 
 import com.cloud.alert.Alert;
 import com.cloud.capacity.Capacity;
-import com.cloud.configuration.Configuration;
 import com.cloud.dc.Pod;
 import com.cloud.dc.Vlan;
 import com.cloud.domain.Domain;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/src/org/apache/cloudstack/api/BaseCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java
index f0e4f8c..4019db0 100644
--- a/api/src/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseCmd.java
@@ -36,7 +36,6 @@ import org.apache.cloudstack.query.QueryService;
 import org.apache.cloudstack.usage.UsageService;
 
 import com.cloud.configuration.ConfigurationService;
-import com.cloud.dao.EntityManager;
 import com.cloud.domain.Domain;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
@@ -75,6 +74,7 @@ import com.cloud.user.Account;
 import com.cloud.user.AccountService;
 import com.cloud.user.DomainService;
 import com.cloud.user.ResourceLimitService;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.vm.UserVmService;
 import com.cloud.vm.snapshot.VMSnapshotService;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/src/org/apache/cloudstack/api/ResponseGenerator.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
index 4a0eb02..386b16c 100644
--- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java
+++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
@@ -110,6 +110,7 @@ import org.apache.cloudstack.api.response.VpcOfferingResponse;
 import org.apache.cloudstack.api.response.VpcResponse;
 import org.apache.cloudstack.api.response.VpnUsersResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.config.Configuration;
 import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
 import org.apache.cloudstack.region.PortableIp;
 import org.apache.cloudstack.region.PortableIpRange;
@@ -117,7 +118,6 @@ import org.apache.cloudstack.region.Region;
 import org.apache.cloudstack.usage.Usage;
 
 import com.cloud.capacity.Capacity;
-import com.cloud.configuration.Configuration;
 import com.cloud.configuration.ResourceCount;
 import com.cloud.configuration.ResourceLimit;
 import com.cloud.dc.DataCenter;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/src/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java b/api/src/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
index 5a3d22f..9454419 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
@@ -31,8 +31,8 @@ import org.apache.cloudstack.api.response.ConfigurationResponse;
 import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.cloudstack.api.response.StoragePoolResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.config.Configuration;
 
-import com.cloud.configuration.Configuration;
 import com.cloud.utils.Pair;
 
 @APICommand(name = "listConfigurations", description = "Lists all configurations.", responseObject = ConfigurationResponse.class)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/src/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java b/api/src/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
index 2aaaa18..1050721 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
@@ -29,8 +29,8 @@ import org.apache.cloudstack.api.response.ClusterResponse;
 import org.apache.cloudstack.api.response.ConfigurationResponse;
 import org.apache.cloudstack.api.response.StoragePoolResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.config.Configuration;
 
-import com.cloud.configuration.Configuration;
 import com.cloud.user.Account;
 
 @APICommand(name = "updateConfiguration", description="Updates a configuration.", responseObject=ConfigurationResponse.class)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/src/org/apache/cloudstack/config/ConfigKey.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/config/ConfigKey.java b/api/src/org/apache/cloudstack/config/ConfigKey.java
deleted file mode 100644
index 9e42831..0000000
--- a/api/src/org/apache/cloudstack/config/ConfigKey.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.config;
-
-/**
- * ConfigKey supplants the original Config.java.  It is just a class
- * declaration where others can declare their config variables.
- * 
- * TODO: This class should be moved to a framework project where the gathering
- *       of these configuration keys should be done by a config server.  I
- *       don't have time yet to do this.  Ask me about it if you want to work
- *       in this area.  Right now, we'll just work with the actual names.
- */
-public class ConfigKey<T> {
-    
-    private final String _category;
-
-    public String category() {
-        return _category;
-    }
-
-    public Class<?> component() {
-        return _componentClass;
-    }
-
-    public Class<T> type() {
-        return _type;
-    }
-
-    public String key() {
-        return _name;
-    }
-
-    public String defaultValue() {
-        return _defaultValue;
-    }
-
-    public String description() {
-        return _description;
-    }
-
-    public String range() {
-        return _range;
-    }
-
-    public String scope() {
-        return _scope;
-    }
-
-    public boolean isDynamic() {
-        return _isDynamic;
-    }
-
-    @Override
-    public String toString() {
-        return _name;
-    }
-
-    private final Class<?> _componentClass;
-    private final Class<T> _type;
-    private final String _name;
-    private final String _defaultValue;
-    private final String _description;
-    private final String _range;
-    private final String _scope; // Parameter can be at different levels (Zone/cluster/pool/account), by default every parameter is at global
-    private final boolean _isDynamic;
-
-    public ConfigKey(Class<T> type, String name, String category, Class<?> componentClass, String defaultValue, String description, boolean isDynamic, String range,
-            String scope) {
-        _category = category;
-        _componentClass = componentClass;
-        _type = type;
-        _name = name;
-        _defaultValue = defaultValue;
-        _description = description;
-        _range = range;
-        _scope = scope;
-        _isDynamic = isDynamic;
-    }
-
-    public ConfigKey(Class<T> type, String name, String category, Class<?> componentClass, String defaultValue, String description, boolean isDynamic, String range) {
-        this(type, name, category, componentClass, defaultValue, description, isDynamic, range, null);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/src/org/apache/cloudstack/context/CallContext.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/context/CallContext.java b/api/src/org/apache/cloudstack/context/CallContext.java
index c4271f5..303a3a9 100644
--- a/api/src/org/apache/cloudstack/context/CallContext.java
+++ b/api/src/org/apache/cloudstack/context/CallContext.java
@@ -23,11 +23,11 @@ import java.util.UUID;
 import org.apache.log4j.Logger;
 import org.apache.log4j.NDC;
 
-import com.cloud.dao.EntityManager;
 import com.cloud.exception.CloudAuthenticationException;
 import com.cloud.user.Account;
 import com.cloud.user.User;
 import com.cloud.utils.UuidUtils;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.exception.CloudRuntimeException;
 
 /**

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/test/org/apache/cloudstack/api/command/test/ListCfgCmdTest.java
----------------------------------------------------------------------
diff --git a/api/test/org/apache/cloudstack/api/command/test/ListCfgCmdTest.java b/api/test/org/apache/cloudstack/api/command/test/ListCfgCmdTest.java
index 7c05eaf..df9d62b 100644
--- a/api/test/org/apache/cloudstack/api/command/test/ListCfgCmdTest.java
+++ b/api/test/org/apache/cloudstack/api/command/test/ListCfgCmdTest.java
@@ -16,7 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.test;
 
-import com.cloud.configuration.Configuration;
 import com.cloud.configuration.ConfigurationService;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.resource.ResourceService;
@@ -29,6 +28,8 @@ import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd;
 import org.apache.cloudstack.api.response.ConfigurationResponse;
 import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.config.Configuration;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/api/test/org/apache/cloudstack/api/command/test/UpdateCfgCmdTest.java
----------------------------------------------------------------------
diff --git a/api/test/org/apache/cloudstack/api/command/test/UpdateCfgCmdTest.java b/api/test/org/apache/cloudstack/api/command/test/UpdateCfgCmdTest.java
index 27000cf..0841abd 100644
--- a/api/test/org/apache/cloudstack/api/command/test/UpdateCfgCmdTest.java
+++ b/api/test/org/apache/cloudstack/api/command/test/UpdateCfgCmdTest.java
@@ -16,7 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.test;
 
-import com.cloud.configuration.Configuration;
 import com.cloud.configuration.ConfigurationService;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.resource.ResourceService;
@@ -26,6 +25,8 @@ import org.apache.cloudstack.api.ResponseGenerator;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
 import org.apache.cloudstack.api.response.ConfigurationResponse;
+import org.apache.cloudstack.config.Configuration;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/engine/components-api/src/com/cloud/vm/ReservationContextImpl.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/com/cloud/vm/ReservationContextImpl.java b/engine/components-api/src/com/cloud/vm/ReservationContextImpl.java
index cab93b4..f988d66 100644
--- a/engine/components-api/src/com/cloud/vm/ReservationContextImpl.java
+++ b/engine/components-api/src/com/cloud/vm/ReservationContextImpl.java
@@ -16,12 +16,12 @@
 // under the License.
 package com.cloud.vm;
 
-import com.cloud.dao.EntityManager;
 import com.cloud.domain.Domain;
 import com.cloud.domain.DomainVO;
 import com.cloud.user.Account;
 import com.cloud.user.User;
 import com.cloud.utils.Journal;
+import com.cloud.utils.db.EntityManager;
 
 public class ReservationContextImpl implements ReservationContext {
     User _caller;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/engine/components-api/src/org/apache/cloudstack/config/ConfigDepot.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/org/apache/cloudstack/config/ConfigDepot.java b/engine/components-api/src/org/apache/cloudstack/config/ConfigDepot.java
deleted file mode 100644
index 640753c..0000000
--- a/engine/components-api/src/org/apache/cloudstack/config/ConfigDepot.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.config;
-
-/**
- * ConfigRepo is a repository of configurations.
- *
- */
-public interface ConfigDepot {
-    <T> ConfigValue<T> get(ConfigKey<T> key);
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/engine/components-api/src/org/apache/cloudstack/config/ConfigValue.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/org/apache/cloudstack/config/ConfigValue.java b/engine/components-api/src/org/apache/cloudstack/config/ConfigValue.java
deleted file mode 100644
index 12a3156..0000000
--- a/engine/components-api/src/org/apache/cloudstack/config/ConfigValue.java
+++ /dev/null
@@ -1,72 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.config;
-
-import com.cloud.configuration.ConfigurationVO;
-import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-/**
- *  This is a match set to ConfigKey.
- *
- * TODO: When we create a framework project for configuration, this should be
- * moved there.
- */
-public class ConfigValue<T> {
-
-    ConfigKey<T> _config;
-    ConfigurationDao _dao;
-    Number _multiplier;
-
-    public ConfigValue(ConfigurationDao dao, ConfigKey<T> config) {
-        _dao = dao;
-        _config = config;
-        _multiplier = 1;
-    }
-
-    public ConfigKey<T> getConfigKey() {
-        return _config;
-    }
-
-    public ConfigValue<T> setMultiplier(Number multiplier) {  // Convience method
-        _multiplier = multiplier;
-        return this;
-    }
-
-    @SuppressWarnings("unchecked")
-    public T value() {
-        ConfigurationVO vo = _dao.findByName(_config.key());
-        String value = vo != null ? vo.getValue() : _config.defaultValue();
-        
-        Class<T> type = _config.type();
-        if (type.isAssignableFrom(Boolean.class)) {
-            return (T)Boolean.valueOf(value);
-        } else if (type.isAssignableFrom(Integer.class)) {
-            return (T)new Integer((Integer.parseInt(value) * _multiplier.intValue()));
-        } else if (type.isAssignableFrom(Long.class)) {
-            return (T)new Long(Long.parseLong(value) * _multiplier.longValue());
-        } else if (type.isAssignableFrom(Short.class)) {
-            return (T)new Short(Short.parseShort(value));
-        } else if (type.isAssignableFrom(String.class)) {
-            return (T)value;
-        } else if (type.isAssignableFrom(Float.class)) {
-            return (T)new Float(Float.parseFloat(value) * _multiplier.floatValue());
-        }
-
-        throw new CloudRuntimeException("Unsupported data type for config values: " + type);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index f3e2add..4f308fb 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -85,7 +85,6 @@ import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.agent.manager.Commands;
 import com.cloud.agent.manager.allocator.HostAllocator;
 import com.cloud.alert.AlertManager;
-import com.cloud.dao.EntityManager;
 import com.cloud.dc.ClusterDetailsDao;
 import com.cloud.dc.ClusterDetailsVO;
 import com.cloud.dc.ClusterVO;
@@ -150,6 +149,7 @@ import com.cloud.utils.Ternary;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.GlobalLock;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java b/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
index 5207fc5..3de9c16 100644
--- a/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
+++ b/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
@@ -32,9 +32,9 @@ import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.api.StringMapTypeAdapter;
-import com.cloud.dao.EntityManager;
 import com.cloud.user.dao.AccountDao;
 import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.vm.dao.VMInstanceDao;
 
 public class VmWorkJobDispatcher extends AdapterBase implements AsyncJobDispatcher {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/engine/orchestration/src/org/apache/cloudstack/engine/vm/VMEntityManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/vm/VMEntityManagerImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/vm/VMEntityManagerImpl.java
index c4e2b4c..77a842e 100755
--- a/engine/orchestration/src/org/apache/cloudstack/engine/vm/VMEntityManagerImpl.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/vm/VMEntityManagerImpl.java
@@ -34,7 +34,6 @@ import org.apache.cloudstack.engine.cloud.entity.dao.VMReservationDao;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 
-import com.cloud.dao.EntityManager;
 import com.cloud.dc.DataCenter;
 import com.cloud.deploy.DataCenterDeployment;
 import com.cloud.deploy.DeployDestination;
@@ -60,6 +59,7 @@ import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VolumeDao;
 import com.cloud.user.dao.AccountDao;
 import com.cloud.user.dao.UserDao;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java
index 3035ba5..607c1e2 100644
--- a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java
+++ b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java
@@ -56,7 +56,6 @@ import com.cloud.agent.api.PrepareForMigrationCommand;
 import com.cloud.agent.api.ScaleVmAnswer;
 import com.cloud.agent.api.ScaleVmCommand;
 import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dao.EntityManager;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.dc.dao.HostPodDao;
@@ -91,6 +90,7 @@ import com.cloud.user.UserVO;
 import com.cloud.user.dao.AccountDao;
 import com.cloud.user.dao.UserDao;
 import com.cloud.utils.Pair;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.VirtualMachine.Event;
 import com.cloud.vm.VirtualMachine.PowerState;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/engine/schema/src/com/cloud/configuration/ConfigurationVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/configuration/ConfigurationVO.java b/engine/schema/src/com/cloud/configuration/ConfigurationVO.java
index 6cd87b0..ac499b8 100644
--- a/engine/schema/src/com/cloud/configuration/ConfigurationVO.java
+++ b/engine/schema/src/com/cloud/configuration/ConfigurationVO.java
@@ -21,6 +21,8 @@ import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.Table;
 
+import org.apache.cloudstack.config.Configuration;
+
 import com.cloud.utils.crypt.DBEncryptionUtil;
 
 @Entity

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/engine/schema/src/com/cloud/vm/VirtualMachineProfileImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/vm/VirtualMachineProfileImpl.java b/engine/schema/src/com/cloud/vm/VirtualMachineProfileImpl.java
index 5805c03..9e9e342 100644
--- a/engine/schema/src/com/cloud/vm/VirtualMachineProfileImpl.java
+++ b/engine/schema/src/com/cloud/vm/VirtualMachineProfileImpl.java
@@ -22,7 +22,6 @@ import java.util.List;
 import java.util.Map;
 
 import com.cloud.agent.api.to.VolumeTO;
-import com.cloud.dao.EntityManager;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.offering.ServiceOffering;
 import com.cloud.service.ServiceOfferingVO;
@@ -31,6 +30,7 @@ import com.cloud.template.VirtualMachineTemplate;
 import com.cloud.template.VirtualMachineTemplate.BootloaderType;
 import com.cloud.user.Account;
 import com.cloud.user.AccountVO;
+import com.cloud.utils.db.EntityManager;
 
 /**
  * Implementation of VirtualMachineProfile.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/src/com/cloud/api/ApiDispatcher.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java
index ff709d0..c95ee5f 100755
--- a/server/src/com/cloud/api/ApiDispatcher.java
+++ b/server/src/com/cloud/api/ApiDispatcher.java
@@ -58,12 +58,12 @@ import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 
-import com.cloud.dao.EntityManager;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.utils.DateUtil;
 import com.cloud.utils.ReflectUtil;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.exception.CSExceptionErrorCode;
 import com.cloud.utils.exception.CloudRuntimeException;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index dee5a7e..f989ddb 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -136,6 +136,7 @@ import org.apache.cloudstack.api.response.VpcOfferingResponse;
 import org.apache.cloudstack.api.response.VpcResponse;
 import org.apache.cloudstack.api.response.VpnUsersResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.config.Configuration;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
@@ -170,12 +171,10 @@ import com.cloud.api.query.vo.VolumeJoinVO;
 import com.cloud.capacity.Capacity;
 import com.cloud.capacity.CapacityVO;
 import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
-import com.cloud.configuration.Configuration;
 import com.cloud.configuration.Resource.ResourceOwnerType;
 import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.configuration.ResourceCount;
 import com.cloud.configuration.ResourceLimit;
-import com.cloud.dao.EntityManager;
 import com.cloud.dc.ClusterVO;
 import com.cloud.dc.DataCenter;
 import com.cloud.dc.DataCenterVO;
@@ -284,6 +283,7 @@ import com.cloud.user.UserAccount;
 import com.cloud.uservm.UserVm;
 import com.cloud.utils.Pair;
 import com.cloud.utils.StringUtils;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.net.Ip;
 import com.cloud.utils.net.NetUtils;
 import com.cloud.vm.ConsoleProxyVO;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index be161c6..6d946a7 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -123,7 +123,6 @@ import com.cloud.api.response.ApiResponseSerializer;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.ConfigurationVO;
 import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dao.EntityManager;
 import com.cloud.domain.Domain;
 import com.cloud.domain.DomainVO;
 import com.cloud.event.ActionEventUtils;
@@ -148,6 +147,7 @@ import com.cloud.utils.component.ComponentContext;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.component.PluggableService;
 import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.SearchCriteria;
 import com.cloud.utils.db.Transaction;
 import com.cloud.utils.exception.CloudRuntimeException;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 9401811..c7947c3 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -72,6 +72,7 @@ import org.apache.cloudstack.config.ConfigDepot;
 import org.apache.cloudstack.config.ConfigKey;
 import org.apache.cloudstack.config.ConfigValue;
 import org.apache.cloudstack.config.Configurable;
+import org.apache.cloudstack.config.Configuration;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.region.PortableIp;
 import org.apache.cloudstack.region.PortableIpDao;
@@ -200,6 +201,7 @@ import com.cloud.utils.StringUtils;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.crypt.DBEncryptionUtil;
 import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.Filter;
 import com.cloud.utils.db.GlobalLock;
 import com.cloud.utils.db.SearchCriteria;
@@ -319,6 +321,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
     public ManagementService _mgr;
     @Inject
     DedicatedResourceDao _dedicatedDao;
+    @Inject
+    EntityManager _entityMgr;
 
     @Inject
     List<Configurable> _configurables;
@@ -4636,7 +4640,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
 
     @Override
     public <T> ConfigValue<T> get(ConfigKey<T> config) {
-        return new ConfigValue<T>(_configDao, config);
+        return new ConfigValue<T>(_entityMgr, config);
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index 513a713..8f0c096 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -53,7 +53,6 @@ import com.cloud.cluster.ClusterManager;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.ZoneConfig;
 import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dao.EntityManager;
 import com.cloud.dc.DataCenter;
 import com.cloud.dc.DataCenter.NetworkType;
 import com.cloud.dc.DataCenterVO;
@@ -116,6 +115,7 @@ import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.GlobalLock;
 import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.SearchCriteria2;
 import com.cloud.utils.db.SearchCriteriaService;
 import com.cloud.utils.db.Transaction;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/src/com/cloud/dao/EntityManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/dao/EntityManagerImpl.java b/server/src/com/cloud/dao/EntityManagerImpl.java
index 18302d9..66a494e 100644
--- a/server/src/com/cloud/dao/EntityManagerImpl.java
+++ b/server/src/com/cloud/dao/EntityManagerImpl.java
@@ -28,6 +28,7 @@ import net.sf.ehcache.Cache;
 import org.springframework.stereotype.Component;
 
 import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.GenericDao;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.GenericSearchBuilder;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index e8090c8..a1bb1ff 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -99,7 +99,6 @@ import com.cloud.configuration.Config;
 import com.cloud.configuration.ConfigurationManager;
 import com.cloud.configuration.ZoneConfig;
 import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dao.EntityManager;
 import com.cloud.dc.ClusterVO;
 import com.cloud.dc.DataCenter;
 import com.cloud.dc.DataCenter.NetworkType;
@@ -219,6 +218,7 @@ import com.cloud.utils.StringUtils;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.Filter;
 import com.cloud.utils.db.GlobalLock;
 import com.cloud.utils.db.JoinBuilder;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
index edf14fc..d0a4797 100755
--- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
+++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
@@ -47,7 +47,6 @@ import com.cloud.configuration.ResourceLimitVO;
 import com.cloud.configuration.dao.ConfigurationDao;
 import com.cloud.configuration.dao.ResourceCountDao;
 import com.cloud.configuration.dao.ResourceLimitDao;
-import com.cloud.dao.EntityManager;
 import com.cloud.dc.VlanVO;
 import com.cloud.dc.dao.VlanDao;
 import com.cloud.domain.Domain;
@@ -83,6 +82,7 @@ import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.Filter;
 import com.cloud.utils.db.GenericSearchBuilder;
 import com.cloud.utils.db.JoinBuilder;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 3d0e5c6..52d573d 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -420,6 +420,7 @@ import org.apache.cloudstack.api.command.user.vpn.ResetVpnConnectionCmd;
 import org.apache.cloudstack.api.command.user.vpn.UpdateVpnCustomerGatewayCmd;
 import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd;
 import org.apache.cloudstack.api.response.ExtractResponse;
+import org.apache.cloudstack.config.Configuration;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
@@ -450,7 +451,6 @@ import com.cloud.capacity.dao.CapacityDao;
 import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
 import com.cloud.cluster.ClusterManager;
 import com.cloud.configuration.Config;
-import com.cloud.configuration.Configuration;
 import com.cloud.configuration.ConfigurationManager;
 import com.cloud.configuration.ConfigurationVO;
 import com.cloud.configuration.dao.ConfigurationDao;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/src/com/cloud/servlet/ConsoleProxyServlet.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/servlet/ConsoleProxyServlet.java b/server/src/com/cloud/servlet/ConsoleProxyServlet.java
index ff16119..ed45698 100644
--- a/server/src/com/cloud/servlet/ConsoleProxyServlet.java
+++ b/server/src/com/cloud/servlet/ConsoleProxyServlet.java
@@ -45,7 +45,6 @@ import com.google.gson.GsonBuilder;
 
 import org.apache.cloudstack.api.IdentityService;
 
-import com.cloud.dao.EntityManager;
 import com.cloud.exception.PermissionDeniedException;
 import com.cloud.host.HostVO;
 import com.cloud.server.ManagementServer;
@@ -56,6 +55,7 @@ import com.cloud.user.User;
 import com.cloud.uservm.UserVm;
 import com.cloud.utils.Pair;
 import com.cloud.utils.Ternary;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.Transaction;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/src/com/cloud/servlet/RegisterCompleteServlet.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/servlet/RegisterCompleteServlet.java b/server/src/com/cloud/servlet/RegisterCompleteServlet.java
index 702b617..04c5ea9 100644
--- a/server/src/com/cloud/servlet/RegisterCompleteServlet.java
+++ b/server/src/com/cloud/servlet/RegisterCompleteServlet.java
@@ -30,7 +30,8 @@ import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 import org.springframework.web.context.support.SpringBeanAutowiringSupport;
 
-import com.cloud.configuration.Configuration;
+import org.apache.cloudstack.config.Configuration;
+
 import com.cloud.configuration.dao.ConfigurationDao;
 import com.cloud.user.Account;
 import com.cloud.user.AccountService;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
index 1324ac7..65e76f6 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
@@ -56,7 +56,6 @@ import com.cloud.configuration.Config;
 import com.cloud.configuration.ZoneConfig;
 import com.cloud.configuration.dao.ConfigurationDao;
 import com.cloud.consoleproxy.ConsoleProxyManager;
-import com.cloud.dao.EntityManager;
 import com.cloud.dc.DataCenter;
 import com.cloud.dc.DataCenter.NetworkType;
 import com.cloud.dc.DataCenterVO;
@@ -111,6 +110,7 @@ import com.cloud.utils.Pair;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.db.GlobalLock;
 import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.SearchCriteria2;
 import com.cloud.utils.db.SearchCriteriaService;
 import com.cloud.utils.events.SubscriptionMgr;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/test/com/cloud/async/AsyncJobTestConfiguration.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/async/AsyncJobTestConfiguration.java b/server/test/com/cloud/async/AsyncJobTestConfiguration.java
index d6b8ee0..f1485ca 100644
--- a/server/test/com/cloud/async/AsyncJobTestConfiguration.java
+++ b/server/test/com/cloud/async/AsyncJobTestConfiguration.java
@@ -37,9 +37,9 @@ import com.cloud.api.ApiDispatcher;
 import com.cloud.cluster.ClusterManager;
 import com.cloud.configuration.ConfigurationManager;
 import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dao.EntityManager;
 import com.cloud.user.AccountManager;
 import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.vm.VirtualMachineManager;
 
 @Configuration

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/test/com/cloud/vm/VmWorkTestConfiguration.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/VmWorkTestConfiguration.java b/server/test/com/cloud/vm/VmWorkTestConfiguration.java
index cd0dc2c..db29b21 100644
--- a/server/test/com/cloud/vm/VmWorkTestConfiguration.java
+++ b/server/test/com/cloud/vm/VmWorkTestConfiguration.java
@@ -40,9 +40,9 @@ import com.cloud.api.ApiDispatcher;
 import com.cloud.cluster.ClusterManager;
 import com.cloud.configuration.ConfigurationManager;
 import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dao.EntityManager;
 import com.cloud.user.AccountManager;
 import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.vm.dao.VMInstanceDao;
 
 @Configuration

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
index 734d274..65fe105 100755
--- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
@@ -50,10 +50,10 @@ import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
 import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
 import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
 import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
+import org.apache.cloudstack.config.Configuration;
 import org.apache.cloudstack.region.PortableIp;
 import org.apache.cloudstack.region.PortableIpRange;
 
-import com.cloud.configuration.Configuration;
 import com.cloud.configuration.ConfigurationManager;
 import com.cloud.configuration.ConfigurationService;
 import com.cloud.dc.ClusterVO;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/com/cloud/utils/db/Condition.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/Condition.java b/utils/src/com/cloud/utils/db/Condition.java
deleted file mode 100644
index 55b19d8..0000000
--- a/utils/src/com/cloud/utils/db/Condition.java
+++ /dev/null
@@ -1,100 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.util.HashMap;
-
-import com.cloud.utils.db.SearchCriteria.Op;
-
-public class Condition<T, K> {
-    Where<T, K> _where;
-    Attribute _attr;
-    String _as;
-    SearchCriteria.Op _op;
-    String _paramName;
-    
-    protected Condition(Where<T, K> where, Attribute attr, String as) {
-        assert (where != null) : "What am I going to return to the user when Where is null?";
-        assert (attr != null) : "What's the point of giving me a null attribute?";
-        _where = where;
-        _attr = attr;
-        _as = as;
-    }
-    
-    protected NextWhere<T, K> set(Op op, String paramName) {
-        _op = op;
-        _paramName = paramName;
-        Where<T, K> where = _where;
-        _where = null;
-        return where;
-    }
-    
-    public NextWhere<T, K> eq(String paramName) {
-        return set(Op.EQ, paramName);
-    }
-    
-    public NextWhere<T, K> lt(String paramName) {
-        return set(Op.LT, paramName);
-    }
-    
-    public NextWhere<T, K> lteq(String paramName) {
-        return set(Op.LTEQ, paramName);
-    }
-    
-    public NextWhere<T, K> gt(String paramName) {
-        return set(Op.GT, paramName);
-    }
-    
-    public NextWhere<T, K> isNull() {
-        return set(Op.NULL, null);
-    }
-    
-    public NextWhere<T, K> isNotNull() {
-        return set(Op.NNULL, null);
-    }
-    
-    public NextWhere<T, K> in(String paramName) {
-        _op = Op.IN;
-        _paramName = paramName;
-        return _where;
-    }
-    
-    protected String getParamName() {
-        assert (_paramName instanceof String) : "Well, how can we get back a parameter name if it was not assigned one?";
-        return _paramName;
-    }
-    
-    @Override
-    public boolean equals(Object obj) {
-        return _paramName.equals(obj);
-    }
-    
-    @Override
-    public int hashCode() {
-        return _paramName.hashCode();
-    }
-    
-    public void toSql(StringBuilder builder, HashMap<String, Object[]> values) {
-        if (_as != null) {
-            builder.append(_as);
-        } else {
-            builder.append(_attr.table);
-        }
-        builder.append(".").append(_attr.columnName);
-    }
-   
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/com/cloud/utils/db/EntityManager.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/EntityManager.java b/utils/src/com/cloud/utils/db/EntityManager.java
new file mode 100644
index 0000000..f4e1ca2
--- /dev/null
+++ b/utils/src/com/cloud/utils/db/EntityManager.java
@@ -0,0 +1,99 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+ * Generic Entity Manager to retrieve database objects.
+ *
+ */
+public interface EntityManager {
+    /**
+     * Finds an entity by its id.
+     * @param <T> class of the entity you're trying to find.
+     * @param <K> class of the id that the entity uses.
+     * @param entityType Type of the entity.
+     * @param id id value
+     * @return T if found; null if not.
+     */
+    public <T, K extends Serializable> T findById(Class<T> entityType, K id);
+
+    /**
+     * Finds an entity by its id including removed.
+     * @param <T> class of the entity you're trying to find.
+     * @param <K> class of the id that the entity uses.
+     * @param entityType Type of the entity.
+     * @param id id value
+     * @return T if found; null if not.
+     */
+    public <T, K extends Serializable> T findByIdIncludingRemoved(Class<T> entityType, K id);
+    
+    /**
+     * Finds a unique entity by uuid string
+     * @param <T> entity class
+     * @param entityType type of entity you're looking for.
+     * @param uuid the unique id
+     * @return T if found, null if not.
+     */
+    public <T> T findByUuid(Class<T> entityType, String uuid);
+
+    /**
+     * Finds a unique entity by uuid string
+     * @param <T> entity class
+     * @param entityType type of entity you're looking for.
+     * @param uuid the unique id
+     * @return T if found, null if not.
+     */
+    public <T> T findByUuidIncludingRemoved(Class<T> entityType, String uuid);
+
+    /**
+     * Finds an entity by external id which is always String
+     * @param <T> entity class
+     * @param entityType type of entity you're looking for.
+     * @param xid external id
+     * @return T if found, null if not.
+     */
+    public <T> T findByXId(Class<T> entityType, String xid);
+
+    /**
+     * Lists all entities.  Use this method at your own risk.
+     * @param <T> entity class
+     * @param entityType type of entity you're looking for.
+     * @return List<T>
+     */
+    public <T> List<? extends T> list(Class<T> entityType);
+
+    /**
+     * Persists the entity.
+     * @param <T> entity class
+     * @param t entity
+     * @return persisted entity.  Only use this after persisting.
+     */
+    public <T> T persist(T t);
+
+    public <T> SearchBuilder<T> createSearchBuilder(Class<T> entityType);
+
+    public <T, K> GenericSearchBuilder<T, K> createGenericSearchBuilder(Class<T> entityType, Class<K> resultType);
+
+    public <T, K> List<K> search(Class<T> entityType, SearchCriteria<K> sc);
+
+    public <T, K extends Serializable> void remove(Class<T> entityType, K id);
+}
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/com/cloud/utils/db/FirstWhere.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/FirstWhere.java b/utils/src/com/cloud/utils/db/FirstWhere.java
deleted file mode 100644
index 46551e9..0000000
--- a/utils/src/com/cloud/utils/db/FirstWhere.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-public interface FirstWhere<T, K> {
-    Condition<T, K> field(Object field);
-    
-    Condition<T, K> field(Object field, String as);
-    
-    NextWhere<T, K> text(String text, String... paramNames);
-    
-    FirstWhere<T, K> op();
-    
-    void done();
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/com/cloud/utils/db/JoinQueryBuilder.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/JoinQueryBuilder.java b/utils/src/com/cloud/utils/db/JoinQueryBuilder.java
deleted file mode 100644
index 090a1d1..0000000
--- a/utils/src/com/cloud/utils/db/JoinQueryBuilder.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-/**
- * JoinQueryBuilder builds queries for joins between multiple tables.
- *
- */
-public interface JoinQueryBuilder<S, T> {
-    Select<S, T> selectField(Object column);
-
-    <J> On<S, J, T> innerJoin(Class<J> entityClazz);
-    
-    <J> J entity(Class<J> entityClazz);
-    
-    FirstWhere<S, T> where();
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/com/cloud/utils/db/NextWhere.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/NextWhere.java b/utils/src/com/cloud/utils/db/NextWhere.java
deleted file mode 100644
index 0d65ae4..0000000
--- a/utils/src/com/cloud/utils/db/NextWhere.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-public interface NextWhere<T, K> extends FirstWhere<T, K> {
-    NextWhere<T, K> and();
-    NextWhere<T, K> or();
-    NextWhere<T, K> not();
-    
-    @Override
-    void done();
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/com/cloud/utils/db/On.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/On.java b/utils/src/com/cloud/utils/db/On.java
deleted file mode 100644
index 6965f4d..0000000
--- a/utils/src/com/cloud/utils/db/On.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-public interface On<S, J, T> {
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/com/cloud/utils/db/QueryBuilder.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/QueryBuilder.java b/utils/src/com/cloud/utils/db/QueryBuilder.java
deleted file mode 100644
index 3303fbd..0000000
--- a/utils/src/com/cloud/utils/db/QueryBuilder.java
+++ /dev/null
@@ -1,194 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.MethodProxy;
-
-import com.cloud.utils.Pair;
-
-public class QueryBuilder<S, T> implements MethodInterceptor, SimpleQueryBuilder<S>, SelectQueryBuilder<S, T>, JoinQueryBuilder<S, T> {
-    public enum Func {
-        NATIVE("@", 1),
-        MAX("MAX(@)", 1),
-        MIN("MIN(@)", 1),
-        FIRST("FIRST(@)", 1),
-        LAST("LAST(@)", 1),
-        SUM("SUM(@)", 1),
-        COUNT("COUNT(@)", 1),
-        DISTINCT("DISTINCT(@)", 1);
-        
-        private String func;
-        private int count;
-        
-        Func(String func, int params) {
-            this.func = func;
-            this.count = params;
-        }
-        
-        @Override
-        public String toString() {
-            return func;
-        }
-        
-        public int getCount() {
-            return count;
-        }
-    }
-    
-    protected HashMap<Class<?>, Pair<GenericDao<?,?>, Object>> _entities;
-    protected ArrayList<Attribute> _specifiedAttrs = new ArrayList<Attribute>();
-    protected T _resultSetClass;
-    protected ArrayList<Select<S, T>> _selects;
-    
-    public QueryBuilder(Class<T> resultSetClass, Class<?>... clazzes) {
-        _entities = new HashMap<Class<?>, Pair<GenericDao<?,?>, Object>>(clazzes.length);
-        for (Class<?> clazz : clazzes) {
-            GenericDao<?,?> dao = GenericDaoBase.getDao(clazz);
-            Enhancer searchEnhancer = new Enhancer();
-            searchEnhancer.setSuperclass(clazz);
-            searchEnhancer.setCallback(this);
-            Object entity = searchEnhancer.create();
-            
-            _entities.put(clazz, new Pair<GenericDao<?, ?>, Object>(dao, entity));
-        }
-    }
-    
-    protected void clean() {
-        _specifiedAttrs = null;
-        _entities = null;
-    }
-    
-    /**
-     * Constructor for SelectQueryBuilder interface.  Must specify the
-     * table to be performing the query on and the result class to place it in.
-     * @param entityClass entity class to do the query on.
-     * @param resultSetClass result class to put the result set in.
-     */
-    public QueryBuilder(Class<S> entityClass, Class<T> resultSetClass) {
-        _entities = new HashMap<Class<?>, Pair<GenericDao<?,?>, Object>>(1);
-        GenericDao<?,?> dao = GenericDaoBase.getDao(entityClass);
-        Enhancer searchEnhancer = new Enhancer();
-        searchEnhancer.setSuperclass(entityClass);
-        searchEnhancer.setCallback(this);
-        Object entity = searchEnhancer.create();
-        
-        _entities.put(entityClass, new Pair<GenericDao<?, ?>, Object>(dao, entity));
-    }
-    
-    @Override
-    public SimpleQueryBuilder<S> selectFields(Object... fields) {
-        assert _entities != null && _entities.size() == 1 : "Now you've done it....Stop casting interfaces on the QueryBuilder";
-        assert _specifiedAttrs.size() > 0 : "You didn't specify any attributes";
-   
-        if (_selects == null) {
-            _selects = new ArrayList<Select<S, T>>(fields.length);
-        }
-        
-        for (Attribute attr : _specifiedAttrs) {
-            _selects.add(new Select<S, T>(this, null, attr));
-        }
-        
-        _specifiedAttrs.clear();
-        
-        return this;
-    }
-    
-    protected void set(GenericDao<?, ?> dao , String name) {
-        Attribute attr = dao.getAllAttributes().get(name);
-        assert (attr != null) : "Searching for a field that's not there: " + name;
-        _specifiedAttrs.add(attr);
-    }
-    
-    
-    @Override
-    public Object intercept(Object entity, Method method, Object[] args, MethodProxy proxy) throws Throwable {
-        Class<?> entityClass = entity.getClass().getSuperclass();
-        
-        Pair<GenericDao<?,?>, Object> daoInfo = _entities.get(entityClass);
-        assert (daoInfo != null) : "You need to specify " + entityClass + " as one of the entities in the Query";
-        GenericDao<?,?> dao = daoInfo.first();
-        
-        String name = method.getName();
-        if (name.startsWith("get")) {
-            String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
-            set(dao, fieldName);
-            return null;
-        } else if (name.startsWith("is")) {
-            String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
-            set(dao, fieldName);
-            return null;
-        } else {
-            assert false : "Perhaps you need to make the method start with get or is?";
-        }
-        return proxy.invokeSuper(entity, args);
-    }
-    
-    @Override
-    @SuppressWarnings("unchecked")
-    public <E> E entity(Class<E> clazz) {
-        return (E)_entities.get(clazz).second();
-    }
-    
-    @Override
-    @SuppressWarnings("unchecked")
-    public S entity() {
-        return (S)_entities.values().iterator().next().second();
-    }
-
-    @Override
-    public FirstWhere<S, T> where() {
-        return new Where<S, T>(this);
-    }
-
-    @Override
-    public SimpleQueryBuilder<S> selectAll() {
-        return this;
-    }
-    
-    public List<Attribute> getSpecifiedAttributes() {
-        return _specifiedAttrs;
-    }
-    
-    public Attribute getSpecifiedAttribute() {
-        assert _specifiedAttrs.size() == 1 : "You can only specify one attribute";
-        return _specifiedAttrs.get(0);
-    }
-
-    @Override
-    public Select<S, T> selectColumn(Object column) {
-        return null;
-    }
-
-    @Override
-    public Select<S, T> selectField(Object column) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public <J> On<S, J, T> innerJoin(Class<J> entityClazz) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/com/cloud/utils/db/Select.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/Select.java b/utils/src/com/cloud/utils/db/Select.java
deleted file mode 100644
index d82d1fa..0000000
--- a/utils/src/com/cloud/utils/db/Select.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.Field;
-
-public class Select<S, T> {
-    QueryBuilder<S,T> _builder;
-    Class<T> _clazz;
-    Attribute _attr;
-    String _as;
-    Field _field;
-    
-    protected Select(QueryBuilder<S, T> builder, Class<T> clazz, Attribute attr) {
-        _builder = builder;
-        _clazz = clazz;
-        _attr = attr;
-    }
-    
-    public QueryBuilder<S, T> into(String fieldName) {
-        if (fieldName != null) {
-            try {
-                _field = _clazz.getDeclaredField(fieldName);
-                _field.setAccessible(true);
-            } catch (SecurityException e) {
-                throw new RuntimeException("Unable to find " + fieldName + " in " + _clazz.getName(), e);
-            } catch (NoSuchFieldException e) {
-                throw new RuntimeException("Unable to find " + fieldName + " in " + _clazz.getName(), e);
-            }
-        }
-        return _builder;
-    }
-    
-    public QueryBuilder<S, T> as(String as) {
-        _as = as;
-        return _builder;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/com/cloud/utils/db/SelectQueryBuilder.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/SelectQueryBuilder.java b/utils/src/com/cloud/utils/db/SelectQueryBuilder.java
deleted file mode 100644
index 82ba134..0000000
--- a/utils/src/com/cloud/utils/db/SelectQueryBuilder.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-/**
- * is defined.
- */
-public interface SelectQueryBuilder<T, S> {
-    Select<T, S> selectColumn(Object column);
-
-    T entity();
-    
-    FirstWhere<T, S> where();
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/com/cloud/utils/db/SimpleQueryBuilder.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/SimpleQueryBuilder.java b/utils/src/com/cloud/utils/db/SimpleQueryBuilder.java
deleted file mode 100644
index 9e446d2..0000000
--- a/utils/src/com/cloud/utils/db/SimpleQueryBuilder.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-/**
- * SimpleQueryBuilder builds queries against a single table.  The
- *
- */
-public interface SimpleQueryBuilder<S> {
-    /**
-     * Select all of the columns in the entity object.  This is default so
-     * it's not necessary to make this method call at all.
-     */
-    SimpleQueryBuilder<S> selectAll();
-    
-    /**
-     * Select the following columns
-     * @param columns array of columsn to select.
-     */
-    SimpleQueryBuilder<S> selectFields(Object... columns);
-    
-    /**
-     * @return the entity object we're building this query for.  By using this
-     * entity object, you can specify which column to select or form
-     */
-    S entity();
-    
-    /**
-     * Starts the query conditionals.
-     * @return
-     */
-    FirstWhere<S, ?> where();
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/com/cloud/utils/db/Where.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/Where.java b/utils/src/com/cloud/utils/db/Where.java
deleted file mode 100644
index 6815f24..0000000
--- a/utils/src/com/cloud/utils/db/Where.java
+++ /dev/null
@@ -1,81 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Where implements any list of search conditions.
- *
- */
-public class Where<T, K> implements FirstWhere<T, K>, NextWhere<T, K> {
-    QueryBuilder<T, K> _builder;
-    List<Object> _conditions = new ArrayList<Object>();
-    
-    protected Where(QueryBuilder<T, K> builder) {
-        _builder = builder;
-    }
-    
-    @Override
-    public Condition<T, K> field(Object useless, String as) {
-        Attribute attr = _builder.getSpecifiedAttribute();
-        Condition<T, K> cond = new Condition<T, K>(this, attr, as);
-        _conditions.add(cond);
-        return cond;
-    }
-    
-    @Override
-    public Where<T, K> and() {
-        _conditions.add(" (");
-        return this;
-    }
-    
-    @Override
-    public Where<T, K> or() {
-        _conditions.add(" OR ");
-        return this;
-    }
-
-    @Override
-    public NextWhere<T, K> not() {
-        _conditions.add(" NOT ");
-        return this;
-    }
-
-    @Override
-    public NextWhere<T, K> text(String text, String... paramNames) {
-        assert ((paramNames.length == 0 && !text.contains("?")) || (text.matches("\\?.*{" + paramNames.length + "}")));
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Condition<T, K> field(Object useless) {
-        return field(useless, null);
-    }
-
-    @Override
-    public FirstWhere<T, K> op() {
-        _conditions.add("(");
-        return this;
-    }
-
-    @Override
-    public void done() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/org/apache/cloudstack/config/ConfigDepot.java
----------------------------------------------------------------------
diff --git a/utils/src/org/apache/cloudstack/config/ConfigDepot.java b/utils/src/org/apache/cloudstack/config/ConfigDepot.java
new file mode 100644
index 0000000..f2f0bad
--- /dev/null
+++ b/utils/src/org/apache/cloudstack/config/ConfigDepot.java
@@ -0,0 +1,25 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.config;
+
+/**
+ * ConfigDepot is a repository of configurations.
+ *
+ */
+public interface ConfigDepot {
+    <T> ConfigValue<T> get(ConfigKey<T> key);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/org/apache/cloudstack/config/ConfigKey.java
----------------------------------------------------------------------
diff --git a/utils/src/org/apache/cloudstack/config/ConfigKey.java b/utils/src/org/apache/cloudstack/config/ConfigKey.java
new file mode 100644
index 0000000..9e42831
--- /dev/null
+++ b/utils/src/org/apache/cloudstack/config/ConfigKey.java
@@ -0,0 +1,98 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.config;
+
+/**
+ * ConfigKey supplants the original Config.java.  It is just a class
+ * declaration where others can declare their config variables.
+ * 
+ * TODO: This class should be moved to a framework project where the gathering
+ *       of these configuration keys should be done by a config server.  I
+ *       don't have time yet to do this.  Ask me about it if you want to work
+ *       in this area.  Right now, we'll just work with the actual names.
+ */
+public class ConfigKey<T> {
+    
+    private final String _category;
+
+    public String category() {
+        return _category;
+    }
+
+    public Class<?> component() {
+        return _componentClass;
+    }
+
+    public Class<T> type() {
+        return _type;
+    }
+
+    public String key() {
+        return _name;
+    }
+
+    public String defaultValue() {
+        return _defaultValue;
+    }
+
+    public String description() {
+        return _description;
+    }
+
+    public String range() {
+        return _range;
+    }
+
+    public String scope() {
+        return _scope;
+    }
+
+    public boolean isDynamic() {
+        return _isDynamic;
+    }
+
+    @Override
+    public String toString() {
+        return _name;
+    }
+
+    private final Class<?> _componentClass;
+    private final Class<T> _type;
+    private final String _name;
+    private final String _defaultValue;
+    private final String _description;
+    private final String _range;
+    private final String _scope; // Parameter can be at different levels (Zone/cluster/pool/account), by default every parameter is at global
+    private final boolean _isDynamic;
+
+    public ConfigKey(Class<T> type, String name, String category, Class<?> componentClass, String defaultValue, String description, boolean isDynamic, String range,
+            String scope) {
+        _category = category;
+        _componentClass = componentClass;
+        _type = type;
+        _name = name;
+        _defaultValue = defaultValue;
+        _description = description;
+        _range = range;
+        _scope = scope;
+        _isDynamic = isDynamic;
+    }
+
+    public ConfigKey(Class<T> type, String name, String category, Class<?> componentClass, String defaultValue, String description, boolean isDynamic, String range) {
+        this(type, name, category, componentClass, defaultValue, description, isDynamic, range, null);
+    }
+}


[2/9] git commit: updated refs/heads/vmsync to 309f8da

Posted by ah...@apache.org.
Removed AsyncJobConstant


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ea6ca5ff
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ea6ca5ff
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ea6ca5ff

Branch: refs/heads/vmsync
Commit: ea6ca5ff5c928a61c024c242f07cc1f813e2f616
Parents: 2b96665
Author: Alex Huang <al...@gmail.com>
Authored: Fri Jun 14 19:21:25 2013 -0700
Committer: Alex Huang <al...@gmail.com>
Committed: Mon Jun 17 17:04:01 2013 -0700

----------------------------------------------------------------------
 .../apache/cloudstack/api/ResponseObject.java   |   1 +
 api/src/org/apache/cloudstack/jobs/JobInfo.java |   8 +-
 .../com/cloud/vm/VirtualMachineManagerImpl.java |   4 +-
 .../src/com/cloud/vm/VmWorkJobDispatcher.java   |   4 +-
 .../cloudstack/vm/jobs/VmWorkJobDaoImpl.java    |   2 +-
 .../cloudstack/framework/jobs/AsyncJob.java     |   2 +-
 .../framework/jobs/AsyncJobConstants.java       |  34 ------
 .../jobs/AsyncJobExecutionContext.java          |  25 ++---
 .../framework/jobs/AsyncJobManager.java         |  10 +-
 .../framework/jobs/dao/AsyncJobDaoImpl.java     |  12 +--
 .../framework/jobs/dao/AsyncJobJoinMapDao.java  |   5 +-
 .../jobs/dao/AsyncJobJoinMapDaoImpl.java        |  50 +++++----
 .../framework/jobs/impl/AsyncJobJoinMapVO.java  |  11 +-
 .../framework/jobs/impl/AsyncJobMBeanImpl.java  |  66 +++++++-----
 .../framework/jobs/impl/AsyncJobVO.java         |  16 ++-
 .../com/cloud/api/ApiAsyncJobDispatcher.java    |   6 +-
 server/src/com/cloud/api/ApiServer.java         |   2 +-
 .../com/cloud/async/AsyncJobManagerImpl.java    | 108 +++++++++----------
 server/src/com/cloud/async/AsyncJobResult.java  |  14 +--
 .../consoleproxy/ConsoleProxyManagerImpl.java   |   8 +-
 .../com/cloud/server/ManagementServerImpl.java  |   4 +-
 .../secondary/SecondaryStorageManagerImpl.java  |   8 +-
 .../storage/snapshot/SnapshotSchedulerImpl.java |   6 +-
 .../cloud/storage/upload/UploadListener.java    |  10 +-
 .../src/com/cloud/vm/SystemVmLoadScanner.java   |   4 +-
 .../com/cloud/async/TestAsyncJobManager.java    |  13 ++-
 .../vm/VmWorkMockVirtualMachineManagerImpl.java |   2 +-
 .../cloud/vm/VmWorkTestWorkJobDispatcher.java   |   2 +-
 28 files changed, 215 insertions(+), 222 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/api/src/org/apache/cloudstack/api/ResponseObject.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ResponseObject.java b/api/src/org/apache/cloudstack/api/ResponseObject.java
index c8bd457..b696159 100644
--- a/api/src/org/apache/cloudstack/api/ResponseObject.java
+++ b/api/src/org/apache/cloudstack/api/ResponseObject.java
@@ -16,6 +16,7 @@
 // under the License.
 package org.apache.cloudstack.api;
 
+
 public interface ResponseObject {
     /**
      * Get the name of the API response

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/api/src/org/apache/cloudstack/jobs/JobInfo.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/jobs/JobInfo.java b/api/src/org/apache/cloudstack/jobs/JobInfo.java
index bce9627..6a53123 100644
--- a/api/src/org/apache/cloudstack/jobs/JobInfo.java
+++ b/api/src/org/apache/cloudstack/jobs/JobInfo.java
@@ -22,6 +22,12 @@ import org.apache.cloudstack.api.Identity;
 import org.apache.cloudstack.api.InternalIdentity;
 
 public interface JobInfo extends Identity, InternalIdentity {
+    public enum Status {
+        IN_PROGRESS,
+        SUCCEEDED,
+        FAILED,
+        CANCELLED;
+    }
 
     String getType();
 
@@ -39,7 +45,7 @@ public interface JobInfo extends Identity, InternalIdentity {
 
     String getCmdInfo();
 
-    int getStatus();
+    Status getStatus();
 
     int getProcessStatus();
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index 4fee49e..0f710d1 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -725,7 +725,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 						return true;
 			
 					VmWorkJobVO workJob = _workJobDao.findById(jobId);
-					if(workJob.getStatus() != AsyncJobConstants.STATUS_IN_PROGRESS)
+					if(workJob.getStatus() != JobInfo.Status.IN_PROGRESS)
 						return true;
 					
 					return false;
@@ -1152,7 +1152,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 						return true;
 			
 					VmWorkJobVO workJob = _workJobDao.findById(jobId);
-					if(workJob.getStatus() != AsyncJobConstants.STATUS_IN_PROGRESS)
+					if(workJob.getStatus() != JobInfo.Status.IN_PROGRESS)
 						return true;
 					
 					return false;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java b/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
index 8c7fd9c..7819c1a 100644
--- a/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
+++ b/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
@@ -99,10 +99,10 @@ public class VmWorkJobDispatcher extends AdapterBase implements AsyncJobDispatch
                 VmWorkStop stop = (VmWorkStop)work;
                 _vmMgr.orchestrateStop(vm.getUuid(), stop.isForceStop());
             }
-            _asyncJobMgr.completeAsyncJob(job.getId(), AsyncJobConstants.STATUS_SUCCEEDED, 0, null);
+            _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, null);
         } catch(Throwable e) {
             s_logger.error("Unable to complete " + job, e);
-            _asyncJobMgr.completeAsyncJob(job.getId(), AsyncJobConstants.STATUS_FAILED, 0, e.getMessage());
+            _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, e.getMessage());
         } finally {
             CallContext.unregister();
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/engine/schema/src/org/apache/cloudstack/vm/jobs/VmWorkJobDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/vm/jobs/VmWorkJobDaoImpl.java b/engine/schema/src/org/apache/cloudstack/vm/jobs/VmWorkJobDaoImpl.java
index 4ece4e8..0135d81 100644
--- a/engine/schema/src/org/apache/cloudstack/vm/jobs/VmWorkJobDaoImpl.java
+++ b/engine/schema/src/org/apache/cloudstack/vm/jobs/VmWorkJobDaoImpl.java
@@ -111,7 +111,7 @@ public class VmWorkJobDaoImpl extends GenericDaoBase<VmWorkJobVO, Long> implemen
 	public void expungeCompletedWorkJobs(Date cutDate) {
 		SearchCriteria<VmWorkJobVO> sc = ExpungeWorkJobSearch.create();
 		sc.setParameters("lastUpdated",cutDate);
-		sc.setParameters("status", AsyncJobConstants.STATUS_IN_PROGRESS);
+		sc.setParameters("status", JobInfo.Status.IN_PROGRESS);
 		
 		expunge(sc);
 	}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java
index dfb67f8..be92846 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java
@@ -57,7 +57,7 @@ public interface AsyncJob extends JobInfo {
     String getCmdInfo();
     
     @Override
-    int getStatus();
+    Status getStatus();
 
     @Override
     int getProcessStatus();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobConstants.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobConstants.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobConstants.java
deleted file mode 100644
index 9568eb4..0000000
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobConstants.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.framework.jobs;
-
-public interface AsyncJobConstants {
-	public static final int STATUS_IN_PROGRESS = 0;
-	public static final int STATUS_SUCCEEDED = 1;
-	public static final int STATUS_FAILED = 2;
-	
-	public static final String JOB_DISPATCHER_PSEUDO = "pseudoJobDispatcher";
-	public static final String PSEUDO_JOB_INSTANCE_TYPE = "Thread";
-	
-	public static final String JOB_POOL_THREAD_PREFIX = "Job-Executor";
-	
-	// Although we may have detailed masks for each individual wakeup event, i.e.
-	// periodical timer, matched topic from message bus, it seems that we don't
-	// need to distinguish them to such level. Therefore, only one wakeup signal
-	// is defined
-	public static final int SIGNAL_MASK_WAKEUP = 1;
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
index 3d5c326..ef0a4a6 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
@@ -22,11 +22,11 @@ import org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDao;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobJoinMapVO;
 import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
 import org.apache.cloudstack.framework.jobs.impl.SyncQueueItem;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.utils.component.ComponentContext;
 
 public class AsyncJobExecutionContext  {
     private AsyncJob _job;
@@ -57,10 +57,6 @@ public class AsyncJobExecutionContext  {
 	}
 	
     public AsyncJob getJob() {
-		if(_job == null) {
-			_job = _jobMgr.getPseudoJob();
-		}
-		
 		return _job;
 	}
 	
@@ -68,7 +64,7 @@ public class AsyncJobExecutionContext  {
 		_job = job;
 	}
 	
-    public void completeAsyncJob(int jobStatus, int resultCode, Object resultObject) {
+    public void completeAsyncJob(JobInfo.Status jobStatus, int resultCode, Object resultObject) {
     	assert(_job != null);
     	_jobMgr.completeAsyncJob(_job.getId(), jobStatus, resultCode, resultObject);
     }
@@ -114,7 +110,7 @@ public class AsyncJobExecutionContext  {
     	assert(_job != null);
     	
     	AsyncJobJoinMapVO record = _joinMapDao.getJoinRecord(_job.getId(), joinedJobId);
-    	if(record.getJoinStatus() == AsyncJobConstants.STATUS_FAILED && record.getJoinResult() != null) {
+    	if(record.getJoinStatus() == JobInfo.Status.FAILED && record.getJoinResult() != null) {
     		Object exception = JobSerializerHelper.fromObjectSerializedString(record.getJoinResult());
     		if(exception != null && exception instanceof Exception) {
     			if(exception instanceof InsufficientCapacityException)
@@ -131,12 +127,12 @@ public class AsyncJobExecutionContext  {
     	_jobMgr.disjoinJob(_job.getId(), joinedJobId);
     }
     
-    public void completeJoin(int joinStatus, String joinResult) {
+    public void completeJoin(JobInfo.Status joinStatus, String joinResult) {
     	assert(_job != null);
     	_jobMgr.completeJoin(_job.getId(), joinStatus, joinResult);
     }
     
-    public void completeJobAndJoin(int joinStatus, String joinResult) {
+    public void completeJobAndJoin(JobInfo.Status joinStatus, String joinResult) {
     	assert(_job != null);
     	_jobMgr.completeJoin(_job.getId(), joinStatus, joinResult);
     	_jobMgr.completeAsyncJob(_job.getId(), joinStatus, 0, null);
@@ -144,21 +140,14 @@ public class AsyncJobExecutionContext  {
 
 	public static AsyncJobExecutionContext getCurrentExecutionContext() {
 		AsyncJobExecutionContext context = s_currentExectionContext.get();
-		if(context == null) {
-			context = new AsyncJobExecutionContext();
-			context = ComponentContext.inject(context);
-			context.getJob();
-			setCurrentExecutionContext(context);
-		}
-		
 		return context;
 	}
 	
-    public static AsyncJobExecutionContext registerPseudoExecutionContext() {
+    public static AsyncJobExecutionContext registerPseudoExecutionContext(long accountId, long userId) {
         AsyncJobExecutionContext context = s_currentExectionContext.get();
         if (context == null) {
             context = new AsyncJobExecutionContext();
-            context.getJob();
+            context.setJob(_jobMgr.getPseudoJob(accountId, userId));
             setCurrentExecutionContext(context);
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java
index e577fb0..3178268 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java
@@ -20,6 +20,7 @@ import java.util.List;
 
 import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.utils.Predicate;
 import com.cloud.utils.component.Manager;
@@ -31,12 +32,9 @@ public interface AsyncJobManager extends Manager {
 	List<? extends AsyncJob> findInstancePendingAsyncJobs(String instanceType, Long accountId);
 	
 	long submitAsyncJob(AsyncJob job);
-	long submitAsyncJob(AsyncJob job, boolean scheduleJobExecutionInContext);
 	long submitAsyncJob(AsyncJob job, String syncObjType, long syncObjId);
 
-//	AsyncJobResult queryAsyncJobResult(long jobId);
-
-    void completeAsyncJob(long jobId, int jobStatus, int resultCode, Object resultObject);
+    void completeAsyncJob(long jobId, JobInfo.Status jobStatus, int resultCode, Object resultObject);
     void updateAsyncJobStatus(long jobId, int processStatus, Object resultObject);
     void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId);
     void logJobJournal(long jobId, AsyncJob.JournalType journalType, String
@@ -50,7 +48,7 @@ public interface AsyncJobManager extends Manager {
 	 *
 	 * @return pseudo job for the thread
 	 */
-	AsyncJob getPseudoJob();
+    AsyncJob getPseudoJob(long accountId, long userId);
 
     /**
      * Used by upper level job to wait for completion of a down-level job (usually VmWork jobs)
@@ -101,7 +99,7 @@ public interface AsyncJobManager extends Manager {
      * 					for legacy code to work. To help pass exception object easier, we use
      * 					object-stream based serialization instead of GSON
      */
-    void completeJoin(long joinJobId, int joinStatus, String joinResult);
+    void completeJoin(long joinJobId, JobInfo.Status joinStatus, String joinResult);
    
     void releaseSyncSource();
     void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java
index c30dbde..96775f7 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java
@@ -23,8 +23,8 @@ import java.util.List;
 
 import org.apache.log4j.Logger;
 
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.Filter;
@@ -100,7 +100,7 @@ public class AsyncJobDaoImpl extends GenericDaoBase<AsyncJobVO, Long> implements
         SearchCriteria<AsyncJobVO> sc = pendingAsyncJobSearch.create();
         sc.setParameters("instanceType", instanceType);
         sc.setParameters("instanceId", instanceId);
-        sc.setParameters("status", AsyncJobConstants.STATUS_IN_PROGRESS);
+        sc.setParameters("status", JobInfo.Status.IN_PROGRESS);
         
         List<AsyncJobVO> l = listIncludingRemovedBy(sc);
         if(l != null && l.size() > 0) {
@@ -121,7 +121,7 @@ public class AsyncJobDaoImpl extends GenericDaoBase<AsyncJobVO, Long> implements
         if (accountId != null) {
             sc.setParameters("accountId", accountId);
         }
-        sc.setParameters("status", AsyncJobConstants.STATUS_IN_PROGRESS);
+        sc.setParameters("status", JobInfo.Status.IN_PROGRESS);
         
         return listBy(sc);
 	}
@@ -129,8 +129,8 @@ public class AsyncJobDaoImpl extends GenericDaoBase<AsyncJobVO, Long> implements
 	@Override
     public AsyncJobVO findPseudoJob(long threadId, long msid) {
 		SearchCriteria<AsyncJobVO> sc = pseudoJobSearch.create();
-		sc.setParameters("jobDispatcher", AsyncJobConstants.JOB_DISPATCHER_PSEUDO);
-		sc.setParameters("instanceType", AsyncJobConstants.PSEUDO_JOB_INSTANCE_TYPE);
+        sc.setParameters("jobDispatcher", AsyncJobVO.JOB_DISPATCHER_PSEUDO);
+        sc.setParameters("instanceType", AsyncJobVO.PSEUDO_JOB_INSTANCE_TYPE);
 		sc.setParameters("instanceId", threadId);
 		
 		List<AsyncJobVO> result = listBy(sc);
@@ -178,7 +178,7 @@ public class AsyncJobDaoImpl extends GenericDaoBase<AsyncJobVO, Long> implements
 	@Override
     @DB
 	public void resetJobProcess(long msid, int jobResultCode, String jobResultMessage) {
-		String sql = "UPDATE async_job SET job_status=" + AsyncJobConstants.STATUS_FAILED + ", job_result_code=" + jobResultCode
+		String sql = "UPDATE async_job SET job_status=" + JobInfo.Status.FAILED + ", job_result_code=" + jobResultCode
 			+ ", job_result='" + jobResultMessage + "' where job_status=0 AND (job_complete_msid=? OR (job_complete_msid IS NULL AND job_init_msid=?))";
 		
         Transaction txn = Transaction.currentTxn();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDao.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDao.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDao.java
index a9e82a7..9c993f1 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDao.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDao.java
@@ -19,12 +19,13 @@ package org.apache.cloudstack.framework.jobs.dao;
 import java.util.List;
 
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobJoinMapVO;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.utils.db.GenericDao;
 
 public interface AsyncJobJoinMapDao extends GenericDao<AsyncJobJoinMapVO, Long> {
 	
-	Long joinJob(long jobId, long joinJobId, long joinMsid, 
+	Long joinJob(long jobId, long joinJobId, long joinMsid,
 		long wakeupIntervalMs, long expirationMs,
 		Long syncSourceId, String wakeupHandler, String wakeupDispatcher);
 	void disjoinJob(long jobId, long joinedJobId);
@@ -33,7 +34,7 @@ public interface AsyncJobJoinMapDao extends GenericDao<AsyncJobJoinMapVO, Long>
 	AsyncJobJoinMapVO getJoinRecord(long jobId, long joinJobId);
 	List<AsyncJobJoinMapVO> listJoinRecords(long jobId);
 	
-	void completeJoin(long joinJobId, int joinStatus, String joinResult, long completeMsid);
+    void completeJoin(long joinJobId, JobInfo.Status joinStatus, String joinResult, long completeMsid);
 	
 	List<Long> wakeupScan();
 	List<Long> wakeupByJoinedJobCompletion(long joinedJobId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java
index 4cc2218..60dea03 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java
@@ -26,23 +26,23 @@ import java.util.TimeZone;
 
 import org.apache.log4j.Logger;
 
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobJoinMapVO;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.utils.DateUtil;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.db.Transaction;
 import com.cloud.utils.db.UpdateBuilder;
-import com.cloud.utils.db.SearchCriteria.Op;
 
 public class AsyncJobJoinMapDaoImpl extends GenericDaoBase<AsyncJobJoinMapVO, Long> implements AsyncJobJoinMapDao {
     public static final Logger s_logger = Logger.getLogger(AsyncJobJoinMapDaoImpl.class);
 	
-	private final SearchBuilder<AsyncJobJoinMapVO> RecordSearch;	
-	private final SearchBuilder<AsyncJobJoinMapVO> RecordSearchByOwner;	
-	private final SearchBuilder<AsyncJobJoinMapVO> CompleteJoinSearch;	
+	private final SearchBuilder<AsyncJobJoinMapVO> RecordSearch;
+	private final SearchBuilder<AsyncJobJoinMapVO> RecordSearchByOwner;
+	private final SearchBuilder<AsyncJobJoinMapVO> CompleteJoinSearch;
 	private final SearchBuilder<AsyncJobJoinMapVO> WakeupSearch;
 	
 	public AsyncJobJoinMapDaoImpl() {
@@ -66,7 +66,8 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase<AsyncJobJoinMapVO, Lo
 		WakeupSearch.done();
 	}
 	
-	public Long joinJob(long jobId, long joinJobId, long joinMsid, 
+	@Override
+    public Long joinJob(long jobId, long joinJobId, long joinMsid,
 		long wakeupIntervalMs, long expirationMs,
 		Long syncSourceId, String wakeupHandler, String wakeupDispatcher) {
 		
@@ -74,7 +75,7 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase<AsyncJobJoinMapVO, Lo
 		record.setJobId(jobId);
 		record.setJoinJobId(joinJobId);
 		record.setJoinMsid(joinMsid);
-		record.setJoinStatus(AsyncJobConstants.STATUS_IN_PROGRESS);
+		record.setJoinStatus(JobInfo.Status.IN_PROGRESS);
 		record.setSyncSourceId(syncSourceId);
 		record.setWakeupInterval(wakeupIntervalMs / 1000);		// convert millisecond to second
 		record.setWakeupHandler(wakeupHandler);
@@ -84,11 +85,12 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase<AsyncJobJoinMapVO, Lo
 			record.setExpiration(new Date(DateUtil.currentGMTTime().getTime() + expirationMs));
 		}
 		
-		this.persist(record);
+		persist(record);
 		return record.getId();
 	}
 	
-	public void disjoinJob(long jobId, long joinedJobId) {
+	@Override
+    public void disjoinJob(long jobId, long joinedJobId) {
 		SearchCriteria<AsyncJobJoinMapVO> sc = RecordSearch.create();
 		sc.setParameters("jobId", jobId);
 		sc.setParameters("joinJobId", joinedJobId);
@@ -96,14 +98,16 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase<AsyncJobJoinMapVO, Lo
 		this.expunge(sc);
 	}
 	
-	public void disjoinAllJobs(long jobId) {
+	@Override
+    public void disjoinAllJobs(long jobId) {
 		SearchCriteria<AsyncJobJoinMapVO> sc = RecordSearchByOwner.create();
 		sc.setParameters("jobId", jobId);
 		
 		this.expunge(sc);
 	}
 	
-	public AsyncJobJoinMapVO getJoinRecord(long jobId, long joinJobId) {
+	@Override
+    public AsyncJobJoinMapVO getJoinRecord(long jobId, long joinJobId) {
 		SearchCriteria<AsyncJobJoinMapVO> sc = RecordSearch.create();
 		sc.setParameters("jobId", jobId);
 		sc.setParameters("joinJobId", joinJobId);
@@ -117,14 +121,16 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase<AsyncJobJoinMapVO, Lo
 		return null;
 	}
 	
-	public List<AsyncJobJoinMapVO> listJoinRecords(long jobId) {
+	@Override
+    public List<AsyncJobJoinMapVO> listJoinRecords(long jobId) {
 		SearchCriteria<AsyncJobJoinMapVO> sc = RecordSearchByOwner.create();
 		sc.setParameters("jobId", jobId);
 		
 		return this.listBy(sc);
 	}
 	
-	public void completeJoin(long joinJobId, int joinStatus, String joinResult, long completeMsid) {
+    @Override
+    public void completeJoin(long joinJobId, JobInfo.Status joinStatus, String joinResult, long completeMsid) {
         AsyncJobJoinMapVO record = createForUpdate();
         record.setJoinStatus(joinStatus);
         record.setJoinResult(joinResult);
@@ -138,7 +144,8 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase<AsyncJobJoinMapVO, Lo
         update(ub, sc, null);
 	}
 
-	public List<Long> wakeupScan() {
+	@Override
+    public List<Long> wakeupScan() {
 		List<Long> standaloneList = new ArrayList<Long>();
 		
 		Date cutDate = DateUtil.currentGMTTime();
@@ -149,9 +156,9 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase<AsyncJobJoinMapVO, Lo
 			txn.start();
 			
 			//
-			// performance sensitive processing, do it in plain SQL 
+			// performance sensitive processing, do it in plain SQL
 			//
-			String sql = "UPDATE async_job SET job_pending_signals=1 WHERE id IN " +  
+			String sql = "UPDATE async_job SET job_pending_signals=1 WHERE id IN " +
 					"(SELECT job_id FROM async_job_join_map WHERE next_wakeup < ? AND expiration > ?)";
 			pstmt = txn.prepareStatement(sql);
 	        pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate));
@@ -159,7 +166,7 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase<AsyncJobJoinMapVO, Lo
 	        pstmt.executeUpdate();
 	        pstmt.close();
 			
-			sql = "UPDATE sync_queue_item SET queue_proc_msid=NULL, queue_proc_number=NULL WHERE content_id IN " + 
+			sql = "UPDATE sync_queue_item SET queue_proc_msid=NULL, queue_proc_number=NULL WHERE content_id IN " +
 					"(SELECT job_id FROM async_job_join_map WHERE next_wakeup < ? AND expiration > ?)";
 			pstmt = txn.prepareStatement(sql);
 	        pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate));
@@ -194,7 +201,8 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase<AsyncJobJoinMapVO, Lo
         return standaloneList;
 	}
 	
-	public List<Long> wakeupByJoinedJobCompletion(long joinedJobId) {
+	@Override
+    public List<Long> wakeupByJoinedJobCompletion(long joinedJobId) {
 		List<Long> standaloneList = new ArrayList<Long>();
 		
 		Transaction txn = Transaction.currentTxn();
@@ -203,16 +211,16 @@ public class AsyncJobJoinMapDaoImpl extends GenericDaoBase<AsyncJobJoinMapVO, Lo
 			txn.start();
 			
 			//
-			// performance sensitive processing, do it in plain SQL 
+			// performance sensitive processing, do it in plain SQL
 			//
-			String sql = "UPDATE async_job SET job_pending_signals=1 WHERE id IN " +  
+			String sql = "UPDATE async_job SET job_pending_signals=1 WHERE id IN " +
 					"(SELECT job_id FROM async_job_join_map WHERE join_job_id = ?)";
 			pstmt = txn.prepareStatement(sql);
 	        pstmt.setLong(1, joinedJobId);
 	        pstmt.executeUpdate();
 	        pstmt.close();
 			
-			sql = "UPDATE sync_queue_item SET queue_proc_msid=NULL, queue_proc_number=NULL WHERE content_id IN " + 
+			sql = "UPDATE sync_queue_item SET queue_proc_msid=NULL, queue_proc_number=NULL WHERE content_id IN " +
 					"(SELECT job_id FROM async_job_join_map WHERE join_job_id = ?)";
 			pstmt = txn.prepareStatement(sql);
 	        pstmt.setLong(1, joinedJobId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobJoinMapVO.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobJoinMapVO.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobJoinMapVO.java
index 0bcdc3b..287121f 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobJoinMapVO.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobJoinMapVO.java
@@ -20,6 +20,8 @@ import java.util.Date;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
@@ -27,6 +29,8 @@ import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
 
+import org.apache.cloudstack.jobs.JobInfo;
+
 import com.cloud.utils.DateUtil;
 import com.cloud.utils.db.GenericDao;
 
@@ -45,7 +49,8 @@ public class AsyncJobJoinMapVO {
 	private long joinJobId;
 
     @Column(name="join_status")
-    private int joinStatus;
+    @Enumerated(EnumType.ORDINAL)
+    private JobInfo.Status joinStatus;
     
     @Column(name="join_result", length=1024)
     private String joinResult;
@@ -112,11 +117,11 @@ public class AsyncJobJoinMapVO {
 		this.joinJobId = joinJobId;
 	}
 
-	public int getJoinStatus() {
+    public JobInfo.Status getJoinStatus() {
 		return joinStatus;
 	}
 
-	public void setJoinStatus(int joinStatus) {
+    public void setJoinStatus(JobInfo.Status joinStatus) {
 		this.joinStatus = joinStatus;
 	}
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMBeanImpl.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMBeanImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMBeanImpl.java
index 95f01e5..0a48da3 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMBeanImpl.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMBeanImpl.java
@@ -22,13 +22,12 @@ import java.util.TimeZone;
 import javax.management.StandardMBean;
 
 import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.AsyncJobMBean;
 
 import com.cloud.utils.DateUtil;
 
 public class AsyncJobMBeanImpl extends StandardMBean implements AsyncJobMBean {
-	private AsyncJob _job;
+	private final AsyncJob _job;
 	
 	public AsyncJobMBeanImpl(AsyncJob job) {
 		super(AsyncJobMBean.class, false);
@@ -36,84 +35,100 @@ public class AsyncJobMBeanImpl extends StandardMBean implements AsyncJobMBean {
 		_job = job;
 	}
 	
-	public long getAccountId() {
+	@Override
+    public long getAccountId() {
 		return _job.getAccountId();
 	}
 	
-	public long getUserId() {
+	@Override
+    public long getUserId() {
 		return _job.getUserId();
 	}
 	
-	public String getCmd() {
+	@Override
+    public String getCmd() {
 		return _job.getCmd();
 	}
 	
-	public String getCmdInfo() {
+	@Override
+    public String getCmdInfo() {
 		return _job.getCmdInfo();
 	}
 	
-	public String getStatus() {
-		int jobStatus = _job.getStatus();
-		switch(jobStatus) {
-		case AsyncJobConstants.STATUS_SUCCEEDED :
+	@Override
+    public String getStatus() {
+        switch (_job.getStatus()) {
+        case SUCCEEDED:
 			return "Completed";
 		
-		case AsyncJobConstants.STATUS_IN_PROGRESS:
+        case IN_PROGRESS:
 			return "In preogress";
 			
-		case AsyncJobConstants.STATUS_FAILED:
+        case FAILED:
 			return "failed";
+			
+        case CANCELLED:
+            return "cancelled";
 		}
 		
 		return "Unknow";
 	}
 	
-	public int getProcessStatus() {
+	@Override
+    public int getProcessStatus() {
 		return _job.getProcessStatus();
 	}
 	
-	public int getResultCode() {
+	@Override
+    public int getResultCode() {
 		return _job.getResultCode();
 	}
 	
-	public String getResult() {
+	@Override
+    public String getResult() {
 		return _job.getResult();
 	}
 	
-	public String getInstanceType() {
+	@Override
+    public String getInstanceType() {
 		if(_job.getInstanceType() != null)
 			return _job.getInstanceType().toString();
 		return "N/A";
 	}
 	
-	public String getInstanceId() {
+	@Override
+    public String getInstanceId() {
 		if(_job.getInstanceId() != null)
 			return String.valueOf(_job.getInstanceId());
 		return "N/A";
 	}
 	
-	public String getInitMsid() {
+	@Override
+    public String getInitMsid() {
 		if(_job.getInitMsid() != null) {
 			return String.valueOf(_job.getInitMsid());
 		}
 		return "N/A";
 	}
 	
-	public String getCreateTime() {
+	@Override
+    public String getCreateTime() {
 		Date time = _job.getCreated();
 		if(time != null)
 			return DateUtil.getDateDisplayString(TimeZone.getDefault(), time);
 		return "N/A";
 	}
 	
-	public String getLastUpdateTime() {
+	@Override
+    public String getLastUpdateTime() {
 		Date time = _job.getLastUpdated();
 		if(time != null)
 			return DateUtil.getDateDisplayString(TimeZone.getDefault(), time);
 		return "N/A";
 	}
 	
-	public String getLastPollTime() {
+	@Override
+    public String getLastPollTime() {
 		Date time = _job.getLastPolled();
 	
 		if(time != null)
@@ -121,7 +136,8 @@ public class AsyncJobMBeanImpl extends StandardMBean implements AsyncJobMBean {
 		return "N/A";
 	}
 	
-	public String getSyncQueueId() {
+	@Override
+    public String getSyncQueueId() {
 		SyncQueueItem item = _job.getSyncSource();
 		if(item != null && item.getQueueId() != null) {
 			return String.valueOf(item.getQueueId());
@@ -129,7 +145,8 @@ public class AsyncJobMBeanImpl extends StandardMBean implements AsyncJobMBean {
 		return "N/A";
 	}
 	
-	public String getSyncQueueContentType() {
+	@Override
+    public String getSyncQueueContentType() {
 		SyncQueueItem item = _job.getSyncSource();
 		if(item != null) {
 			return item.getContentType();
@@ -137,7 +154,8 @@ public class AsyncJobMBeanImpl extends StandardMBean implements AsyncJobMBean {
 		return "N/A";
 	}
 	
-	public String getSyncQueueContentId() {
+	@Override
+    public String getSyncQueueContentId() {
 		SyncQueueItem item = _job.getSyncSource();
 		if(item != null && item.getContentId() != null) {
 			return String.valueOf(item.getContentId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
index 0e103b9..cab047b 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
@@ -23,6 +23,8 @@ import javax.persistence.Column;
 import javax.persistence.DiscriminatorColumn;
 import javax.persistence.DiscriminatorType;
 import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
@@ -44,11 +46,14 @@ import com.cloud.utils.db.GenericDao;
 @Inheritance(strategy=InheritanceType.JOINED)
 @DiscriminatorColumn(name="job_type", discriminatorType=DiscriminatorType.STRING, length=32)
 public class AsyncJobVO implements AsyncJob, JobInfo {
+
+    public static final String JOB_DISPATCHER_PSEUDO = "pseudoJobDispatcher";
+    public static final String PSEUDO_JOB_INSTANCE_TYPE = "Thread";
 	
 	@Id
     @GeneratedValue(strategy=GenerationType.IDENTITY)
     @Column(name="id")
-    private Long id = null;
+    private long id;
 	
     @Column(name="job_type", length=32)
     protected String type;
@@ -78,7 +83,8 @@ public class AsyncJobVO implements AsyncJob, JobInfo {
     private String cmdInfo;
   
     @Column(name="job_status")
-    private int status;
+    @Enumerated(value = EnumType.ORDINAL)
+    private Status status;
     
     @Column(name="job_process_status")
     private int processStatus;
@@ -145,7 +151,7 @@ public class AsyncJobVO implements AsyncJob, JobInfo {
 		return id;
 	}
 
-	public void setId(Long id) {
+    public void setId(long id) {
 		this.id = id;
 	}
 	
@@ -236,11 +242,11 @@ public class AsyncJobVO implements AsyncJob, JobInfo {
 	}
 	
 	@Override
-    public int getStatus() {
+    public Status getStatus() {
 		return status;
 	}
 
-	public void setStatus(int status) {
+    public void setStatus(Status status) {
 		this.status = status;
 	}
 	

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/src/com/cloud/api/ApiAsyncJobDispatcher.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiAsyncJobDispatcher.java b/server/src/com/cloud/api/ApiAsyncJobDispatcher.java
index c442559..e0823dc 100644
--- a/server/src/com/cloud/api/ApiAsyncJobDispatcher.java
+++ b/server/src/com/cloud/api/ApiAsyncJobDispatcher.java
@@ -33,9 +33,9 @@ import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.ExceptionResponse;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.user.Account;
 import com.cloud.user.dao.AccountDao;
@@ -93,7 +93,7 @@ public class ApiAsyncJobDispatcher extends AdapterBase implements AsyncJobDispat
                 _dispatcher.dispatch(cmdObj, params, true);
 
                 // serialize this to the async job table
-                _asyncJobMgr.completeAsyncJob(job.getId(), AsyncJobConstants.STATUS_SUCCEEDED, 0, cmdObj.getResponseObject());
+                _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, cmdObj.getResponseObject());
             } finally {
                 CallContext.unregister();
             }
@@ -116,7 +116,7 @@ public class ApiAsyncJobDispatcher extends AdapterBase implements AsyncJobDispat
 
             // FIXME:  setting resultCode to ApiErrorCode.INTERNAL_ERROR is not right, usually executors have their exception handling
             //         and we need to preserve that as much as possible here
-            _asyncJobMgr.completeAsyncJob(job.getId(), AsyncJobConstants.STATUS_FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), response);
+            _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), response);
         }
 	}
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index ae5be33..be161c6 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -605,7 +605,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                 if (response.getObjectId() != null && objectJobMap.containsKey(response.getObjectId())) {
                     AsyncJob job = objectJobMap.get(response.getObjectId());
                     response.setJobId(job.getUuid());
-                    response.setJobStatus(job.getStatus());
+                    response.setJobStatus(job.getStatus().ordinal());
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/src/com/cloud/async/AsyncJobManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/async/AsyncJobManagerImpl.java b/server/src/com/cloud/async/AsyncJobManagerImpl.java
index 332587a..2e3a9a0 100644
--- a/server/src/com/cloud/async/AsyncJobManagerImpl.java
+++ b/server/src/com/cloud/async/AsyncJobManagerImpl.java
@@ -38,9 +38,9 @@ import org.apache.log4j.Logger;
 import org.apache.cloudstack.api.ApiErrorCode;
 import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
 import org.apache.cloudstack.api.response.ExceptionResponse;
+import org.apache.cloudstack.config.ConfigRepo;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
 import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
@@ -60,11 +60,14 @@ import org.apache.cloudstack.framework.jobs.impl.SyncQueueVO;
 import org.apache.cloudstack.framework.messagebus.MessageBus;
 import org.apache.cloudstack.framework.messagebus.MessageDetector;
 import org.apache.cloudstack.framework.messagebus.PublishScope;
+import org.apache.cloudstack.jobs.JobInfo;
+import org.apache.cloudstack.jobs.JobInfo.Status;
 
 import com.cloud.api.ApiSerializerHelper;
 import com.cloud.cluster.ClusterManager;
 import com.cloud.cluster.ClusterManagerListener;
 import com.cloud.cluster.ManagementServerHost;
+import com.cloud.cluster.ManagementServerNode;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.dao.ConfigurationDao;
 import com.cloud.exception.InvalidParameterValueException;
@@ -76,7 +79,6 @@ import com.cloud.utils.DateUtil;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Predicate;
 import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.component.ComponentContext;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
@@ -87,11 +89,16 @@ import com.cloud.utils.db.Transaction;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.exception.ExceptionUtil;
 import com.cloud.utils.mgmt.JmxUtil;
-import com.cloud.utils.net.MacAddress;
 
 public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, ClusterManagerListener {
-    public static final Logger s_logger = Logger.getLogger(AsyncJobManagerImpl.class);
+    private static final Logger s_logger = Logger.getLogger(AsyncJobManagerImpl.class);
     private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3; 	// 3 seconds
+    private static final String JOB_POOL_THREAD_PREFIX = "Job-Executor";
+    // Although we may have detailed masks for each individual wakeup event, i.e.
+    // periodical timer, matched topic from message bus, it seems that we don't
+    // need to distinguish them to such level. Therefore, only one wakeup signal
+    // is defined
+    public static final int SIGNAL_MASK_WAKEUP = 1;
 
     private static final int MAX_ONETIME_SCHEDULE_SIZE = 50;
     private static final int HEARTBEAT_INTERVAL = 2000;
@@ -107,6 +114,8 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
     @Inject private List<AsyncJobDispatcher> _jobDispatchers;
     @Inject private MessageBus _messageBus;
     @Inject private AsyncJobMonitor _jobMonitor;
+    @Inject
+    private ConfigRepo _configRepo;
 
 	private long _jobExpireSeconds = 86400;						// 1 day
     private long _jobCancelThresholdSeconds = 3600;         	// 1 hour (for cancelling the jobs blocking other jobs)
@@ -128,15 +137,15 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
     }
     
     @Override @DB
-	public AsyncJob getPseudoJob() {
+    public AsyncJob getPseudoJob(long accountId, long userId) {
     	AsyncJobVO job = _jobDao.findPseudoJob(Thread.currentThread().getId(), getMsid());
     	if(job == null) {
 	    	job = new AsyncJobVO();
-	    	job.setAccountId(_accountMgr.getSystemAccount().getId());
-	    	job.setUserId(_accountMgr.getSystemUser().getId());
+            job.setAccountId(accountId);
+            job.setUserId(userId);
 	    	job.setInitMsid(getMsid());
-	    	job.setDispatcher(AsyncJobConstants.JOB_DISPATCHER_PSEUDO);
-	    	job.setInstanceType(AsyncJobConstants.PSEUDO_JOB_INSTANCE_TYPE);
+            job.setDispatcher(AsyncJobVO.JOB_DISPATCHER_PSEUDO);
+            job.setInstanceType(AsyncJobVO.PSEUDO_JOB_INSTANCE_TYPE);
 	    	job.setInstanceId(Thread.currentThread().getId());
 	    	_jobDao.persist(job);
     	}
@@ -149,31 +158,19 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
     }
 
     @SuppressWarnings("unchecked")
-	@Override @DB
+    @DB
     public long submitAsyncJob(AsyncJob job, boolean scheduleJobExecutionInContext) {
-        Transaction txt = Transaction.currentTxn();
-        try {
-        	@SuppressWarnings("rawtypes")
-			GenericDao dao = GenericDaoBase.getDao(job.getClass());
-        	
-            txt.start();
-            job.setInitMsid(getMsid());
-            dao.persist(job);
-            txt.commit();
-
-            // no sync source originally
-            job.setSyncSource(null);
-            scheduleExecution(job, scheduleJobExecutionInContext);
-            if(s_logger.isDebugEnabled()) {
-                s_logger.debug("submit async job-" + job.getId() + ", details: " + job.toString());
-            }
-            return job.getId();
-        } catch(Exception e) {
-            txt.rollback();
-            String errMsg = "Unable to schedule async job for command " + job.getCmd() + ", unexpected exception.";
-            s_logger.warn(errMsg, e);
-            throw new CloudRuntimeException(errMsg);
+        @SuppressWarnings("rawtypes")
+        GenericDao dao = GenericDaoBase.getDao(job.getClass());
+        job.setInitMsid(getMsid());
+        job.setSyncSource(null);        // no sync source originally
+        dao.persist(job);
+
+        scheduleExecution(job, scheduleJobExecutionInContext);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("submit async job-" + job.getId() + ", details: " + job.toString());
         }
+        return job.getId();
     }
 
     @SuppressWarnings("unchecked")
@@ -199,7 +196,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
 	}
     
     @Override @DB
-    public void completeAsyncJob(long jobId, int jobStatus, int resultCode, Object resultObject) {
+    public void completeAsyncJob(long jobId, Status jobStatus, int resultCode, Object resultObject) {
         if(s_logger.isDebugEnabled()) {
             s_logger.debug("Complete async job-" + jobId + ", jobStatus: " + jobStatus +
                     ", resultCode: " + resultCode + ", result: " + resultObject);
@@ -219,7 +216,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                 return;
             }
             
-            if(job.getStatus() != AsyncJobConstants.STATUS_IN_PROGRESS) {
+            if(job.getStatus() != JobInfo.Status.IN_PROGRESS) {
                 if(s_logger.isDebugEnabled()) {
                     s_logger.debug("job-" + jobId + " is already completed.");
                 }
@@ -251,7 +248,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
             for(Long id : wakeupList) {
             	// TODO, we assume that all jobs in this category is API job only
             	AsyncJobVO jobToWakeup = _jobDao.findById(id);
-            	if(jobToWakeup != null && (jobToWakeup.getPendingSignals() & AsyncJobConstants.SIGNAL_MASK_WAKEUP) != 0)
+                if (jobToWakeup != null && (jobToWakeup.getPendingSignals() & SIGNAL_MASK_WAKEUP) != 0)
             	    scheduleExecution(jobToWakeup, false);
             }
              
@@ -358,7 +355,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
     }
     
     @Override @DB
-    public void completeJoin(long joinJobId, int joinStatus, String joinResult) {
+    public void completeJoin(long joinJobId, JobInfo.Status joinStatus, String joinResult) {
     	_joinMapDao.completeJoin(joinJobId, joinStatus, joinResult, getMsid());
     }
     
@@ -436,8 +433,8 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                 jobResult.setResultCode(job.getResultCode());
                 jobResult.setUuid(job.getUuid());
 
-                if(job.getStatus() == AsyncJobConstants.STATUS_SUCCEEDED ||
-                        job.getStatus() == AsyncJobConstants.STATUS_FAILED) {
+                if(job.getStatus() == JobInfo.Status.SUCCEEDED ||
+                        job.getStatus() == JobInfo.Status.FAILED) {
 
                     if(s_logger.isDebugEnabled()) {
                         s_logger.debug("Async job-" + jobId + " completed");
@@ -451,14 +448,14 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                     s_logger.debug("Async job-" + jobId + " does not exist, invalid job id?");
                 }
 
-                jobResult.setJobStatus(AsyncJobConstants.STATUS_FAILED);
+                jobResult.setJobStatus(JobInfo.Status.FAILED);
                 jobResult.setResult("job-" + jobId + " does not exist");
             }
             txt.commit();
         } catch(Exception e) {
             s_logger.error("Unexpected exception while querying async job-" + jobId + " status: ", e);
 
-            jobResult.setJobStatus(AsyncJobConstants.STATUS_FAILED);
+            jobResult.setJobStatus(JobInfo.Status.FAILED);
             jobResult.setResult("Exception: " + e.toString());
             txt.rollback();
         }
@@ -475,7 +472,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
     }
 
     private void scheduleExecution(final AsyncJob job, boolean executeInContext) {
-        Runnable runnable = getExecutorRunnable(this, job);
+        Runnable runnable = getExecutorRunnable(job);
         if (executeInContext) {
             runnable.run();
         } else {
@@ -516,7 +513,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
     	}
     }
     
-    private Runnable getExecutorRunnable(final AsyncJobManager mgr, final AsyncJob job) {
+    private Runnable getExecutorRunnable(final AsyncJob job) {
         return new Runnable() {
             @Override
             public void run() {
@@ -539,20 +536,19 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                     }
                     
                     _jobMonitor.registerActiveTask(runNumber, job.getId());
-                    AsyncJobExecutionContext.setCurrentExecutionContext((AsyncJobExecutionContext)ComponentContext.inject(new AsyncJobExecutionContext(job))
-                    );
+                    AsyncJobExecutionContext.setCurrentExecutionContext(new AsyncJobExecutionContext(job));
                     
                     // execute the job
                     if(s_logger.isDebugEnabled()) {
                         s_logger.debug("Executing " + job);
                     }
 
-                    if((getAndResetPendingSignals(job) & AsyncJobConstants.SIGNAL_MASK_WAKEUP) != 0) {
+                    if ((getAndResetPendingSignals(job) & SIGNAL_MASK_WAKEUP) != 0) {
                     	AsyncJobDispatcher jobDispatcher = getWakeupDispatcher(job);
                     	if(jobDispatcher != null) {
                     		jobDispatcher.runJob(job);
                     	} else {
-                    		s_logger.error("Unable to find a wakeup dispatcher from the joined job. job-" + job.getId());
+                    		s_logger.error("Unable to find a wakeup dispatcher from the joined job: " + job);
                     	}
                     } else {
 	                    AsyncJobDispatcher jobDispatcher = getDispatcher(job.getDispatcher());
@@ -560,7 +556,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
 	                    	jobDispatcher.runJob(job);
 	                    } else {
 	                    	s_logger.error("Unable to find job dispatcher, job will be cancelled");
-	                        completeAsyncJob(job.getId(), AsyncJobConstants.STATUS_FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), null);
+	                        completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), null);
 	                    }
                     }
                     
@@ -570,7 +566,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                    
             	} catch (Throwable e) {
             		s_logger.error("Unexpected exception", e);
-                    completeAsyncJob(job.getId(), AsyncJobConstants.STATUS_FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), null);
+                    completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), null);
             	} finally {
             		// guard final clause as well
                     try {
@@ -598,7 +594,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                     	//
                     	// clean execution environment
                     	//
-                        AsyncJobExecutionContext.setCurrentExecutionContext(null);
+                        AsyncJobExecutionContext.unregister();
                         _jobMonitor.unregisterActiveTask(runNumber);
 	                    
                     } catch(Throwable e) {
@@ -727,7 +723,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                     for(Long jobId : standaloneWakeupJobs) {
                     	// TODO, we assume that all jobs in this category is API job only
                     	AsyncJobVO job = _jobDao.findById(jobId);
-                    	if(job != null && (job.getPendingSignals() & AsyncJobConstants.SIGNAL_MASK_WAKEUP) != 0)
+                        if (job != null && (job.getPendingSignals() & SIGNAL_MASK_WAKEUP) != 0)
                     	    scheduleExecution(job, false);
                     }
                 } catch(Throwable e) {
@@ -789,7 +785,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                     if(blockItems != null && blockItems.size() > 0) {
                         for(SyncQueueItemVO item : blockItems) {
                             if(item.getContentType().equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) {
-                                completeAsyncJob(item.getContentId(), AsyncJobConstants.STATUS_FAILED, 0,
+                                completeAsyncJob(item.getContentId(), JobInfo.Status.FAILED, 0,
                                         getResetResultResponse("Job is cancelled as it has been blocking others for too long"));
                             }
 
@@ -819,11 +815,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
     }
 
     private long getMsid() {
-        if(_clusterMgr != null) {
-            return _clusterMgr.getManagementNodeId();
-        }
-
-        return MacAddress.getMacAddress().toLong();
+        return ManagementServerNode.getManagementServerId();
     }
 
     private void cleanupPendingJobs(List<SyncQueueItemVO> l) {
@@ -838,7 +830,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                     Long jobId = item.getContentId();
                     if(jobId != null) {
                         s_logger.warn("Mark job as failed as its correspoding queue-item has been discarded. job id: " + jobId);
-                        completeAsyncJob(jobId, AsyncJobConstants.STATUS_FAILED, 0, getResetResultResponse("Execution was cancelled because of server shutdown"));
+                        completeAsyncJob(jobId, JobInfo.Status.FAILED, 0, getResetResultResponse("Execution was cancelled because of server shutdown"));
                     }
                 }
                 _queueMgr.purgeItem(item.getId());
@@ -864,7 +856,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
             int poolSize = (cloudMaxActive * 2) / 3;
 
             s_logger.info("Start AsyncJobManager thread pool in size " + poolSize);
-            _executor = Executors.newFixedThreadPool(poolSize, new NamedThreadFactory(AsyncJobConstants.JOB_POOL_THREAD_PREFIX));
+            _executor = Executors.newFixedThreadPool(poolSize, new NamedThreadFactory(JOB_POOL_THREAD_PREFIX));
         } catch (final Exception e) {
             throw new ConfigurationException("Unable to load db.properties to configure AsyncJobManagerImpl");
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/src/com/cloud/async/AsyncJobResult.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/async/AsyncJobResult.java b/server/src/com/cloud/async/AsyncJobResult.java
index 783655e..d71e64b 100644
--- a/server/src/com/cloud/async/AsyncJobResult.java
+++ b/server/src/com/cloud/async/AsyncJobResult.java
@@ -16,14 +16,14 @@
 // under the License.
 package com.cloud.async;
 
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.api.ApiSerializerHelper;
 
 public class AsyncJobResult {
 	
 	private long jobId;
-	private int jobStatus;
+    private JobInfo.Status jobStatus;
 	private int processStatus;
 	private int resultCode;
 	private String result;
@@ -31,7 +31,7 @@ public class AsyncJobResult {
 
 	public AsyncJobResult(long jobId) {
 		this.jobId = jobId;
-		jobStatus = AsyncJobConstants.STATUS_IN_PROGRESS;
+		jobStatus = JobInfo.Status.IN_PROGRESS;
 		processStatus = 0;
 		resultCode = 0;
 		result = "";
@@ -46,18 +46,18 @@ public class AsyncJobResult {
 	}
 	
 	public String getUuid() {
-		return this.uuid;
+		return uuid;
 	}
 	
 	public void setUuid(String uuid) {
 		this.uuid = uuid;
 	}
 	
-	public int getJobStatus() {
+    public JobInfo.Status getJobStatus() {
 		return jobStatus;
 	}
 	
-	public void setJobStatus(int jobStatus) {
+    public void setJobStatus(JobInfo.Status jobStatus) {
 		this.jobStatus = jobStatus;
 	}
 	
@@ -97,7 +97,7 @@ public class AsyncJobResult {
     public String toString() {
 		StringBuffer sb = new StringBuffer();
 		sb.append("AsyncJobResult {jobId:").append(getJobId());
-		sb.append(", jobStatus: ").append(getJobStatus());
+        sb.append(", jobStatus: ").append(getJobStatus().ordinal());
 		sb.append(", processStatus: ").append(getProcessStatus());
 		sb.append(", resultCode: ").append(getResultCode());
 		sb.append(", result: ").append(result);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index f6bddf0..513a713 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -1728,11 +1728,11 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
 //	    	_itMgr.processVmStartWork(vm, ((VmWorkStart)work).getParams(),
 //	    		user, account,  ((VmWorkStart)work).getPlan());
 //
-//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(AsyncJobConstants.STATUS_SUCCEEDED, null);
+//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(JobInfo.Status.SUCCEEDED, null);
 //    	} catch(Exception e) {
 //    		s_logger.error("Exception in process VM-start work", e);
 //    		String result = SerializerHelper.toObjectSerializedString(e);
-//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(AsyncJobConstants.STATUS_FAILED, result);
+//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(JobInfo.Status.FAILED, result);
 //    	}
 //    }
 //
@@ -1748,11 +1748,11 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
 //    	try {
 //	    	_itMgr.processVmStopWork(vm, ((VmWorkStop)work).isForceStop(), user, account);
 //
-//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(AsyncJobConstants.STATUS_SUCCEEDED, null);
+//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(JobInfo.Status.SUCCEEDED, null);
 //    	} catch(Exception e) {
 //    		s_logger.error("Exception in process VM-stop work", e);
 //    		String result = SerializerHelper.toObjectSerializedString(e);
-//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(AsyncJobConstants.STATUS_FAILED, result);
+//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(JobInfo.Status.FAILED, result);
 //    	}
 //    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 6de8840..9fc4645 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -3469,7 +3469,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
             if (asyncExecutionContext != null) {
                 job = asyncExecutionContext.getJob();
                 _asyncMgr.updateAsyncJobAttachment(job.getId(), Upload.Type.VOLUME.toString(), volumeId);
-                _asyncMgr.updateAsyncJobStatus(job.getId(), AsyncJobConstants.STATUS_IN_PROGRESS, resultObj);
+                _asyncMgr.updateAsyncJobStatus(job.getId(), JobInfo.Status.IN_PROGRESS, resultObj);
             }
             String value = _configs.get(Config.CopyVolumeWait.toString());
             int copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
@@ -3490,7 +3490,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
                 resultObj.setResultString(errorString);
                 resultObj.setUploadStatus(UploadVO.Status.COPY_ERROR.toString());
                 if (asyncExecutionContext != null) {
-                    _asyncMgr.completeAsyncJob(job.getId(), AsyncJobConstants.STATUS_FAILED, 0, resultObj);
+                    _asyncMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, resultObj);
                 }
 
                 // Update the DB that volume couldn't be copied

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
index 562db28..1324ac7 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
@@ -1462,11 +1462,11 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
 //	    	_itMgr.processVmStartWork(vm, ((VmWorkStart)work).getParams(),
 //	    		user, account,  ((VmWorkStart)work).getPlan());
 //
-//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(AsyncJobConstants.STATUS_SUCCEEDED, null);
+//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(JobInfo.Status.SUCCEEDED, null);
 //    	} catch(Exception e) {
 //    		s_logger.error("Exception in process VM-start work", e);
 //    		String result = SerializerHelper.toObjectSerializedString(e);
-//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(AsyncJobConstants.STATUS_FAILED, result);
+//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(JobInfo.Status.FAILED, result);
 //    	}
 //    }
 //
@@ -1482,11 +1482,11 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
 //    	try {
 //	    	_itMgr.processVmStopWork(vm, ((VmWorkStop)work).isForceStop(), user, account);
 //
-//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(AsyncJobConstants.STATUS_SUCCEEDED, null);
+//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(JobInfo.Status.SUCCEEDED, null);
 //    	} catch(Exception e) {
 //    		s_logger.error("Exception in process VM-stop work", e);
 //    		String result = SerializerHelper.toObjectSerializedString(e);
-//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(AsyncJobConstants.STATUS_FAILED, result);
+//    		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(JobInfo.Status.FAILED, result);
 //    	}
 //    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
index c6dd772..607e39b 100644
--- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
@@ -143,14 +143,14 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
             Long asyncJobId = snapshotSchedule.getAsyncJobId();
             AsyncJobVO asyncJob = _asyncJobDao.findById(asyncJobId);
             switch (asyncJob.getStatus()) {
-            case AsyncJobConstants.STATUS_SUCCEEDED:
+            case JobInfo.Status.SUCCEEDED:
                 // The snapshot has been successfully backed up.
                 // The snapshot state has also been cleaned up.
                 // We can schedule the next job for this snapshot.
                 // Remove the existing entry in the snapshot_schedule table.
                 scheduleNextSnapshotJob(snapshotSchedule);
                 break;
-            case AsyncJobConstants.STATUS_FAILED:
+            case JobInfo.Status.FAILED:
                 // Check the snapshot status.
                 Long snapshotId = snapshotSchedule.getSnapshotId();
                 if (snapshotId == null) {
@@ -188,7 +188,7 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
                 }
 
                 break;
-            case AsyncJobConstants.STATUS_IN_PROGRESS:
+            case JobInfo.Status.IN_PROGRESS:
                 // There is no way of knowing from here whether
                 // 1) Another management server is processing this snapshot job
                 // 2) The management server has crashed and this snapshot is lying

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/src/com/cloud/storage/upload/UploadListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/com/cloud/storage/upload/UploadListener.java
index b66624d..b6a9288 100755
--- a/server/src/com/cloud/storage/upload/UploadListener.java
+++ b/server/src/com/cloud/storage/upload/UploadListener.java
@@ -365,7 +365,7 @@ public class UploadListener implements Listener {
 		resultObj.setResultString(uploadErrorString);
 		resultObj.setState(state.toString());
 		asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
-		asyncMgr.updateAsyncJobStatus(asyncJobId, AsyncJobConstants.STATUS_IN_PROGRESS, resultObj);
+		asyncMgr.updateAsyncJobStatus(asyncJobId, JobInfo.Status.IN_PROGRESS, resultObj);
 
 		UploadVO vo = uploadDao.createForUpdate();
 		vo.setUploadState(state);
@@ -378,7 +378,7 @@ public class UploadListener implements Listener {
 		resultObj.setResultString(uploadErrorString);
 		resultObj.setState(state.toString());
 		asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
-		asyncMgr.updateAsyncJobStatus(asyncJobId, AsyncJobConstants.STATUS_IN_PROGRESS, resultObj);
+		asyncMgr.updateAsyncJobStatus(asyncJobId, JobInfo.Status.IN_PROGRESS, resultObj);
 
 
 		UploadVO vo = uploadDao.createForUpdate();
@@ -407,12 +407,12 @@ public class UploadListener implements Listener {
 
 		if (answer.getUploadStatus() == Status.UPLOAD_IN_PROGRESS){
 			asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
-			asyncMgr.updateAsyncJobStatus(asyncJobId, AsyncJobConstants.STATUS_IN_PROGRESS, resultObj);
+			asyncMgr.updateAsyncJobStatus(asyncJobId, JobInfo.Status.IN_PROGRESS, resultObj);
 		}else if(answer.getUploadStatus() == Status.UPLOADED){
 		    resultObj.setResultString("Success");
-			asyncMgr.completeAsyncJob(asyncJobId, AsyncJobConstants.STATUS_SUCCEEDED, 1, resultObj);
+			asyncMgr.completeAsyncJob(asyncJobId, JobInfo.Status.SUCCEEDED, 1, resultObj);
 		}else{
-			asyncMgr.completeAsyncJob(asyncJobId, AsyncJobConstants.STATUS_FAILED, 2, resultObj);
+			asyncMgr.completeAsyncJob(asyncJobId, JobInfo.Status.FAILED, 2, resultObj);
 		}
         UploadVO updateBuilder = uploadDao.createForUpdate();
 		updateBuilder.setUploadPercent(answer.getUploadPct());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/src/com/cloud/vm/SystemVmLoadScanner.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/SystemVmLoadScanner.java b/server/src/com/cloud/vm/SystemVmLoadScanner.java
index 704129d..4d378ce 100644
--- a/server/src/com/cloud/vm/SystemVmLoadScanner.java
+++ b/server/src/com/cloud/vm/SystemVmLoadScanner.java
@@ -71,8 +71,8 @@ public class SystemVmLoadScanner<T> {
             @Override
             public void run() {
                 try {
-                    CallContext.registerSystemCallContextOnceOnly();
-                    AsyncJobExecutionContext.registerPseudoExecutionContext();
+                    CallContext cc = CallContext.registerSystemCallContextOnceOnly();
+                    AsyncJobExecutionContext.registerPseudoExecutionContext(cc.getCallingAccountId(), cc.getCallingUserId());
                 } catch (Exception e) {
                     s_logger.fatal("Unable to start the capacity scan task", e);
                     System.exit(1);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/test/com/cloud/async/TestAsyncJobManager.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/async/TestAsyncJobManager.java b/server/test/com/cloud/async/TestAsyncJobManager.java
index 320c68f..419f5fa 100644
--- a/server/test/com/cloud/async/TestAsyncJobManager.java
+++ b/server/test/com/cloud/async/TestAsyncJobManager.java
@@ -48,10 +48,13 @@ import org.apache.cloudstack.framework.jobs.impl.SyncQueueItemVO;
 import org.apache.cloudstack.framework.jobs.impl.SyncQueueVO;
 import org.apache.cloudstack.framework.messagebus.MessageBus;
 import org.apache.cloudstack.framework.messagebus.PublishScope;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.cluster.ClusterManager;
+import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.user.AccountVO;
+import com.cloud.user.User;
 import com.cloud.user.UserVO;
 import com.cloud.utils.Predicate;
 import com.cloud.utils.component.ComponentContext;
@@ -142,21 +145,21 @@ public class TestAsyncJobManager extends TestCase {
     	AsyncJobJoinMapVO record = joinMapDao.getJoinRecord(2, 1);
     	Assert.assertTrue(record != null);
     	Assert.assertTrue(record.getJoinMsid() == 100);
-    	Assert.assertTrue(record.getJoinStatus() == AsyncJobConstants.STATUS_IN_PROGRESS);
+    	Assert.assertTrue(record.getJoinStatus() == JobInfo.Status.IN_PROGRESS);
     	
-    	joinMapDao.completeJoin(1, AsyncJobConstants.STATUS_SUCCEEDED, "Done", 101);
+    	joinMapDao.completeJoin(1, JobInfo.Status.SUCCEEDED, "Done", 101);
     	
     	record = joinMapDao.getJoinRecord(2, 1);
     	Assert.assertTrue(record != null);
     	Assert.assertTrue(record.getJoinMsid() == 100);
-    	Assert.assertTrue(record.getJoinStatus() == AsyncJobConstants.STATUS_SUCCEEDED);
+    	Assert.assertTrue(record.getJoinStatus() == JobInfo.Status.SUCCEEDED);
     	Assert.assertTrue(record.getJoinResult().equals("Done"));
     	Assert.assertTrue(record.getCompleteMsid() == 101);
     	
     	record = joinMapDao.getJoinRecord(3, 1);
     	Assert.assertTrue(record != null);
     	Assert.assertTrue(record.getJoinMsid() == 100);
-    	Assert.assertTrue(record.getJoinStatus() == AsyncJobConstants.STATUS_SUCCEEDED);
+    	Assert.assertTrue(record.getJoinStatus() == JobInfo.Status.SUCCEEDED);
     	Assert.assertTrue(record.getJoinResult().equals("Done"));
     	Assert.assertTrue(record.getCompleteMsid() == 101);
     	
@@ -198,7 +201,7 @@ public class TestAsyncJobManager extends TestCase {
     
     @Test
     public void testPseudoJob() {
-    	AsyncJob job = asyncMgr.getPseudoJob();
+        AsyncJob job = asyncMgr.getPseudoJob(Account.ACCOUNT_ID_SYSTEM, User.UID_SYSTEM);
     	Assert.assertTrue(job.getInstanceType().equals(AsyncJobConstants.PSEUDO_JOB_INSTANCE_TYPE));
     	Assert.assertTrue(job.getInstanceId().longValue() == Thread.currentThread().getId());
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
index 2c1249e..49b0e31 100644
--- a/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
+++ b/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
@@ -316,7 +316,7 @@ public class VmWorkMockVirtualMachineManagerImpl implements VirtualMachineManage
 		if(wakeupCount++ < 3) {
 			AsyncJobExecutionContext.getCurrentExecutionContext().resetSyncSource();
 		} else {
-			AsyncJobExecutionContext.getCurrentExecutionContext().completeAsyncJob(AsyncJobConstants.STATUS_SUCCEEDED, 0, null);
+			AsyncJobExecutionContext.getCurrentExecutionContext().completeAsyncJob(JobInfo.Status.SUCCEEDED, 0, null);
 		}
 	}
 	

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea6ca5ff/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java b/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java
index 72210b4..eb5e81f 100644
--- a/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java
+++ b/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java
@@ -20,7 +20,7 @@ public class VmWorkTestWorkJobDispatcher extends AdapterBase implements AsyncJob
 		} catch (InterruptedException e) {
 		}
 		
-		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(AsyncJobConstants.STATUS_SUCCEEDED, null);
+		AsyncJobExecutionContext.getCurrentExecutionContext().completeJobAndJoin(JobInfo.Status.SUCCEEDED, null);
 		s_logger.info("End work job execution. job-" + job.getId());
 	}
 }


[9/9] git commit: updated refs/heads/vmsync to 309f8da

Posted by ah...@apache.org.
Finally starting vm again


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/309f8da6
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/309f8da6
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/309f8da6

Branch: refs/heads/vmsync
Commit: 309f8da6de19108343749ac2f2edde80107e4f37
Parents: 6adf761
Author: Alex Huang <al...@gmail.com>
Authored: Mon Jun 17 17:03:52 2013 -0700
Committer: Alex Huang <al...@gmail.com>
Committed: Mon Jun 17 17:25:04 2013 -0700

----------------------------------------------------------------------
 .../cloudstack/engine/config/Configs.java       | 46 --------------------
 .../com/cloud/vm/VirtualMachineManagerImpl.java | 11 +++--
 .../framework/jobs/impl/OutcomeImpl.java        |  6 ++-
 3 files changed, 12 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/309f8da6/engine/components-api/src/org/apache/cloudstack/engine/config/Configs.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/org/apache/cloudstack/engine/config/Configs.java b/engine/components-api/src/org/apache/cloudstack/engine/config/Configs.java
deleted file mode 100644
index 14598bd..0000000
--- a/engine/components-api/src/org/apache/cloudstack/engine/config/Configs.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.engine.config;
-
-import org.apache.cloudstack.config.ConfigKey;
-import org.apache.cloudstack.engine.service.api.OrchestrationService;
-
-public interface Configs {
-    
-    public static final ConfigKey<Integer> StartRetry = new ConfigKey<Integer>(
-            Integer.class, "start.retry", "Advanced", OrchestrationService.class, "10", "Number of times to retry create and start commands", true, null);
-    public static final ConfigKey<Long> VmOpWaitInterval = new ConfigKey<Long>(
-            Long.class, "vm.op.wait.interval", "Advanced", OrchestrationService.class, "120", "Time (in seconds) to wait before checking if a previous operation has succeeded",
-            true, null);
-    public static final ConfigKey<Integer> VmOpLockStateRetry = new ConfigKey<Integer>(
-            Integer.class, "vm.op.lock.state.retry", "Advanced", OrchestrationService.class, "5", "Times to retry locking the state of a VM for operations",
-            true, "-1 means try forever");
-    public static final ConfigKey<Long> VmOpCleanupInterval = new ConfigKey<Long>(
-            Long.class, "vm.op.cleanup.interval", "Advanced", OrchestrationService.class, "86400", "Interval to run the thread that cleans up the vm operations (in seconds)",
-            false, "Seconds");
-    public static final ConfigKey<Long> VmOpCleanupWait = new ConfigKey<Long>(
-            Long.class, "vm.op.cleanup.wait", "Advanced", OrchestrationService.class, "3600", "Time (in seconds) to wait before cleanuping up any vm work items", false, "Seconds");
-    public static final ConfigKey<Integer> VmOpCancelInterval = new ConfigKey<Integer>(
-            Integer.class, "vm.op.cancel.interval", "Advanced", OrchestrationService.class, "3600", "Time (in seconds) to wait before cancelling a operation", false, "Seconds");
-    public static final ConfigKey<Integer> Wait = new ConfigKey<Integer>(
-            Integer.class, "wait", "Advanced", OrchestrationService.class, "1800", "Time in seconds to wait for control commands to return", false, null);
-    public static final ConfigKey<Boolean> VmDestroyForcestop = new ConfigKey<Boolean>(
-            Boolean.class, "vm.destroy.forcestop", "Advanced", OrchestrationService.class, "false", "On destroy, force-stop takes this value ", true, null);
-
-    public static final ConfigKey<Long> PingInterval = new ConfigKey<Long>(
-            Long.class, "ping.interval", "Advanced", OrchestrationService.class, "60", "Ping interval in seconds", null);
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/309f8da6/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index 4dd0e3c..8989235 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -739,7 +739,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
         txn.commit();
     	final long jobId = workJob.getId();
     	AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
-        return new VmOutcome(workJob, VirtualMachine.PowerState.PowerOn);
+        return new VmOutcome(workJob, VirtualMachine.PowerState.PowerOn, vm.getId());
     }
 
     private Pair<DeploymentPlan, DeployDestination> findDestination(VirtualMachineProfileImpl profile, DeploymentPlan planRequested, boolean reuseVolume,
@@ -3664,11 +3664,13 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     }
 
     public class VmOutcome extends OutcomeImpl<VirtualMachine> {
-        public VmOutcome(final AsyncJob job, final PowerState desiredPowerState) {
+        private long _vmId;
+
+        public VmOutcome(final AsyncJob job, final PowerState desiredPowerState, final long vmId) {
             super(VirtualMachine.class, job, _jobCheckInterval.value(), new Predicate() {
                 @Override
                 public boolean checkCondition() {
-                    VMInstanceVO instance = _vmDao.findById(job.getInstanceId());
+                    VMInstanceVO instance = _vmDao.findById(vmId);
                     if (instance.getPowerState() == desiredPowerState)
                         return true;
 
@@ -3679,11 +3681,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
                     return false;
                 }
             }, Topics.VM_POWER_STATE, AsyncJob.Topics.JOB_STATE);
+            _vmId = vmId;
         }
 
         @Override
         protected VirtualMachine retrieve() {
-            return _vmDao.findById(_job.getInstanceId());
+            return _vmDao.findById(_vmId);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/309f8da6/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
index 020029d..8a8b8d6 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
@@ -63,7 +63,11 @@ public class OutcomeImpl<T> implements Outcome<T> {
     @Override
     public T get() throws InterruptedException, ExecutionException {
         s_jobMgr.waitAndCheck(_topics, _checkIntervalInMs, -1, _predicate);
-        s_jobMgr.disjoinJob(AsyncJobExecutionContext.getCurrentExecutionContext().getJob().getId(), _job.getId());
+        try {
+            AsyncJobExecutionContext.getCurrentExecutionContext().disjoinJob(_job.getId());
+        } catch (Throwable e) {
+            throw new ExecutionException("Job task has trouble executing", e);
+        }
 
         return retrieve();
     }


[6/9] git commit: updated refs/heads/vmsync to 309f8da

Posted by ah...@apache.org.
Finally, we moved AsyncJobManagerImpl out of server package


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/8f00c191
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/8f00c191
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/8f00c191

Branch: refs/heads/vmsync
Commit: 8f00c1919228069e1c4a8f9912048b8be45663b7
Parents: 3a074f3
Author: Alex Huang <al...@gmail.com>
Authored: Sat Jun 15 06:44:38 2013 -0700
Committer: Alex Huang <al...@gmail.com>
Committed: Mon Jun 17 17:04:05 2013 -0700

----------------------------------------------------------------------
 client/tomcatconf/applicationContext.xml.in     |   2 +-
 .../jobs/impl/AsyncJobManagerImpl.java          | 831 ++++++++++++++++++
 .../com/cloud/async/AsyncJobManagerImpl.java    | 841 -------------------
 3 files changed, 832 insertions(+), 842 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8f00c191/client/tomcatconf/applicationContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in
index 6b1dad6..d3b5369 100644
--- a/client/tomcatconf/applicationContext.xml.in
+++ b/client/tomcatconf/applicationContext.xml.in
@@ -817,7 +817,7 @@
   <bean id="asyncJobJoinDaoImpl" class="com.cloud.api.query.dao.AsyncJobJoinDaoImpl" />
   <bean id="asyncJobJournalDaoImpl" class="org.apache.cloudstack.framework.jobs.dao.AsyncJobJournalDaoImpl" />
   <bean id="asyncJobJoinMapDaoImpl" class="org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDaoImpl" />
-  <bean id="asyncJobManagerImpl" class="com.cloud.async.AsyncJobManagerImpl"/>
+  <bean id="asyncJobManagerImpl" class="org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl"/>
   <bean id="asyncJobMonitor" class="org.apache.cloudstack.framework.jobs.impl.AsyncJobMonitor"/>
   <bean id="syncQueueDaoImpl" class="org.apache.cloudstack.framework.jobs.dao.SyncQueueDaoImpl" />
   <bean id="syncQueueItemDaoImpl" class="org.apache.cloudstack.framework.jobs.dao.SyncQueueItemDaoImpl" />

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8f00c191/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java
new file mode 100644
index 0000000..4dee7e9
--- /dev/null
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java
@@ -0,0 +1,831 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.cloudstack.framework.jobs.impl;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.config.ConfigDepot;
+import org.apache.cloudstack.config.ConfigKey;
+import org.apache.cloudstack.config.ConfigValue;
+import org.apache.cloudstack.config.Configurable;
+import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.framework.jobs.dao.AsyncJobDao;
+import org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDao;
+import org.apache.cloudstack.framework.jobs.dao.AsyncJobJournalDao;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.MessageDetector;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
+import org.apache.cloudstack.jobs.JobInfo;
+import org.apache.cloudstack.jobs.JobInfo.Status;
+
+import com.cloud.cluster.ClusterManagerListener;
+import com.cloud.cluster.ManagementServerHost;
+import com.cloud.cluster.ManagementServerNode;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.Predicate;
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExceptionUtil;
+import com.cloud.utils.mgmt.JmxUtil;
+
+public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, ClusterManagerListener, Configurable {
+    // Advanced
+    private static final ConfigKey<Long> JobExpireMinutes = new ConfigKey<Long>(Long.class, "job.expire.minutes", "Advanced", AsyncJobManager.class, "1440",
+            "Time (in minutes) for async-jobs to be kept in system", true, null);
+    private static final ConfigKey<Long> JobCancelThresholdMinutes = new ConfigKey<Long>(Long.class, "job.cancel.threshold.minutes", "Advanced", AsyncJobManager.class,
+            "60", "Time (in minutes) for async-jobs to be forcely cancelled if it has been in process for long", true, null);
+
+    private static final Logger s_logger = Logger.getLogger(AsyncJobManagerImpl.class);
+    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3; 	// 3 seconds
+    // Although we may have detailed masks for each individual wakeup event, i.e.
+    // periodical timer, matched topic from message bus, it seems that we don't
+    // need to distinguish them to such level. Therefore, only one wakeup signal
+    // is defined
+    public static final int SIGNAL_MASK_WAKEUP = 1;
+
+    private static final int MAX_ONETIME_SCHEDULE_SIZE = 50;
+    private static final int HEARTBEAT_INTERVAL = 2000;
+    private static final int GC_INTERVAL = 10000;				// 10 seconds
+
+    @Inject private SyncQueueManager _queueMgr;
+    @Inject private AsyncJobDao _jobDao;
+    @Inject private AsyncJobJournalDao _journalDao;
+    @Inject private AsyncJobJoinMapDao _joinMapDao;
+    @Inject private List<AsyncJobDispatcher> _jobDispatchers;
+    @Inject private MessageBus _messageBus;
+    @Inject private AsyncJobMonitor _jobMonitor;
+    @Inject
+    private ConfigDepot _configDepot;
+
+    private ConfigValue<Long> _jobExpireSeconds;						// 1 day
+    private ConfigValue<Long> _jobCancelThresholdSeconds;         	// 1 hour (for cancelling the jobs blocking other jobs)
+    
+    private volatile long _executionRunNumber = 1;
+
+    private final ScheduledExecutorService _heartbeatScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AsyncJobMgr-Heartbeat"));
+    private ExecutorService _executor;
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {JobExpireMinutes, JobCancelThresholdMinutes};
+    }
+
+    @Override
+    public AsyncJobVO getAsyncJob(long jobId) {
+        return _jobDao.findById(jobId);
+    }
+
+    @Override
+    public List<AsyncJobVO> findInstancePendingAsyncJobs(String instanceType, Long accountId) {
+        return _jobDao.findInstancePendingAsyncJobs(instanceType, accountId);
+    }
+    
+    @Override @DB
+    public AsyncJob getPseudoJob(long accountId, long userId) {
+    	AsyncJobVO job = _jobDao.findPseudoJob(Thread.currentThread().getId(), getMsid());
+    	if(job == null) {
+	    	job = new AsyncJobVO();
+            job.setAccountId(accountId);
+            job.setUserId(userId);
+	    	job.setInitMsid(getMsid());
+            job.setDispatcher(AsyncJobVO.JOB_DISPATCHER_PSEUDO);
+            job.setInstanceType(AsyncJobVO.PSEUDO_JOB_INSTANCE_TYPE);
+	    	job.setInstanceId(Thread.currentThread().getId());
+	    	_jobDao.persist(job);
+    	}
+    	return job;
+    }
+
+    @Override
+    public long submitAsyncJob(AsyncJob job) {
+        return submitAsyncJob(job, false);
+    }
+
+    @SuppressWarnings("unchecked")
+    @DB
+    public long submitAsyncJob(AsyncJob job, boolean scheduleJobExecutionInContext) {
+        @SuppressWarnings("rawtypes")
+        GenericDao dao = GenericDaoBase.getDao(job.getClass());
+        job.setInitMsid(getMsid());
+        job.setSyncSource(null);        // no sync source originally
+        dao.persist(job);
+
+        scheduleExecution(job, scheduleJobExecutionInContext);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("submit async job-" + job.getId() + ", details: " + job.toString());
+        }
+        return job.getId();
+    }
+
+    @SuppressWarnings("unchecked")
+	@Override @DB
+	public long submitAsyncJob(AsyncJob job, String syncObjType, long syncObjId) {
+        Transaction txt = Transaction.currentTxn();
+        try {
+        	@SuppressWarnings("rawtypes")
+			GenericDao dao = GenericDaoBase.getDao(job.getClass());
+        	
+            txt.start();
+            job.setInitMsid(getMsid());
+            dao.persist(job);
+
+            syncAsyncJobExecution(job, syncObjType, syncObjId, 1);
+            txt.commit();
+            return job.getId();
+        } catch(Exception e) {
+            String errMsg = "Unable to schedule async job for command " + job.getCmd() + ", unexpected exception.";
+            s_logger.warn(errMsg, e);
+            throw new CloudRuntimeException(errMsg);
+        }
+	}
+    
+    @Override @DB
+    public void completeAsyncJob(long jobId, Status jobStatus, int resultCode, String resultObject) {
+        if(s_logger.isDebugEnabled()) {
+            s_logger.debug("Complete async job-" + jobId + ", jobStatus: " + jobStatus +
+                    ", resultCode: " + resultCode + ", result: " + resultObject);
+        }
+
+        Transaction txn = Transaction.currentTxn();
+        try {
+            txn.start();
+            AsyncJobVO job = _jobDao.findById(jobId);
+            if(job == null) {
+                if(s_logger.isDebugEnabled()) {
+                    s_logger.debug("job-" + jobId + " no longer exists, we just log completion info here. " + jobStatus +
+                            ", resultCode: " + resultCode + ", result: " + resultObject);
+                }
+
+                txn.rollback();
+                return;
+            }
+            
+            if(job.getStatus() != JobInfo.Status.IN_PROGRESS) {
+                if(s_logger.isDebugEnabled()) {
+                    s_logger.debug("job-" + jobId + " is already completed.");
+                }
+            	
+            	txn.rollback();
+            	return;
+            }
+
+            job.setCompleteMsid(getMsid());
+            job.setStatus(jobStatus);
+            job.setResultCode(resultCode);
+
+            // reset attached object
+            job.setInstanceType(null);
+            job.setInstanceId(null);
+
+            if (resultObject != null) {
+                job.setResult(resultObject);
+            }
+
+            job.setLastUpdated(DateUtil.currentGMTTime());
+            _jobDao.update(jobId, job);
+            
+        	List<Long> wakeupList = _joinMapDao.wakeupByJoinedJobCompletion(jobId);
+            _joinMapDao.disjoinAllJobs(jobId);
+            
+            txn.commit();
+
+            for(Long id : wakeupList) {
+            	// TODO, we assume that all jobs in this category is API job only
+            	AsyncJobVO jobToWakeup = _jobDao.findById(id);
+                if (jobToWakeup != null && (jobToWakeup.getPendingSignals() & SIGNAL_MASK_WAKEUP) != 0)
+            	    scheduleExecution(jobToWakeup, false);
+            }
+             
+            _messageBus.publish(null, AsyncJob.Topics.JOB_STATE, PublishScope.GLOBAL, jobId);
+        } catch(Exception e) {
+            s_logger.error("Unexpected exception while completing async job-" + jobId, e);
+            txn.rollback();
+        }
+    }
+
+    @Override @DB
+    public void updateAsyncJobStatus(long jobId, int processStatus, String resultObject) {
+        if(s_logger.isDebugEnabled()) {
+            s_logger.debug("Update async-job progress, job-" + jobId + ", processStatus: " + processStatus +
+                    ", result: " + resultObject);
+        }
+
+        Transaction txt = Transaction.currentTxn();
+        try {
+            txt.start();
+            AsyncJobVO job = _jobDao.findById(jobId);
+            if(job == null) {
+                if(s_logger.isDebugEnabled()) {
+                    s_logger.debug("job-" + jobId + " no longer exists, we just log progress info here. progress status: " + processStatus);
+                }
+
+                txt.rollback();
+                return;
+            }
+
+            job.setProcessStatus(processStatus);
+            if(resultObject != null) {
+                job.setResult(resultObject);
+            }
+            job.setLastUpdated(DateUtil.currentGMTTime());
+            _jobDao.update(jobId, job);
+            txt.commit();
+        } catch(Exception e) {
+            s_logger.error("Unexpected exception while updating async job-" + jobId + " status: ", e);
+            txt.rollback();
+        }
+    }
+
+    @Override @DB
+    public void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId) {
+        if(s_logger.isDebugEnabled()) {
+            s_logger.debug("Update async-job attachment, job-" + jobId + ", instanceType: " + instanceType +
+                    ", instanceId: " + instanceId);
+        }
+
+        Transaction txt = Transaction.currentTxn();
+        try {
+            txt.start();
+
+            AsyncJobVO job = _jobDao.createForUpdate();
+            job.setInstanceType(instanceType);
+            job.setInstanceId(instanceId);
+            job.setLastUpdated(DateUtil.currentGMTTime());
+            _jobDao.update(jobId, job);
+
+            txt.commit();
+        } catch(Exception e) {
+            s_logger.error("Unexpected exception while updating async job-" + jobId + " attachment: ", e);
+            txt.rollback();
+        }
+    }
+    
+    @Override @DB
+    public void logJobJournal(long jobId, AsyncJob.JournalType journalType, String
+        journalText, String journalObjJson) {
+    	AsyncJobJournalVO journal = new AsyncJobJournalVO();
+    	journal.setJobId(jobId);
+    	journal.setJournalType(journalType);
+    	journal.setJournalText(journalText);
+    	journal.setJournalObjJsonString(journalObjJson);
+    	
+    	_journalDao.persist(journal);
+    }
+    
+    @Override @DB
+	public void joinJob(long jobId, long joinJobId) {
+    	_joinMapDao.joinJob(jobId, joinJobId, getMsid(), 0, 0, null, null, null);
+    }
+    
+    @Override @DB
+    public void joinJob(long jobId, long joinJobId, String wakeupHandler, String wakeupDispatcher,
+    		String[] wakeupTopcisOnMessageBus, long wakeupIntervalInMilliSeconds, long timeoutInMilliSeconds) {
+    	
+    	Long syncSourceId = null;
+    	AsyncJobExecutionContext context = AsyncJobExecutionContext.getCurrentExecutionContext();
+    	assert(context.getJob() != null);
+    	if(context.getJob().getSyncSource() != null) {
+    		syncSourceId = context.getJob().getSyncSource().getQueueId();
+    	}
+    	
+    	_joinMapDao.joinJob(jobId, joinJobId, getMsid(),
+    		wakeupIntervalInMilliSeconds, timeoutInMilliSeconds,
+    		syncSourceId, wakeupHandler, wakeupDispatcher);
+    }
+    
+    @Override @DB
+    public void disjoinJob(long jobId, long joinedJobId) {
+    	_joinMapDao.disjoinJob(jobId, joinedJobId);
+    }
+    
+    @Override @DB
+    public void completeJoin(long joinJobId, JobInfo.Status joinStatus, String joinResult) {
+    	_joinMapDao.completeJoin(joinJobId, joinStatus, joinResult, getMsid());
+    }
+    
+    @Override
+    public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit) {
+        if(s_logger.isDebugEnabled()) {
+            s_logger.debug("Sync job-" + job.getId() + " execution on object " + syncObjType + "." + syncObjId);
+        }
+
+        SyncQueueVO queue = null;
+
+        // to deal with temporary DB exceptions like DB deadlock/Lock-wait time out cased rollbacks
+        // we retry five times until we throw an exception
+        Random random = new Random();
+
+        for(int i = 0; i < 5; i++) {
+            queue = _queueMgr.queue(syncObjType, syncObjId, SyncQueueItem.AsyncJobContentType, job.getId(), queueSizeLimit);
+            if(queue != null) {
+                break;
+            }
+
+            try {
+                Thread.sleep(1000 + random.nextInt(5000));
+            } catch (InterruptedException e) {
+            }
+        }
+
+        if (queue == null)
+            throw new CloudRuntimeException("Unable to insert queue item into database, DB is full?");
+    }
+
+    @Override
+    public AsyncJob queryJob(long jobId, boolean updatePollTime) {
+        AsyncJobVO job = _jobDao.findById(jobId);
+        
+        if (updatePollTime) {
+            job.setLastPolled(DateUtil.currentGMTTime());
+            _jobDao.update(jobId, job);
+        }
+        return job;
+    }
+
+
+    private void scheduleExecution(final AsyncJobVO job) {
+        scheduleExecution(job, false);
+    }
+
+    private void scheduleExecution(final AsyncJob job, boolean executeInContext) {
+        Runnable runnable = getExecutorRunnable(job);
+        if (executeInContext) {
+            runnable.run();
+        } else {
+            _executor.submit(runnable);
+        }
+    }
+    
+    private AsyncJobDispatcher getDispatcher(String dispatcherName) {
+        assert (dispatcherName != null && !dispatcherName.isEmpty()) : "Who's not setting the dispatcher when submitting a job?  Who am I suppose to call if you do that!";
+    	
+        for (AsyncJobDispatcher dispatcher : _jobDispatchers) {
+            if (dispatcherName.equals(dispatcher.getName()))
+                return dispatcher;
+        }
+
+        throw new CloudRuntimeException("Unable to find dispatcher name: " + dispatcherName);
+    }
+    
+    private AsyncJobDispatcher getWakeupDispatcher(AsyncJob job) {
+    	if(_jobDispatchers != null) {
+    		List<AsyncJobJoinMapVO> joinRecords = _joinMapDao.listJoinRecords(job.getId());
+    		if(joinRecords.size() > 0) {
+    			AsyncJobJoinMapVO joinRecord = joinRecords.get(0);
+	    		for(AsyncJobDispatcher dispatcher : _jobDispatchers) {
+	    			if(dispatcher.getName().equals(joinRecord.getWakeupDispatcher()))
+	    				return dispatcher;
+	    		}
+    		} else {
+    			s_logger.warn("job-" + job.getId() + " is scheduled for wakeup run, but there is no joining info anymore");
+    		}
+    	}
+    	return null;
+    }
+    
+    private long getJobRunNumber() {
+    	synchronized(this) {
+    		return _executionRunNumber++;
+    	}
+    }
+    
+    private Runnable getExecutorRunnable(final AsyncJob job) {
+        return new Runnable() {
+            @Override
+            public void run() {
+            	Transaction txn = null;
+            	long runNumber = getJobRunNumber();
+            	
+            	try {
+            		//
+            		// setup execution environment
+            		//
+            		txn = Transaction.open(Transaction.CLOUD_DB);
+            		
+                    try {
+                        JmxUtil.registerMBean("AsyncJobManager", "Active Job " + job.getId(), new AsyncJobMBeanImpl(job));
+                    } catch(Exception e) {
+                		// Due to co-existence of normal-dispatched-job/wakeup-dispatched-job, MBean register() call
+                		// is expected to fail under situations
+                    	if(s_logger.isTraceEnabled())
+                    		s_logger.trace("Unable to register active job " + job.getId() + " to JMX monitoring due to exception " + ExceptionUtil.toString(e));
+                    }
+                    
+                    _jobMonitor.registerActiveTask(runNumber, job.getId());
+                    AsyncJobExecutionContext.setCurrentExecutionContext(new AsyncJobExecutionContext(job));
+                    
+                    // execute the job
+                    if(s_logger.isDebugEnabled()) {
+                        s_logger.debug("Executing " + job);
+                    }
+
+                    if ((getAndResetPendingSignals(job) & SIGNAL_MASK_WAKEUP) != 0) {
+                    	AsyncJobDispatcher jobDispatcher = getWakeupDispatcher(job);
+                    	if(jobDispatcher != null) {
+                    		jobDispatcher.runJob(job);
+                    	} else {
+                    		s_logger.error("Unable to find a wakeup dispatcher from the joined job: " + job);
+                    	}
+                    } else {
+	                    AsyncJobDispatcher jobDispatcher = getDispatcher(job.getDispatcher());
+	                    if(jobDispatcher != null) {
+	                    	jobDispatcher.runJob(job);
+	                    } else {
+	                    	s_logger.error("Unable to find job dispatcher, job will be cancelled");
+	                        completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), null);
+	                    }
+                    }
+                    
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Done executing " + job.getCmd() + " for job-" + job.getId());
+                    }
+                   
+            	} catch (Throwable e) {
+            		s_logger.error("Unexpected exception", e);
+                    completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), null);
+            	} finally {
+            		// guard final clause as well
+                    try {
+                    	AsyncJobVO jobToUpdate = _jobDao.findById(job.getId());
+                    	jobToUpdate.setExecutingMsid(null);
+                    	_jobDao.update(job.getId(), jobToUpdate);
+                    	
+                    	if (job.getSyncSource() != null) {
+                            _queueMgr.purgeItem(job.getSyncSource().getId());
+                            checkQueue(job.getSyncSource().getQueueId());
+                        }
+
+                    	try {
+                    		JmxUtil.unregisterMBean("AsyncJobManager", "Active Job " + job.getId());
+                    	} catch(Exception e) {
+                    		// Due to co-existence of normal-dispatched-job/wakeup-dispatched-job, MBean unregister() call
+                    		// is expected to fail under situations
+                    		if(s_logger.isTraceEnabled())
+                    			s_logger.trace("Unable to unregister job " + job.getId() + " to JMX monitoring due to exception " + ExceptionUtil.toString(e));
+                    	}
+                    	
+	                    if(txn != null)
+	                    	txn.close();
+	                    
+                    	//
+                    	// clean execution environment
+                    	//
+                        AsyncJobExecutionContext.unregister();
+                        _jobMonitor.unregisterActiveTask(runNumber);
+	                    
+                    } catch(Throwable e) {
+                		s_logger.error("Double exception", e);
+                    }
+            	}
+            }
+        };
+    }
+    
+    private int getAndResetPendingSignals(AsyncJob job) {
+    	int signals = job.getPendingSignals();
+    	if(signals != 0) {
+	    	AsyncJobVO jobRecord = _jobDao.findById(job.getId());
+	    	jobRecord.setPendingSignals(0);
+	    	_jobDao.update(job.getId(), jobRecord);
+    	}
+    	return signals;
+    }
+    
+    private void executeQueueItem(SyncQueueItemVO item, boolean fromPreviousSession) {
+        AsyncJobVO job = _jobDao.findById(item.getContentId());
+        if (job != null) {
+            if(s_logger.isDebugEnabled()) {
+                s_logger.debug("Schedule queued job-" + job.getId());
+            }
+
+            job.setSyncSource(item);
+            
+            job.setExecutingMsid(getMsid());
+            _jobDao.update(job.getId(), job);
+
+            try {
+                scheduleExecution(job);
+            } catch(RejectedExecutionException e) {
+                s_logger.warn("Execution for job-" + job.getId() + " is rejected, return it to the queue for next turn");
+                _queueMgr.returnItem(item.getId());
+                
+            	job.setExecutingMsid(null);
+            	_jobDao.update(job.getId(), job);
+            }
+
+        } else {
+            if(s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to find related job for queue item: " + item.toString());
+            }
+
+            _queueMgr.purgeItem(item.getId());
+        }
+    }
+
+    @Override
+    public void releaseSyncSource() {
+    	AsyncJobExecutionContext executionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+    	assert(executionContext != null);
+    	
+    	if(executionContext.getSyncSource() != null) {
+            if(s_logger.isDebugEnabled()) {
+                s_logger.debug("Release sync source for job-" + executionContext.getJob().getId() + " sync source: "
+                        + executionContext.getSyncSource().getContentType() + "-"
+                        + executionContext.getSyncSource().getContentId());
+            }
+
+            _queueMgr.purgeItem(executionContext.getSyncSource().getId());
+            checkQueue(executionContext.getSyncSource().getQueueId());
+    	}
+    }
+    
+    @Override
+    public boolean waitAndCheck(String[] wakupTopicsOnMessageBus, long checkIntervalInMilliSeconds,
+        long timeoutInMiliseconds, Predicate predicate) {
+    	
+    	MessageDetector msgDetector = new MessageDetector();
+    	msgDetector.open(_messageBus, wakupTopicsOnMessageBus);
+    	try {
+    		long startTick = System.currentTimeMillis();
+    		while(System.currentTimeMillis() - startTick < timeoutInMiliseconds) {
+    			msgDetector.waitAny(checkIntervalInMilliSeconds);
+    			if(predicate.checkCondition())
+    				return true;
+    		}
+    	} finally {
+    		msgDetector.close();
+    	}
+    	
+    	return false;
+    }
+
+    private void checkQueue(long queueId) {
+        while(true) {
+            try {
+                SyncQueueItemVO item = _queueMgr.dequeueFromOne(queueId, getMsid());
+                if(item != null) {
+                    if(s_logger.isDebugEnabled()) {
+                        s_logger.debug("Executing sync queue item: " + item.toString());
+                    }
+
+                    executeQueueItem(item, false);
+                } else {
+                    break;
+                }
+            } catch(Throwable e) {
+                s_logger.error("Unexpected exception when kicking sync queue-" + queueId, e);
+                break;
+            }
+        }
+    }
+
+    private Runnable getHeartbeatTask() {
+        return new Runnable() {
+            @Override
+            public void run() {
+            	Transaction txn = Transaction.open("AsyncJobManagerImpl.getHeartbeatTask");
+                try {
+                    List<SyncQueueItemVO> l = _queueMgr.dequeueFromAny(getMsid(), MAX_ONETIME_SCHEDULE_SIZE);
+                    if(l != null && l.size() > 0) {
+                        for(SyncQueueItemVO item: l) {
+                            if(s_logger.isDebugEnabled()) {
+                                s_logger.debug("Execute sync-queue item: " + item.toString());
+                            }
+                            executeQueueItem(item, false);
+                        }
+                    }
+              
+                    List<Long> standaloneWakeupJobs = _joinMapDao.wakeupScan();
+                    for(Long jobId : standaloneWakeupJobs) {
+                    	// TODO, we assume that all jobs in this category is API job only
+                    	AsyncJobVO job = _jobDao.findById(jobId);
+                        if (job != null && (job.getPendingSignals() & SIGNAL_MASK_WAKEUP) != 0)
+                    	    scheduleExecution(job, false);
+                    }
+                } catch(Throwable e) {
+                    s_logger.error("Unexpected exception when trying to execute queue item, ", e);
+                } finally {
+                	try {
+                		txn.close();
+                	} catch(Throwable e) {
+                        s_logger.error("Unexpected exception", e);
+                	}
+                }
+            }
+        };
+    }
+
+    @DB
+    private Runnable getGCTask() {
+        return new Runnable() {
+            @Override
+            public void run() {
+                GlobalLock scanLock = GlobalLock.getInternLock("AsyncJobManagerGC");
+                try {
+                    if(scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
+                        try {
+                            reallyRun();
+                        } finally {
+                            scanLock.unlock();
+                        }
+                    }
+                } finally {
+                    scanLock.releaseRef();
+                }
+            }
+
+            public void reallyRun() {
+                try {
+                    s_logger.trace("Begin cleanup expired async-jobs");
+
+                    Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - _jobExpireSeconds.value() * 1000);
+
+                    // limit to 100 jobs per turn, this gives cleanup throughput as 600 jobs per minute
+                    // hopefully this will be fast enough to balance potential growth of job table
+                    //1) Expire unfinished jobs that weren't processed yet
+                    List<AsyncJobVO> l = _jobDao.getExpiredUnfinishedJobs(cutTime, 100);
+                        for(AsyncJobVO job : l) {
+                    	s_logger.trace("Expunging unfinished job " + job);
+                            expungeAsyncJob(job);
+                        }
+                    
+                    //2) Expunge finished jobs
+                    List<AsyncJobVO> completedJobs = _jobDao.getExpiredCompletedJobs(cutTime, 100);
+                    for(AsyncJobVO job : completedJobs) {
+                    	s_logger.trace("Expunging completed job " + job);
+                        expungeAsyncJob(job);
+                    }
+
+                    // forcefully cancel blocking queue items if they've been staying there for too long
+                    List<SyncQueueItemVO> blockItems = _queueMgr.getBlockedQueueItems(_jobCancelThresholdSeconds.value()
+                            * 1000, false);
+                    if(blockItems != null && blockItems.size() > 0) {
+                        for(SyncQueueItemVO item : blockItems) {
+                            if(item.getContentType().equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) {
+                                completeAsyncJob(item.getContentId(), JobInfo.Status.FAILED, 0, "Job is cancelled as it has been blocking others for too long");
+                            }
+
+                            // purge the item and resume queue processing
+                            _queueMgr.purgeItem(item.getId());
+                        }
+                    }
+
+                    s_logger.trace("End cleanup expired async-jobs");
+                } catch(Throwable e) {
+                    s_logger.error("Unexpected exception when trying to execute queue item, ", e);
+                }
+            }
+        };
+    }
+
+    @DB
+    protected void expungeAsyncJob(AsyncJobVO job) {
+        Transaction txn = Transaction.currentTxn();
+        txn.start();
+        _jobDao.expunge(job.getId());
+        //purge corresponding sync queue item
+        _queueMgr.purgeAsyncJobQueueItemId(job.getId());
+        txn.commit();
+    }
+
+    private long getMsid() {
+        return ManagementServerNode.getManagementServerId();
+    }
+
+    private void cleanupPendingJobs(List<SyncQueueItemVO> l) {
+        for (SyncQueueItemVO item : l) {
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Discard left-over queue item: " + item.toString());
+            }
+
+            String contentType = item.getContentType();
+            if (contentType != null && contentType.equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) {
+                Long jobId = item.getContentId();
+                if (jobId != null) {
+                    s_logger.warn("Mark job as failed as its correspoding queue-item has been discarded. job id: " + jobId);
+                    completeAsyncJob(jobId, JobInfo.Status.FAILED, 0, "Execution was cancelled because of server shutdown");
+                }
+            }
+            _queueMgr.purgeItem(item.getId());
+        }
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _jobExpireSeconds = _configDepot.get(JobExpireMinutes).setMultiplier(60);
+        _jobCancelThresholdSeconds = _configDepot.get(JobCancelThresholdMinutes).setMultiplier(60);
+
+        try {
+            final File dbPropsFile = PropertiesUtil.findConfigFile("db.properties");
+            final Properties dbProps = new Properties();
+            dbProps.load(new FileInputStream(dbPropsFile));
+
+            final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
+
+            int poolSize = (cloudMaxActive * 2) / 3;
+
+            s_logger.info("Start AsyncJobManager thread pool in size " + poolSize);
+            _executor = Executors.newFixedThreadPool(poolSize, new NamedThreadFactory(AsyncJobManager.JOB_POOL_THREAD_PREFIX));
+        } catch (final Exception e) {
+            throw new ConfigurationException("Unable to load db.properties to configure AsyncJobManagerImpl");
+        }
+
+        AsyncJobExecutionContext.init(this, _joinMapDao);
+        OutcomeImpl.init(this);
+
+        return true;
+    }
+
+    @Override
+    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+    }
+
+    @Override
+    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+        for (ManagementServerHost msHost : nodeList) {
+            Transaction txn = Transaction.open(Transaction.CLOUD_DB);
+            try {
+                txn.start();
+                List<SyncQueueItemVO> items = _queueMgr.getActiveQueueItems(msHost.getId(), true);
+                cleanupPendingJobs(items);
+                _jobDao.resetJobProcess(msHost.getId(), ApiErrorCode.INTERNAL_ERROR.getHttpCode(), "job cancelled because of management server restart");
+                txn.commit();
+            } catch(Throwable e) {
+                s_logger.warn("Unexpected exception ", e);
+            } finally {
+                txn.close();
+            }
+        }
+    }
+
+    @Override
+    public void onManagementNodeIsolated() {
+    }
+
+    @Override
+    public boolean start() {
+        try {
+        	_jobDao.cleanupPseduoJobs(getMsid());
+        	
+            List<SyncQueueItemVO> l = _queueMgr.getActiveQueueItems(getMsid(), false);
+            cleanupPendingJobs(l);
+            _jobDao.resetJobProcess(getMsid(), ApiErrorCode.INTERNAL_ERROR.getHttpCode(), "job cancelled because of management server restart");
+        } catch(Throwable e) {
+            s_logger.error("Unexpected exception " + e.getMessage(), e);
+        }
+
+        _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HEARTBEAT_INTERVAL, HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS);
+        _heartbeatScheduler.scheduleAtFixedRate(getGCTask(), GC_INTERVAL, GC_INTERVAL, TimeUnit.MILLISECONDS);
+
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        _heartbeatScheduler.shutdown();
+        _executor.shutdown();
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8f00c191/server/src/com/cloud/async/AsyncJobManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/async/AsyncJobManagerImpl.java b/server/src/com/cloud/async/AsyncJobManagerImpl.java
deleted file mode 100644
index bc8f99b..0000000
--- a/server/src/com/cloud/async/AsyncJobManagerImpl.java
+++ /dev/null
@@ -1,841 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.async;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Random;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.config.ConfigDepot;
-import org.apache.cloudstack.config.ConfigKey;
-import org.apache.cloudstack.config.ConfigValue;
-import org.apache.cloudstack.config.Configurable;
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
-import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-import org.apache.cloudstack.framework.jobs.dao.AsyncJobDao;
-import org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDao;
-import org.apache.cloudstack.framework.jobs.dao.AsyncJobJournalDao;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobJoinMapVO;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobJournalVO;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobMBeanImpl;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobMonitor;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
-import org.apache.cloudstack.framework.jobs.impl.OutcomeImpl;
-import org.apache.cloudstack.framework.jobs.impl.SyncQueueItem;
-import org.apache.cloudstack.framework.jobs.impl.SyncQueueItemVO;
-import org.apache.cloudstack.framework.jobs.impl.SyncQueueManager;
-import org.apache.cloudstack.framework.jobs.impl.SyncQueueVO;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.MessageDetector;
-import org.apache.cloudstack.framework.messagebus.PublishScope;
-import org.apache.cloudstack.jobs.JobInfo;
-import org.apache.cloudstack.jobs.JobInfo.Status;
-
-import com.cloud.cluster.ClusterManagerListener;
-import com.cloud.cluster.ManagementServerHost;
-import com.cloud.cluster.ManagementServerNode;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.Predicate;
-import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GenericDao;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExceptionUtil;
-import com.cloud.utils.mgmt.JmxUtil;
-
-public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, ClusterManagerListener, Configurable {
-    // Advanced
-    private static final ConfigKey<Long> JobExpireMinutes = new ConfigKey<Long>(Long.class, "job.expire.minutes", "Advanced", AsyncJobManager.class, "1440",
-            "Time (in minutes) for async-jobs to be kept in system", true, null);
-    private static final ConfigKey<Long> JobCancelThresholdMinutes = new ConfigKey<Long>(Long.class, "job.cancel.threshold.minutes", "Advanced", AsyncJobManager.class,
-            "60", "Time (in minutes) for async-jobs to be forcely cancelled if it has been in process for long", true, null);
-
-    private static final Logger s_logger = Logger.getLogger(AsyncJobManagerImpl.class);
-    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3; 	// 3 seconds
-    // Although we may have detailed masks for each individual wakeup event, i.e.
-    // periodical timer, matched topic from message bus, it seems that we don't
-    // need to distinguish them to such level. Therefore, only one wakeup signal
-    // is defined
-    public static final int SIGNAL_MASK_WAKEUP = 1;
-
-    private static final int MAX_ONETIME_SCHEDULE_SIZE = 50;
-    private static final int HEARTBEAT_INTERVAL = 2000;
-    private static final int GC_INTERVAL = 10000;				// 10 seconds
-
-    @Inject private SyncQueueManager _queueMgr;
-    @Inject private AsyncJobDao _jobDao;
-    @Inject private AsyncJobJournalDao _journalDao;
-    @Inject private AsyncJobJoinMapDao _joinMapDao;
-    @Inject private List<AsyncJobDispatcher> _jobDispatchers;
-    @Inject private MessageBus _messageBus;
-    @Inject private AsyncJobMonitor _jobMonitor;
-    @Inject
-    private ConfigDepot _configDepot;
-
-    private ConfigValue<Long> _jobExpireSeconds;						// 1 day
-    private ConfigValue<Long> _jobCancelThresholdSeconds;         	// 1 hour (for cancelling the jobs blocking other jobs)
-    
-    private volatile long _executionRunNumber = 1;
-
-    private final ScheduledExecutorService _heartbeatScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AsyncJobMgr-Heartbeat"));
-    private ExecutorService _executor;
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {JobExpireMinutes, JobCancelThresholdMinutes};
-    }
-
-    @Override
-    public AsyncJobVO getAsyncJob(long jobId) {
-        return _jobDao.findById(jobId);
-    }
-
-    @Override
-    public List<AsyncJobVO> findInstancePendingAsyncJobs(String instanceType, Long accountId) {
-        return _jobDao.findInstancePendingAsyncJobs(instanceType, accountId);
-    }
-    
-    @Override @DB
-    public AsyncJob getPseudoJob(long accountId, long userId) {
-    	AsyncJobVO job = _jobDao.findPseudoJob(Thread.currentThread().getId(), getMsid());
-    	if(job == null) {
-	    	job = new AsyncJobVO();
-            job.setAccountId(accountId);
-            job.setUserId(userId);
-	    	job.setInitMsid(getMsid());
-            job.setDispatcher(AsyncJobVO.JOB_DISPATCHER_PSEUDO);
-            job.setInstanceType(AsyncJobVO.PSEUDO_JOB_INSTANCE_TYPE);
-	    	job.setInstanceId(Thread.currentThread().getId());
-	    	_jobDao.persist(job);
-    	}
-    	return job;
-    }
-
-    @Override
-    public long submitAsyncJob(AsyncJob job) {
-        return submitAsyncJob(job, false);
-    }
-
-    @SuppressWarnings("unchecked")
-    @DB
-    public long submitAsyncJob(AsyncJob job, boolean scheduleJobExecutionInContext) {
-        @SuppressWarnings("rawtypes")
-        GenericDao dao = GenericDaoBase.getDao(job.getClass());
-        job.setInitMsid(getMsid());
-        job.setSyncSource(null);        // no sync source originally
-        dao.persist(job);
-
-        scheduleExecution(job, scheduleJobExecutionInContext);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("submit async job-" + job.getId() + ", details: " + job.toString());
-        }
-        return job.getId();
-    }
-
-    @SuppressWarnings("unchecked")
-	@Override @DB
-	public long submitAsyncJob(AsyncJob job, String syncObjType, long syncObjId) {
-        Transaction txt = Transaction.currentTxn();
-        try {
-        	@SuppressWarnings("rawtypes")
-			GenericDao dao = GenericDaoBase.getDao(job.getClass());
-        	
-            txt.start();
-            job.setInitMsid(getMsid());
-            dao.persist(job);
-
-            syncAsyncJobExecution(job, syncObjType, syncObjId, 1);
-            txt.commit();
-            return job.getId();
-        } catch(Exception e) {
-            String errMsg = "Unable to schedule async job for command " + job.getCmd() + ", unexpected exception.";
-            s_logger.warn(errMsg, e);
-            throw new CloudRuntimeException(errMsg);
-        }
-	}
-    
-    @Override @DB
-    public void completeAsyncJob(long jobId, Status jobStatus, int resultCode, String resultObject) {
-        if(s_logger.isDebugEnabled()) {
-            s_logger.debug("Complete async job-" + jobId + ", jobStatus: " + jobStatus +
-                    ", resultCode: " + resultCode + ", result: " + resultObject);
-        }
-
-        Transaction txn = Transaction.currentTxn();
-        try {
-            txn.start();
-            AsyncJobVO job = _jobDao.findById(jobId);
-            if(job == null) {
-                if(s_logger.isDebugEnabled()) {
-                    s_logger.debug("job-" + jobId + " no longer exists, we just log completion info here. " + jobStatus +
-                            ", resultCode: " + resultCode + ", result: " + resultObject);
-                }
-
-                txn.rollback();
-                return;
-            }
-            
-            if(job.getStatus() != JobInfo.Status.IN_PROGRESS) {
-                if(s_logger.isDebugEnabled()) {
-                    s_logger.debug("job-" + jobId + " is already completed.");
-                }
-            	
-            	txn.rollback();
-            	return;
-            }
-
-            job.setCompleteMsid(getMsid());
-            job.setStatus(jobStatus);
-            job.setResultCode(resultCode);
-
-            // reset attached object
-            job.setInstanceType(null);
-            job.setInstanceId(null);
-
-            if (resultObject != null) {
-                job.setResult(resultObject);
-            }
-
-            job.setLastUpdated(DateUtil.currentGMTTime());
-            _jobDao.update(jobId, job);
-            
-        	List<Long> wakeupList = _joinMapDao.wakeupByJoinedJobCompletion(jobId);
-            _joinMapDao.disjoinAllJobs(jobId);
-            
-            txn.commit();
-
-            for(Long id : wakeupList) {
-            	// TODO, we assume that all jobs in this category is API job only
-            	AsyncJobVO jobToWakeup = _jobDao.findById(id);
-                if (jobToWakeup != null && (jobToWakeup.getPendingSignals() & SIGNAL_MASK_WAKEUP) != 0)
-            	    scheduleExecution(jobToWakeup, false);
-            }
-             
-            _messageBus.publish(null, AsyncJob.Topics.JOB_STATE, PublishScope.GLOBAL, jobId);
-        } catch(Exception e) {
-            s_logger.error("Unexpected exception while completing async job-" + jobId, e);
-            txn.rollback();
-        }
-    }
-
-    @Override @DB
-    public void updateAsyncJobStatus(long jobId, int processStatus, String resultObject) {
-        if(s_logger.isDebugEnabled()) {
-            s_logger.debug("Update async-job progress, job-" + jobId + ", processStatus: " + processStatus +
-                    ", result: " + resultObject);
-        }
-
-        Transaction txt = Transaction.currentTxn();
-        try {
-            txt.start();
-            AsyncJobVO job = _jobDao.findById(jobId);
-            if(job == null) {
-                if(s_logger.isDebugEnabled()) {
-                    s_logger.debug("job-" + jobId + " no longer exists, we just log progress info here. progress status: " + processStatus);
-                }
-
-                txt.rollback();
-                return;
-            }
-
-            job.setProcessStatus(processStatus);
-            if(resultObject != null) {
-                job.setResult(resultObject);
-            }
-            job.setLastUpdated(DateUtil.currentGMTTime());
-            _jobDao.update(jobId, job);
-            txt.commit();
-        } catch(Exception e) {
-            s_logger.error("Unexpected exception while updating async job-" + jobId + " status: ", e);
-            txt.rollback();
-        }
-    }
-
-    @Override @DB
-    public void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId) {
-        if(s_logger.isDebugEnabled()) {
-            s_logger.debug("Update async-job attachment, job-" + jobId + ", instanceType: " + instanceType +
-                    ", instanceId: " + instanceId);
-        }
-
-        Transaction txt = Transaction.currentTxn();
-        try {
-            txt.start();
-
-            AsyncJobVO job = _jobDao.createForUpdate();
-            job.setInstanceType(instanceType);
-            job.setInstanceId(instanceId);
-            job.setLastUpdated(DateUtil.currentGMTTime());
-            _jobDao.update(jobId, job);
-
-            txt.commit();
-        } catch(Exception e) {
-            s_logger.error("Unexpected exception while updating async job-" + jobId + " attachment: ", e);
-            txt.rollback();
-        }
-    }
-    
-    @Override @DB
-    public void logJobJournal(long jobId, AsyncJob.JournalType journalType, String
-        journalText, String journalObjJson) {
-    	AsyncJobJournalVO journal = new AsyncJobJournalVO();
-    	journal.setJobId(jobId);
-    	journal.setJournalType(journalType);
-    	journal.setJournalText(journalText);
-    	journal.setJournalObjJsonString(journalObjJson);
-    	
-    	_journalDao.persist(journal);
-    }
-    
-    @Override @DB
-	public void joinJob(long jobId, long joinJobId) {
-    	_joinMapDao.joinJob(jobId, joinJobId, getMsid(), 0, 0, null, null, null);
-    }
-    
-    @Override @DB
-    public void joinJob(long jobId, long joinJobId, String wakeupHandler, String wakeupDispatcher,
-    		String[] wakeupTopcisOnMessageBus, long wakeupIntervalInMilliSeconds, long timeoutInMilliSeconds) {
-    	
-    	Long syncSourceId = null;
-    	AsyncJobExecutionContext context = AsyncJobExecutionContext.getCurrentExecutionContext();
-    	assert(context.getJob() != null);
-    	if(context.getJob().getSyncSource() != null) {
-    		syncSourceId = context.getJob().getSyncSource().getQueueId();
-    	}
-    	
-    	_joinMapDao.joinJob(jobId, joinJobId, getMsid(),
-    		wakeupIntervalInMilliSeconds, timeoutInMilliSeconds,
-    		syncSourceId, wakeupHandler, wakeupDispatcher);
-    }
-    
-    @Override @DB
-    public void disjoinJob(long jobId, long joinedJobId) {
-    	_joinMapDao.disjoinJob(jobId, joinedJobId);
-    }
-    
-    @Override @DB
-    public void completeJoin(long joinJobId, JobInfo.Status joinStatus, String joinResult) {
-    	_joinMapDao.completeJoin(joinJobId, joinStatus, joinResult, getMsid());
-    }
-    
-    @Override
-    public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit) {
-        if(s_logger.isDebugEnabled()) {
-            s_logger.debug("Sync job-" + job.getId() + " execution on object " + syncObjType + "." + syncObjId);
-        }
-
-        SyncQueueVO queue = null;
-
-        // to deal with temporary DB exceptions like DB deadlock/Lock-wait time out cased rollbacks
-        // we retry five times until we throw an exception
-        Random random = new Random();
-
-        for(int i = 0; i < 5; i++) {
-            queue = _queueMgr.queue(syncObjType, syncObjId, SyncQueueItem.AsyncJobContentType, job.getId(), queueSizeLimit);
-            if(queue != null) {
-                break;
-            }
-
-            try {
-                Thread.sleep(1000 + random.nextInt(5000));
-            } catch (InterruptedException e) {
-            }
-        }
-
-        if (queue == null)
-            throw new CloudRuntimeException("Unable to insert queue item into database, DB is full?");
-    }
-
-    @Override
-    public AsyncJob queryJob(long jobId, boolean updatePollTime) {
-        AsyncJobVO job = _jobDao.findById(jobId);
-        
-        if (updatePollTime) {
-            job.setLastPolled(DateUtil.currentGMTTime());
-            _jobDao.update(jobId, job);
-        }
-        return job;
-    }
-
-
-    private void scheduleExecution(final AsyncJobVO job) {
-        scheduleExecution(job, false);
-    }
-
-    private void scheduleExecution(final AsyncJob job, boolean executeInContext) {
-        Runnable runnable = getExecutorRunnable(job);
-        if (executeInContext) {
-            runnable.run();
-        } else {
-            _executor.submit(runnable);
-        }
-    }
-    
-    private AsyncJobDispatcher getDispatcher(String dispatcherName) {
-        assert (dispatcherName != null && !dispatcherName.isEmpty()) : "Who's not setting the dispatcher when submitting a job?  Who am I suppose to call if you do that!";
-    	
-        for (AsyncJobDispatcher dispatcher : _jobDispatchers) {
-            if (dispatcherName.equals(dispatcher.getName()))
-                return dispatcher;
-        }
-
-        throw new CloudRuntimeException("Unable to find dispatcher name: " + dispatcherName);
-    }
-    
-    private AsyncJobDispatcher getWakeupDispatcher(AsyncJob job) {
-    	if(_jobDispatchers != null) {
-    		List<AsyncJobJoinMapVO> joinRecords = _joinMapDao.listJoinRecords(job.getId());
-    		if(joinRecords.size() > 0) {
-    			AsyncJobJoinMapVO joinRecord = joinRecords.get(0);
-	    		for(AsyncJobDispatcher dispatcher : _jobDispatchers) {
-	    			if(dispatcher.getName().equals(joinRecord.getWakeupDispatcher()))
-	    				return dispatcher;
-	    		}
-    		} else {
-    			s_logger.warn("job-" + job.getId() + " is scheduled for wakeup run, but there is no joining info anymore");
-    		}
-    	}
-    	return null;
-    }
-    
-    private long getJobRunNumber() {
-    	synchronized(this) {
-    		return _executionRunNumber++;
-    	}
-    }
-    
-    private Runnable getExecutorRunnable(final AsyncJob job) {
-        return new Runnable() {
-            @Override
-            public void run() {
-            	Transaction txn = null;
-            	long runNumber = getJobRunNumber();
-            	
-            	try {
-            		//
-            		// setup execution environment
-            		//
-            		txn = Transaction.open(Transaction.CLOUD_DB);
-            		
-                    try {
-                        JmxUtil.registerMBean("AsyncJobManager", "Active Job " + job.getId(), new AsyncJobMBeanImpl(job));
-                    } catch(Exception e) {
-                		// Due to co-existence of normal-dispatched-job/wakeup-dispatched-job, MBean register() call
-                		// is expected to fail under situations
-                    	if(s_logger.isTraceEnabled())
-                    		s_logger.trace("Unable to register active job " + job.getId() + " to JMX monitoring due to exception " + ExceptionUtil.toString(e));
-                    }
-                    
-                    _jobMonitor.registerActiveTask(runNumber, job.getId());
-                    AsyncJobExecutionContext.setCurrentExecutionContext(new AsyncJobExecutionContext(job));
-                    
-                    // execute the job
-                    if(s_logger.isDebugEnabled()) {
-                        s_logger.debug("Executing " + job);
-                    }
-
-                    if ((getAndResetPendingSignals(job) & SIGNAL_MASK_WAKEUP) != 0) {
-                    	AsyncJobDispatcher jobDispatcher = getWakeupDispatcher(job);
-                    	if(jobDispatcher != null) {
-                    		jobDispatcher.runJob(job);
-                    	} else {
-                    		s_logger.error("Unable to find a wakeup dispatcher from the joined job: " + job);
-                    	}
-                    } else {
-	                    AsyncJobDispatcher jobDispatcher = getDispatcher(job.getDispatcher());
-	                    if(jobDispatcher != null) {
-	                    	jobDispatcher.runJob(job);
-	                    } else {
-	                    	s_logger.error("Unable to find job dispatcher, job will be cancelled");
-	                        completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), null);
-	                    }
-                    }
-                    
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Done executing " + job.getCmd() + " for job-" + job.getId());
-                    }
-                   
-            	} catch (Throwable e) {
-            		s_logger.error("Unexpected exception", e);
-                    completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), null);
-            	} finally {
-            		// guard final clause as well
-                    try {
-                    	AsyncJobVO jobToUpdate = _jobDao.findById(job.getId());
-                    	jobToUpdate.setExecutingMsid(null);
-                    	_jobDao.update(job.getId(), jobToUpdate);
-                    	
-                    	if (job.getSyncSource() != null) {
-                            _queueMgr.purgeItem(job.getSyncSource().getId());
-                            checkQueue(job.getSyncSource().getQueueId());
-                        }
-
-                    	try {
-                    		JmxUtil.unregisterMBean("AsyncJobManager", "Active Job " + job.getId());
-                    	} catch(Exception e) {
-                    		// Due to co-existence of normal-dispatched-job/wakeup-dispatched-job, MBean unregister() call
-                    		// is expected to fail under situations
-                    		if(s_logger.isTraceEnabled())
-                    			s_logger.trace("Unable to unregister job " + job.getId() + " to JMX monitoring due to exception " + ExceptionUtil.toString(e));
-                    	}
-                    	
-	                    if(txn != null)
-	                    	txn.close();
-	                    
-                    	//
-                    	// clean execution environment
-                    	//
-                        AsyncJobExecutionContext.unregister();
-                        _jobMonitor.unregisterActiveTask(runNumber);
-	                    
-                    } catch(Throwable e) {
-                		s_logger.error("Double exception", e);
-                    }
-            	}
-            }
-        };
-    }
-    
-    private int getAndResetPendingSignals(AsyncJob job) {
-    	int signals = job.getPendingSignals();
-    	if(signals != 0) {
-	    	AsyncJobVO jobRecord = _jobDao.findById(job.getId());
-	    	jobRecord.setPendingSignals(0);
-	    	_jobDao.update(job.getId(), jobRecord);
-    	}
-    	return signals;
-    }
-    
-    private void executeQueueItem(SyncQueueItemVO item, boolean fromPreviousSession) {
-        AsyncJobVO job = _jobDao.findById(item.getContentId());
-        if (job != null) {
-            if(s_logger.isDebugEnabled()) {
-                s_logger.debug("Schedule queued job-" + job.getId());
-            }
-
-            job.setSyncSource(item);
-            
-            job.setExecutingMsid(getMsid());
-            _jobDao.update(job.getId(), job);
-
-            try {
-                scheduleExecution(job);
-            } catch(RejectedExecutionException e) {
-                s_logger.warn("Execution for job-" + job.getId() + " is rejected, return it to the queue for next turn");
-                _queueMgr.returnItem(item.getId());
-                
-            	job.setExecutingMsid(null);
-            	_jobDao.update(job.getId(), job);
-            }
-
-        } else {
-            if(s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to find related job for queue item: " + item.toString());
-            }
-
-            _queueMgr.purgeItem(item.getId());
-        }
-    }
-
-    @Override
-    public void releaseSyncSource() {
-    	AsyncJobExecutionContext executionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-    	assert(executionContext != null);
-    	
-    	if(executionContext.getSyncSource() != null) {
-            if(s_logger.isDebugEnabled()) {
-                s_logger.debug("Release sync source for job-" + executionContext.getJob().getId() + " sync source: "
-                        + executionContext.getSyncSource().getContentType() + "-"
-                        + executionContext.getSyncSource().getContentId());
-            }
-
-            _queueMgr.purgeItem(executionContext.getSyncSource().getId());
-            checkQueue(executionContext.getSyncSource().getQueueId());
-    	}
-    }
-    
-    @Override
-    public boolean waitAndCheck(String[] wakupTopicsOnMessageBus, long checkIntervalInMilliSeconds,
-        long timeoutInMiliseconds, Predicate predicate) {
-    	
-    	MessageDetector msgDetector = new MessageDetector();
-    	msgDetector.open(_messageBus, wakupTopicsOnMessageBus);
-    	try {
-    		long startTick = System.currentTimeMillis();
-    		while(System.currentTimeMillis() - startTick < timeoutInMiliseconds) {
-    			msgDetector.waitAny(checkIntervalInMilliSeconds);
-    			if(predicate.checkCondition())
-    				return true;
-    		}
-    	} finally {
-    		msgDetector.close();
-    	}
-    	
-    	return false;
-    }
-
-    private void checkQueue(long queueId) {
-        while(true) {
-            try {
-                SyncQueueItemVO item = _queueMgr.dequeueFromOne(queueId, getMsid());
-                if(item != null) {
-                    if(s_logger.isDebugEnabled()) {
-                        s_logger.debug("Executing sync queue item: " + item.toString());
-                    }
-
-                    executeQueueItem(item, false);
-                } else {
-                    break;
-                }
-            } catch(Throwable e) {
-                s_logger.error("Unexpected exception when kicking sync queue-" + queueId, e);
-                break;
-            }
-        }
-    }
-
-    private Runnable getHeartbeatTask() {
-        return new Runnable() {
-            @Override
-            public void run() {
-            	Transaction txn = Transaction.open("AsyncJobManagerImpl.getHeartbeatTask");
-                try {
-                    List<SyncQueueItemVO> l = _queueMgr.dequeueFromAny(getMsid(), MAX_ONETIME_SCHEDULE_SIZE);
-                    if(l != null && l.size() > 0) {
-                        for(SyncQueueItemVO item: l) {
-                            if(s_logger.isDebugEnabled()) {
-                                s_logger.debug("Execute sync-queue item: " + item.toString());
-                            }
-                            executeQueueItem(item, false);
-                        }
-                    }
-              
-                    List<Long> standaloneWakeupJobs = _joinMapDao.wakeupScan();
-                    for(Long jobId : standaloneWakeupJobs) {
-                    	// TODO, we assume that all jobs in this category is API job only
-                    	AsyncJobVO job = _jobDao.findById(jobId);
-                        if (job != null && (job.getPendingSignals() & SIGNAL_MASK_WAKEUP) != 0)
-                    	    scheduleExecution(job, false);
-                    }
-                } catch(Throwable e) {
-                    s_logger.error("Unexpected exception when trying to execute queue item, ", e);
-                } finally {
-                	try {
-                		txn.close();
-                	} catch(Throwable e) {
-                        s_logger.error("Unexpected exception", e);
-                	}
-                }
-            }
-        };
-    }
-
-    @DB
-    private Runnable getGCTask() {
-        return new Runnable() {
-            @Override
-            public void run() {
-                GlobalLock scanLock = GlobalLock.getInternLock("AsyncJobManagerGC");
-                try {
-                    if(scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
-                        try {
-                            reallyRun();
-                        } finally {
-                            scanLock.unlock();
-                        }
-                    }
-                } finally {
-                    scanLock.releaseRef();
-                }
-            }
-
-            public void reallyRun() {
-                try {
-                    s_logger.trace("Begin cleanup expired async-jobs");
-
-                    Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - _jobExpireSeconds.value() * 1000);
-
-                    // limit to 100 jobs per turn, this gives cleanup throughput as 600 jobs per minute
-                    // hopefully this will be fast enough to balance potential growth of job table
-                    //1) Expire unfinished jobs that weren't processed yet
-                    List<AsyncJobVO> l = _jobDao.getExpiredUnfinishedJobs(cutTime, 100);
-                        for(AsyncJobVO job : l) {
-                    	s_logger.trace("Expunging unfinished job " + job);
-                            expungeAsyncJob(job);
-                        }
-                    
-                    //2) Expunge finished jobs
-                    List<AsyncJobVO> completedJobs = _jobDao.getExpiredCompletedJobs(cutTime, 100);
-                    for(AsyncJobVO job : completedJobs) {
-                    	s_logger.trace("Expunging completed job " + job);
-                        expungeAsyncJob(job);
-                    }
-
-                    // forcefully cancel blocking queue items if they've been staying there for too long
-                    List<SyncQueueItemVO> blockItems = _queueMgr.getBlockedQueueItems(_jobCancelThresholdSeconds.value()
-                            * 1000, false);
-                    if(blockItems != null && blockItems.size() > 0) {
-                        for(SyncQueueItemVO item : blockItems) {
-                            if(item.getContentType().equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) {
-                                completeAsyncJob(item.getContentId(), JobInfo.Status.FAILED, 0, "Job is cancelled as it has been blocking others for too long");
-                            }
-
-                            // purge the item and resume queue processing
-                            _queueMgr.purgeItem(item.getId());
-                        }
-                    }
-
-                    s_logger.trace("End cleanup expired async-jobs");
-                } catch(Throwable e) {
-                    s_logger.error("Unexpected exception when trying to execute queue item, ", e);
-                }
-            }
-        };
-    }
-
-    @DB
-    protected void expungeAsyncJob(AsyncJobVO job) {
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        _jobDao.expunge(job.getId());
-        //purge corresponding sync queue item
-        _queueMgr.purgeAsyncJobQueueItemId(job.getId());
-        txn.commit();
-    }
-
-    private long getMsid() {
-        return ManagementServerNode.getManagementServerId();
-    }
-
-    private void cleanupPendingJobs(List<SyncQueueItemVO> l) {
-        for (SyncQueueItemVO item : l) {
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Discard left-over queue item: " + item.toString());
-            }
-
-            String contentType = item.getContentType();
-            if (contentType != null && contentType.equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) {
-                Long jobId = item.getContentId();
-                if (jobId != null) {
-                    s_logger.warn("Mark job as failed as its correspoding queue-item has been discarded. job id: " + jobId);
-                    completeAsyncJob(jobId, JobInfo.Status.FAILED, 0, "Execution was cancelled because of server shutdown");
-                }
-            }
-            _queueMgr.purgeItem(item.getId());
-        }
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _jobExpireSeconds = _configDepot.get(JobExpireMinutes).setMultiplier(60);
-        _jobCancelThresholdSeconds = _configDepot.get(JobCancelThresholdMinutes).setMultiplier(60);
-
-        try {
-            final File dbPropsFile = PropertiesUtil.findConfigFile("db.properties");
-            final Properties dbProps = new Properties();
-            dbProps.load(new FileInputStream(dbPropsFile));
-
-            final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
-
-            int poolSize = (cloudMaxActive * 2) / 3;
-
-            s_logger.info("Start AsyncJobManager thread pool in size " + poolSize);
-            _executor = Executors.newFixedThreadPool(poolSize, new NamedThreadFactory(AsyncJobManager.JOB_POOL_THREAD_PREFIX));
-        } catch (final Exception e) {
-            throw new ConfigurationException("Unable to load db.properties to configure AsyncJobManagerImpl");
-        }
-
-        AsyncJobExecutionContext.init(this, _joinMapDao);
-        OutcomeImpl.init(this);
-
-        return true;
-    }
-
-    @Override
-    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-    }
-
-    @Override
-    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-        for (ManagementServerHost msHost : nodeList) {
-            Transaction txn = Transaction.open(Transaction.CLOUD_DB);
-            try {
-                txn.start();
-                List<SyncQueueItemVO> items = _queueMgr.getActiveQueueItems(msHost.getId(), true);
-                cleanupPendingJobs(items);
-                _jobDao.resetJobProcess(msHost.getId(), ApiErrorCode.INTERNAL_ERROR.getHttpCode(), "job cancelled because of management server restart");
-                txn.commit();
-            } catch(Throwable e) {
-                s_logger.warn("Unexpected exception ", e);
-            } finally {
-                txn.close();
-            }
-        }
-    }
-
-    @Override
-    public void onManagementNodeIsolated() {
-    }
-
-    @Override
-    public boolean start() {
-        try {
-        	_jobDao.cleanupPseduoJobs(getMsid());
-        	
-            List<SyncQueueItemVO> l = _queueMgr.getActiveQueueItems(getMsid(), false);
-            cleanupPendingJobs(l);
-            _jobDao.resetJobProcess(getMsid(), ApiErrorCode.INTERNAL_ERROR.getHttpCode(), "job cancelled because of management server restart");
-        } catch(Throwable e) {
-            s_logger.error("Unexpected exception " + e.getMessage(), e);
-        }
-
-        _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HEARTBEAT_INTERVAL, HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS);
-        _heartbeatScheduler.scheduleAtFixedRate(getGCTask(), GC_INTERVAL, GC_INTERVAL, TimeUnit.MILLISECONDS);
-
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        _heartbeatScheduler.shutdown();
-        _executor.shutdown();
-        return true;
-    }
-}


[8/9] git commit: updated refs/heads/vmsync to 309f8da

Posted by ah...@apache.org.
fixes null pointer


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/6adf7618
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/6adf7618
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/6adf7618

Branch: refs/heads/vmsync
Commit: 6adf761848d2844fa6ecd391585e87d201658348
Parents: fa525a7
Author: Alex Huang <al...@gmail.com>
Authored: Mon Jun 17 16:06:04 2013 -0700
Committer: Alex Huang <al...@gmail.com>
Committed: Mon Jun 17 17:25:01 2013 -0700

----------------------------------------------------------------------
 .../cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java  |  9 +++++----
 .../cloudstack/framework/jobs/impl/AsyncJobVO.java      |  2 ++
 utils/src/com/cloud/utils/db/GenericDaoBase.java        | 12 ++++++++++--
 utils/src/org/apache/cloudstack/config/ConfigValue.java |  5 +++--
 4 files changed, 20 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6adf7618/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java
index 96775f7..9b1eda6 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java
@@ -161,7 +161,7 @@ public class AsyncJobDaoImpl extends GenericDaoBase<AsyncJobVO, Long> implements
 	public List<AsyncJobVO> getExpiredUnfinishedJobs(Date cutTime, int limit) {
 		SearchCriteria<AsyncJobVO> sc = expiringUnfinishedAsyncJobSearch.create();
 		sc.setParameters("created", cutTime);
-		sc.setParameters("jobStatus", 0);
+        sc.setParameters("jobStatus", JobInfo.Status.IN_PROGRESS);
 		Filter filter = new Filter(AsyncJobVO.class, "created", true, 0L, (long)limit);
 		return listIncludingRemovedBy(sc, filter);
 	}
@@ -170,7 +170,7 @@ public class AsyncJobDaoImpl extends GenericDaoBase<AsyncJobVO, Long> implements
 	public List<AsyncJobVO> getExpiredCompletedJobs(Date cutTime, int limit) {
 		SearchCriteria<AsyncJobVO> sc = expiringCompletedAsyncJobSearch.create();
 		sc.setParameters("created", cutTime);
-		sc.setParameters("jobStatus", 0);
+        sc.setParameters("jobStatus", JobInfo.Status.IN_PROGRESS);
 		Filter filter = new Filter(AsyncJobVO.class, "created", true, 0L, (long)limit);
 		return listIncludingRemovedBy(sc, filter);
 	}
@@ -178,8 +178,9 @@ public class AsyncJobDaoImpl extends GenericDaoBase<AsyncJobVO, Long> implements
 	@Override
     @DB
 	public void resetJobProcess(long msid, int jobResultCode, String jobResultMessage) {
-		String sql = "UPDATE async_job SET job_status=" + JobInfo.Status.FAILED + ", job_result_code=" + jobResultCode
-			+ ", job_result='" + jobResultMessage + "' where job_status=0 AND (job_complete_msid=? OR (job_complete_msid IS NULL AND job_init_msid=?))";
+        String sql = "UPDATE async_job SET job_status=" + JobInfo.Status.FAILED.ordinal() + ", job_result_code=" + jobResultCode
+                + ", job_result='" + jobResultMessage + "' where job_status=" + JobInfo.Status.IN_PROGRESS.ordinal()
+                + " AND (job_complete_msid=? OR (job_complete_msid IS NULL AND job_init_msid=?))";
 		
         Transaction txn = Transaction.currentTxn();
         PreparedStatement pstmt = null;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6adf7618/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
index cab047b..89bbd86 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
@@ -133,6 +133,7 @@ public class AsyncJobVO implements AsyncJob, JobInfo {
     public AsyncJobVO() {
         uuid = UUID.randomUUID().toString();
         related = UUID.randomUUID().toString();
+        status = Status.IN_PROGRESS;
     }
 
     public AsyncJobVO(String related, long userId, long accountId, String cmd, String cmdInfo, Long instanceId, String instanceType) {
@@ -144,6 +145,7 @@ public class AsyncJobVO implements AsyncJob, JobInfo {
         this.related = related;
 	    this.instanceId = instanceId;
 	    this.instanceType = instanceType;
+        status = Status.IN_PROGRESS;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6adf7618/utils/src/com/cloud/utils/db/GenericDaoBase.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java
index 9e91ef6..f593c38 100755
--- a/utils/src/com/cloud/utils/db/GenericDaoBase.java
+++ b/utils/src/com/cloud/utils/db/GenericDaoBase.java
@@ -1485,7 +1485,11 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
             if (type == EnumType.STRING) {
                 pstmt.setString(j, value == null ? null :  value.toString());
             } else if (type == EnumType.ORDINAL) {
-                pstmt.setInt(j, value == null ? null : ((Enum<?>)value).ordinal());
+                if (value == null) {
+                    pstmt.setObject(j, null);
+                } else {
+                    pstmt.setInt(j, ((Enum<?>)value).ordinal());
+                }
             }
         } else if (attr.field.getType() == URI.class) {
             pstmt.setString(j, value == null ? null : value.toString());
@@ -1499,7 +1503,11 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
             if (type == EnumType.STRING) {
                 pstmt.setString(j, value == null ? null : value.toString());
             } else if (type == EnumType.ORDINAL) {
-                pstmt.setLong(j, value == null ? null : (value instanceof Ip) ? ((Ip)value).longValue() : NetUtils.ip2Long((String)value));
+                if (value == null) {
+                    pstmt.setObject(j, null);
+                } else {
+                    pstmt.setLong(j, (value instanceof Ip) ? ((Ip)value).longValue() : NetUtils.ip2Long((String)value));
+                }
             }
         } else {
             pstmt.setObject(j, value);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6adf7618/utils/src/org/apache/cloudstack/config/ConfigValue.java
----------------------------------------------------------------------
diff --git a/utils/src/org/apache/cloudstack/config/ConfigValue.java b/utils/src/org/apache/cloudstack/config/ConfigValue.java
index 36ff38a..013b835 100644
--- a/utils/src/org/apache/cloudstack/config/ConfigValue.java
+++ b/utils/src/org/apache/cloudstack/config/ConfigValue.java
@@ -49,7 +49,7 @@ public class ConfigValue<T> {
 
     @SuppressWarnings("unchecked")
     public T value() {
-        if (_config.isDynamic()) {
+        if (_value == null || _config.isDynamic()) {
             Configuration vo = _entityMgr.findById(Configuration.class, _config.key());
             String value = vo != null ? vo.getValue() : _config.defaultValue();
 
@@ -66,8 +66,9 @@ public class ConfigValue<T> {
                 _value = (T)value;
             } else if (type.isAssignableFrom(Float.class)) {
                 _value = (T)new Float(Float.parseFloat(value) * _multiplier.floatValue());
+            } else {
+                throw new CloudRuntimeException("Unsupported data type for config values: " + type);
             }
-            throw new CloudRuntimeException("Unsupported data type for config values: " + type);
         }
 
         return _value;


[4/9] Removed a bunch of useless classes. Move configuration into utils package

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/org/apache/cloudstack/config/ConfigValue.java
----------------------------------------------------------------------
diff --git a/utils/src/org/apache/cloudstack/config/ConfigValue.java b/utils/src/org/apache/cloudstack/config/ConfigValue.java
new file mode 100644
index 0000000..36ff38a
--- /dev/null
+++ b/utils/src/org/apache/cloudstack/config/ConfigValue.java
@@ -0,0 +1,75 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.config;
+
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+/**
+ *  This is a match set to ConfigKey.
+ *
+ * TODO: When we create a framework project for configuration, this should be
+ * moved there.
+ */
+public class ConfigValue<T> {
+
+    ConfigKey<T> _config;
+    EntityManager _entityMgr;
+    Number _multiplier;
+    T _value;
+
+    public ConfigValue(EntityManager entityMgr, ConfigKey<T> config) {
+        _entityMgr = entityMgr;
+        _config = config;
+        _multiplier = 1;
+    }
+
+    public ConfigKey<T> getConfigKey() {
+        return _config;
+    }
+
+    public ConfigValue<T> setMultiplier(Number multiplier) {  // Convience method
+        _multiplier = multiplier;
+        return this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public T value() {
+        if (_config.isDynamic()) {
+            Configuration vo = _entityMgr.findById(Configuration.class, _config.key());
+            String value = vo != null ? vo.getValue() : _config.defaultValue();
+
+            Class<T> type = _config.type();
+            if (type.isAssignableFrom(Boolean.class)) {
+                _value = (T)Boolean.valueOf(value);
+            } else if (type.isAssignableFrom(Integer.class)) {
+                _value = (T)new Integer((Integer.parseInt(value) * _multiplier.intValue()));
+            } else if (type.isAssignableFrom(Long.class)) {
+                _value = (T)new Long(Long.parseLong(value) * _multiplier.longValue());
+            } else if (type.isAssignableFrom(Short.class)) {
+                _value = (T)new Short(Short.parseShort(value));
+            } else if (type.isAssignableFrom(String.class)) {
+                _value = (T)value;
+            } else if (type.isAssignableFrom(Float.class)) {
+                _value = (T)new Float(Float.parseFloat(value) * _multiplier.floatValue());
+            }
+            throw new CloudRuntimeException("Unsupported data type for config values: " + type);
+        }
+
+        return _value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3a074f31/utils/src/org/apache/cloudstack/config/Configuration.java
----------------------------------------------------------------------
diff --git a/utils/src/org/apache/cloudstack/config/Configuration.java b/utils/src/org/apache/cloudstack/config/Configuration.java
new file mode 100644
index 0000000..8657832
--- /dev/null
+++ b/utils/src/org/apache/cloudstack/config/Configuration.java
@@ -0,0 +1,33 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.config;
+
+public interface Configuration {
+
+    public String getCategory();
+
+    public String getInstance();
+
+    public String getComponent();
+
+    public String getName();
+
+    public String getValue();
+
+    public String getDescription();
+
+}


[3/9] git commit: updated refs/heads/vmsync to 309f8da

Posted by ah...@apache.org.
Completely Isolated job manager from user


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/aad2bc78
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/aad2bc78
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/aad2bc78

Branch: refs/heads/vmsync
Commit: aad2bc78c1f9b60e15905251f33b2920577786e9
Parents: ea6ca5f
Author: Alex Huang <al...@gmail.com>
Authored: Sat Jun 15 05:15:53 2013 -0700
Committer: Alex Huang <al...@gmail.com>
Committed: Mon Jun 17 17:04:03 2013 -0700

----------------------------------------------------------------------
 .../org/apache/cloudstack/config/ConfigKey.java |  13 +-
 .../apache/cloudstack/config/Configurable.java  |  21 ++
 .../apache/cloudstack/config/ConfigDepot.java   |  25 +++
 .../apache/cloudstack/config/ConfigRepo.java    |  26 ---
 .../cloudstack/engine/config/Configs.java       |  18 +-
 .../com/cloud/vm/VirtualMachineManagerImpl.java |  16 +-
 .../src/com/cloud/vm/VmWorkJobDispatcher.java   |   2 +-
 .../cloudstack/vm/jobs/VmWorkJobDaoImpl.java    |  20 +-
 .../jobs/AsyncJobExecutionContext.java          |   4 +-
 .../framework/jobs/AsyncJobManager.java         |  20 +-
 .../framework/jobs/impl/AsyncJobMonitor.java    |   4 +-
 .../com/cloud/api/ApiAsyncJobDispatcher.java    |   4 +-
 server/src/com/cloud/api/ApiResponseHelper.java |  33 ++-
 .../com/cloud/async/AsyncJobManagerImpl.java    | 201 +++++--------------
 .../configuration/ConfigurationManagerImpl.java |   8 +-
 .../com/cloud/server/ManagementServerImpl.java  |   7 +-
 .../com/cloud/storage/VolumeManagerImpl.java    |   6 +-
 .../storage/snapshot/SnapshotSchedulerImpl.java |   7 +-
 .../cloud/storage/upload/UploadListener.java    |  48 ++---
 .../com/cloud/async/TestAsyncJobManager.java    |   4 +-
 .../vm/VmWorkMockVirtualMachineManagerImpl.java |   2 +-
 .../cloud/vm/VmWorkTestWorkJobDispatcher.java   |   2 +-
 22 files changed, 227 insertions(+), 264 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/api/src/org/apache/cloudstack/config/ConfigKey.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/config/ConfigKey.java b/api/src/org/apache/cloudstack/config/ConfigKey.java
index 2a77a9b..9e42831 100644
--- a/api/src/org/apache/cloudstack/config/ConfigKey.java
+++ b/api/src/org/apache/cloudstack/config/ConfigKey.java
@@ -61,6 +61,10 @@ public class ConfigKey<T> {
         return _scope;
     }
 
+    public boolean isDynamic() {
+        return _isDynamic;
+    }
+
     @Override
     public String toString() {
         return _name;
@@ -73,8 +77,10 @@ public class ConfigKey<T> {
     private final String _description;
     private final String _range;
     private final String _scope; // Parameter can be at different levels (Zone/cluster/pool/account), by default every parameter is at global
+    private final boolean _isDynamic;
 
-    public ConfigKey(Class<T> type, String name, String category, Class<?> componentClass, String defaultValue, String description, String range, String scope) {
+    public ConfigKey(Class<T> type, String name, String category, Class<?> componentClass, String defaultValue, String description, boolean isDynamic, String range,
+            String scope) {
         _category = category;
         _componentClass = componentClass;
         _type = type;
@@ -83,9 +89,10 @@ public class ConfigKey<T> {
         _description = description;
         _range = range;
         _scope = scope;
+        _isDynamic = isDynamic;
     }
 
-    public ConfigKey(Class<T> type, String name, String category, Class<?> componentClass, String defaultValue, String description, String range) {
-        this(type, name, category, componentClass, defaultValue, description, range, null);
+    public ConfigKey(Class<T> type, String name, String category, Class<?> componentClass, String defaultValue, String description, boolean isDynamic, String range) {
+        this(type, name, category, componentClass, defaultValue, description, isDynamic, range, null);
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/api/src/org/apache/cloudstack/config/Configurable.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/config/Configurable.java b/api/src/org/apache/cloudstack/config/Configurable.java
new file mode 100644
index 0000000..3c50eba
--- /dev/null
+++ b/api/src/org/apache/cloudstack/config/Configurable.java
@@ -0,0 +1,21 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.config;
+
+public interface Configurable {
+    ConfigKey<?>[] getConfigKeys();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/engine/components-api/src/org/apache/cloudstack/config/ConfigDepot.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/org/apache/cloudstack/config/ConfigDepot.java b/engine/components-api/src/org/apache/cloudstack/config/ConfigDepot.java
new file mode 100644
index 0000000..640753c
--- /dev/null
+++ b/engine/components-api/src/org/apache/cloudstack/config/ConfigDepot.java
@@ -0,0 +1,25 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.config;
+
+/**
+ * ConfigRepo is a repository of configurations.
+ *
+ */
+public interface ConfigDepot {
+    <T> ConfigValue<T> get(ConfigKey<T> key);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/engine/components-api/src/org/apache/cloudstack/config/ConfigRepo.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/org/apache/cloudstack/config/ConfigRepo.java b/engine/components-api/src/org/apache/cloudstack/config/ConfigRepo.java
deleted file mode 100644
index 823d754..0000000
--- a/engine/components-api/src/org/apache/cloudstack/config/ConfigRepo.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.config;
-
-/**
- * ConfigRepo is a repository of configurations.
- *
- */
-public interface ConfigRepo {
-    <T> ConfigValue<T> get(ConfigKey<T> key);
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/engine/components-api/src/org/apache/cloudstack/engine/config/Configs.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/org/apache/cloudstack/engine/config/Configs.java b/engine/components-api/src/org/apache/cloudstack/engine/config/Configs.java
index 9dcb86d..14598bd 100644
--- a/engine/components-api/src/org/apache/cloudstack/engine/config/Configs.java
+++ b/engine/components-api/src/org/apache/cloudstack/engine/config/Configs.java
@@ -22,24 +22,24 @@ import org.apache.cloudstack.engine.service.api.OrchestrationService;
 public interface Configs {
     
     public static final ConfigKey<Integer> StartRetry = new ConfigKey<Integer>(
-            Integer.class, "start.retry", "Advanced", OrchestrationService.class, "10", "Number of times to retry create and start commands", null);
+            Integer.class, "start.retry", "Advanced", OrchestrationService.class, "10", "Number of times to retry create and start commands", true, null);
     public static final ConfigKey<Long> VmOpWaitInterval = new ConfigKey<Long>(
             Long.class, "vm.op.wait.interval", "Advanced", OrchestrationService.class, "120", "Time (in seconds) to wait before checking if a previous operation has succeeded",
-            null);
+            true, null);
     public static final ConfigKey<Integer> VmOpLockStateRetry = new ConfigKey<Integer>(
-            Integer.class, "vm.op.lock.state.retry", "Advanced", OrchestrationService.class, "5", "Times to retry locking the state of a VM for operations", "-1 means try forever");
+            Integer.class, "vm.op.lock.state.retry", "Advanced", OrchestrationService.class, "5", "Times to retry locking the state of a VM for operations",
+            true, "-1 means try forever");
     public static final ConfigKey<Long> VmOpCleanupInterval = new ConfigKey<Long>(
             Long.class, "vm.op.cleanup.interval", "Advanced", OrchestrationService.class, "86400", "Interval to run the thread that cleans up the vm operations (in seconds)",
-            "Seconds");
+            false, "Seconds");
     public static final ConfigKey<Long> VmOpCleanupWait = new ConfigKey<Long>(
-            Long.class, "vm.op.cleanup.wait", "Advanced", OrchestrationService.class, "3600", "Time (in seconds) to wait before cleanuping up any vm work items", "Seconds");
+            Long.class, "vm.op.cleanup.wait", "Advanced", OrchestrationService.class, "3600", "Time (in seconds) to wait before cleanuping up any vm work items", false, "Seconds");
     public static final ConfigKey<Integer> VmOpCancelInterval = new ConfigKey<Integer>(
-            Integer.class, "vm.op.cancel.interval", "Advanced", OrchestrationService.class, "3600", "Time (in seconds) to wait before cancelling a operation", "Seconds");
-
+            Integer.class, "vm.op.cancel.interval", "Advanced", OrchestrationService.class, "3600", "Time (in seconds) to wait before cancelling a operation", false, "Seconds");
     public static final ConfigKey<Integer> Wait = new ConfigKey<Integer>(
-            Integer.class, "wait", "Advanced", OrchestrationService.class, "1800", "Time in seconds to wait for control commands to return", null);
+            Integer.class, "wait", "Advanced", OrchestrationService.class, "1800", "Time in seconds to wait for control commands to return", false, null);
     public static final ConfigKey<Boolean> VmDestroyForcestop = new ConfigKey<Boolean>(
-            Boolean.class, "vm.destroy.forcestop", "Advanced", OrchestrationService.class, "false", "On destroy, force-stop takes this value ", null);
+            Boolean.class, "vm.destroy.forcestop", "Advanced", OrchestrationService.class, "false", "On destroy, force-stop takes this value ", true, null);
 
     public static final ConfigKey<Long> PingInterval = new ConfigKey<Long>(
             Long.class, "ping.interval", "Advanced", OrchestrationService.class, "60", "Ping interval in seconds", null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index 0f710d1..f3e2add 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -39,19 +39,19 @@ import javax.naming.ConfigurationException;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
-import org.apache.cloudstack.config.ConfigRepo;
+import org.apache.cloudstack.config.ConfigDepot;
 import org.apache.cloudstack.config.ConfigValue;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.config.Configs;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.framework.messagebus.MessageBus;
 import org.apache.cloudstack.framework.messagebus.MessageDispatcher;
 import org.apache.cloudstack.framework.messagebus.MessageHandler;
+import org.apache.cloudstack.jobs.JobInfo;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.vm.jobs.VmWorkJobDao;
 import org.apache.cloudstack.vm.jobs.VmWorkJobVO;
@@ -175,7 +175,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     @Inject
     protected EntityManager _entityMgr;
     @Inject
-    ConfigRepo _configRepo;
+    ConfigDepot _configRepo;
     @Inject
     DataStoreManager _dataStoreMgr;
     @Inject
@@ -3536,7 +3536,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     	//	1) no pending VmWork job
     	//	2) on hostId host and host is UP
     	//
-    	// When host is UP, soon or later we will get a report from the host about the VM, 
+    	// When host is UP, soon or later we will get a report from the host about the VM,
     	// however, if VM is missing from the host report (it may happen in out of band changes
     	// or from designed behave of XS/KVM), the VM may not get a chance to run the state-sync logic
     	//
@@ -3580,9 +3580,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     // VMs that in transitional state without recent power state report
     @DB
     private List<Long> listStalledVMInTransitionStateOnUpHost(long hostId, Date cutTime) {
-    	String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status = 'UP' " + 
+    	String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status = 'UP' " +
                      "AND h.id = ? AND i.power_state_update_time < ? AND i.host_id = h.id " +
-    			     "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " + 
+    			     "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
     			     "AND i.id NOT IN (SELECT vm_instance_id FROM vm_work_job)";
     	
     	List<Long> l = new ArrayList<Long>();
@@ -3631,9 +3631,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     
     @DB
     private List<Long> listStalledVMInTransitionStateOnDisconnectedHosts(Date cutTime) {
-    	String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status != 'UP' " + 
+    	String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status != 'UP' " +
                  "AND i.power_state_update_time < ? AND i.host_id = h.id " +
-			     "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " + 
+			     "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
 			     "AND i.id NOT IN (SELECT vm_instance_id FROM vm_work_job)";
 	
     	List<Long> l = new ArrayList<Long>();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java b/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
index 7819c1a..5207fc5 100644
--- a/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
+++ b/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
@@ -27,9 +27,9 @@ import com.google.gson.GsonBuilder;
 
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.api.StringMapTypeAdapter;
 import com.cloud.dao.EntityManager;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/engine/schema/src/org/apache/cloudstack/vm/jobs/VmWorkJobDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/vm/jobs/VmWorkJobDaoImpl.java b/engine/schema/src/org/apache/cloudstack/vm/jobs/VmWorkJobDaoImpl.java
index 0135d81..6361a23 100644
--- a/engine/schema/src/org/apache/cloudstack/vm/jobs/VmWorkJobDaoImpl.java
+++ b/engine/schema/src/org/apache/cloudstack/vm/jobs/VmWorkJobDaoImpl.java
@@ -21,7 +21,7 @@ import java.util.List;
 
 import javax.annotation.PostConstruct;
 
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
+import org.apache.cloudstack.jobs.JobInfo;
 import org.apache.cloudstack.vm.jobs.VmWorkJobVO.Step;
 
 import com.cloud.utils.DateUtil;
@@ -31,7 +31,6 @@ import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
 import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Type;
 
 public class VmWorkJobDaoImpl extends GenericDaoBase<VmWorkJobVO, Long> implements VmWorkJobDao {
 
@@ -63,7 +62,8 @@ public class VmWorkJobDaoImpl extends GenericDaoBase<VmWorkJobVO, Long> implemen
 		ExpungeWorkJobSearch.done();
 	}
 	
-	public VmWorkJobVO findPendingWorkJob(VirtualMachine.Type type, long instanceId) {
+	@Override
+    public VmWorkJobVO findPendingWorkJob(VirtualMachine.Type type, long instanceId) {
 		
 		SearchCriteria<VmWorkJobVO> sc = PendingWorkJobSearch.create();
 		sc.setParameters("vmType", type);
@@ -78,7 +78,8 @@ public class VmWorkJobDaoImpl extends GenericDaoBase<VmWorkJobVO, Long> implemen
 		return null;
 	}
 	
-	public List<VmWorkJobVO> listPendingWorkJobs(VirtualMachine.Type type, long instanceId) {
+	@Override
+    public List<VmWorkJobVO> listPendingWorkJobs(VirtualMachine.Type type, long instanceId) {
 		
 		SearchCriteria<VmWorkJobVO> sc = PendingWorkJobSearch.create();
 		sc.setParameters("vmType", type);
@@ -89,7 +90,8 @@ public class VmWorkJobDaoImpl extends GenericDaoBase<VmWorkJobVO, Long> implemen
 		return this.listBy(sc, filter);
 	}
 
-	public List<VmWorkJobVO> listPendingWorkJobs(VirtualMachine.Type type, long instanceId, String jobCmd) {
+	@Override
+    public List<VmWorkJobVO> listPendingWorkJobs(VirtualMachine.Type type, long instanceId, String jobCmd) {
 		
 		SearchCriteria<VmWorkJobVO> sc = PendingWorkJobByCommandSearch.create();
 		sc.setParameters("vmType", type);
@@ -101,17 +103,19 @@ public class VmWorkJobDaoImpl extends GenericDaoBase<VmWorkJobVO, Long> implemen
 		return this.listBy(sc, filter);
 	}
 	
-	public void updateStep(long workJobId, Step step) {
+	@Override
+    public void updateStep(long workJobId, Step step) {
 		VmWorkJobVO jobVo = findById(workJobId);
 		jobVo.setStep(step);
 		jobVo.setLastUpdated(DateUtil.currentGMTTime());
 		update(workJobId, jobVo);
 	}
 	
-	public void expungeCompletedWorkJobs(Date cutDate) {
+	@Override
+    public void expungeCompletedWorkJobs(Date cutDate) {
 		SearchCriteria<VmWorkJobVO> sc = ExpungeWorkJobSearch.create();
 		sc.setParameters("lastUpdated",cutDate);
-		sc.setParameters("status", JobInfo.Status.IN_PROGRESS);
+        sc.setParameters("status", JobInfo.Status.IN_PROGRESS);
 		
 		expunge(sc);
 	}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
index ef0a4a6..0136593 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
@@ -64,12 +64,12 @@ public class AsyncJobExecutionContext  {
 		_job = job;
 	}
 	
-    public void completeAsyncJob(JobInfo.Status jobStatus, int resultCode, Object resultObject) {
+    public void completeAsyncJob(JobInfo.Status jobStatus, int resultCode, String resultObject) {
     	assert(_job != null);
     	_jobMgr.completeAsyncJob(_job.getId(), jobStatus, resultCode, resultObject);
     }
     
-    public void updateAsyncJobStatus(int processStatus, Object resultObject) {
+    public void updateAsyncJobStatus(int processStatus, String resultObject) {
     	assert(_job != null);
     	_jobMgr.updateAsyncJobStatus(_job.getId(), processStatus, resultObject);
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java
index 3178268..f172581 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java
@@ -18,7 +18,6 @@ package org.apache.cloudstack.framework.jobs;
 
 import java.util.List;
 
-import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
 import org.apache.cloudstack.jobs.JobInfo;
 
@@ -27,15 +26,18 @@ import com.cloud.utils.component.Manager;
 
 public interface AsyncJobManager extends Manager {
     
-	AsyncJobVO getAsyncJob(long jobId);
+	public static final String JOB_POOL_THREAD_PREFIX = "Job-Executor";
+
+    AsyncJobVO getAsyncJob(long jobId);
 	
 	List<? extends AsyncJob> findInstancePendingAsyncJobs(String instanceType, Long accountId);
 	
 	long submitAsyncJob(AsyncJob job);
 	long submitAsyncJob(AsyncJob job, String syncObjType, long syncObjId);
 
-    void completeAsyncJob(long jobId, JobInfo.Status jobStatus, int resultCode, Object resultObject);
-    void updateAsyncJobStatus(long jobId, int processStatus, Object resultObject);
+    void completeAsyncJob(long jobId, JobInfo.Status jobStatus, int resultCode, String result);
+
+    void updateAsyncJobStatus(long jobId, int processStatus, String resultObject);
     void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId);
     void logJobJournal(long jobId, AsyncJob.JournalType journalType, String
     	journalText, String journalObjJson);
@@ -118,11 +120,7 @@ public interface AsyncJobManager extends Manager {
     @Deprecated
     boolean waitAndCheck(String[] wakupTopicsOnMessageBus, long checkIntervalInMilliSeconds,
     	long timeoutInMiliseconds, Predicate predicate);
-    
-    /**
-     * Queries for the status or final result of an async job.
-     * @param cmd the command that specifies the job id
-     * @return an async-call result object
-     */
-    AsyncJob queryAsyncJobResult(QueryAsyncJobResultCmd cmd);
+
+    AsyncJob queryJob(long jobId, boolean updatePollTime);
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java
index 1042fac..3bf3622 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java
@@ -27,7 +27,7 @@ import javax.naming.ConfigurationException;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.framework.messagebus.MessageBus;
 import org.apache.cloudstack.framework.messagebus.MessageDispatcher;
 import org.apache.cloudstack.framework.messagebus.MessageHandler;
@@ -114,7 +114,7 @@ public class AsyncJobMonitor extends ManagerBase {
 			assert(_activeTasks.get(runNumber) == null);
 			
 			long threadId = Thread.currentThread().getId();
-			boolean fromPoolThread = Thread.currentThread().getName().contains(AsyncJobConstants.JOB_POOL_THREAD_PREFIX);
+            boolean fromPoolThread = Thread.currentThread().getName().contains(AsyncJobManager.JOB_POOL_THREAD_PREFIX);
             ActiveTaskRecord record = new ActiveTaskRecord(jobId, threadId, fromPoolThread);
 			_activeTasks.put(runNumber, record);
 			if(fromPoolThread)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/server/src/com/cloud/api/ApiAsyncJobDispatcher.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiAsyncJobDispatcher.java b/server/src/com/cloud/api/ApiAsyncJobDispatcher.java
index e0823dc..7ec4c70 100644
--- a/server/src/com/cloud/api/ApiAsyncJobDispatcher.java
+++ b/server/src/com/cloud/api/ApiAsyncJobDispatcher.java
@@ -93,7 +93,7 @@ public class ApiAsyncJobDispatcher extends AdapterBase implements AsyncJobDispat
                 _dispatcher.dispatch(cmdObj, params, true);
 
                 // serialize this to the async job table
-                _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, cmdObj.getResponseObject());
+                _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, ApiSerializerHelper.toSerializedString(cmdObj.getResponseObject()));
             } finally {
                 CallContext.unregister();
             }
@@ -116,7 +116,7 @@ public class ApiAsyncJobDispatcher extends AdapterBase implements AsyncJobDispat
 
             // FIXME:  setting resultCode to ApiErrorCode.INTERNAL_ERROR is not right, usually executors have their exception handling
             //         and we need to preserve that as much as possible here
-            _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), response);
+            _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), ApiSerializerHelper.toSerializedString(response));
         }
 	}
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 65214f6..dee5a7e 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -34,7 +34,6 @@ import java.util.TimeZone;
 import javax.inject.Inject;
 
 import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
 
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
@@ -139,6 +138,7 @@ import org.apache.cloudstack.api.response.VpnUsersResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
 import org.apache.cloudstack.region.PortableIp;
 import org.apache.cloudstack.region.PortableIpRange;
@@ -187,6 +187,8 @@ import com.cloud.dc.Vlan.VlanType;
 import com.cloud.dc.VlanVO;
 import com.cloud.domain.Domain;
 import com.cloud.event.Event;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
 import com.cloud.host.Host;
 import com.cloud.host.HostVO;
 import com.cloud.hypervisor.HypervisorCapabilities;
@@ -276,6 +278,7 @@ import com.cloud.storage.snapshot.SnapshotPolicy;
 import com.cloud.storage.snapshot.SnapshotSchedule;
 import com.cloud.template.VirtualMachineTemplate;
 import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
 import com.cloud.user.User;
 import com.cloud.user.UserAccount;
 import com.cloud.uservm.UserVm;
@@ -295,7 +298,6 @@ import com.cloud.vm.VirtualMachine.Type;
 import com.cloud.vm.dao.NicSecondaryIpVO;
 import com.cloud.vm.snapshot.VMSnapshot;
 
-@Component
 public class ApiResponseHelper implements ResponseGenerator {
 
     public final Logger s_logger = Logger.getLogger(ApiResponseHelper.class);
@@ -303,6 +305,10 @@ public class ApiResponseHelper implements ResponseGenerator {
     @Inject private final EntityManager _entityMgr = null;
     @Inject private final UsageService _usageSvc = null;
     @Inject NetworkModel _ntwkModel;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    AsyncJobManager _jobMgr;
 
     @Override
     public UserResponse createUserResponse(User user) {
@@ -1967,8 +1973,27 @@ public class ApiResponseHelper implements ResponseGenerator {
 
     @Override
     public AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd) {
-        AsyncJob result = ApiDBUtils._asyncMgr.queryAsyncJobResult(cmd);
-        return createAsyncJobResponse(result);
+        Account caller = CallContext.current().getCallingAccount();
+
+        AsyncJob job = _entityMgr.findById(AsyncJob.class, cmd.getId());
+        if (job == null) {
+            throw new InvalidParameterValueException("Unable to find a job by id " + cmd.getId());
+        }
+
+        User userJobOwner = _accountMgr.getUserIncludingRemoved(job.getUserId());
+        Account jobOwner = _accountMgr.getAccount(userJobOwner.getAccountId());
+
+        //check permissions
+        if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+            //regular user can see only jobs he owns
+            if (caller.getId() != jobOwner.getId()) {
+                throw new PermissionDeniedException("Account " + caller + " is not authorized to see job id=" + job.getId());
+            }
+        } else if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
+            _accountMgr.checkAccess(caller, null, true, jobOwner);
+        }
+
+        return createAsyncJobResponse(_jobMgr.queryJob(cmd.getId(), true));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/server/src/com/cloud/async/AsyncJobManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/async/AsyncJobManagerImpl.java b/server/src/com/cloud/async/AsyncJobManagerImpl.java
index 2e3a9a0..bc8f99b 100644
--- a/server/src/com/cloud/async/AsyncJobManagerImpl.java
+++ b/server/src/com/cloud/async/AsyncJobManagerImpl.java
@@ -36,10 +36,10 @@ import javax.naming.ConfigurationException;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
-import org.apache.cloudstack.api.response.ExceptionResponse;
-import org.apache.cloudstack.config.ConfigRepo;
-import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.config.ConfigDepot;
+import org.apache.cloudstack.config.ConfigKey;
+import org.apache.cloudstack.config.ConfigValue;
+import org.apache.cloudstack.config.Configurable;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
 import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
 import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
@@ -63,20 +63,10 @@ import org.apache.cloudstack.framework.messagebus.PublishScope;
 import org.apache.cloudstack.jobs.JobInfo;
 import org.apache.cloudstack.jobs.JobInfo.Status;
 
-import com.cloud.api.ApiSerializerHelper;
-import com.cloud.cluster.ClusterManager;
 import com.cloud.cluster.ClusterManagerListener;
 import com.cloud.cluster.ManagementServerHost;
 import com.cloud.cluster.ManagementServerNode;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.User;
 import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Predicate;
 import com.cloud.utils.PropertiesUtil;
 import com.cloud.utils.component.ManagerBase;
@@ -90,10 +80,15 @@ import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.exception.ExceptionUtil;
 import com.cloud.utils.mgmt.JmxUtil;
 
-public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, ClusterManagerListener {
+public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, ClusterManagerListener, Configurable {
+    // Advanced
+    private static final ConfigKey<Long> JobExpireMinutes = new ConfigKey<Long>(Long.class, "job.expire.minutes", "Advanced", AsyncJobManager.class, "1440",
+            "Time (in minutes) for async-jobs to be kept in system", true, null);
+    private static final ConfigKey<Long> JobCancelThresholdMinutes = new ConfigKey<Long>(Long.class, "job.cancel.threshold.minutes", "Advanced", AsyncJobManager.class,
+            "60", "Time (in minutes) for async-jobs to be forcely cancelled if it has been in process for long", true, null);
+
     private static final Logger s_logger = Logger.getLogger(AsyncJobManagerImpl.class);
     private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3; 	// 3 seconds
-    private static final String JOB_POOL_THREAD_PREFIX = "Job-Executor";
     // Although we may have detailed masks for each individual wakeup event, i.e.
     // periodical timer, matched topic from message bus, it seems that we don't
     // need to distinguish them to such level. Therefore, only one wakeup signal
@@ -105,26 +100,27 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
     private static final int GC_INTERVAL = 10000;				// 10 seconds
 
     @Inject private SyncQueueManager _queueMgr;
-    @Inject private ClusterManager _clusterMgr;
-    @Inject private AccountManager _accountMgr;
     @Inject private AsyncJobDao _jobDao;
     @Inject private AsyncJobJournalDao _journalDao;
-    @Inject private ConfigurationDao _configDao;
     @Inject private AsyncJobJoinMapDao _joinMapDao;
     @Inject private List<AsyncJobDispatcher> _jobDispatchers;
     @Inject private MessageBus _messageBus;
     @Inject private AsyncJobMonitor _jobMonitor;
     @Inject
-    private ConfigRepo _configRepo;
+    private ConfigDepot _configDepot;
 
-	private long _jobExpireSeconds = 86400;						// 1 day
-    private long _jobCancelThresholdSeconds = 3600;         	// 1 hour (for cancelling the jobs blocking other jobs)
+    private ConfigValue<Long> _jobExpireSeconds;						// 1 day
+    private ConfigValue<Long> _jobCancelThresholdSeconds;         	// 1 hour (for cancelling the jobs blocking other jobs)
     
     private volatile long _executionRunNumber = 1;
 
-    private final ScheduledExecutorService _heartbeatScheduler =
-            Executors.newScheduledThreadPool(1, new NamedThreadFactory("AsyncJobMgr-Heartbeat"));
-    private ExecutorService _executor;
+    private final ScheduledExecutorService _heartbeatScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AsyncJobMgr-Heartbeat"));
+    private ExecutorService _executor;
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {JobExpireMinutes, JobCancelThresholdMinutes};
+    }
 
     @Override
     public AsyncJobVO getAsyncJob(long jobId) {
@@ -196,7 +192,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
 	}
     
     @Override @DB
-    public void completeAsyncJob(long jobId, Status jobStatus, int resultCode, Object resultObject) {
+    public void completeAsyncJob(long jobId, Status jobStatus, int resultCode, String resultObject) {
         if(s_logger.isDebugEnabled()) {
             s_logger.debug("Complete async job-" + jobId + ", jobStatus: " + jobStatus +
                     ", resultCode: " + resultCode + ", result: " + resultObject);
@@ -234,7 +230,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
             job.setInstanceId(null);
 
             if (resultObject != null) {
-                job.setResult(ApiSerializerHelper.toSerializedString(resultObject));
+                job.setResult(resultObject);
             }
 
             job.setLastUpdated(DateUtil.currentGMTTime());
@@ -260,7 +256,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
     }
 
     @Override @DB
-    public void updateAsyncJobStatus(long jobId, int processStatus, Object resultObject) {
+    public void updateAsyncJobStatus(long jobId, int processStatus, String resultObject) {
         if(s_logger.isDebugEnabled()) {
             s_logger.debug("Update async-job progress, job-" + jobId + ", processStatus: " + processStatus +
                     ", result: " + resultObject);
@@ -281,7 +277,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
 
             job.setProcessStatus(processStatus);
             if(resultObject != null) {
-                job.setResult(ApiSerializerHelper.toSerializedString(resultObject));
+                job.setResult(resultObject);
             }
             job.setLastUpdated(DateUtil.currentGMTTime());
             _jobDao.update(jobId, job);
@@ -388,84 +384,16 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
     }
 
     @Override
-    public AsyncJob queryAsyncJobResult(QueryAsyncJobResultCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        AsyncJobVO job = _jobDao.findById(cmd.getId());
-        if (job == null) {
-            throw new InvalidParameterValueException("Unable to find a job by id " + cmd.getId());
-        }
-
-        User userJobOwner = _accountMgr.getUserIncludingRemoved(job.getUserId());
-        Account jobOwner = _accountMgr.getAccount(userJobOwner.getAccountId());
-
-        //check permissions
-        if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
-            //regular user can see only jobs he owns
-            if (caller.getId() != jobOwner.getId()) {
-                throw new PermissionDeniedException("Account " + caller + " is not authorized to see job id=" + job.getId());
-            }
-        } else if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
-            _accountMgr.checkAccess(caller, null, true, jobOwner);
+    public AsyncJob queryJob(long jobId, boolean updatePollTime) {
+        AsyncJobVO job = _jobDao.findById(jobId);
+        
+        if (updatePollTime) {
+            job.setLastPolled(DateUtil.currentGMTTime());
+            _jobDao.update(jobId, job);
         }
-
-        //poll the job
-        queryAsyncJobResult(cmd.getId());
-        return _jobDao.findById(cmd.getId());
+        return job;
     }
 
-    @DB
-    public AsyncJobResult queryAsyncJobResult(long jobId) {
-        if(s_logger.isTraceEnabled()) {
-            s_logger.trace("Query async-job status, job-" + jobId);
-        }
-
-        Transaction txt = Transaction.currentTxn();
-        AsyncJobResult jobResult = new AsyncJobResult(jobId);
-
-        try {
-            txt.start();
-            AsyncJobVO job = _jobDao.findById(jobId);
-            if(job != null) {
-                jobResult.setJobStatus(job.getStatus());
-                jobResult.setProcessStatus(job.getProcessStatus());
-                jobResult.setResult(job.getResult());
-                jobResult.setResultCode(job.getResultCode());
-                jobResult.setUuid(job.getUuid());
-
-                if(job.getStatus() == JobInfo.Status.SUCCEEDED ||
-                        job.getStatus() == JobInfo.Status.FAILED) {
-
-                    if(s_logger.isDebugEnabled()) {
-                        s_logger.debug("Async job-" + jobId + " completed");
-                    }
-                } else {
-                    job.setLastPolled(DateUtil.currentGMTTime());
-                    _jobDao.update(jobId, job);
-                }
-            } else {
-                if(s_logger.isDebugEnabled()) {
-                    s_logger.debug("Async job-" + jobId + " does not exist, invalid job id?");
-                }
-
-                jobResult.setJobStatus(JobInfo.Status.FAILED);
-                jobResult.setResult("job-" + jobId + " does not exist");
-            }
-            txt.commit();
-        } catch(Exception e) {
-            s_logger.error("Unexpected exception while querying async job-" + jobId + " status: ", e);
-
-            jobResult.setJobStatus(JobInfo.Status.FAILED);
-            jobResult.setResult("Exception: " + e.toString());
-            txt.rollback();
-        }
-
-        if(s_logger.isTraceEnabled()) {
-            s_logger.trace("Job status: " + jobResult.toString());
-        }
-
-        return jobResult;
-    }
 
     private void scheduleExecution(final AsyncJobVO job) {
         scheduleExecution(job, false);
@@ -762,7 +690,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                 try {
                     s_logger.trace("Begin cleanup expired async-jobs");
 
-                    Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - _jobExpireSeconds*1000);
+                    Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - _jobExpireSeconds.value() * 1000);
 
                     // limit to 100 jobs per turn, this gives cleanup throughput as 600 jobs per minute
                     // hopefully this will be fast enough to balance potential growth of job table
@@ -781,12 +709,12 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                     }
 
                     // forcefully cancel blocking queue items if they've been staying there for too long
-                    List<SyncQueueItemVO> blockItems = _queueMgr.getBlockedQueueItems(_jobCancelThresholdSeconds*1000, false);
+                    List<SyncQueueItemVO> blockItems = _queueMgr.getBlockedQueueItems(_jobCancelThresholdSeconds.value()
+                            * 1000, false);
                     if(blockItems != null && blockItems.size() > 0) {
                         for(SyncQueueItemVO item : blockItems) {
                             if(item.getContentType().equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) {
-                                completeAsyncJob(item.getContentId(), JobInfo.Status.FAILED, 0,
-                                        getResetResultResponse("Job is cancelled as it has been blocking others for too long"));
+                                completeAsyncJob(item.getContentId(), JobInfo.Status.FAILED, 0, "Job is cancelled as it has been blocking others for too long");
                             }
 
                             // purge the item and resume queue processing
@@ -799,8 +727,6 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                     s_logger.error("Unexpected exception when trying to execute queue item, ", e);
                 }
             }
-
-
         };
     }
 
@@ -819,32 +745,27 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
     }
 
     private void cleanupPendingJobs(List<SyncQueueItemVO> l) {
-        if(l != null && l.size() > 0) {
-            for(SyncQueueItemVO item: l) {
-                if(s_logger.isInfoEnabled()) {
-                    s_logger.info("Discard left-over queue item: " + item.toString());
-                }
+        for (SyncQueueItemVO item : l) {
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Discard left-over queue item: " + item.toString());
+            }
 
-                String contentType = item.getContentType();
-                if(contentType != null && contentType.equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) {
-                    Long jobId = item.getContentId();
-                    if(jobId != null) {
-                        s_logger.warn("Mark job as failed as its correspoding queue-item has been discarded. job id: " + jobId);
-                        completeAsyncJob(jobId, JobInfo.Status.FAILED, 0, getResetResultResponse("Execution was cancelled because of server shutdown"));
-                    }
+            String contentType = item.getContentType();
+            if (contentType != null && contentType.equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) {
+                Long jobId = item.getContentId();
+                if (jobId != null) {
+                    s_logger.warn("Mark job as failed as its correspoding queue-item has been discarded. job id: " + jobId);
+                    completeAsyncJob(jobId, JobInfo.Status.FAILED, 0, "Execution was cancelled because of server shutdown");
                 }
-                _queueMgr.purgeItem(item.getId());
             }
+            _queueMgr.purgeItem(item.getId());
         }
     }
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        int expireMinutes = NumbersUtil.parseInt(_configDao.getValue(Config.JobExpireMinutes.key()), 24 * 60);
-        _jobExpireSeconds = (long)expireMinutes*60;
-
-        _jobCancelThresholdSeconds = NumbersUtil.parseInt(_configDao.getValue(Config.JobCancelThresholdMinutes.key()), 60);
-        _jobCancelThresholdSeconds *= 60;
+        _jobExpireSeconds = _configDepot.get(JobExpireMinutes).setMultiplier(60);
+        _jobCancelThresholdSeconds = _configDepot.get(JobCancelThresholdMinutes).setMultiplier(60);
 
         try {
             final File dbPropsFile = PropertiesUtil.findConfigFile("db.properties");
@@ -856,7 +777,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
             int poolSize = (cloudMaxActive * 2) / 3;
 
             s_logger.info("Start AsyncJobManager thread pool in size " + poolSize);
-            _executor = Executors.newFixedThreadPool(poolSize, new NamedThreadFactory(JOB_POOL_THREAD_PREFIX));
+            _executor = Executors.newFixedThreadPool(poolSize, new NamedThreadFactory(AsyncJobManager.JOB_POOL_THREAD_PREFIX));
         } catch (final Exception e) {
             throw new ConfigurationException("Unable to load db.properties to configure AsyncJobManagerImpl");
         }
@@ -879,11 +800,10 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
                 txn.start();
                 List<SyncQueueItemVO> items = _queueMgr.getActiveQueueItems(msHost.getId(), true);
                 cleanupPendingJobs(items);
-                _jobDao.resetJobProcess(msHost.getId(), ApiErrorCode.INTERNAL_ERROR.getHttpCode(), getSerializedErrorMessage("job cancelled because of management server restart"));
+                _jobDao.resetJobProcess(msHost.getId(), ApiErrorCode.INTERNAL_ERROR.getHttpCode(), "job cancelled because of management server restart");
                 txn.commit();
             } catch(Throwable e) {
                 s_logger.warn("Unexpected exception ", e);
-                txn.rollback();
             } finally {
                 txn.close();
             }
@@ -901,30 +821,17 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
         	
             List<SyncQueueItemVO> l = _queueMgr.getActiveQueueItems(getMsid(), false);
             cleanupPendingJobs(l);
-            _jobDao.resetJobProcess(getMsid(), ApiErrorCode.INTERNAL_ERROR.getHttpCode(), getSerializedErrorMessage("job cancelled because of management server restart"));
+            _jobDao.resetJobProcess(getMsid(), ApiErrorCode.INTERNAL_ERROR.getHttpCode(), "job cancelled because of management server restart");
         } catch(Throwable e) {
             s_logger.error("Unexpected exception " + e.getMessage(), e);
         }
 
-        _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HEARTBEAT_INTERVAL,
-                HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS);
-        _heartbeatScheduler.scheduleAtFixedRate(getGCTask(), GC_INTERVAL,
-                GC_INTERVAL, TimeUnit.MILLISECONDS);
+        _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HEARTBEAT_INTERVAL, HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS);
+        _heartbeatScheduler.scheduleAtFixedRate(getGCTask(), GC_INTERVAL, GC_INTERVAL, TimeUnit.MILLISECONDS);
 
         return true;
     }
 
-    private static ExceptionResponse getResetResultResponse(String errorMessage) {
-        ExceptionResponse resultObject = new ExceptionResponse();
-        resultObject.setErrorCode(ApiErrorCode.INTERNAL_ERROR.getHttpCode());
-        resultObject.setErrorText(errorMessage);
-        return resultObject;
-    }
-
-    private static String getSerializedErrorMessage(String errorMessage) {
-        return ApiSerializerHelper.toSerializedString(getResetResultResponse(errorMessage));
-    }
-
     @Override
     public boolean stop() {
         _heartbeatScheduler.shutdown();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 15f9d0f..9401811 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -68,9 +68,10 @@ import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
 import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
 import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
 import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
+import org.apache.cloudstack.config.ConfigDepot;
 import org.apache.cloudstack.config.ConfigKey;
-import org.apache.cloudstack.config.ConfigRepo;
 import org.apache.cloudstack.config.ConfigValue;
+import org.apache.cloudstack.config.Configurable;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.region.PortableIp;
 import org.apache.cloudstack.region.PortableIpDao;
@@ -215,7 +216,7 @@ import com.cloud.vm.dao.NicSecondaryIpDao;
 import edu.emory.mathcs.backport.java.util.Arrays;
 
 @Local(value = { ConfigurationManager.class, ConfigurationService.class })
-public class ConfigurationManagerImpl extends ManagerBase implements ConfigurationManager, ConfigurationService, ConfigRepo {
+public class ConfigurationManagerImpl extends ManagerBase implements ConfigurationManager, ConfigurationService, ConfigDepot {
     public static final Logger s_logger = Logger.getLogger(ConfigurationManagerImpl.class.getName());
 
     @Inject
@@ -319,6 +320,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
     @Inject
     DedicatedResourceDao _dedicatedDao;
 
+    @Inject
+    List<Configurable> _configurables;
+
     // FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
     @Inject protected DataCenterLinkLocalIpAddressDao _LinkLocalIpAllocDao;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 9fc4645..3d0e5c6 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -424,9 +424,9 @@ import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.jobs.JobInfo;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 
@@ -443,6 +443,7 @@ import com.cloud.alert.AlertManager;
 import com.cloud.alert.AlertVO;
 import com.cloud.alert.dao.AlertDao;
 import com.cloud.api.ApiDBUtils;
+import com.cloud.api.ApiSerializerHelper;
 import com.cloud.capacity.Capacity;
 import com.cloud.capacity.CapacityVO;
 import com.cloud.capacity.dao.CapacityDao;
@@ -3469,7 +3470,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
             if (asyncExecutionContext != null) {
                 job = asyncExecutionContext.getJob();
                 _asyncMgr.updateAsyncJobAttachment(job.getId(), Upload.Type.VOLUME.toString(), volumeId);
-                _asyncMgr.updateAsyncJobStatus(job.getId(), JobInfo.Status.IN_PROGRESS, resultObj);
+                _asyncMgr.updateAsyncJobStatus(job.getId(), JobInfo.Status.IN_PROGRESS.ordinal(), ApiSerializerHelper.toSerializedString(resultObj));
             }
             String value = _configs.get(Config.CopyVolumeWait.toString());
             int copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
@@ -3490,7 +3491,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
                 resultObj.setResultString(errorString);
                 resultObj.setUploadStatus(UploadVO.Status.COPY_ERROR.toString());
                 if (asyncExecutionContext != null) {
-                    _asyncMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, resultObj);
+                    _asyncMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, ApiSerializerHelper.toSerializedString(resultObj));
                 }
 
                 // Update the DB that volume couldn't be copied

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/server/src/com/cloud/storage/VolumeManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java
index 2eeb206..2d2bccc 100644
--- a/server/src/com/cloud/storage/VolumeManagerImpl.java
+++ b/server/src/com/cloud/storage/VolumeManagerImpl.java
@@ -1797,8 +1797,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
             }
 
             _asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volumeId);
-            _asyncMgr.updateAsyncJobStatus(job.getId(),
-                    BaseCmd.PROGRESS_INSTANCE_CREATED, volumeId);
+            _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, Long.toString(volumeId));
         }
 
         VolumeVO newVol = _volumeDao.findById(volumeOnPrimaryStorage.getId());
@@ -1896,8 +1895,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
             }
 
             _asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volumeId);
-            _asyncMgr.updateAsyncJobStatus(job.getId(),
-                    BaseCmd.PROGRESS_INSTANCE_CREATED, volumeId);
+            _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, volumeId.toString());
         }
 
         String errorMsg = "Failed to detach volume: " + volume.getName()

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
index 607e39b..1902b3a 100644
--- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
@@ -34,7 +34,6 @@ import org.springframework.stereotype.Component;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotCmd;
 import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.framework.jobs.dao.AsyncJobDao;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
@@ -143,14 +142,14 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
             Long asyncJobId = snapshotSchedule.getAsyncJobId();
             AsyncJobVO asyncJob = _asyncJobDao.findById(asyncJobId);
             switch (asyncJob.getStatus()) {
-            case JobInfo.Status.SUCCEEDED:
+            case SUCCEEDED:
                 // The snapshot has been successfully backed up.
                 // The snapshot state has also been cleaned up.
                 // We can schedule the next job for this snapshot.
                 // Remove the existing entry in the snapshot_schedule table.
                 scheduleNextSnapshotJob(snapshotSchedule);
                 break;
-            case JobInfo.Status.FAILED:
+            case FAILED:
                 // Check the snapshot status.
                 Long snapshotId = snapshotSchedule.getSnapshotId();
                 if (snapshotId == null) {
@@ -188,7 +187,7 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
                 }
 
                 break;
-            case JobInfo.Status.IN_PROGRESS:
+            case IN_PROGRESS:
                 // There is no way of knowing from here whether
                 // 1) Another management server is processing this snapshot job
                 // 2) The management server has crashed and this snapshot is lying

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/server/src/com/cloud/storage/upload/UploadListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/com/cloud/storage/upload/UploadListener.java
index b6a9288..038cc38 100755
--- a/server/src/com/cloud/storage/upload/UploadListener.java
+++ b/server/src/com/cloud/storage/upload/UploadListener.java
@@ -24,11 +24,16 @@ import java.util.Map;
 import java.util.Timer;
 import java.util.TimerTask;
 
-import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
-import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
 import org.apache.log4j.Level;
 import org.apache.log4j.Logger;
 
+import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
+import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
+import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
+import org.apache.cloudstack.api.response.ExtractResponse;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.jobs.JobInfo;
+
 import com.cloud.agent.Listener;
 import com.cloud.agent.api.AgentControlAnswer;
 import com.cloud.agent.api.AgentControlCommand;
@@ -40,13 +45,8 @@ import com.cloud.agent.api.storage.UploadAnswer;
 import com.cloud.agent.api.storage.UploadCommand;
 import com.cloud.agent.api.storage.UploadProgressCommand;
 import com.cloud.agent.api.storage.UploadProgressCommand.RequestType;
-import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
-import org.apache.cloudstack.api.response.ExtractResponse;
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-
 import com.cloud.api.ApiDBUtils;
-import com.cloud.async.AsyncJobResult;
+import com.cloud.api.ApiSerializerHelper;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.host.HostVO;
 import com.cloud.storage.Storage;
@@ -65,7 +65,7 @@ public class UploadListener implements Listener {
 		private final RequestType reqType;
 
 		public StatusTask( UploadListener ul,  RequestType req) {
-			this.reqType = req;
+			reqType = req;
 			this.ul = ul;
 		}
 
@@ -165,19 +165,19 @@ public class UploadListener implements Listener {
 	public UploadListener(HostVO host, Timer _timer, UploadDao uploadDao,
 			UploadVO uploadObj, UploadMonitorImpl uploadMonitor, UploadCommand cmd,
 			Long accountId, String typeName, Type type, long eventId, long asyncJobId, AsyncJobManager asyncMgr) {
-		this.sserver = host;
+		sserver = host;
 		this.uploadDao = uploadDao;
 		this.uploadMonitor = uploadMonitor;
 		this.cmd = cmd;
-		this.uploadId = uploadObj.getId();
+		uploadId = uploadObj.getId();
 		this.accountId = accountId;
 		this.typeName = typeName;
 		this.type = type;
 		initStateMachine();
-		this.currState = getState(Status.NOT_UPLOADED.toString());
-		this.timer = _timer;
-		this.timeoutTask = new TimeoutTask(this);
-		this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL);
+		currState = getState(Status.NOT_UPLOADED.toString());
+		timer = _timer;
+		timeoutTask = new TimeoutTask(this);
+		timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL);
 		this.eventId = eventId;
 		this.asyncJobId = asyncJobId;
 		this.asyncMgr = asyncMgr;
@@ -188,7 +188,7 @@ public class UploadListener implements Listener {
 		else{
 		    extractId = ApiDBUtils.findTemplateById(uploadObj.getTypeId()).getUuid();
 		}
-		this.resultObj = new ExtractResponse(extractId, typeName, ApiDBUtils.findAccountById(accountId).getUuid(), Status.NOT_UPLOADED.toString(),
+		resultObj = new ExtractResponse(extractId, typeName, ApiDBUtils.findAccountById(accountId).getUuid(), Status.NOT_UPLOADED.toString(),
 		        ApiDBUtils.findUploadById(uploadId).getUuid());
 		resultObj.setResponseName(responseNameMap.get(type.toString()));
 		updateDatabase(Status.NOT_UPLOADED, cmd.getUrl(),"");
@@ -213,11 +213,11 @@ public class UploadListener implements Listener {
 	}
 
 	public void setCommand(UploadCommand _cmd) {
-		this.cmd = _cmd;
+		cmd = _cmd;
 	}
 
 	public void setJobId(String _jobId) {
-		this.jobId = _jobId;
+		jobId = _jobId;
 	}
 
 	public String getJobId() {
@@ -365,7 +365,7 @@ public class UploadListener implements Listener {
 		resultObj.setResultString(uploadErrorString);
 		resultObj.setState(state.toString());
 		asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
-		asyncMgr.updateAsyncJobStatus(asyncJobId, JobInfo.Status.IN_PROGRESS, resultObj);
+        asyncMgr.updateAsyncJobStatus(asyncJobId, JobInfo.Status.IN_PROGRESS.ordinal(), ApiSerializerHelper.toSerializedString(resultObj));
 
 		UploadVO vo = uploadDao.createForUpdate();
 		vo.setUploadState(state);
@@ -378,7 +378,7 @@ public class UploadListener implements Listener {
 		resultObj.setResultString(uploadErrorString);
 		resultObj.setState(state.toString());
 		asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
-		asyncMgr.updateAsyncJobStatus(asyncJobId, JobInfo.Status.IN_PROGRESS, resultObj);
+        asyncMgr.updateAsyncJobStatus(asyncJobId, JobInfo.Status.IN_PROGRESS.ordinal(), ApiSerializerHelper.toSerializedString(resultObj));
 
 
 		UploadVO vo = uploadDao.createForUpdate();
@@ -407,12 +407,12 @@ public class UploadListener implements Listener {
 
 		if (answer.getUploadStatus() == Status.UPLOAD_IN_PROGRESS){
 			asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
-			asyncMgr.updateAsyncJobStatus(asyncJobId, JobInfo.Status.IN_PROGRESS, resultObj);
+            asyncMgr.updateAsyncJobStatus(asyncJobId, JobInfo.Status.IN_PROGRESS.ordinal(), ApiSerializerHelper.toSerializedString(resultObj));
 		}else if(answer.getUploadStatus() == Status.UPLOADED){
 		    resultObj.setResultString("Success");
-			asyncMgr.completeAsyncJob(asyncJobId, JobInfo.Status.SUCCEEDED, 1, resultObj);
+            asyncMgr.completeAsyncJob(asyncJobId, JobInfo.Status.SUCCEEDED, 1, ApiSerializerHelper.toSerializedString(resultObj));
 		}else{
-			asyncMgr.completeAsyncJob(asyncJobId, JobInfo.Status.FAILED, 2, resultObj);
+            asyncMgr.completeAsyncJob(asyncJobId, JobInfo.Status.FAILED, 2, ApiSerializerHelper.toSerializedString(resultObj));
 		}
         UploadVO updateBuilder = uploadDao.createForUpdate();
 		updateBuilder.setUploadPercent(answer.getUploadPct());
@@ -454,6 +454,6 @@ public class UploadListener implements Listener {
 	}
 
 	public void setCurrState(Status uploadState) {
-		this.currState = getState(currState.toString());
+		currState = getState(currState.toString());
 	}
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/server/test/com/cloud/async/TestAsyncJobManager.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/async/TestAsyncJobManager.java b/server/test/com/cloud/async/TestAsyncJobManager.java
index 419f5fa..4d2f2e3 100644
--- a/server/test/com/cloud/async/TestAsyncJobManager.java
+++ b/server/test/com/cloud/async/TestAsyncJobManager.java
@@ -35,7 +35,6 @@ import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
 import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDao;
 import org.apache.cloudstack.framework.jobs.dao.AsyncJobJournalDao;
@@ -44,6 +43,7 @@ import org.apache.cloudstack.framework.jobs.dao.SyncQueueItemDao;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobJoinMapVO;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobJournalVO;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobMonitor;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
 import org.apache.cloudstack.framework.jobs.impl.SyncQueueItemVO;
 import org.apache.cloudstack.framework.jobs.impl.SyncQueueVO;
 import org.apache.cloudstack.framework.messagebus.MessageBus;
@@ -202,7 +202,7 @@ public class TestAsyncJobManager extends TestCase {
     @Test
     public void testPseudoJob() {
         AsyncJob job = asyncMgr.getPseudoJob(Account.ACCOUNT_ID_SYSTEM, User.UID_SYSTEM);
-    	Assert.assertTrue(job.getInstanceType().equals(AsyncJobConstants.PSEUDO_JOB_INSTANCE_TYPE));
+        Assert.assertTrue(job.getInstanceType().equals(AsyncJobVO.PSEUDO_JOB_INSTANCE_TYPE));
     	Assert.assertTrue(job.getInstanceId().longValue() == Thread.currentThread().getId());
     }
     

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
index 49b0e31..3f35a42 100644
--- a/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
+++ b/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
@@ -25,9 +25,9 @@ import javax.naming.ConfigurationException;
 
 import org.apache.log4j.Logger;
 
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.VirtualMachineTO;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aad2bc78/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java b/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java
index eb5e81f..36e5aa7 100644
--- a/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java
+++ b/server/test/com/cloud/vm/VmWorkTestWorkJobDispatcher.java
@@ -3,9 +3,9 @@ package com.cloud.vm;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobConstants;
 import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
 import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
+import org.apache.cloudstack.jobs.JobInfo;
 
 import com.cloud.utils.component.AdapterBase;
 


[7/9] git commit: updated refs/heads/vmsync to 309f8da

Posted by ah...@apache.org.
Added outcome


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/fa525a7d
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/fa525a7d
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/fa525a7d

Branch: refs/heads/vmsync
Commit: fa525a7d3862cac28ba12da37155d80de5d0e9a1
Parents: 8f00c19
Author: Alex Huang <al...@gmail.com>
Authored: Mon Jun 17 11:40:14 2013 -0700
Committer: Alex Huang <al...@gmail.com>
Committed: Mon Jun 17 17:25:01 2013 -0700

----------------------------------------------------------------------
 .../src/com/cloud/vm/VirtualMachineManager.java |  34 ++-
 .../com/cloud/vm/VirtualMachineManagerImpl.java | 240 +++++++++++--------
 .../engine/vm/VMEntityManagerImpl.java          |   8 +-
 .../jobs/JobCancellationException.java          |   7 +-
 .../framework/jobs/impl/OutcomeImpl.java        |   8 +
 .../lb/ElasticLoadBalancerManagerImpl.java      |   2 +-
 .../lb/InternalLoadBalancerVMManagerImpl.java   |   2 +-
 .../consoleproxy/ConsoleProxyManagerImpl.java   |   4 +-
 .../cloud/ha/HighAvailabilityManagerImpl.java   | 173 +++++++------
 .../VirtualNetworkApplianceManagerImpl.java     |   2 +-
 .../com/cloud/resource/ResourceManagerImpl.java |   2 +-
 .../storage/StoragePoolAutomationImpl.java      |  20 +-
 .../secondary/SecondaryStorageManagerImpl.java  |   4 +-
 .../src/com/cloud/user/AccountManagerImpl.java  |   2 +-
 server/src/com/cloud/vm/UserVmManagerImpl.java  |   4 +-
 .../vm/snapshot/VMSnapshotManagerImpl.java      |   2 +-
 .../vm/VmWorkMockVirtualMachineManagerImpl.java |  15 +-
 17 files changed, 312 insertions(+), 217 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/engine/components-api/src/com/cloud/vm/VirtualMachineManager.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/com/cloud/vm/VirtualMachineManager.java b/engine/components-api/src/com/cloud/vm/VirtualMachineManager.java
index f1ace6c..e1365e2 100644
--- a/engine/components-api/src/com/cloud/vm/VirtualMachineManager.java
+++ b/engine/components-api/src/com/cloud/vm/VirtualMachineManager.java
@@ -20,6 +20,8 @@ import java.net.URI;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.cloudstack.framework.jobs.Outcome;
+
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.deploy.DeployDestination;
@@ -88,11 +90,11 @@ public interface VirtualMachineManager extends Manager {
             HypervisorType hyperType,
             Account owner);
 
-    void start(String vmUuid, Map<VirtualMachineProfile.Param, Object> params);
+    void easyStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params);
 
-    void start(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy);
+    void easyStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy);
 
-    void stop(String vmUuid);
+    void easyStop(String vmUuid);
 
     void expunge(String vmUuid);
 
@@ -100,8 +102,29 @@ public interface VirtualMachineManager extends Manager {
     
     boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId) throws NoTransitionException;
 
-    void advanceStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy)
-            throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException;
+    /**
+     * Files a start job to start the virtual machine.  The caller can use
+     * the Outcome object to wait for the result.  The Outcome throws
+     * ExecutionException if there's a problem with the job execution.
+     * The cause of the ExecutionException carries the reason to why
+     * there is a problem.
+     *   - ConcurrentOperationException: There are multiple operations happening on the same objects.
+     *   - InsufficientCapacityException: Insufficient capacity to start a VM.  The exception carries the cause.
+     *   - ResourceUnavailableException: The resource needed to start a VM is not available.
+     *   - OperationTimedoutException: The operation has been sent to the physical resource but we timed out waiting for results.
+     * 
+     * Most callers should use this method to start VMs.  Of the various
+     * possible exceptions, the worst is OperationTimedoutException.  This
+     * indicates that the operation was sent to the physical resource but
+     * there was no response.  Under these situations, we do not know if the
+     * operation succeeded or failed and require manual intervention.
+     * 
+     * @param vmUuid uuid to the VM to start
+     * @param params parameters passed to be passed down
+     * @param planToDeploy plan on where to deploy the vm.
+     * @return Outcome to wait for the result.
+     */
+    Outcome<VirtualMachine> start(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy);
 
     void advanceStop(String vmUuid, boolean cleanup) throws ResourceUnavailableException, OperationTimedoutException,
             ConcurrentOperationException;
@@ -191,4 +214,5 @@ public interface VirtualMachineManager extends Manager {
             ManagementServerException, VirtualMachineMigrationException;
 
     NicTO toNicTO(NicProfile nic, HypervisorType hypervisorType);
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index 4f308fb..4dd0e3c 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -31,6 +31,7 @@ import java.util.TimeZone;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 import javax.ejb.Local;
 import javax.inject.Inject;
@@ -40,14 +41,18 @@ import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
 import org.apache.cloudstack.config.ConfigDepot;
+import org.apache.cloudstack.config.ConfigKey;
 import org.apache.cloudstack.config.ConfigValue;
+import org.apache.cloudstack.config.Configurable;
 import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.config.Configs;
+import org.apache.cloudstack.engine.service.api.OrchestrationService;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
 import org.apache.cloudstack.framework.jobs.AsyncJob;
 import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.framework.jobs.Outcome;
+import org.apache.cloudstack.framework.jobs.impl.OutcomeImpl;
 import org.apache.cloudstack.framework.messagebus.MessageBus;
 import org.apache.cloudstack.framework.messagebus.MessageDispatcher;
 import org.apache.cloudstack.framework.messagebus.MessageHandler;
@@ -167,15 +172,45 @@ import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.snapshot.VMSnapshotManager;
 
 @Local(value = VirtualMachineManager.class)
-public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMachineManager, Listener {
+public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMachineManager, Listener, Configurable {
     private static final Logger s_logger = Logger.getLogger(VirtualMachineManagerImpl.class);
 
     private static final String VM_SYNC_ALERT_SUBJECT = "VM state sync alert";
     
+    protected static final ConfigKey<Integer> StartRetry = new ConfigKey<Integer>(
+            Integer.class, "start.retry", "Advanced", OrchestrationService.class, "10", "Number of times to retry create and start commands", true, null);
+    protected static final ConfigKey<Long> VmOpWaitInterval = new ConfigKey<Long>(
+            Long.class, "vm.op.wait.interval", "Advanced", OrchestrationService.class, "120", "Time (in seconds) to wait before checking if a previous operation has succeeded",
+            true, null);
+    protected static final ConfigKey<Integer> VmOpLockStateRetry = new ConfigKey<Integer>(
+            Integer.class, "vm.op.lock.state.retry", "Advanced", OrchestrationService.class, "5", "Times to retry locking the state of a VM for operations",
+            true, "-1 means try forever");
+    protected static final ConfigKey<Long> VmOpCleanupInterval = new ConfigKey<Long>(
+            Long.class, "vm.op.cleanup.interval", "Advanced", OrchestrationService.class, "86400", "Interval to run the thread that cleans up the vm operations (in seconds)",
+            false, "Seconds");
+    protected static final ConfigKey<Long> VmOpCleanupWait = new ConfigKey<Long>(
+            Long.class, "vm.op.cleanup.wait", "Advanced", OrchestrationService.class, "3600", "Time (in seconds) to wait before cleanuping up any vm work items", false, "Seconds");
+    protected static final ConfigKey<Integer> VmOpCancelInterval = new ConfigKey<Integer>(
+            Integer.class, "vm.op.cancel.interval", "Advanced", OrchestrationService.class, "3600", "Time (in seconds) to wait before cancelling a operation", false, "Seconds");
+    protected static final ConfigKey<Integer> Wait = new ConfigKey<Integer>(
+            Integer.class, "wait", "Advanced", OrchestrationService.class, "1800", "Time in seconds to wait for control commands to return", false, null);
+    protected static final ConfigKey<Boolean> VmDestroyForceStop = new ConfigKey<Boolean>(
+            Boolean.class, "vm.destroy.forcestop", "Advanced", OrchestrationService.class, "false", "On destroy, force-stop takes this value ", true, null);
+
+    // New
+    protected static final ConfigKey<Long> VmJobCheckInterval = new ConfigKey<Long>(
+            Long.class, "vm.job.check.interval", "VM Orchestration", OrchestrationService.class, "3000", "Interval in milliseconds to check if the job is complete", true,
+            "Milliseconds");
+    protected static final ConfigKey<Long> VmJobTimeout = new ConfigKey<Long>(
+            Long.class, "vm.job.timeout", "VM Orchestration", OrchestrationService.class, "600000", "Time in milliseconds to wait before attempting to cancel a job", true,
+            "Milliseconds");
+    public static final ConfigKey<Long> PingInterval = new ConfigKey<Long>(
+            Long.class, "ping.interval", "Advanced", OrchestrationService.class, "60", "Ping interval in seconds", false, null);
+
     @Inject
     protected EntityManager _entityMgr;
     @Inject
-    ConfigDepot _configRepo;
+    ConfigDepot _configDepot;
     @Inject
     DataStoreManager _dataStoreMgr;
     @Inject
@@ -255,6 +290,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     protected ConfigValue<Integer> _operationTimeout;
     protected ConfigValue<Boolean> _forceStop;
     protected ConfigValue<Long> _pingInterval;
+    protected ConfigValue<Long> _jobCheckInterval;
+    protected ConfigValue<Long> _jobTimeout;
+
     protected long _nodeId;
 
     SearchBuilder<VolumeVO> RootVolumeSearch;
@@ -437,16 +475,18 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 
     @Override
     public boolean configure(String name, Map<String, Object> xmlParams) throws ConfigurationException {
-        _retry = _configRepo.get(Configs.StartRetry);
-
-        _cancelWait = _configRepo.get(Configs.VmOpCancelInterval);
-        _cleanupWait = _configRepo.get(Configs.VmOpCleanupWait);
-        _cleanupInterval = _configRepo.get(Configs.VmOpCleanupInterval).setMultiplier(1000);
-        _opWaitInterval = _configRepo.get(Configs.VmOpWaitInterval).setMultiplier(1000);
-        _lockStateRetry = _configRepo.get(Configs.VmOpLockStateRetry);
-        _operationTimeout = _configRepo.get(Configs.Wait).setMultiplier(2);
-        _forceStop = _configRepo.get(Configs.VmDestroyForcestop);
-        _pingInterval = _configRepo.get(Configs.PingInterval).setMultiplier(1000);
+        _retry = _configDepot.get(StartRetry);
+
+        _pingInterval = _configDepot.get(PingInterval).setMultiplier(1000);
+        _cancelWait = _configDepot.get(VmOpCancelInterval);
+        _cleanupWait = _configDepot.get(VmOpCleanupWait);
+        _cleanupInterval = _configDepot.get(VmOpCleanupInterval).setMultiplier(1000);
+        _opWaitInterval = _configDepot.get(VmOpWaitInterval).setMultiplier(1000);
+        _lockStateRetry = _configDepot.get(VmOpLockStateRetry);
+        _operationTimeout = _configDepot.get(Wait).setMultiplier(2);
+        _forceStop = _configDepot.get(VmDestroyForceStop);
+        _jobCheckInterval = _configDepot.get(VmJobCheckInterval);
+        _jobTimeout = _configDepot.get(VmJobTimeout);
 
         ReservationContextImpl.setComponents(_entityMgr);
         VirtualMachineProfileImpl.setComponents(_entityMgr);
@@ -474,20 +514,21 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     }
 
     @Override
-    public void start(String vmUuid, Map<VirtualMachineProfile.Param, Object> params) {
-        start(vmUuid, params, null);
+    public void easyStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params) {
+        easyStart(vmUuid, params, null);
     }
 
     @Override
-    public void start(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy) {
+    public void easyStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy) {
+        Outcome<VirtualMachine> outcome = start(vmUuid, params, planToDeploy);
         try {
-            advanceStart(vmUuid, params, planToDeploy);
-        } catch (ConcurrentOperationException e) {
-            throw new CloudRuntimeException(e).add(VirtualMachine.class, vmUuid);
-        } catch (InsufficientCapacityException e) {
-            throw new CloudRuntimeException(e).add(VirtualMachine.class, vmUuid);
-        } catch (ResourceUnavailableException e) {
-            throw new CloudRuntimeException(e).add(VirtualMachine.class, vmUuid);
+            outcome.get(_jobTimeout.value(), TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            // FIXME: What to do
+        } catch (java.util.concurrent.ExecutionException e) {
+            // FIXME: What to do
+        } catch (TimeoutException e) {
+            // FIXME: What to do
         }
     }
 
@@ -653,8 +694,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
 
     @Override
     @DB
-    public void advanceStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy)
-        throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
+    public Outcome<VirtualMachine> start(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy) {
         CallContext context = CallContext.current();
         User callingUser = context.getCallingUser();
         Account callingAccount = context.getCallingAccount();
@@ -663,77 +703,43 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     	
     	VmWorkJobVO workJob = null;
     	Transaction txn = Transaction.currentTxn();
-    	try {
-        	txn.start();
-        	
-        	_vmDao.lockRow(vm.getId(), true);
-        	
-        	List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                    VirtualMachine.Type.Instance, vm.getId(), VmWorkJobDispatcher.Start);
-        	
-        	if(pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-        		assert(pendingWorkJobs.size() == 1);
-        		workJob = pendingWorkJobs.get(0);
-        	} else {
-                workJob = new VmWorkJobVO(context.getContextId());
-        	
-                workJob.setDispatcher(VmWorkJobDispatcher.VM_WORK_JOB_DISPATCHER);
-                workJob.setCmd(VmWorkJobDispatcher.Start);
-        		
-                workJob.setAccountId(callingAccount.getId());
-        		workJob.setUserId(callingUser.getId());
-        		workJob.setStep(VmWorkJobVO.Step.Starting);
-        		workJob.setVmType(vm.getType());
-        		workJob.setVmInstanceId(vm.getId());
+        txn.start();
 
-        		// save work context info (there are some duplications)
-        		VmWorkStart workInfo = new VmWorkStart();
-                workInfo.setAccountId(callingAccount.getId());
-        		workInfo.setUserId(callingUser.getId());
-        		workInfo.setVmId(vm.getId());
-        		workInfo.setPlan(planToDeploy);
-        		workInfo.setParams(params);
-                workJob.setCmdInfo(VmWorkJobDispatcher.serialize(workInfo));
-        		
-                _jobMgr.submitAsyncJob(workJob, VmWorkJobDispatcher.VM_WORK_QUEUE, vm.getId());
-        	}
-    	
-        	txn.commit();
-    	} catch(Throwable e) {
-    		s_logger.error("Unexpected exception", e);
-            throw new ConcurrentOperationException("Unhandled exception, converted to ConcurrentOperationException", e);
+        _vmDao.lockRow(vm.getId(), true);
+
+        List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(VirtualMachine.Type.Instance, vm.getId(), VmWorkJobDispatcher.Start);
+
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert (pendingWorkJobs.size() == 1);
+            workJob = pendingWorkJobs.get(0);
+        } else {
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkJobDispatcher.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkJobDispatcher.Start);
+
+            workJob.setAccountId(callingAccount.getId());
+            workJob.setUserId(callingUser.getId());
+            workJob.setStep(VmWorkJobVO.Step.Starting);
+            workJob.setVmType(vm.getType());
+            workJob.setVmInstanceId(vm.getId());
+
+            // save work context info (there are some duplications)
+            VmWorkStart workInfo = new VmWorkStart();
+            workInfo.setAccountId(callingAccount.getId());
+            workInfo.setUserId(callingUser.getId());
+            workInfo.setVmId(vm.getId());
+            workInfo.setPlan(planToDeploy);
+            workInfo.setParams(params);
+            workJob.setCmdInfo(VmWorkJobDispatcher.serialize(workInfo));
+
+            _jobMgr.submitAsyncJob(workJob, VmWorkJobDispatcher.VM_WORK_QUEUE, vm.getId());
     	}
 
+        txn.commit();
     	final long jobId = workJob.getId();
-    	
     	AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(jobId);
-
-    	//
-    	// TODO : this will be replaced with fully-asynchronous way later so that we don't need
-    	// to wait here. The reason we do synchronous-wait here is that callers of advanceStart is expecting
-    	// synchronous semantics
-    	//
-    	//
-    	_jobMgr.waitAndCheck(
-                new String[] {Topics.VM_POWER_STATE, AsyncJob.Topics.JOB_STATE},
-    		3000L, 600000L, new Predicate() {
-
-				@Override
-				public boolean checkCondition() {
-					VMInstanceVO instance = _vmDao.findById(vm.getId());
-					if(instance.getPowerState() == VirtualMachine.PowerState.PowerOn)
-						return true;
-			
-					VmWorkJobVO workJob = _workJobDao.findById(jobId);
-					if(workJob.getStatus() != JobInfo.Status.IN_PROGRESS)
-						return true;
-					
-					return false;
-				}
-    		});
-    	AsyncJobExecutionContext.getCurrentExecutionContext().disjoinJob(jobId);
-    	
-        return;
+        return new VmOutcome(workJob, VirtualMachine.PowerState.PowerOn);
     }
 
     private Pair<DeploymentPlan, DeployDestination> findDestination(VirtualMachineProfileImpl profile, DeploymentPlan planRequested, boolean reuseVolume,
@@ -988,7 +994,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     }
     
     @Override
-    public void stop(String vmUuid) {
+    public void easyStop(String vmUuid) {
         try {
             advanceStop(vmUuid, false);
         } catch (OperationTimedoutException e) {
@@ -1169,8 +1175,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     public void orchestrateStop(String vmUuid, boolean forced) throws AgentUnavailableException,
             OperationTimedoutException, ConcurrentOperationException {
         CallContext context = CallContext.current();
-        User user = context.getCallingUser();
-        Account account = context.getCallingAccount();
 
         VmWorkJobVO work = _workJobDao.findById(AsyncJobExecutionContext.getCurrentExecutionContext().getJob().getId());
 
@@ -2730,7 +2734,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
             }
             
             try {
-/*            	
+/*
                 lock.addRef();
                 List<VMInstanceVO> instances = _vmDao.findVMInTransition(new Date(new Date().getTime() - (_operationTimeout.value() * 1000)), State.Starting, State.Stopping);
                 for (VMInstanceVO instance : instances) {
@@ -2741,7 +2745,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
                         _haMgr.scheduleRestart(instance, true);
                     }
                 }
-*/               
+*/
             	scanStalledVMInTransitionStateOnDisconnectedHosts();
                 
             } catch (Exception e) {
@@ -3448,7 +3452,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     		}
     		
     		// we need to alert admin or user about this risky state transition
-    		_alertMgr.sendAlert(AlertManager.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), 
+    		_alertMgr.sendAlert(AlertManager.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(),
     			VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") state is sync-ed (Starting -> Running) from out-of-context transition. VM network environment may need to be reset");
     		break;
     		
@@ -3469,7 +3473,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     		} catch(NoTransitionException e) {
     			s_logger.warn("Unexpected VM state transition exception, race-condition?", e);
     		}
-      		_alertMgr.sendAlert(AlertManager.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), 
+      		_alertMgr.sendAlert(AlertManager.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(),
         			VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") state is sync-ed (" + vm.getState() + " -> Running) from out-of-context transition. VM network environment may need to be reset");
           		break;
     		
@@ -3541,7 +3545,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     	// or from designed behave of XS/KVM), the VM may not get a chance to run the state-sync logic
     	//
     	// Therefor, we will scan thoses VMs on UP host based on last update timestamp, if the host is UP
-    	// and a VM stalls for status update, we will consider them to be powered off 
+    	// and a VM stalls for status update, we will consider them to be powered off
     	// (which is relatively safe to do so)
     	
     	long stallThresholdInMs = _pingInterval.value() + (_pingInterval.value() >> 1);
@@ -3565,13 +3569,13 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     }
     
     private void scanStalledVMInTransitionStateOnDisconnectedHosts() {
-    	Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - this._operationTimeout.value()*1000);
+    	Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - _operationTimeout.value()*1000);
     	List<Long> stuckAndUncontrollableVMs = listStalledVMInTransitionStateOnDisconnectedHosts(cutTime);
     	for(Long vmId : stuckAndUncontrollableVMs) {
     		VMInstanceVO vm = _vmDao.findById(vmId);
     		
     		// We now only alert administrator about this situation
-      		_alertMgr.sendAlert(AlertManager.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(), 
+      		_alertMgr.sendAlert(AlertManager.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(),
         		VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") is stuck in " + vm.getState() + " state and its host is unreachable for too long");
     	}
     }
@@ -3606,9 +3610,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     // VMs that in transitional state and recently have power state update
     @DB
     private List<Long> listVMInTransitionStateWithRecentReportOnUpHost(long hostId, Date cutTime) {
-    	String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status = 'UP' " + 
+    	String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status = 'UP' " +
                      "AND h.id = ? AND i.power_state_update_time > ? AND i.host_id = h.id " +
-    			     "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " + 
+    			     "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
     			     "AND i.id NOT IN (SELECT vm_instance_id FROM vm_work_job)";
     	
     	List<Long> l = new ArrayList<Long>();
@@ -3652,4 +3656,34 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
     	}
     	return l;
     }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {StartRetry, VmOpWaitInterval, VmOpLockStateRetry, VmOpCleanupInterval, VmOpCleanupWait, VmOpCancelInterval, VmDestroyForceStop,
+                VmJobCheckInterval, VmJobTimeout, PingInterval};
+    }
+
+    public class VmOutcome extends OutcomeImpl<VirtualMachine> {
+        public VmOutcome(final AsyncJob job, final PowerState desiredPowerState) {
+            super(VirtualMachine.class, job, _jobCheckInterval.value(), new Predicate() {
+                @Override
+                public boolean checkCondition() {
+                    VMInstanceVO instance = _vmDao.findById(job.getInstanceId());
+                    if (instance.getPowerState() == desiredPowerState)
+                        return true;
+
+                    VmWorkJobVO workJob = _workJobDao.findById(job.getId());
+                    if (workJob.getStatus() != JobInfo.Status.IN_PROGRESS)
+                        return true;
+
+                    return false;
+                }
+            }, Topics.VM_POWER_STATE, AsyncJob.Topics.JOB_STATE);
+        }
+
+        @Override
+        protected VirtualMachine retrieve() {
+            return _vmDao.findById(_job.getInstanceId());
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/engine/orchestration/src/org/apache/cloudstack/engine/vm/VMEntityManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/vm/VMEntityManagerImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/vm/VMEntityManagerImpl.java
index 77a842e..3b25dfe 100755
--- a/engine/orchestration/src/org/apache/cloudstack/engine/vm/VMEntityManagerImpl.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/vm/VMEntityManagerImpl.java
@@ -242,14 +242,14 @@ public class VMEntityManagerImpl implements VMEntityManager {
             DataCenterDeployment reservedPlan = new DataCenterDeployment(vm.getDataCenterId(),
                     vmReservation.getPodId(), vmReservation.getClusterId(), vmReservation.getHostId(), null, null);
             try {
-                _itMgr.start(vm.getUuid(), params, reservedPlan);
+                _itMgr.easyStart(vm.getUuid(), params, reservedPlan);
             } catch (CloudRuntimeException ex) {
                 // Retry the deployment without using the reservation plan
-                _itMgr.start(vm.getUuid(), params, null);
+                _itMgr.easyStart(vm.getUuid(), params, null);
             }
         } else {
             // no reservation found. Let VirtualMachineManager retry
-            _itMgr.start(vm.getUuid(), params, null);
+            _itMgr.easyStart(vm.getUuid(), params, null);
         }
 
     }
@@ -257,7 +257,7 @@ public class VMEntityManagerImpl implements VMEntityManager {
     @Override
     public boolean stop(VMEntityVO vm, String caller) throws ResourceUnavailableException {
         try {
-            _itMgr.stop(vm.getUuid());
+            _itMgr.easyStop(vm.getUuid());
             return true;
         } catch (CloudRuntimeException e) {
             s_logger.warn("Unable to stop " + vm, e);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/framework/jobs/src/org/apache/cloudstack/framework/jobs/JobCancellationException.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/JobCancellationException.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/JobCancellationException.java
index a433b2b..28c1e5b 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/JobCancellationException.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/JobCancellationException.java
@@ -16,14 +16,16 @@
 // under the License.
 package org.apache.cloudstack.framework.jobs;
 
+import java.util.concurrent.CancellationException;
+
 import com.cloud.utils.SerialVersionUID;
-import com.cloud.utils.exception.CloudRuntimeException;
+
 
 /**
  * This exception is fired when the job has been cancelled
  *
  */
-public class JobCancellationException extends CloudRuntimeException {
+public class JobCancellationException extends CancellationException {
     
     private static final long serialVersionUID = SerialVersionUID.AffinityConflictException;
 
@@ -33,7 +35,6 @@ public class JobCancellationException extends CloudRuntimeException {
         TimedOut;
     }
 
-
     Reason reason;
 
     public JobCancellationException(Reason reason) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
----------------------------------------------------------------------
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
index f1e4f4b..020029d 100644
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
+++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
@@ -21,6 +21,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
 import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
 import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.framework.jobs.Outcome;
 
@@ -62,12 +63,19 @@ public class OutcomeImpl<T> implements Outcome<T> {
     @Override
     public T get() throws InterruptedException, ExecutionException {
         s_jobMgr.waitAndCheck(_topics, _checkIntervalInMs, -1, _predicate);
+        s_jobMgr.disjoinJob(AsyncJobExecutionContext.getCurrentExecutionContext().getJob().getId(), _job.getId());
+
         return retrieve();
     }
 
     @Override
     public T get(long timeToWait, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
         s_jobMgr.waitAndCheck(_topics, _checkIntervalInMs, unit.toMillis(timeToWait), _predicate);
+        try {
+            AsyncJobExecutionContext.getCurrentExecutionContext().disjoinJob(_job.getId());
+        } catch (Throwable e) {
+            throw new ExecutionException("Job task has trouble executing", e);
+        }
         return retrieve();
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java
index d8daeae..2bb3ba3 100644
--- a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java
+++ b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java
@@ -546,7 +546,7 @@ public class ElasticLoadBalancerManagerImpl extends ManagerBase implements
     ConcurrentOperationException, ResourceUnavailableException {
         s_logger.debug("Starting ELB VM " + elbVm);
         try {
-            _itMgr.start(elbVm.getUuid(), params);
+            _itMgr.easyStart(elbVm.getUuid(), params);
             return _routerDao.findById(elbVm.getId());
         } catch (CloudRuntimeException e) {
             s_logger.warn("Unable to start " + elbVm, e);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java
index 6754103..2a91c95 100644
--- a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java
+++ b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java
@@ -830,7 +830,7 @@ public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements
             ConcurrentOperationException, ResourceUnavailableException {
         s_logger.debug("Starting Internal LB VM " + internalLbVm);
         try {
-            _itMgr.start(internalLbVm.getUuid(), params, null);
+            _itMgr.easyStart(internalLbVm.getUuid(), params, null);
             internalLbVm = _internalLbVmDao.findById(internalLbVm.getId());
             if (internalLbVm.isStopPending()) {
                 s_logger.info("Clear the stop pending flag of Internal LB VM " + internalLbVm.getHostName() + " after start router successfully!");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index 8f0c096..59e3901 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -558,7 +558,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
             }
 
             if (proxy.getState() == VirtualMachine.State.Stopped) {
-                _itMgr.start(proxy.getUuid(), null);
+                _itMgr.easyStart(proxy.getUuid(), null);
                 proxy = _consoleProxyDao.findById(proxyVmId);
                 if (proxy.getState() == State.Running) {
                     return null;
@@ -1036,7 +1036,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
         }
 
         try {
-            _itMgr.stop(proxy.getUuid());
+            _itMgr.easyStop(proxy.getUuid());
             return true;
         } catch (CloudRuntimeException e) {
             s_logger.warn("Unable to stop " + proxy, e);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java
index 2385b16..fb20711 100755
--- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java
+++ b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java
@@ -21,6 +21,8 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -33,6 +35,7 @@ import org.apache.log4j.Logger;
 import org.apache.log4j.NDC;
 
 import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.jobs.Outcome;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.alert.AlertManager;
@@ -97,7 +100,7 @@ import com.cloud.vm.dao.VMInstanceDao;
  *         ha.retry.wait | time to wait before retrying the work item | seconds | 120 || || stop.retry.wait | time to wait
  *         before retrying the stop | seconds | 120 || * }
  **/
-@Local(value = { HighAvailabilityManager.class })
+@Local(value = {HighAvailabilityManager.class})
 public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvailabilityManager, ClusterManagerListener {
     protected static final Logger s_logger = Logger.getLogger(HighAvailabilityManagerImpl.class);
     WorkerThread[] _workers;
@@ -118,22 +121,26 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
     long _serverId;
 
     List<Investigator> _investigators;
+
     public List<Investigator> getInvestigators() {
-		return _investigators;
-	}
-	public void setInvestigators(List<Investigator> _investigators) {
-		this._investigators = _investigators;
-	}
+        return _investigators;
+    }
+
+    public void setInvestigators(List<Investigator> _investigators) {
+        this._investigators = _investigators;
+    }
+
+    List<FenceBuilder> _fenceBuilders;
 
-	List<FenceBuilder> _fenceBuilders;
     public List<FenceBuilder> getFenceBuilders() {
-		return _fenceBuilders;
-	}
-	public void setFenceBuilders(List<FenceBuilder> _fenceBuilders) {
-		this._fenceBuilders = _fenceBuilders;
-	}
+        return _fenceBuilders;
+    }
 
-	@Inject
+    public void setFenceBuilders(List<FenceBuilder> _fenceBuilders) {
+        this._fenceBuilders = _fenceBuilders;
+    }
+
+    @Inject
     AgentManager _agentMgr;
     @Inject
     AlertManager _alertMgr;
@@ -180,7 +187,7 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
         }
 
         Status hostState = null;
-        for(Investigator investigator : _investigators) {
+        for (Investigator investigator : _investigators) {
             hostState = investigator.isAgentAlive(host);
             if (hostState != null) {
                 if (s_logger.isDebugEnabled()) {
@@ -203,7 +210,7 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
             return;
         }
 
-        if(host.getHypervisorType() == HypervisorType.VMware) {
+        if (host.getHypervisorType() == HypervisorType.VMware) {
             s_logger.info("Don't restart for VMs on host " + host.getId() + " as the host is VMware host");
             return;
         }
@@ -288,18 +295,18 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
                 _itMgr.advanceStop(vm.getUuid(), true);
             } catch (ResourceUnavailableException e) {
                 assert false : "How do we hit this when force is true?";
-            throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
             } catch (OperationTimedoutException e) {
                 assert false : "How do we hit this when force is true?";
-            throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
             } catch (ConcurrentOperationException e) {
                 assert false : "How do we hit this when force is true?";
-            throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
             }
             return;
         }
 
-        if(vm.getHypervisorType() == HypervisorType.VMware) {
+        if (vm.getHypervisorType() == HypervisorType.VMware) {
             s_logger.info("Skip HA for VMware VM " + vm.getInstanceName());
             return;
         }
@@ -320,7 +327,8 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
 
             if (!(_forceHA || vm.isHaEnabled())) {
                 String hostDesc = "id:" + vm.getHostId() + ", availability zone id:" + vm.getDataCenterId() + ", pod id:" + vm.getPodIdToDeployIn();
-                _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "VM (name: " + vm.getHostName() + ", id: " + vm.getId() + ") stopped unexpectedly on host " + hostDesc,
+                _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "VM (name: " + vm.getHostName() + ", id: " + vm.getId()
+                        + ") stopped unexpectedly on host " + hostDesc,
                         "Virtual Machine " + vm.getHostName() + " (id: " + vm.getId() + ") running on host [" + vm.getHostId() + "] stopped unexpectedly.");
 
                 if (s_logger.isDebugEnabled()) {
@@ -332,13 +340,13 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
                 _itMgr.advanceStop(vm.getUuid(), true);
             } catch (ResourceUnavailableException e) {
                 assert false : "How do we hit this when force is true?";
-            throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
             } catch (OperationTimedoutException e) {
                 assert false : "How do we hit this when force is true?";
-            throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
             } catch (ConcurrentOperationException e) {
                 assert false : "How do we hit this when force is true?";
-            throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
             }
         }
 
@@ -351,7 +359,8 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
             }
         }
 
-        HaWorkVO work = new HaWorkVO(vm.getId(), vm.getType(), WorkType.HA, investigate ? Step.Investigating : Step.Scheduled, hostId, vm.getState(), maxRetries + 1, vm.getUpdated());
+        HaWorkVO work = new HaWorkVO(vm.getId(), vm.getType(), WorkType.HA, investigate ? Step.Investigating : Step.Scheduled, hostId, vm.getState(), maxRetries + 1,
+                vm.getUpdated());
         _haDao.persist(work);
 
         if (s_logger.isInfoEnabled()) {
@@ -395,7 +404,8 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
 
         s_logger.info("HA on " + vm);
         if (vm.getState() != work.getPreviousState() || vm.getUpdated() != work.getUpdateTime()) {
-            s_logger.info("VM " + vm + " has been changed.  Current State = " + vm.getState() + " Previous State = " + work.getPreviousState() + " last updated = " + vm.getUpdated()
+            s_logger.info("VM " + vm + " has been changed.  Current State = " + vm.getState() + " Previous State = " + work.getPreviousState() + " last updated = "
+                    + vm.getUpdated()
                     + " previous updated = " + work.getUpdateTime());
             return null;
         }
@@ -432,7 +442,7 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
                 }
 
                 Investigator investigator = null;
-                for(Investigator it : _investigators) {
+                for (Investigator it : _investigators) {
                     investigator = it;
                     alive = investigator.isVmAlive(vm, host);
                     s_logger.info(investigator.getName() + " found " + vm + "to be alive? " + alive);
@@ -444,7 +454,7 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
                 boolean fenced = false;
                 if (alive == null) {
                     s_logger.debug("Fencing off VM that we don't know the state of");
-                    for(FenceBuilder fb : _fenceBuilders) {
+                    for (FenceBuilder fb : _fenceBuilders) {
                         Boolean result = fb.fenceOff(vm, host);
                         s_logger.info("Fencer " + fb.getName() + " returned " + result);
                         if (result != null && result) {
@@ -468,7 +478,8 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
 
                 if (!fenced) {
                     s_logger.debug("We were unable to fence off the VM " + vm);
-                    _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc,
+                    _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host "
+                            + hostDesc,
                             "Insufficient capacity to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
                     return (System.currentTimeMillis() >> 10) + _restartRetryInterval;
                 }
@@ -477,13 +488,13 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
                     _itMgr.advanceStop(vm.getUuid(), true);
                 } catch (ResourceUnavailableException e) {
                     assert false : "How do we hit this when force is true?";
-                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
                 } catch (OperationTimedoutException e) {
                     assert false : "How do we hit this when force is true?";
-                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
                 } catch (ConcurrentOperationException e) {
                     assert false : "How do we hit this when force is true?";
-                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
                 }
 
                 work.setStep(Step.Scheduled);
@@ -494,13 +505,13 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
                     _itMgr.advanceStop(vm.getUuid(), true);
                 } catch (ResourceUnavailableException e) {
                     assert false : "How do we hit this when force is true?";
-                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
                 } catch (OperationTimedoutException e) {
                     assert false : "How do we hit this when force is true?";
-                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
                 } catch (ConcurrentOperationException e) {
                     assert false : "How do we hit this when force is true?";
-                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
                 }
             }
         }
@@ -526,45 +537,59 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
             return null;
         }
 
-        try {
-            HashMap<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>();
-            if (_haTag != null) {
-                params.put(VirtualMachineProfile.Param.HaTag, _haTag);
-            }
-            _itMgr.advanceStart(vm.getUuid(), params, null);
-            
-            VMInstanceVO started = _instanceDao.findById(vm.getId());
+        HashMap<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>();
+        if (_haTag != null) {
+            params.put(VirtualMachineProfile.Param.HaTag, _haTag);
+        }
+        Outcome<VirtualMachine> outcome = _itMgr.start(vm.getUuid(), params, null);
 
-            if (started.getState() == State.Running) {
-                s_logger.info("VM is now restarted: " + vmId + " on " + started.getHostId());
+        VirtualMachine started = null;
+        try {
+            started = outcome.get();
+        } catch (InterruptedException e) {
+            s_logger.warn("Received interrupted exception ", e);
+            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc,
+                    "Interrupted while attempting to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
+            return null;
+        } catch (ExecutionException e) {
+            Throwable cause = e.getCause();
+            if (cause instanceof InsufficientCapacityException) {
+                s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
+                _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc,
+                        "Insufficient capacity to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
+            } else if (cause instanceof ResourceUnavailableException) {
+                s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
+                _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc,
+                        "Resource is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
+            } else if (cause instanceof ConcurrentOperationException) {
+                s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
+                _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc,
+                        "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
+            } else if (cause instanceof OperationTimedoutException) {
+                s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
+                _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc,
+                        "Operations on the resource timed out for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
+            } else {
+                s_logger.warn("Unable to restart " + vm, e);
+                _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc,
+                        "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
                 return null;
             }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Rescheduling VM " + vm.toString() + " to try again in " + _restartRetryInterval);
-            }
-        } catch (final InsufficientCapacityException e) {
-            s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
-            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc,
-                    "Insufficient capacity to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
-        } catch (final ResourceUnavailableException e) {
-            s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
-            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc,
-                    "Resource is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
-        } catch (ConcurrentOperationException e) {
-            s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
-            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc,
-                    "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
-        } catch (OperationTimedoutException e) {
-            s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
+        } catch (CancellationException e) {
+            s_logger.warn("Received interrupted exception ", e);
             _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc,
-                    "Operations on the resource timed out for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
-        } catch (Exception e) {
-            s_logger.warn("Unable to restart " + vm, e);
-            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " + hostDesc,
-                    "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
+                    "Interrupted while attempting to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
             return null;
         }
+
+        if (started != null && started.getState() == State.Running) {
+            s_logger.info("VM is now restarted: " + vmId + " on " + started.getHostId());
+            return null;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Rescheduling VM " + vm.toString() + " to try again in " + _restartRetryInterval);
+        }
         vm = _instanceDao.findById(vm.getId());
         work.setUpdateTime(vm.getUpdated());
         work.setPreviousState(vm.getState());
@@ -650,16 +675,20 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
                 s_logger.info("Successfully stopped " + vm);
                 return null;
             } else if (work.getWorkType() == WorkType.CheckStop) {
-                if ((vm.getState() != work.getPreviousState()) || vm.getUpdated() != work.getUpdateTime() || vm.getHostId() == null || vm.getHostId().longValue() != work.getHostId()) {
-                    s_logger.info(vm + " is different now.  Scheduled Host: " + work.getHostId() + " Current Host: " + (vm.getHostId() != null ? vm.getHostId() : "none") + " State: " + vm.getState());
+                if ((vm.getState() != work.getPreviousState()) || vm.getUpdated() != work.getUpdateTime() || vm.getHostId() == null
+                        || vm.getHostId().longValue() != work.getHostId()) {
+                    s_logger.info(vm + " is different now.  Scheduled Host: " + work.getHostId() + " Current Host: " + (vm.getHostId() != null ? vm.getHostId() : "none")
+                            + " State: " + vm.getState());
                     return null;
                 }
                 _itMgr.advanceStop(vm.getUuid(), false);
                 s_logger.info("Stop for " + vm + " was successful");
                 return null;
             } else if (work.getWorkType() == WorkType.ForceStop) {
-                if ((vm.getState() != work.getPreviousState()) || vm.getUpdated() != work.getUpdateTime() || vm.getHostId() == null || vm.getHostId().longValue() != work.getHostId()) {
-                    s_logger.info(vm + " is different now.  Scheduled Host: " + work.getHostId() + " Current Host: " + (vm.getHostId() != null ? vm.getHostId() : "none") + " State: " + vm.getState());
+                if ((vm.getState() != work.getPreviousState()) || vm.getUpdated() != work.getUpdateTime() || vm.getHostId() == null
+                        || vm.getHostId().longValue() != work.getHostId()) {
+                    s_logger.info(vm + " is different now.  Scheduled Host: " + work.getHostId() + " Current Host: " + (vm.getHostId() != null ? vm.getHostId() : "none")
+                            + " State: " + vm.getState());
                     return null;
                 }
                 _itMgr.advanceStop(vm.getUuid(), true);
@@ -834,7 +863,7 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
                             nextTime = destroyVM(work);
                         } else {
                             assert false : "How did we get here with " + wt.toString();
-                        continue;
+                            continue;
                         }
 
                         if (nextTime == null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index a1bb1ff..ab66bb0 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -2717,7 +2717,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
             ConcurrentOperationException, ResourceUnavailableException {
         s_logger.debug("Starting router " + router);
         try {
-            _itMgr.start(router.getUuid(), params, planToDeploy);
+            _itMgr.easyStart(router.getUuid(), params, planToDeploy);
             router = _routerDao.findById(router.getId());
             if (router.isStopPending()) {
                 s_logger.info("Clear the stop pending flag of router " + router.getHostName() + " after start router successfully!");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java
index b429e01..effc4e0 100755
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@ -2375,7 +2375,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
 									+ " as a part of deleteHost id="
 									+ host.getId());
                             try {
-                                _vmMgr.stop(vm.getUuid());
+                                _vmMgr.easyStop(vm.getUuid());
                             } catch (Exception e) {
 								String errorMsg = "There was an error stopping the vm: "
 										+ vm

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/server/src/com/cloud/storage/StoragePoolAutomationImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java b/server/src/com/cloud/storage/StoragePoolAutomationImpl.java
index 0e6d53b..e1550b8 100644
--- a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java
+++ b/server/src/com/cloud/storage/StoragePoolAutomationImpl.java
@@ -203,32 +203,32 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation {
                     // call the consoleproxymanager
                     ConsoleProxyVO consoleProxy = _consoleProxyDao
                             .findById(vmInstance.getId());
-                    vmMgr.stop(consoleProxy.getUuid());
+                    vmMgr.easyStop(consoleProxy.getUuid());
                         // update work status
                     work.setStoppedForMaintenance(true);
                     _storagePoolWorkDao.update(work.getId(), work);
 
                     if (restart) {
 
-                        vmMgr.start(consoleProxy.getUuid(), null);
+                        vmMgr.easyStart(consoleProxy.getUuid(), null);
                         work.setStartedAfterMaintenance(true);
                         _storagePoolWorkDao.update(work.getId(), work);
                     }
                 } else if (vmInstance.getType().equals(VirtualMachine.Type.User)) {
                     UserVmVO userVm = userVmDao.findById(vmInstance.getId());
-                    vmMgr.stop(userVm.getUuid());
+                    vmMgr.easyStop(userVm.getUuid());
                     // update work status
                     work.setStoppedForMaintenance(true);
                     _storagePoolWorkDao.update(work.getId(), work);
                 } else if (vmInstance.getType().equals(VirtualMachine.Type.SecondaryStorageVm)) {
                     SecondaryStorageVmVO secStrgVm = _secStrgDao
                             .findById(vmInstance.getId());
-                    vmMgr.stop(secStrgVm.getUuid());
+                    vmMgr.easyStop(secStrgVm.getUuid());
                     work.setStoppedForMaintenance(true);
                     _storagePoolWorkDao.update(work.getId(), work);
 
                     if (restart) {
-                        vmMgr.start(secStrgVm.getUuid(), null);
+                        vmMgr.easyStart(secStrgVm.getUuid(), null);
                         work.setStartedAfterMaintenance(true);
                         _storagePoolWorkDao.update(work.getId(), work);
                     }
@@ -238,7 +238,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation {
                     work.setStoppedForMaintenance(true);
                     _storagePoolWorkDao.update(work.getId(), work);
                     if (restart) {
-                        vmMgr.start(domR.getUuid(), null);
+                        vmMgr.easyStart(domR.getUuid(), null);
                         work.setStartedAfterMaintenance(true);
                         _storagePoolWorkDao.update(work.getId(), work);
                     }
@@ -302,23 +302,23 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation {
 
                 if (vmInstance.getType().equals(VirtualMachine.Type.ConsoleProxy)) {
                     ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(vmInstance.getId());
-                    vmMgr.start(consoleProxy.getUuid(), null);
+                    vmMgr.easyStart(consoleProxy.getUuid(), null);
                     work.setStartedAfterMaintenance(true);
                     _storagePoolWorkDao.update(work.getId(), work);
                 } else if (vmInstance.getType().equals(VirtualMachine.Type.SecondaryStorageVm)) {
                     SecondaryStorageVmVO ssVm = _secStrgDao.findById(vmInstance.getId());
-                    vmMgr.advanceStart(ssVm.getUuid(), null, null);
+                    vmMgr.start(ssVm.getUuid(), null, null);
                     work.setStartedAfterMaintenance(true);
                     _storagePoolWorkDao.update(work.getId(), work);
                 } else if (vmInstance.getType().equals(VirtualMachine.Type.DomainRouter)) {
                     DomainRouterVO domR = _domrDao.findById(vmInstance.getId());
-                    vmMgr.start(domR.getUuid(), null);
+                    vmMgr.easyStart(domR.getUuid(), null);
                     work.setStartedAfterMaintenance(true);
                     _storagePoolWorkDao.update(work.getId(), work);
                 } else if (vmInstance.getType().equals(VirtualMachine.Type.User)) {
                     UserVmVO userVm = userVmDao.findById(vmInstance.getId());
 
-                    vmMgr.start(userVm.getUuid(), null);
+                    vmMgr.easyStart(userVm.getUuid(), null);
                     work.setStartedAfterMaintenance(true);
                     _storagePoolWorkDao.update(work.getId(), work);
                 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
index 65e76f6..d4e360a 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
@@ -258,7 +258,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
             SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
             Account systemAcct = _accountMgr.getSystemAccount();
             User systemUser = _accountMgr.getSystemUser();
-            _itMgr.start(secStorageVm.getUuid(), null);
+            _itMgr.easyStart(secStorageVm.getUuid(), null);
             return _secStorageVmDao.findById(secStorageVmId);
         } catch (Exception e) {
             s_logger.warn("Exception while trying to start secondary storage vm", e);
@@ -921,7 +921,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
             try {
                 if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
                     try {
-                        _itMgr.stop(secStorageVm.getUuid());
+                        _itMgr.easyStop(secStorageVm.getUuid());
                         return true;
                     } catch (Exception e) {
                         s_logger.warn("Unable to stop " + secStorageVm, e);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/server/src/com/cloud/user/AccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java
index 3e4520c..ad2654b 100755
--- a/server/src/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/com/cloud/user/AccountManagerImpl.java
@@ -815,7 +815,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
         boolean success = true;
         for (VMInstanceVO vm : vms) {
             try {
-                _itMgr.stop(vm.getUuid());
+                _itMgr.easyStop(vm.getUuid());
             } catch (CloudRuntimeException ote) {
                 s_logger.warn("Operation for stopping vm timed out, unable to stop vm " + vm.getHostName(), ote);
                 success = false;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 7a79fc6..d37ef95 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -4552,7 +4552,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
 
         if (needRestart) {
             try {
-                _itMgr.stop(vm.getUuid());
+                _itMgr.easyStop(vm.getUuid());
             } catch (CloudRuntimeException e) {
                 s_logger.debug("Stop vm " + vm.getUuid() + " failed");
                 CloudRuntimeException ex = new CloudRuntimeException("Stop vm failed for specified vmId");
@@ -4612,7 +4612,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
 
         if (needRestart) {
             try {
-                _itMgr.start(vm.getUuid(), null);
+                _itMgr.easyStart(vm.getUuid(), null);
             } catch (Exception e) {
                 s_logger.debug("Unable to start VM " + vm.getUuid(), e);
                 CloudRuntimeException ex = new CloudRuntimeException(

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
index 8d1c628..64adc92 100644
--- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
+++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
@@ -673,7 +673,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
         // start or stop VM first, if revert from stopped state to running state, or from running to stopped
         if(userVm.getState() == VirtualMachine.State.Stopped && vmSnapshotVo.getType() == VMSnapshot.Type.DiskAndMemory){
             try {
-                _itMgr.start(userVm.getUuid(), new HashMap<VirtualMachineProfile.Param, Object>());
+                _itMgr.easyStart(userVm.getUuid(), new HashMap<VirtualMachineProfile.Param, Object>());
                 userVm = _userVMDao.findById(userVm.getId());
                 hostId = userVm.getHostId();
             } catch (CloudRuntimeException e) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa525a7d/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
index 3f35a42..0c23220 100644
--- a/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
+++ b/server/test/com/cloud/vm/VmWorkMockVirtualMachineManagerImpl.java
@@ -26,6 +26,7 @@ import javax.naming.ConfigurationException;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
+import org.apache.cloudstack.framework.jobs.Outcome;
 import org.apache.cloudstack.framework.messagebus.MessageBus;
 import org.apache.cloudstack.jobs.JobInfo;
 
@@ -139,17 +140,17 @@ public class VmWorkMockVirtualMachineManagerImpl implements VirtualMachineManage
 	}
 
 	@Override
-    public void start(String vmUuid, Map<Param, Object> params) {
+    public void easyStart(String vmUuid, Map<Param, Object> params) {
 		// TODO Auto-generated method stub
 	}
 
 	@Override
-    public void start(String vmUuid, Map<Param, Object> params, DeploymentPlan planToDeploy) {
+    public void easyStart(String vmUuid, Map<Param, Object> params, DeploymentPlan planToDeploy) {
 		// TODO Auto-generated method stub
 	}
 
 	@Override
-    public void stop(String vmUuid) {
+    public void easyStop(String vmUuid) {
 		// TODO Auto-generated method stub
 	}
 
@@ -172,11 +173,9 @@ public class VmWorkMockVirtualMachineManagerImpl implements VirtualMachineManage
 	}
 
 	@Override
-    public void advanceStart(String vmUuid, Map<Param, Object> params,
-			DeploymentPlan planToDeploy) throws InsufficientCapacityException,
-			ResourceUnavailableException, ConcurrentOperationException,
-			OperationTimedoutException {
-		// TODO Auto-generated method stub
+    public Outcome<VirtualMachine> start(String vmUuid, Map<Param, Object> params,
+            DeploymentPlan planToDeploy) {
+        return null;
 	}
 
 	@Override