diff --git a/api/src/org/apache/cloudstack/context/CallContext.java b/api/src/org/apache/cloudstack/context/CallContext.java index 114f626cf95..f10444ea418 100644 --- a/api/src/org/apache/cloudstack/context/CallContext.java +++ b/api/src/org/apache/cloudstack/context/CallContext.java @@ -18,8 +18,10 @@ package org.apache.cloudstack.context; import java.util.HashMap; import java.util.Map; +import java.util.Stack; import java.util.UUID; +import org.apache.cloudstack.managed.threadlocal.ManagedThreadLocal; import org.apache.log4j.Logger; import org.apache.log4j.NDC; @@ -37,7 +39,14 @@ import com.cloud.utils.exception.CloudRuntimeException; */ public class CallContext { private static final Logger s_logger = Logger.getLogger(CallContext.class); - private static final ThreadLocal s_currentContext = new ThreadLocal(); + private static ManagedThreadLocal s_currentContext = new ManagedThreadLocal(); + private static ManagedThreadLocal> s_currentContextStack = + new ManagedThreadLocal>() { + @Override + protected Stack initialValue() { + return new Stack(); + } + }; private String contextId; private Account account; @@ -115,6 +124,9 @@ public class CallContext { if (s_logger.isTraceEnabled()) { s_logger.trace("Registered: " + callingContext); } + + s_currentContextStack.get().push(callingContext); + return callingContext; } @@ -162,10 +174,15 @@ public class CallContext { return register(user, account); } + public static void unregisterAll() { + while ( unregister() != null ) { + // NOOP + } + } + public static CallContext unregister() { CallContext context = s_currentContext.get(); if (context == null) { - s_logger.debug("No context to remove"); return null; } s_currentContext.remove(); @@ -183,6 +200,14 @@ public class CallContext { s_logger.trace("Popping from NDC: " + contextId); } } + + Stack stack = s_currentContextStack.get(); + stack.pop(); + + if ( ! stack.isEmpty() ) { + s_currentContext.set(stack.peek()); + } + return context; } diff --git a/api/src/org/apache/cloudstack/context/CallContextListener.java b/api/src/org/apache/cloudstack/context/CallContextListener.java new file mode 100644 index 00000000000..c528fa2d236 --- /dev/null +++ b/api/src/org/apache/cloudstack/context/CallContextListener.java @@ -0,0 +1,41 @@ +/* + * 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.context; + +import org.apache.cloudstack.managed.context.ManagedContextListener; + +public class CallContextListener implements ManagedContextListener { + + @Override + public Object onEnterContext(boolean reentry) { + if ( ! reentry ) { + CallContext.registerSystemCallContextOnceOnly(); + } + + return null; + } + + @Override + public void onLeaveContext(Object unused, boolean reentry) { + if ( ! reentry ) { + CallContext.unregisterAll(); + } + } + +} diff --git a/engine/components-api/src/org/apache/cloudstack/context/ServerContexts.java b/engine/components-api/src/org/apache/cloudstack/context/ServerContexts.java deleted file mode 100644 index b9c249ce620..00000000000 --- a/engine/components-api/src/org/apache/cloudstack/context/ServerContexts.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.context; - -import org.apache.cloudstack.framework.jobs.AsyncJob; - -import com.cloud.utils.db.Transaction; - -/** - * ServerContextInitializer is responsible for properly setting up the - * contexts that all of the CloudStack code expects. This includes - * - CallContext - * - JobContext - * - TransactionContext - */ -public class ServerContexts { - public static void registerUserContext(long userId, long accountId) { - Transaction txn = Transaction.open(Thread.currentThread().getName()); - CallContext context = CallContext.register(userId, accountId); - context.putContextParameter("Transaction", txn); -// AsyncJobExecutionContext.registerPseudoExecutionContext(userId, accountId); - } - - public static void unregisterUserContext() { - CallContext context = CallContext.unregister(); - if (context != null) { -// AsyncJobExecutionContext.unregister(); - Transaction txn = (Transaction)context.getContextParameter("Transaction"); - txn.close(Thread.currentThread().getName()); - } - } - - /** - * Use this method to initialize the internal background threads. - */ - public static void registerSystemContext() { - Transaction txn = Transaction.open(Thread.currentThread().getName()); - CallContext context = CallContext.registerSystemCallContextOnceOnly(); - context.putContextParameter("Transaction", txn); -// AsyncJobExecutionContext.registerPseudoExecutionContext(Account.ACCOUNT_ID_SYSTEM, User.UID_SYSTEM); - } - - public static void unregisterSystemContext() { - CallContext context = CallContext.unregister(); -// AsyncJobExecutionContext.unregister(); - Transaction txn = (Transaction)context.getContextParameter("Transaction"); - txn.close(Thread.currentThread().getName()); - } - - public static void registerJobContext(long userId, long accountId, AsyncJob job) { - CallContext.register(userId, accountId); - } -} diff --git a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java index 51f6d72109e..6b521a2ef2d 100755 --- a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -38,13 +38,12 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; - -import org.apache.cloudstack.context.ServerContexts; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.utils.identity.ManagementServerNode; +import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; @@ -843,7 +842,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl return true; } - protected class DisconnectTask implements Runnable { + protected class DisconnectTask extends ManagedContextRunnable { AgentAttache _attache; Status.Event _event; boolean _investigate; @@ -855,7 +854,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl } @Override - public void run() { + protected void runInContext() { try { if (_investigate == true) { handleDisconnectWithInvestigation(_attache, _event); @@ -1017,7 +1016,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl return attache; } - protected class SimulateStartTask implements Runnable { + protected class SimulateStartTask extends ManagedContextRunnable implements Runnable { ServerResource resource; Map details; long id; @@ -1029,8 +1028,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl } @Override - public void run() { - ServerContexts.registerSystemContext(); + protected void runInContext() { try { if (s_logger.isDebugEnabled()) { s_logger.debug("Simulating start for resource " + resource.getName() + " id " + id); @@ -1054,13 +1052,11 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl } } catch (Exception e) { s_logger.warn("Unable to simulate start on resource " + id + " name " + resource.getName(), e); - } finally { - ServerContexts.unregisterSystemContext(); } } } - protected class HandleAgentConnectTask implements Runnable { + protected class HandleAgentConnectTask extends ManagedContextRunnable implements Runnable { Link _link; Command[] _cmds; Request _request; @@ -1071,22 +1067,16 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl _request = request; } - @Override - public void run() { - ServerContexts.registerSystemContext(); - try { - _request.logD("Processing the first command "); - StartupCommand[] startups = new StartupCommand[_cmds.length]; - for (int i = 0; i < _cmds.length; i++) { - startups[i] = (StartupCommand)_cmds[i]; - } + protected void runInContext() { + _request.logD("Processing the first command "); + StartupCommand[] startups = new StartupCommand[_cmds.length]; + for (int i = 0; i < _cmds.length; i++) { + startups[i] = (StartupCommand)_cmds[i]; + } - AgentAttache attache = handleConnectedAgent(_link, startups, _request); - if (attache == null) { - s_logger.warn("Unable to create attache for agent: " + _request); - } - } finally { - ServerContexts.unregisterSystemContext(); + AgentAttache attache = handleConnectedAgent(_link, startups, _request); + if (attache == null) { + s_logger.warn("Unable to create attache for agent: " + _request); } } } @@ -1439,9 +1429,9 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl _pingMap.put(agentId, InaccurateClock.getTimeInSeconds()); } - protected class MonitorTask implements Runnable { + protected class MonitorTask extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { s_logger.trace("Agent Monitor is started."); try { diff --git a/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java b/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java index 76e1d8e33b6..48f096ade22 100755 --- a/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java +++ b/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java @@ -32,7 +32,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.Timer; -import java.util.TimerTask; import java.util.concurrent.Executors; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ScheduledExecutorService; @@ -51,6 +50,8 @@ import com.google.gson.Gson; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; +import org.apache.cloudstack.managed.context.ManagedContextTimerTask; import org.apache.cloudstack.utils.identity.ManagementServerNode; import com.cloud.agent.AgentManager; @@ -231,9 +232,9 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } } - private class DirectAgentScanTimerTask extends TimerTask { + private class DirectAgentScanTimerTask extends ManagedContextTimerTask { @Override - public void run() { + protected void runInContext() { try { runDirectAgentScanTimerTask(); } catch (Throwable e) { @@ -746,7 +747,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust _timer.schedule(new AgentLoadBalancerTask(), 30000); } - public class AgentLoadBalancerTask extends TimerTask { + public class AgentLoadBalancerTask extends ManagedContextTimerTask { protected volatile boolean cancelled = false; public AgentLoadBalancerTask() { @@ -764,7 +765,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } @Override - public synchronized void run() { + protected synchronized void runInContext() { try { if (!cancelled) { startRebalanceAgents(); @@ -925,9 +926,9 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } private Runnable getTransferScanTask() { - return new Runnable() { + return new ManagedContextRunnable() { @Override - public void run() { + protected void runInContext() { try { if (s_logger.isTraceEnabled()) { s_logger.trace("Clustered agent transfer scan check, management server id:" + _nodeId); @@ -1173,7 +1174,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } - protected class RebalanceTask implements Runnable { + protected class RebalanceTask extends ManagedContextRunnable { Long hostId = null; Long currentOwnerId = null; Long futureOwnerId = null; @@ -1186,7 +1187,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } @Override - public void run() { + protected void runInContext() { try { if (s_logger.isDebugEnabled()) { s_logger.debug("Rebalancing host id=" + hostId); diff --git a/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java b/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java index 5b5d8d21289..2808c6af91a 100755 --- a/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java +++ b/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -127,9 +128,9 @@ public class DirectAgentAttache extends AgentAttache { } } - protected class PingTask implements Runnable { + protected class PingTask extends ManagedContextRunnable { @Override - public synchronized void run() { + protected synchronized void runInContext() { try { ServerResource resource = _resource; @@ -160,7 +161,7 @@ public class DirectAgentAttache extends AgentAttache { } - protected class Task implements Runnable { + protected class Task extends ManagedContextRunnable { Request _req; public Task(Request req) { @@ -168,7 +169,7 @@ public class DirectAgentAttache extends AgentAttache { } @Override - public void run() { + protected void runInContext() { long seq = _req.getSequence(); try { ServerResource resource = _resource; diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 560bab26fff..8bf419f1a65 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.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.utils.identity.ManagementServerNode; @@ -1835,9 +1836,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } } - protected class CleanupTask implements Runnable { + protected class CleanupTask extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { s_logger.trace("VM Operation Thread Running"); try { _workDao.cleanup(VmOpCleanupWait.value()); @@ -2588,9 +2589,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } } - protected class TransitionTask implements Runnable { + protected class TransitionTask extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { GlobalLock lock = GlobalLock.getInternLock("TransitionChecking"); if (lock == null) { s_logger.debug("Couldn't get the global lock"); diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 0b13fb40003..3c4b1ed5e72 100755 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -37,15 +37,14 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.context.CallContext; -import org.apache.cloudstack.context.ServerContexts; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.region.PortableIpDao; import com.cloud.agent.AgentManager; @@ -2195,10 +2194,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra return result; } - public class NetworkGarbageCollector implements Runnable { + public class NetworkGarbageCollector extends ManagedContextRunnable { @Override - public void run() { - ServerContexts.registerSystemContext(); + protected void runInContext() { GlobalLock gcLock = GlobalLock.getInternLock("Network.GC.Lock"); try { if (gcLock.lock(3)) { @@ -2210,7 +2208,6 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } } finally { gcLock.releaseRef(); - ServerContexts.unregisterSystemContext(); } } diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java index 7f335c53315..bb8d67d321f 100644 --- a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java @@ -45,6 +45,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.cache.allocator.StorageCacheAllocator; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; @@ -145,10 +146,10 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { return true; } - protected class CacheReplacementRunner implements Runnable { + protected class CacheReplacementRunner extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { GlobalLock replacementLock = null; try { replacementLock = GlobalLock.getInternLock("storageCacheMgr.replacement"); @@ -271,4 +272,4 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { public boolean deleteCacheObject(DataObject data) { return data.getDataStore().delete(data); } -} \ No newline at end of file +} diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java index 0f1cf9da487..f19bb3c603c 100644 --- a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java +++ b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java @@ -48,6 +48,7 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.utils.identity.ManagementServerNode; import com.cloud.cluster.dao.ManagementServerHostDao; @@ -636,9 +637,9 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C } private Runnable getNotificationTask() { - return new Runnable() { + return new ManagedContextRunnable() { @Override - public void run() { + protected void runInContext() { while(true) { synchronized(_notificationMsgs) { try { diff --git a/framework/cluster/src/com/cloud/cluster/ClusterServiceServletContainer.java b/framework/cluster/src/com/cloud/cluster/ClusterServiceServletContainer.java index def3e178116..019d83de8ac 100644 --- a/framework/cluster/src/com/cloud/cluster/ClusterServiceServletContainer.java +++ b/framework/cluster/src/com/cloud/cluster/ClusterServiceServletContainer.java @@ -22,6 +22,7 @@ import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.http.ConnectionClosedException; import org.apache.http.HttpException; import org.apache.http.impl.DefaultConnectionReuseStrategy; @@ -129,8 +130,9 @@ public class ClusterServiceServletContainer { final DefaultHttpServerConnection conn = new DefaultHttpServerConnection(); conn.bind(socket, _params); - _executor.execute(new Runnable() { - public void run() { + _executor.execute(new ManagedContextRunnable() { + @Override + protected void runInContext() { HttpContext context = new BasicHttpContext(null); try { while(!Thread.interrupted() && conn.isOpen()) { 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 01365939127..595800d2524 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java @@ -17,12 +17,12 @@ 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 org.apache.cloudstack.jobs.JobInfo; +import org.apache.cloudstack.managed.threadlocal.ManagedThreadLocal; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -39,7 +39,7 @@ public class AsyncJobExecutionContext { _joinMapDao = joinMapDao; } - private static ThreadLocal s_currentExectionContext = new ThreadLocal(); + private static ManagedThreadLocal s_currentExectionContext = new ManagedThreadLocal(); public AsyncJobExecutionContext() { } 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 index 2ddb1158c8c..c6332b7d2ce 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java @@ -36,7 +36,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; @@ -54,6 +53,7 @@ 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 org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.utils.identity.ManagementServerNode; import com.cloud.cluster.ClusterManagerListener; @@ -724,9 +724,9 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, @DB private Runnable getGCTask() { - return new Runnable() { + return new ManagedContextRunnable() { @Override - public void run() { + protected void runInContext() { GlobalLock scanLock = GlobalLock.getInternLock("AsyncJobManagerGC"); try { if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) { 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 ad0da35adb3..8ea75289dfd 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 @@ -26,12 +26,12 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.framework.jobs.AsyncJob; 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.managed.context.ManagedContextTimerTask; import com.cloud.utils.component.ManagerBase; @@ -97,10 +97,9 @@ public class AsyncJobMonitor extends ManagerBase { throws ConfigurationException { _messageBus.subscribe(AsyncJob.Topics.JOB_HEARTBEAT, MessageDispatcher.getDispatcher(this)); - _timer.scheduleAtFixedRate(new TimerTask() { - + _timer.scheduleAtFixedRate(new ManagedContextTimerTask() { @Override - public void run() { + protected void runInContext() { heartbeat(); } diff --git a/framework/pom.xml b/framework/pom.xml index 1764076d498..4ea2df14cf2 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -37,5 +37,6 @@ cluster db config + managed-context diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java index 8da9da086af..125faba6e7a 100755 --- a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java +++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java @@ -98,7 +98,7 @@ public class UcsManagerImpl implements UcsManager { private ScheduledExecutorService syncBladesExecutor; private int syncBladeInterval; - private class SyncBladesThread implements Runnable { + private class SyncBladesThread extends ManagedContextRunnable { private void discoverNewBlades(Map previous, Map now, UcsManagerVO mgr) { @@ -156,7 +156,7 @@ public class UcsManagerImpl implements UcsManager { } @Override - public void run() { + protected void runInContext() { try { List mgrs = ucsDao.listAll(); for (UcsManagerVO mgr : mgrs) { 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 6b719eb1476..3f8fc5c6f9d 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 @@ -36,11 +36,11 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerRuleCmd; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -749,9 +749,9 @@ public class ElasticLoadBalancerManagerImpl extends ManagerBase implements Elast _gcCandidateElbVmIds = currentGcCandidates; } - public class CleanupThread implements Runnable { + public class CleanupThread extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { garbageCollectUnusedElbVms(); } diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java index 6f5d25a61c1..ed0c9fdcb46 100755 --- a/server/src/com/cloud/alert/AlertManagerImpl.java +++ b/server/src/com/cloud/alert/AlertManagerImpl.java @@ -48,6 +48,7 @@ import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextTimerTask; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; @@ -455,9 +456,9 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi } - class CapacityChecker extends TimerTask { + class CapacityChecker extends ManagedContextTimerTask { @Override - public void run() { + protected void runInContext() { try { s_logger.debug("Running Capacity Checker ... "); checkForAlerts(); diff --git a/server/src/com/cloud/api/ApiAsyncJobDispatcher.java b/server/src/com/cloud/api/ApiAsyncJobDispatcher.java index 7092ef3779f..22ccb891e62 100644 --- a/server/src/com/cloud/api/ApiAsyncJobDispatcher.java +++ b/server/src/com/cloud/api/ApiAsyncJobDispatcher.java @@ -36,6 +36,7 @@ import org.apache.cloudstack.framework.jobs.AsyncJob; import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.jobs.JobInfo; +import org.apache.cloudstack.managed.context.ManagedContext; import com.cloud.user.Account; import com.cloud.user.User; @@ -51,12 +52,23 @@ public class ApiAsyncJobDispatcher extends AdapterBase implements AsyncJobDispat @Inject private AsyncJobManager _asyncJobMgr; @Inject private EntityManager _entityMgr; + @Inject + ManagedContext _managedContext; public ApiAsyncJobDispatcher() { } - @Override - public void runJob(AsyncJob job) { + @Override + public void runJob(final AsyncJob job) { + _managedContext.runWithContext(new Runnable() { + @Override + public void run() { + runJobInContext(job); + } + }); + } + + protected void runJobInContext(AsyncJob job) { BaseAsyncCmd cmdObj = null; try { Class cmdClass = Class.forName(job.getCmd()); diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 26789e3a81a..57dd03db0ad 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -119,6 +119,7 @@ import org.apache.cloudstack.framework.config.impl.ConfigurationVO; import org.apache.cloudstack.framework.jobs.AsyncJob; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import com.cloud.api.response.ApiResponseSerializer; import com.cloud.configuration.Config; @@ -976,7 +977,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer } } - static class WorkerTask implements Runnable { + static class WorkerTask extends ManagedContextRunnable { private final HttpService _httpService; private final HttpServerConnection _conn; @@ -986,7 +987,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer } @Override - public void run() { + protected void runInContext() { HttpContext context = new BasicHttpContext(null); try { while (!Thread.interrupted() && _conn.isOpen()) { diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 552327c83d1..def18d0919d 100755 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -34,11 +34,11 @@ import javax.servlet.http.HttpSession; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import org.springframework.web.context.support.SpringBeanAutowiringSupport; - import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.managed.context.ManagedContext; import com.cloud.exception.CloudAuthenticationException; import com.cloud.user.Account; @@ -57,6 +57,8 @@ public class ApiServlet extends HttpServlet { @Inject AccountService _accountMgr; @Inject EntityManager _entityMgr; + @Inject + ManagedContext _managedContext; public ApiServlet() { } @@ -105,8 +107,16 @@ public class ApiServlet extends HttpServlet { } } - @SuppressWarnings("unchecked") - private void processRequest(HttpServletRequest req, HttpServletResponse resp) { + private void processRequest(final HttpServletRequest req, final HttpServletResponse resp) { + _managedContext.runWithContext(new Runnable() { + @Override + public void run() { + processRequestInContext(req, resp); + } + }); + } + + private void processRequestInContext(HttpServletRequest req, HttpServletResponse resp) { StringBuffer auditTrailSb = new StringBuffer(); auditTrailSb.append(" " + req.getRemoteAddr()); auditTrailSb.append(" -- " + req.getMethod() + " "); diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java index 8cd44f44673..dcfb24c9d33 100644 --- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java +++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java @@ -22,7 +22,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Timer; -import java.util.TimerTask; import java.util.TreeSet; import javax.ejb.Local; @@ -43,6 +42,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.messagebus.MessageBus; import org.apache.cloudstack.framework.messagebus.MessageSubscriber; +import org.apache.cloudstack.managed.context.ManagedContextTimerTask; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.utils.identity.ManagementServerNode; @@ -688,9 +688,9 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy return false; } - class HostReservationReleaseChecker extends TimerTask { + class HostReservationReleaseChecker extends ManagedContextTimerTask { @Override - public void run() { + protected void runInContext() { try { s_logger.debug("Checking if any host reservation can be released ... "); checkHostReservations(); diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java index f1e0f3f5dec..1107a7a031d 100644 --- a/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java @@ -26,8 +26,8 @@ import javax.naming.ConfigurationException; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; - import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import com.cloud.alert.AlertManager; import com.cloud.usage.dao.UsageJobDao; @@ -65,9 +65,9 @@ public class HighAvailabilityManagerExtImpl extends HighAvailabilityManagerImpl return true; } - protected class UsageServerMonitorTask implements Runnable { + protected class UsageServerMonitorTask extends ManagedContextRunnable{ @Override - public void run() { + protected void runInContext() { if (s_logger.isInfoEnabled()) { s_logger.info("checking health of usage server"); } diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java index 464b9524556..59337c0326d 100755 --- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java @@ -31,10 +31,10 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.apache.log4j.NDC; - -import org.apache.cloudstack.context.ServerContexts; import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContext; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import com.cloud.agent.AgentManager; import com.cloud.alert.AlertManager; @@ -116,6 +116,9 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai @Inject ClusterDetailsDao _clusterDetailsDao; long _serverId; + + @Inject + ManagedContext _managedContext; List _investigators; public List getInvestigators() { @@ -773,9 +776,9 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai return true; } - protected class CleanupTask implements Runnable { + protected class CleanupTask extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { s_logger.info("HA Cleanup Thread Running"); try { @@ -793,71 +796,75 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai @Override public void run() { - ServerContexts.registerSystemContext(); - try { - s_logger.info("Starting work"); - while (!_stopped) { - HaWorkVO work = null; - try { - s_logger.trace("Checking the database"); - work = _haDao.take(_serverId); - if (work == null) { - try { - synchronized (this) { - wait(_timeToSleep); - } - continue; - } catch (final InterruptedException e) { - s_logger.info("Interrupted"); - continue; - } - } - - NDC.push("work-" + work.getId()); - s_logger.info("Processing " + work); - - try { - final WorkType wt = work.getWorkType(); - Long nextTime = null; - if (wt == WorkType.Migration) { - nextTime = migrate(work); - } else if (wt == WorkType.HA) { - nextTime = restart(work); - } else if (wt == WorkType.Stop || wt == WorkType.CheckStop || wt == WorkType.ForceStop) { - nextTime = stopVM(work); - } else if (wt == WorkType.Destroy) { - nextTime = destroyVM(work); - } else { - assert false : "How did we get here with " + wt.toString(); - continue; - } - - if (nextTime == null) { - s_logger.info("Completed " + work); - work.setStep(Step.Done); - } else { - s_logger.info("Rescheduling " + work + " to try again at " + new Date(nextTime << 10)); - work.setTimeToTry(nextTime); - work.setServerId(null); - work.setDateTaken(null); - } - } catch (Exception e) { - s_logger.error("Terminating " + work, e); - work.setStep(Step.Error); - } - _haDao.update(work.getId(), work); - } catch (final Throwable th) { - s_logger.error("Caught this throwable, ", th); - } finally { - if (work != null) { - NDC.pop(); - } - } + s_logger.info("Starting work"); + while (!_stopped) { + _managedContext.runWithContext(new Runnable() { + @Override + public void run() { + runWithContext(); } - s_logger.info("Time to go home!"); - } finally { - ServerContexts.unregisterSystemContext(); + }); } + s_logger.info("Time to go home!"); + } + + private void runWithContext() { + HaWorkVO work = null; + try { + s_logger.trace("Checking the database"); + work = _haDao.take(_serverId); + if (work == null) { + try { + synchronized (this) { + wait(_timeToSleep); + } + return; + } catch (final InterruptedException e) { + s_logger.info("Interrupted"); + return; + } + } + + NDC.push("work-" + work.getId()); + s_logger.info("Processing " + work); + + try { + final WorkType wt = work.getWorkType(); + Long nextTime = null; + if (wt == WorkType.Migration) { + nextTime = migrate(work); + } else if (wt == WorkType.HA) { + nextTime = restart(work); + } else if (wt == WorkType.Stop || wt == WorkType.CheckStop || wt == WorkType.ForceStop) { + nextTime = stopVM(work); + } else if (wt == WorkType.Destroy) { + nextTime = destroyVM(work); + } else { + assert false : "How did we get here with " + wt.toString(); + return; + } + + if (nextTime == null) { + s_logger.info("Completed " + work); + work.setStep(Step.Done); + } else { + s_logger.info("Rescheduling " + work + " to try again at " + new Date(nextTime << 10)); + work.setTimeToTry(nextTime); + work.setServerId(null); + work.setDateTaken(null); + } + } catch (Exception e) { + s_logger.error("Terminating " + work, e); + work.setStep(Step.Error); + } + _haDao.update(work.getId(), work); + } catch (final Throwable th) { + s_logger.error("Caught this throwable, ", th); + } finally { + if (work != null) { + NDC.pop(); + } + } } public synchronized void wakup() { diff --git a/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java b/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java index f5c6eeca18d..00dd25c4a86 100644 --- a/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java +++ b/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java @@ -31,8 +31,8 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import com.cloud.agent.AgentManager; import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer; @@ -331,14 +331,14 @@ public class ExternalDeviceUsageManagerImpl extends ManagerBase implements Exter } } - protected class ExternalDeviceNetworkUsageTask implements Runnable { + protected class ExternalDeviceNetworkUsageTask extends ManagedContextRunnable { public ExternalDeviceNetworkUsageTask() { } @Override - public void run() { + protected void runInContext() { GlobalLock scanLock = GlobalLock.getInternLock("ExternalDeviceNetworkUsageManagerImpl"); try { if (scanLock.lock(20)) { diff --git a/server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java b/server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java index 1daa3f0dc1c..4794ee425ba 100644 --- a/server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java +++ b/server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java @@ -29,8 +29,8 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import com.cloud.configuration.Config; import com.cloud.exception.ResourceUnavailableException; @@ -87,9 +87,9 @@ public class LBHealthCheckManagerImpl extends ManagerBase implements LBHealthChe return this.name; } - protected class UpdateLBHealthCheck implements Runnable { + protected class UpdateLBHealthCheck extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { try { updateLBHealthCheck(Scheme.Public); updateLBHealthCheck(Scheme.Internal); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 043c376f558..5ea75604ebe 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -41,16 +41,15 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; - import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd; import org.apache.cloudstack.context.CallContext; -import org.apache.cloudstack.context.ServerContexts; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.utils.identity.ManagementServerNode; +import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; @@ -852,14 +851,13 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } - protected class NetworkUsageTask implements Runnable { + protected class NetworkUsageTask extends ManagedContextRunnable { public NetworkUsageTask() { } @Override - public void run() { - ServerContexts.registerSystemContext(); + protected void runInContext() { try{ final List routers = _routerDao.listByStateAndNetworkType(State.Running, GuestType.Isolated, mgmtSrvrId); s_logger.debug("Found " + routers.size() + " running routers. "); @@ -957,19 +955,17 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } } catch (Exception e) { s_logger.warn("Error while collecting network stats", e); - } finally { - ServerContexts.unregisterSystemContext(); } } } - protected class NetworkStatsUpdateTask implements Runnable { + protected class NetworkStatsUpdateTask extends ManagedContextRunnable { public NetworkStatsUpdateTask() { } @Override - public void run() { + protected void runInContext() { GlobalLock scanLock = GlobalLock.getInternLock("network.stats"); try { if(scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) { @@ -1201,7 +1197,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V return priority; } - protected class RvRStatusUpdateTask implements Runnable { + protected class RvRStatusUpdateTask extends ManagedContextRunnable { public RvRStatusUpdateTask() { } @@ -1280,60 +1276,54 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } @Override - public void run() { - ServerContexts.registerSystemContext(); - try { - while (true) { - try { - Long networkId = _vrUpdateQueue.take(); // This is a blocking call so this thread won't run all the time if no work item in queue. - List routers = _routerDao.listByNetworkAndRole(networkId, Role.VIRTUAL_ROUTER); - - if (routers.size() != 2) { - continue; - } - /* - * We update the router pair which the lower id router owned by this mgmt server, in order - * to prevent duplicate update of router status from cluster mgmt servers - */ - DomainRouterVO router0 = routers.get(0); - DomainRouterVO router1 = routers.get(1); - DomainRouterVO router = router0; - if ((router0.getId() < router1.getId()) && router0.getHostId() != null) { - router = router0; - } else { - router = router1; - } - if (router.getHostId() == null) { - s_logger.debug("Skip router pair (" + router0.getInstanceName() + "," + router1.getInstanceName() + ") due to can't find host"); - continue; - } - HostVO host = _hostDao.findById(router.getHostId()); - if (host == null || host.getManagementServerId() == null || - host.getManagementServerId() != ManagementServerNode.getManagementServerId()) { - s_logger.debug("Skip router pair (" + router0.getInstanceName() + "," + router1.getInstanceName() + ") due to not belong to this mgmt server"); - continue; - } - updateRoutersRedundantState(routers); - checkDuplicateMaster(routers); - checkSanity(routers); - } catch (Exception ex) { - s_logger.error("Fail to complete the RvRStatusUpdateTask! ", ex); - } + protected void runInContext() { + while (true) { + try { + Long networkId = _vrUpdateQueue.take(); // This is a blocking call so this thread won't run all the time if no work item in queue. + List routers = _routerDao.listByNetworkAndRole(networkId, Role.VIRTUAL_ROUTER); + + if (routers.size() != 2) { + continue; + } + /* + * We update the router pair which the lower id router owned by this mgmt server, in order + * to prevent duplicate update of router status from cluster mgmt servers + */ + DomainRouterVO router0 = routers.get(0); + DomainRouterVO router1 = routers.get(1); + DomainRouterVO router = router0; + if ((router0.getId() < router1.getId()) && router0.getHostId() != null) { + router = router0; + } else { + router = router1; + } + if (router.getHostId() == null) { + s_logger.debug("Skip router pair (" + router0.getInstanceName() + "," + router1.getInstanceName() + ") due to can't find host"); + continue; + } + HostVO host = _hostDao.findById(router.getHostId()); + if (host == null || host.getManagementServerId() == null || + host.getManagementServerId() != ManagementServerNode.getManagementServerId()) { + s_logger.debug("Skip router pair (" + router0.getInstanceName() + "," + router1.getInstanceName() + ") due to not belong to this mgmt server"); + continue; + } + updateRoutersRedundantState(routers); + checkDuplicateMaster(routers); + checkSanity(routers); + } catch (Exception ex) { + s_logger.error("Fail to complete the RvRStatusUpdateTask! ", ex); } - } finally { - ServerContexts.unregisterSystemContext(); } } } - protected class CheckRouterTask implements Runnable { + protected class CheckRouterTask extends ManagedContextRunnable { public CheckRouterTask() { } @Override - public void run() { - ServerContexts.registerSystemContext(); + protected void runInContext() { try { final List routers = _routerDao.listIsolatedByHostId(null); s_logger.debug("Found " + routers.size() + " routers to update status. "); @@ -1350,8 +1340,6 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } } catch (Exception ex) { s_logger.error("Fail to complete the CheckRouterTask! ", ex); - } finally { - ServerContexts.unregisterSystemContext(); } } } diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index 18ee0f1124f..8b2db9dde90 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -40,7 +40,6 @@ import javax.naming.ConfigurationException; import org.apache.commons.codec.digest.DigestUtils; import org.apache.log4j.Logger; - import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupEgressCmd; import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupIngressCmd; import org.apache.cloudstack.api.command.user.securitygroup.CreateSecurityGroupCmd; @@ -50,6 +49,7 @@ import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupI import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.utils.identity.ManagementServerNode; import com.cloud.agent.AgentManager; @@ -187,9 +187,9 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro } } - public class WorkerThread implements Runnable { + public class WorkerThread extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { try { Transaction txn = Transaction.open("SG Work"); try { @@ -210,9 +210,9 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro } } - public class CleanupThread implements Runnable { + public class CleanupThread extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { try { Transaction txn = Transaction.open("SG Cleanup"); try { diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java index a42881ec905..2fee7f312c8 100644 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java @@ -25,8 +25,10 @@ import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import javax.ejb.Local; +import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.managed.context.ManagedContext; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @@ -54,6 +56,9 @@ public class SecurityGroupManagerImpl2 extends SecurityGroupManagerImpl{ SecurityGroupWorkTracker _workTracker; SecurityManagerMBeanImpl _mBean; + @Inject + ManagedContext _managedContext; + WorkerThread[] _workers; private Set _disabledVms = Collections.newSetFromMap(new ConcurrentHashMap()); private boolean _schedulerDisabled = false; @@ -68,7 +73,12 @@ public class SecurityGroupManagerImpl2 extends SecurityGroupManagerImpl{ public void run() { while (true) { try{ - work(); + _managedContext.runWithContext(new Runnable() { + @Override + public void run() { + work(); + } + }); } catch (final Throwable th) { s_logger.error("SG Work: Caught this throwable, ", th); } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 73b3aea66a2..651e82c6d21 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -31,8 +31,6 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd; import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd; @@ -40,6 +38,8 @@ import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; +import org.apache.log4j.Logger; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; @@ -1932,9 +1932,9 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis } } - protected class VpcCleanupTask implements Runnable { + protected class VpcCleanupTask extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { try { GlobalLock lock = GlobalLock.getInternLock("VpcCleanup"); if (lock == null) { diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index edcdf3f1a2b..a385739f9aa 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -42,7 +42,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; - +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -83,7 +83,6 @@ import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; - import com.sun.mail.smtp.SMTPMessage; import com.sun.mail.smtp.SMTPSSLTransport; import com.sun.mail.smtp.SMTPTransport; @@ -1003,9 +1002,9 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { } } - public class ExpiredInvitationsCleanup implements Runnable { + public class ExpiredInvitationsCleanup extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { try { TimeZone.getDefault(); List invitationsToExpire = _projectInvitationDao.listInvitationsToExpire(_invitationTimeOut); diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 376e943393b..1f8713aae76 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -32,9 +32,9 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; - import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -939,13 +939,13 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim return _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type); } - protected class ResourceCountCheckTask implements Runnable { + protected class ResourceCountCheckTask extends ManagedContextRunnable { public ResourceCountCheckTask() { } @Override - public void run() { + protected void runInContext() { s_logger.info("Running resource count check periodic task"); List domains = _domainDao.findImmediateChildrenForParent(DomainVO.ROOT_DOMAIN); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 1c316103424..0a0fcdc08c3 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -432,6 +432,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.config.impl.ConfigurationVO; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; @@ -2862,9 +2863,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return cmdList; } - protected class EventPurgeTask implements Runnable { + protected class EventPurgeTask extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { try { GlobalLock lock = GlobalLock.getInternLock("EventPurge"); if (lock == null) { @@ -2896,9 +2897,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe } } - protected class AlertPurgeTask implements Runnable { + protected class AlertPurgeTask extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { try { GlobalLock lock = GlobalLock.getInternLock("AlertPurge"); if (lock == null) { diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index 5e110aa53d5..b4ec9155faf 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -37,6 +37,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; @@ -230,9 +231,9 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc } - class HostCollector implements Runnable { + class HostCollector extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { try { s_logger.debug("HostStatsCollector is running..."); @@ -273,9 +274,9 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc } } - class VmStatsCollector implements Runnable { + class VmStatsCollector extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { try { s_logger.debug("VmStatsCollector is running..."); @@ -350,9 +351,9 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc return _VmStats.get(id); } - class VmDiskStatsUpdaterTask implements Runnable { + class VmDiskStatsUpdaterTask extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { GlobalLock scanLock = GlobalLock.getInternLock("vm.disk.stats"); try { if(scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) { @@ -397,9 +398,9 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc } } - class VmDiskStatsTask implements Runnable { + class VmDiskStatsTask extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { // collect the vm disk statistics(total) from hypervisor. added by weizhou, 2013.03. Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { @@ -520,9 +521,9 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc } } - class StorageCollector implements Runnable { + class StorageCollector extends ManagedContextRunnable { @Override - public void run() { + protected void runInContext() { try { if (s_logger.isDebugEnabled()) { s_logger.debug("StorageCollector is running..."); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 415111d4c91..c046057db51 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -43,7 +43,6 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd; import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd; @@ -74,6 +73,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeAp import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; @@ -1243,13 +1243,13 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return (PrimaryDataStoreInfo) dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary); } - protected class StorageGarbageCollector implements Runnable { + protected class StorageGarbageCollector extends ManagedContextRunnable { public StorageGarbageCollector() { } @Override - public void run() { + protected void runInContext() { try { s_logger.trace("Storage Garbage Collection Thread is running."); diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index e5efcb2bbd7..91ae0ae786a 100755 --- a/server/src/com/cloud/storage/download/DownloadListener.java +++ b/server/src/com/cloud/storage/download/DownloadListener.java @@ -27,7 +27,6 @@ import javax.inject.Inject; import org.apache.log4j.Level; import org.apache.log4j.Logger; - import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; @@ -36,6 +35,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.managed.context.ManagedContextTimerTask; import org.apache.cloudstack.storage.command.DownloadCommand; import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; import org.apache.cloudstack.storage.command.DownloadProgressCommand; @@ -68,7 +68,7 @@ import com.cloud.utils.exception.CloudRuntimeException; public class DownloadListener implements Listener { - private static final class StatusTask extends TimerTask { + private static final class StatusTask extends ManagedContextTimerTask { private final DownloadListener dl; private final RequestType reqType; @@ -78,13 +78,13 @@ public class DownloadListener implements Listener { } @Override - public void run() { + protected void runInContext() { dl.sendCommand(reqType); } } - private static final class TimeoutTask extends TimerTask { + private static final class TimeoutTask extends ManagedContextTimerTask { private final DownloadListener dl; public TimeoutTask( DownloadListener dl) { @@ -92,7 +92,7 @@ public class DownloadListener implements Listener { } @Override - public void run() { + protected void runInContext() { dl.checkProgress(); } } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java index 52e20f02c08..1cddfa7d22d 100644 --- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java @@ -38,6 +38,8 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.framework.jobs.dao.AsyncJobDao; import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; +import org.apache.cloudstack.managed.context.ManagedContext; +import org.apache.cloudstack.managed.context.ManagedContextTimerTask; import com.cloud.api.ApiDispatcher; import com.cloud.api.ApiGsonHelper; @@ -371,17 +373,14 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu _testClockTimer.schedule(_testTimerTask, 100*1000L, 60*1000L); } else { - TimerTask timerTask = new TimerTask() { + TimerTask timerTask = new ManagedContextTimerTask() { @Override - public void run() { - ServerContexts.registerSystemContext(); + protected void runInContext() { try { Date currentTimestamp = new Date(); poll(currentTimestamp); } catch (Throwable t) { s_logger.warn("Catch throwable in snapshot scheduler ", t); - } finally { - ServerContexts.unregisterSystemContext(); } } }; diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/com/cloud/storage/upload/UploadListener.java index 09db421617f..add58774c28 100755 --- a/server/src/com/cloud/storage/upload/UploadListener.java +++ b/server/src/com/cloud/storage/upload/UploadListener.java @@ -27,7 +27,6 @@ import javax.inject.Inject; 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; @@ -38,6 +37,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.jobs.JobInfo; +import org.apache.cloudstack.managed.context.ManagedContextTimerTask; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; @@ -63,7 +63,7 @@ import com.cloud.utils.exception.CloudRuntimeException; public class UploadListener implements Listener { - private static final class StatusTask extends TimerTask { + private static final class StatusTask extends ManagedContextTimerTask { private final UploadListener ul; private final RequestType reqType; @@ -73,13 +73,13 @@ public class UploadListener implements Listener { } @Override - public void run() { + protected void runInContext() { ul.sendCommand(reqType); } } - private static final class TimeoutTask extends TimerTask { + private static final class TimeoutTask extends ManagedContextTimerTask { private final UploadListener ul; public TimeoutTask(UploadListener ul) { @@ -87,7 +87,7 @@ public class UploadListener implements Listener { } @Override - public void run() { + protected void runInContext() { ul.checkProgress(); } } diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 12378de870d..4eb4900e67d 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -34,13 +34,13 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.jobs.AsyncJobManager; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; @@ -441,13 +441,13 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { } - protected class StorageGarbageCollector implements Runnable { + protected class StorageGarbageCollector extends ManagedContextRunnable { public StorageGarbageCollector() { } @Override - public void run() { + protected void runInContext() { try { GlobalLock scanLock = GlobalLock.getInternLock("uploadmonitor.storageGC"); try { diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 5240102a879..c1ce89205ad 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -73,6 +73,7 @@ import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.jobs.AsyncJobManager; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.command.AttachCommand; import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.DettachCommand; @@ -488,9 +489,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, for (final StoragePoolVO pool : pools) { if (pool.getDataCenterId() == zoneId) { s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId()); - _preloadExecutor.execute(new Runnable() { + _preloadExecutor.execute(new ManagedContextRunnable() { @Override - public void run() { + protected void runInContext() { try { reallyRun(); } catch (Throwable e) { diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 396319af538..078ed34a190 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -53,6 +53,7 @@ import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.ServerContexts; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleDao; import com.cloud.api.ApiDBUtils; @@ -1492,18 +1493,10 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M return _userDao.remove(id); } - public class ResourceCountCalculateTask implements Runnable { + protected class AccountCleanupTask extends ManagedContextRunnable { @Override - public void run() { - - } - } - - protected class AccountCleanupTask implements Runnable { - @Override - public void run() { + protected void runInContext() { try { - ServerContexts.registerSystemContext(); GlobalLock lock = GlobalLock.getInternLock("AccountCleanup"); if (lock == null) { s_logger.debug("Couldn't get the global lock"); @@ -1585,7 +1578,6 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M s_logger.error("Exception ", e); } finally { lock.unlock(); - ServerContexts.unregisterSystemContext(); } } catch (Exception e) { s_logger.error("Exception ", e); diff --git a/server/src/com/cloud/vm/SystemVmLoadScanner.java b/server/src/com/cloud/vm/SystemVmLoadScanner.java index 3932c3b9641..6e5521632c2 100644 --- a/server/src/com/cloud/vm/SystemVmLoadScanner.java +++ b/server/src/com/cloud/vm/SystemVmLoadScanner.java @@ -21,8 +21,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; - -import org.apache.cloudstack.context.ServerContexts; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import com.cloud.utils.Pair; import com.cloud.utils.concurrency.NamedThreadFactory; @@ -64,17 +63,14 @@ public class SystemVmLoadScanner { } private Runnable getCapacityScanTask() { - return new Runnable() { + return new ManagedContextRunnable() { @Override - public void run() { - ServerContexts.registerSystemContext(); + protected void runInContext() { try { reallyRun(); } catch (Throwable e) { s_logger.warn("Unexpected exception " + e.getMessage(), e); - } finally { - ServerContexts.unregisterSystemContext(); } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 9b694e15056..aa2d98b2398 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -72,6 +72,7 @@ import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.jobs.AsyncJobManager; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.to.TemplateObjectTO; @@ -1708,13 +1709,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } - protected class ExpungeTask implements Runnable { + protected class ExpungeTask extends ManagedContextRunnable { public ExpungeTask() { } @Override - public void run() { - ServerContexts.registerSystemContext(); + protected void runInContext() { GlobalLock scanLock = GlobalLock.getInternLock("UserVMExpunge"); try { if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) { @@ -1748,7 +1748,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } finally { scanLock.releaseRef(); - ServerContexts.unregisterSystemContext(); } } diff --git a/usage/src/com/cloud/usage/UsageManagerImpl.java b/usage/src/com/cloud/usage/UsageManagerImpl.java index 90ce4db7635..d2a7cc0609d 100644 --- a/usage/src/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/com/cloud/usage/UsageManagerImpl.java @@ -35,10 +35,9 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; - import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.managed.context.ManagedContext; import org.apache.cloudstack.usage.UsageTypes; - import org.springframework.stereotype.Component; import com.cloud.alert.AlertManager; @@ -120,6 +119,7 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna @Inject protected UsageEventDao _usageEventDao; @Inject ConfigurationDao _configDao; @Inject private UsageVMSnapshotDao m_usageVMSnapshotDao; + @Inject ManagedContext _managedContext; private String m_version = null; private final Calendar m_jobExecTime = Calendar.getInstance(); @@ -279,7 +279,17 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna return true; } + @Override public void run() { + _managedContext.runWithContext(new Runnable() { + @Override + public void run() { + runInContext(); + } + }); + } + + protected void runInContext() { if (s_logger.isInfoEnabled()) { s_logger.info("starting usage job..."); } diff --git a/usage/src/com/cloud/usage/parser/UsageParser.java b/usage/src/com/cloud/usage/parser/UsageParser.java index 410e876fd1c..80437d579a0 100644 --- a/usage/src/com/cloud/usage/parser/UsageParser.java +++ b/usage/src/com/cloud/usage/parser/UsageParser.java @@ -18,12 +18,13 @@ package com.cloud.usage.parser; import java.util.Date; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.log4j.Logger; -public abstract class UsageParser implements Runnable { +public abstract class UsageParser extends ManagedContextRunnable { public static final Logger s_logger = Logger.getLogger(UsageParser.class.getName()); - public void run() { + protected void runInContext() { try { parse(null); } catch (Exception e) { diff --git a/utils/pom.xml b/utils/pom.xml index 09c960258a6..3eea8fef3ed 100644 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -26,15 +26,32 @@ 4.3.0-SNAPSHOT ../pom.xml - + + + org.apache.cloudstack + cloud-framework-managed-context + ${project.version} + org.springframework spring-context + + org.aspectj + aspectjweaver + log4j log4j + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-log4j12 + cglib cglib-nodep