Add Manage Context framework

The managed context framework provides a simple way to add logic
to ACS at the various entry points of the system.  As threads are
launched and ran listeners can be registered for onEntry or onLeave
of the managed context.  This framework will be used specifically
to handle DB transaction checking and setting up the CallContext.
This framework is need to transition away from ACS custom AOP to
Spring AOP.
This commit is contained in:
Darren Shepherd 2013-10-02 09:51:58 -07:00
parent a2bf7f035e
commit aed5e9dc2a
73 changed files with 1340 additions and 439 deletions

View File

@ -26,7 +26,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
@ -36,6 +35,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
import org.apache.log4j.Logger;
import com.cloud.agent.api.AgentControlAnswer;
@ -731,7 +731,7 @@ public class Agent implements HandlerFactory, IAgentControl {
}
}
public class WatchTask extends TimerTask {
public class WatchTask extends ManagedContextTimerTask {
protected Request _request;
protected Agent _agent;
protected Link _link;
@ -744,7 +744,7 @@ public class Agent implements HandlerFactory, IAgentControl {
}
@Override
public void run() {
protected void runInContext() {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Scheduling " + (_request instanceof Response ? "Ping" : "Watch Task"));
}
@ -760,7 +760,7 @@ public class Agent implements HandlerFactory, IAgentControl {
}
}
public class StartupTask extends TimerTask {
public class StartupTask extends ManagedContextTimerTask {
protected Link _link;
protected volatile boolean cancelled = false;
@ -782,7 +782,7 @@ public class Agent implements HandlerFactory, IAgentControl {
}
@Override
public synchronized void run() {
protected synchronized void runInContext() {
if (!cancelled) {
if (s_logger.isInfoEnabled()) {
s_logger.info("The startup command is now cancelled");

View File

@ -32,6 +32,7 @@ import java.util.Properties;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.log4j.Logger;
import com.cloud.agent.Agent.ExitStatus;
@ -357,8 +358,9 @@ public class ConsoleProxyResource extends ServerResourceBase implements
private void launchConsoleProxy(final byte[] ksBits, final String ksPassword, final String encryptorPassword) {
final Object resource = this;
if (_consoleProxyMain == null) {
_consoleProxyMain = new Thread(new Runnable() {
public void run() {
_consoleProxyMain = new Thread(new ManagedContextRunnable() {
@Override
protected void runInContext() {
try {
Class<?> consoleProxyClazz = Class.forName("com.cloud.consoleproxy.ConsoleProxy");
try {

View File

@ -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<CallContext> s_currentContext = new ThreadLocal<CallContext>();
private static ManagedThreadLocal<CallContext> s_currentContext = new ManagedThreadLocal<CallContext>();
private static ManagedThreadLocal<Stack<CallContext>> s_currentContextStack =
new ManagedThreadLocal<Stack<CallContext>>() {
@Override
protected Stack<CallContext> initialValue() {
return new Stack<CallContext>();
}
};
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<CallContext> stack = s_currentContextStack.get();
stack.pop();
if ( ! stack.isEmpty() ) {
s_currentContext.set(stack.peek());
}
return context;
}

View File

@ -0,0 +1,53 @@
/*
* 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 javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.apache.cloudstack.managed.context.ManagedContextListener;
import com.cloud.utils.db.EntityManager;
public class CallContextListener implements ManagedContextListener<Object> {
@Inject
EntityManager entityMgr;
@Override
public Object onEnterContext(boolean reentry) {
if ( ! reentry ) {
CallContext.registerSystemCallContextOnceOnly();
}
return null;
}
@Override
public void onLeaveContext(Object unused, boolean reentry) {
if ( ! reentry ) {
CallContext.unregisterAll();
}
}
@PostConstruct
public void init() {
CallContext.init(entityMgr);
}
}

View File

@ -35,6 +35,7 @@ import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.apache.axis2.AxisFault;
import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.springframework.stereotype.Component;
@ -280,10 +281,9 @@ public class ServiceProvider extends ManagerBase {
}
private TimerTask getHeartbeatTask() {
return new TimerTask() {
return new ManagedContextTimerTask() {
@Override
public void run() {
protected void runInContext() {
try {
mhost.setLastHeartbeatTime(DateHelper.currentGMTTime());
mhostDao.updateHeartBeat(mhost);

View File

@ -52,6 +52,22 @@
</property>
</bean>
<!--
Managed Context
-->
<bean id="ManagedContext" class="org.apache.cloudstack.managed.context.impl.DefaultManagedContext" >
<property name="listeners">
<list>
<bean class="org.apache.cloudstack.context.CallContextListener" />
</list>
</property>
</bean>
<bean class="org.apache.cloudstack.managed.context.ManagedContextRunnable" factory-method="initializeGlobalContext"
autowire-candidate="false" >
<constructor-arg><ref bean="ManagedContext"/></constructor-arg>
</bean>
<!--
RPC/Async/EventBus
-->

View File

@ -40,7 +40,7 @@ import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.log4j.Logger;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
import com.cloud.agent.api.storage.Proxy;
@ -52,7 +52,7 @@ import com.cloud.utils.UriUtils;
* Download a template file using HTTP
*
*/
public class HttpTemplateDownloader implements TemplateDownloader {
public class HttpTemplateDownloader extends ManagedContextRunnable implements TemplateDownloader {
public static final Logger s_logger = Logger.getLogger(HttpTemplateDownloader.class.getName());
private static final MultiThreadedHttpConnectionManager s_httpClientManager = new MultiThreadedHttpConnectionManager();
@ -350,7 +350,7 @@ public class HttpTemplateDownloader implements TemplateDownloader {
}
@Override
public void run() {
protected void runInContext() {
try {
download(resume, completionCallback);
} catch (Throwable t) {

View File

@ -50,6 +50,7 @@ import com.amazonaws.services.s3.model.StorageClass;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.Upload;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
import com.cloud.agent.api.storage.Proxy;
@ -62,7 +63,7 @@ import com.cloud.utils.UriUtils;
* Download a template file using HTTP
*
*/
public class S3TemplateDownloader implements TemplateDownloader {
public class S3TemplateDownloader extends ManagedContextRunnable implements TemplateDownloader {
public static final Logger s_logger = Logger.getLogger(S3TemplateDownloader.class.getName());
private static final MultiThreadedHttpConnectionManager s_httpClientManager = new MultiThreadedHttpConnectionManager();
@ -361,7 +362,7 @@ public class S3TemplateDownloader implements TemplateDownloader {
}
@Override
public void run() {
protected void runInContext() {
try {
download(resume, completionCallback);
} catch (Throwable t) {

View File

@ -18,11 +18,12 @@ package com.cloud.storage.template;
import java.io.File;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.log4j.Logger;
import com.cloud.storage.StorageLayer;
public abstract class TemplateDownloaderBase implements TemplateDownloader {
public abstract class TemplateDownloaderBase extends ManagedContextRunnable implements TemplateDownloader {
private static final Logger s_logger = Logger.getLogger(TemplateDownloaderBase.class);
protected String _downloadUrl;
@ -123,7 +124,7 @@ public abstract class TemplateDownloaderBase implements TemplateDownloader {
}
@Override
public void run() {
protected void runInContext() {
try {
download(_resume, _callback);
} catch (Exception e) {

View File

@ -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);
}
}

View File

@ -31,6 +31,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.log4j.Logger;
import com.cloud.agent.Listener;
@ -497,14 +498,14 @@ public abstract class AgentAttache {
*/
protected abstract boolean isClosed();
protected class Alarm implements Runnable {
protected class Alarm extends ManagedContextRunnable {
long _seq;
public Alarm(long seq) {
_seq = seq;
}
@Override
public void run() {
protected void runInContext() {
try {
Listener listener = unregisterListener(_seq);
if (listener != null) {

View File

@ -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 {
ServerResource resource;
Map<String, String> 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 {
Link _link;
Command[] _cmds;
Request _request;
@ -1071,10 +1067,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
_request = request;
}
@Override
public void run() {
ServerContexts.registerSystemContext();
try {
protected void runInContext() {
_request.logD("Processing the first command ");
StartupCommand[] startups = new StartupCommand[_cmds.length];
for (int i = 0; i < _cmds.length; i++) {
@ -1085,9 +1078,6 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
if (attache == null) {
s_logger.warn("Unable to create attache for agent: " + _request);
}
} finally {
ServerContexts.unregisterSystemContext();
}
}
}
@ -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 {

View File

@ -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);

View File

@ -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;

View File

@ -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");

View File

@ -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();
}
}

View File

@ -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");

View File

@ -21,24 +21,23 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.cloud.configuration.Config;
import com.cloud.utils.component.ComponentContext;
import javax.inject.Inject;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.framework.config.dao.ConfigurationDaoImpl;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.storage.command.CopyCommand;
import org.apache.cloudstack.storage.command.DownloadCommand;
import org.apache.cloudstack.storage.resource.LocalNfsSecondaryStorageResource;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.configuration.Config;
import com.cloud.resource.ServerResource;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.net.NetUtils;
import javax.inject.Inject;
public class LocalHostEndpoint implements EndPoint {
private ScheduledExecutorService executor;
protected ServerResource resource;
@ -97,7 +96,7 @@ public class LocalHostEndpoint implements EndPoint {
return new Answer(cmd, false, "unsupported command:" + cmd.toString());
}
private class CmdRunner implements Runnable {
private class CmdRunner extends ManagedContextRunnable {
final Command cmd;
final AsyncCompletionCallback<Answer> callback;
@ -107,7 +106,7 @@ public class LocalHostEndpoint implements EndPoint {
}
@Override
public void run() {
protected void runInContext() {
Answer answer = sendMessage(cmd);
callback.complete(answer);
}

View File

@ -26,6 +26,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@ -104,7 +105,7 @@ public class RemoteHostEndPoint implements EndPoint {
throw new CloudRuntimeException("Failed to send command, due to Agent:" + getId() + ", " + errMsg);
}
private class CmdRunner implements Listener, Runnable {
private class CmdRunner extends ManagedContextRunnable implements Listener {
final AsyncCompletionCallback<Answer> callback;
Answer answer;
@ -162,7 +163,7 @@ public class RemoteHostEndPoint implements EndPoint {
}
@Override
public void run() {
protected void runInContext() {
callback.complete(answer);
}
}

View File

@ -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;
@ -217,18 +218,18 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C
}
private Runnable getClusterPduSendingTask() {
return new Runnable() {
return new ManagedContextRunnable() {
@Override
public void run() {
protected void runInContext() {
onSendingClusterPdu();
}
};
}
private Runnable getClusterPduNotificationTask() {
return new Runnable() {
return new ManagedContextRunnable() {
@Override
public void run() {
protected void runInContext() {
onNotifyingClusterPdu();
}
};
@ -289,9 +290,9 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C
if(pdu == null)
continue;
_executor.execute(new Runnable() {
_executor.execute(new ManagedContextRunnable() {
@Override
public void run() {
protected void runInContext() {
if(pdu.getPduType() == ClusterServicePdu.PDU_TYPE_RESPONSE) {
ClusterServiceRequestPdu requestPdu = popRequestPdu(pdu.getAckSequenceId());
if(requestPdu != null) {
@ -528,9 +529,9 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C
}
private Runnable getHeartbeatTask() {
return new Runnable() {
return new ManagedContextRunnable() {
@Override
public void run() {
protected void runInContext() {
Transaction txn = Transaction.open("ClusterHeartbeat");
try {
Profiler profiler = new Profiler();
@ -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 {

View File

@ -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()) {

View File

@ -30,6 +30,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import javax.management.StandardMBean;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.log4j.Logger;
import com.cloud.utils.concurrency.NamedThreadFactory;
@ -198,10 +199,9 @@ public class ConnectionConcierge {
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ConnectionConcierge"));
_executor.scheduleAtFixedRate(new Runnable() {
_executor.scheduleAtFixedRate(new ManagedContextRunnable() {
@Override
public void run() {
protected void runInContext() {
s_logger.trace("connection concierge keep alive task");
for (Map.Entry<String, ConnectionConcierge> entry : _conns.entrySet()) {
ConnectionConcierge concierge = entry.getValue();

View File

@ -27,6 +27,7 @@ import org.apache.cloudstack.framework.serializer.MessageSerializer;
import org.apache.cloudstack.framework.transport.TransportEndpoint;
import org.apache.cloudstack.framework.transport.TransportEndpointSite;
import org.apache.cloudstack.framework.transport.TransportProvider;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import com.cloud.utils.concurrency.NamedThreadFactory;
@ -62,10 +63,9 @@ public class ClientTransportProvider implements TransportProvider {
_executor = Executors.newFixedThreadPool(_poolSize, new NamedThreadFactory("Transport-Worker"));
_connection = new ClientTransportConnection(this);
_executor.execute(new Runnable() {
_executor.execute(new ManagedContextRunnable() {
@Override
public void run() {
protected void runInContext() {
try {
_connection.connect(_serverAddress, _serverPort);
} catch(Throwable e) {

View File

@ -31,6 +31,7 @@ import org.apache.cloudstack.framework.transport.TransportEndpoint;
import org.apache.cloudstack.framework.transport.TransportEndpointSite;
import org.apache.cloudstack.framework.transport.TransportPdu;
import org.apache.cloudstack.framework.transport.TransportProvider;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.log4j.Logger;
import com.cloud.utils.concurrency.NamedThreadFactory;
@ -132,10 +133,9 @@ public class ServerTransportProvider implements TransportProvider {
@Override
public void requestSiteOutput(final TransportEndpointSite site) {
_executor.execute(new Runnable() {
_executor.execute(new ManagedContextRunnable() {
@Override
public void run() {
protected void runInContext() {
try {
site.processOutput();
site.ackOutputProcessSignal();

View File

@ -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<AsyncJobExecutionContext> s_currentExectionContext = new ThreadLocal<AsyncJobExecutionContext>();
private static ManagedThreadLocal<AsyncJobExecutionContext> s_currentExectionContext = new ManagedThreadLocal<AsyncJobExecutionContext>();
public AsyncJobExecutionContext() {
}

View File

@ -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;
@ -490,9 +490,9 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
}
private Runnable getExecutorRunnable(final AsyncJob job) {
return new Runnable() {
return new ManagedContextRunnable() {
@Override
public void run() {
protected void runInContext() {
Transaction txn = null;
long runNumber = getJobRunNumber();
@ -687,9 +687,9 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
}
private Runnable getHeartbeatTask() {
return new Runnable() {
return new ManagedContextRunnable() {
@Override
public void run() {
protected void runInContext() {
Transaction txn = Transaction.open("AsyncJobManagerImpl.getHeartbeatTask");
try {
List<SyncQueueItemVO> l = _queueMgr.dequeueFromAny(getMsid(), MAX_ONETIME_SCHEDULE_SIZE);
@ -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)) {

View File

@ -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();
}

View File

@ -0,0 +1,36 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-framework-managed-context</artifactId>
<name>Apache CloudStack Framework - Managed Context</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-maven-standard</artifactId>
<version>4.3.0-SNAPSHOT</version>
<relativePath>../../maven-standard/pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,32 @@
/*
* 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.managed.context;
public class AbstractManagedContextListener<T> implements ManagedContextListener<T> {
@Override
public T onEnterContext(boolean reentry) {
return null;
}
@Override
public void onLeaveContext(T data, boolean reentry) {
}
}

View File

@ -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.managed.context;
import java.util.concurrent.Callable;
public interface ManagedContext {
public void registerListener(ManagedContextListener<?> listener);
public void unregisterListener(ManagedContextListener<?> listener);
public void runWithContext(Runnable run);
public <T> T callWithContext(Callable<T> callable) throws Exception;
}

View File

@ -0,0 +1,36 @@
/*
* 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.managed.context;
public interface ManagedContextListener<T> {
/**
* @param reentry True if listener is being invoked in a nested context
* @return
*/
public T onEnterContext(boolean reentry);
/**
* @param data The data returned from the onEnterContext call
* @param reentry True if listener is being invoked in a nested context
*/
public void onLeaveContext(T data, boolean reentry);
}

View File

@ -0,0 +1,86 @@
/*
* 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.managed.context;
import org.apache.cloudstack.managed.context.impl.DefaultManagedContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class ManagedContextRunnable implements Runnable {
private static final int SLEEP_COUNT = 120;
private static final Logger log = LoggerFactory.getLogger(ManagedContextRunnable.class);
private static final ManagedContext DEFAULT_MANAGED_CONTEXT = new DefaultManagedContext();
private static ManagedContext context;
private static boolean managedContext = false;
/* This is slightly dirty, but the idea is that we only save the ManagedContext
* in a static global. Any ManagedContextListener can be a fully managed object
* and not have to rely on global statics
*/
public static ManagedContext initializeGlobalContext(ManagedContext context) {
setManagedContext(true);
return ManagedContextRunnable.context = context;
}
@Override
final public void run() {
getContext().runWithContext(new Runnable() {
@Override
public void run() {
runInContext();
}
});
}
protected abstract void runInContext();
protected ManagedContext getContext() {
if ( ! managedContext )
return DEFAULT_MANAGED_CONTEXT;
for ( int i = 0 ; i < SLEEP_COUNT ; i++ ) {
if ( context == null ) {
try {
Thread.sleep(1000);
if ( context == null )
log.info("Sleeping until ManagedContext becomes available");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} else {
return context;
}
}
throw new RuntimeException("Failed to obtain ManagedContext");
}
public static boolean isManagedContext() {
return managedContext;
}
public static void setManagedContext(boolean managedContext) {
ManagedContextRunnable.managedContext = managedContext;
}
}

View File

@ -0,0 +1,37 @@
/*
* 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.managed.context;
import java.util.TimerTask;
public abstract class ManagedContextTimerTask extends TimerTask {
@Override
public final void run() {
new ManagedContextRunnable() {
@Override
protected void runInContext() {
ManagedContextTimerTask.this.runInContext();
}
}.run();
}
protected abstract void runInContext();
}

View File

@ -0,0 +1,55 @@
/*
* 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.managed.context;
public class ManagedContextUtils {
private static final ThreadLocal<Object> OWNER = new ThreadLocal<Object>();
public static boolean setAndCheckOwner(Object owner) {
if ( OWNER.get() == null ) {
OWNER.set(owner);
return true;
}
return false;
}
public static boolean clearOwner(Object owner) {
if ( OWNER.get() == owner ) {
OWNER.remove();
return true;
}
return false;
}
public static boolean isInContext() {
return OWNER.get() != null;
}
public static void rethrowException(Throwable t) {
if ( t instanceof RuntimeException ) {
throw (RuntimeException)t;
} else if ( t instanceof Error ) {
throw (Error)t;
}
}
}

View File

@ -0,0 +1,155 @@
/*
* 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.managed.context.impl;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.cloudstack.managed.context.ManagedContext;
import org.apache.cloudstack.managed.context.ManagedContextListener;
import org.apache.cloudstack.managed.context.ManagedContextUtils;
import org.apache.cloudstack.managed.threadlocal.ManagedThreadLocal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DefaultManagedContext implements ManagedContext {
private static final Logger log = LoggerFactory.getLogger(DefaultManagedContext.class);
List<ManagedContextListener<?>> listeners =
new CopyOnWriteArrayList<ManagedContextListener<?>>();
@Override
public void registerListener(ManagedContextListener<?> listener) {
listeners.add(listener);
}
@Override
public void unregisterListener(ManagedContextListener<?> listener) {
listeners.remove(listener);
}
@Override
public void runWithContext(final Runnable run) {
try {
callWithContext(new Callable<Object>() {
@Override
public Object call() throws Exception {
run.run();
return null;
}
});
} catch (Exception e) {
/* Only care about non-checked exceptions
* as the nature of runnable prevents checked
* exceptions from happening
*/
ManagedContextUtils.rethrowException(e);
}
}
@SuppressWarnings("unchecked")
@Override
public <T> T callWithContext(Callable<T> callable) throws Exception {
Object owner = new Object();
Stack<ListenerInvocation> invocations = new Stack<ListenerInvocation>();
boolean reentry = ! ManagedContextUtils.setAndCheckOwner(owner);
Throwable firstError = null;
try {
for ( ManagedContextListener<?> listener : listeners ) {
Object data = null;
try {
data = listener.onEnterContext(reentry);
} catch ( Throwable t ) {
/* If one listener fails, still call all other listeners
* and then we will call onLeaveContext for all
*/
if ( firstError == null ) {
firstError = t;
}
log.error("Failed onEnterContext for listener [{}]", listener, t);
}
/* Stack data structure is used because in between onEnter and onLeave
* the listeners list could have changed
*/
invocations.push(new ListenerInvocation((ManagedContextListener<Object>) listener, data));
}
try {
if ( firstError == null ) {
/* Only call if all the listeners didn't blow up on onEnterContext */
return callable.call();
} else {
throwException(firstError);
return null;
}
} finally {
Throwable lastError = null;
while ( ! invocations.isEmpty() ) {
ListenerInvocation invocation = invocations.pop();
try {
invocation.listener.onLeaveContext(invocation.data, reentry);
} catch ( Throwable t ) {
lastError = t;
log.error("Failed onLeaveContext for listener [{}]", invocation.listener, t);
}
}
if ( firstError == null && lastError != null ) {
throwException(lastError);
}
}
} finally {
if ( ManagedContextUtils.clearOwner(owner) )
ManagedThreadLocal.reset();
}
};
protected void throwException(Throwable t) throws Exception {
ManagedContextUtils.rethrowException(t);
if ( t instanceof Exception ) {
throw (Exception)t;
}
}
public List<ManagedContextListener<?>> getListeners() {
return listeners;
}
public void setListeners(List<ManagedContextListener<?>> listeners) {
this.listeners = new CopyOnWriteArrayList<ManagedContextListener<?>>(listeners);
}
private static class ListenerInvocation {
ManagedContextListener<Object> listener;
Object data;
public ListenerInvocation(ManagedContextListener<Object> listener, Object data) {
super();
this.listener = listener;
this.data = data;
}
}
}

View File

@ -0,0 +1,82 @@
/*
* 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.managed.threadlocal;
import java.util.HashMap;
import java.util.Map;
import org.apache.cloudstack.managed.context.ManagedContextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ManagedThreadLocal<T> extends ThreadLocal<T> {
private static final ThreadLocal<Map<Object,Object>> MANAGED_THREAD_LOCAL = new ThreadLocal<Map<Object,Object>>() {
@Override
protected Map<Object, Object> initialValue() {
return new HashMap<Object, Object>();
}
};
private static boolean VALIDATE_CONTEXT = false;
private static final Logger log = LoggerFactory.getLogger(ManagedThreadLocal.class);
@SuppressWarnings("unchecked")
@Override
public T get() {
validateInContext(this);
Map<Object,Object> map = MANAGED_THREAD_LOCAL.get();
Object result = map.get(this);
if ( result == null ) {
result = initialValue();
map.put(this, result);
}
return (T) result;
}
@Override
public void set(T value) {
validateInContext(this);
Map<Object,Object> map = MANAGED_THREAD_LOCAL.get();
map.put(this, value);
}
public static void reset() {
validateInContext(null);
MANAGED_THREAD_LOCAL.remove();
}
@Override
public void remove() {
Map<Object,Object> map = MANAGED_THREAD_LOCAL.get();
map.remove(this);
}
private static void validateInContext(Object tl) {
if ( VALIDATE_CONTEXT && ! ManagedContextUtils.isInContext() ) {
String msg = "Using a managed thread local in a non managed context this WILL cause errors at runtime. TL ["
+ tl + "]";
log.error(msg, new IllegalStateException(msg));
}
}
public static void setValidateInContext(boolean validate) {
VALIDATE_CONTEXT = validate;
}
}

View File

@ -0,0 +1,269 @@
/*
* 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.managed.context.impl;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import org.apache.cloudstack.managed.context.ManagedContextListener;
import org.apache.cloudstack.managed.threadlocal.ManagedThreadLocal;
import org.junit.Before;
import org.junit.Test;
public class DefaultManagedContextTest {
DefaultManagedContext context;
@Before
public void init() {
ManagedThreadLocal.setValidateInContext(false);
context = new DefaultManagedContext();
}
@Test
public void testCallable() throws Exception {
assertEquals(5, context.callWithContext(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 5;
}
}).intValue());
}
@Test
public void testRunnable() throws Exception {
final List<Object> touch = new ArrayList<Object>();
context.runWithContext(new Runnable() {
@Override
public void run() {
touch.add(new Object());
}
});
assertEquals(1, touch.size());
}
@Test
public void testGoodListeners() throws Exception {
final List<Object> touch = new ArrayList<Object>();
context.registerListener(new ManagedContextListener<Object>() {
@Override
public Object onEnterContext(boolean reentry) {
touch.add("enter");
return "hi";
}
@Override
public void onLeaveContext(Object data, boolean reentry) {
touch.add("leave");
assertEquals("hi", data);
}
});
context.registerListener(new ManagedContextListener<Object>() {
@Override
public Object onEnterContext(boolean reentry) {
touch.add("enter1");
return "hi";
}
@Override
public void onLeaveContext(Object data, boolean reentry) {
touch.add("leave1");
assertEquals("hi", data);
}
});
assertEquals(5, context.callWithContext(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 5;
}
}).intValue());
assertEquals("enter", touch.get(0));
assertEquals("enter1", touch.get(1));
assertEquals("leave1", touch.get(2));
assertEquals("leave", touch.get(3));
}
@Test
public void testBadListeners() throws Exception {
final List<Object> touch = new ArrayList<Object>();
context.registerListener(new ManagedContextListener<Object>() {
@Override
public Object onEnterContext(boolean reentry) {
touch.add("enter");
throw new RuntimeException("I'm a failure");
}
@Override
public void onLeaveContext(Object data, boolean reentry) {
touch.add("leave");
assertNull(data);
}
});
context.registerListener(new ManagedContextListener<Object>() {
@Override
public Object onEnterContext(boolean reentry) {
touch.add("enter1");
return "hi";
}
@Override
public void onLeaveContext(Object data, boolean reentry) {
touch.add("leave1");
assertEquals("hi", data);
}
});
try {
context.callWithContext(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 5;
}
}).intValue();
fail();
} catch ( Throwable t ) {
assertTrue(t instanceof RuntimeException);
assertEquals("I'm a failure", t.getMessage());
}
assertEquals("enter", touch.get(0));
assertEquals("enter1", touch.get(1));
assertEquals("leave1", touch.get(2));
assertEquals("leave", touch.get(3));
}
@Test
public void testBadInvocation() throws Exception {
final List<Object> touch = new ArrayList<Object>();
context.registerListener(new ManagedContextListener<Object>() {
@Override
public Object onEnterContext(boolean reentry) {
touch.add("enter");
return "hi";
}
@Override
public void onLeaveContext(Object data, boolean reentry) {
touch.add("leave");
assertEquals("hi", data);
}
});
context.registerListener(new ManagedContextListener<Object>() {
@Override
public Object onEnterContext(boolean reentry) {
touch.add("enter1");
return "hi1";
}
@Override
public void onLeaveContext(Object data, boolean reentry) {
touch.add("leave1");
assertEquals("hi1", data);
}
});
try {
context.callWithContext(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
throw new RuntimeException("I'm a failure");
}
}).intValue();
fail();
} catch ( Throwable t ) {
assertTrue(t.getMessage(), t instanceof RuntimeException);
assertEquals("I'm a failure", t.getMessage());
}
assertEquals("enter", touch.get(0));
assertEquals("enter1", touch.get(1));
assertEquals("leave1", touch.get(2));
assertEquals("leave", touch.get(3));
}
@Test
public void testBadListernInExit() throws Exception {
final List<Object> touch = new ArrayList<Object>();
context.registerListener(new ManagedContextListener<Object>() {
@Override
public Object onEnterContext(boolean reentry) {
touch.add("enter");
return "hi";
}
@Override
public void onLeaveContext(Object data, boolean reentry) {
touch.add("leave");
assertEquals("hi", data);
throw new RuntimeException("I'm a failure");
}
});
context.registerListener(new ManagedContextListener<Object>() {
@Override
public Object onEnterContext(boolean reentry) {
touch.add("enter1");
return "hi1";
}
@Override
public void onLeaveContext(Object data, boolean reentry) {
touch.add("leave1");
assertEquals("hi1", data);
}
});
try {
context.callWithContext(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 5;
}
}).intValue();
fail();
} catch ( Throwable t ) {
assertTrue(t.getMessage(), t instanceof RuntimeException);
assertEquals("I'm a failure", t.getMessage());
}
assertEquals("enter", touch.get(0));
assertEquals("enter1", touch.get(1));
assertEquals("leave1", touch.get(2));
assertEquals("leave", touch.get(3));
}
}

View File

@ -37,5 +37,6 @@
<module>cluster</module>
<module>db</module>
<module>config</module>
<module>managed-context</module>
</modules>
</project>

View File

@ -20,7 +20,9 @@
package org.apache.cloudstack.mom.rabbitmq;
import com.rabbitmq.client.*;
import org.apache.cloudstack.framework.events.*;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.log4j.Logger;
import com.cloud.utils.Ternary;
@ -28,6 +30,7 @@ import com.cloud.utils.component.ManagerBase;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import java.io.IOException;
import java.net.ConnectException;
import java.util.Map;
@ -493,12 +496,13 @@ public class RabbitMQEventBus extends ManagerBase implements EventBus {
}
// retry logic to connect back to AMQP server after loss of connection
private class ReconnectionTask implements Runnable {
private class ReconnectionTask extends ManagedContextRunnable {
boolean connected = false;
Connection connection = null;
public void run() {
@Override
protected void runInContext() {
while (!connected) {
try {

View File

@ -20,7 +20,10 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.log4j.Logger;
import com.cloud.utils.script.Script;
import org.libvirt.Connect;
@ -68,10 +71,10 @@ public class KVMHAMonitor extends KVMHABase implements Runnable {
}
}
private class Monitor implements Runnable {
private class Monitor extends ManagedContextRunnable {
@Override
public void run() {
protected void runInContext() {
synchronized (_storagePool) {
for (String uuid : _storagePool.keySet()) {
NfsStoragePool primaryStoragePool = _storagePool.get(uuid);

View File

@ -31,7 +31,6 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.AddUcsManagerCmd;
import org.apache.cloudstack.api.AssociateUcsProfileToBladeCmd;
import org.apache.cloudstack.api.DeleteUcsManagerCmd;
@ -43,6 +42,7 @@ import org.apache.cloudstack.api.response.UcsBladeResponse;
import org.apache.cloudstack.api.response.UcsManagerResponse;
import org.apache.cloudstack.api.response.UcsProfileResponse;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import com.cloud.configuration.Config;
import com.cloud.dc.ClusterDetailsDao;
@ -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<String, UcsBladeVO> previous,
Map<String, ComputeBlade> now, UcsManagerVO mgr) {
@ -156,7 +156,7 @@ public class UcsManagerImpl implements UcsManager {
}
@Override
public void run() {
protected void runInContext() {
try {
List<UcsManagerVO> mgrs = ucsDao.listAll();
for (UcsManagerVO mgr : mgrs) {

View File

@ -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();
}

11
pom.xml
View File

@ -172,6 +172,7 @@
<module>test</module>
<module>client</module>
<module>services</module>
<module>maven-standard</module>
</modules>
<dependencyManagement>
@ -380,6 +381,16 @@
<artifactId>wsdl4j</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -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();

View File

@ -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) {
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());

View File

@ -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;
@ -183,11 +184,6 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
public ApiServer() {
}
@PostConstruct
void initComponent() {
CallContext.init(_entityMgr);
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
init();
@ -976,7 +972,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 +982,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()) {

View File

@ -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() + " ");

View File

@ -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();

View File

@ -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");
}

View File

@ -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;
@ -117,6 +117,9 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
ClusterDetailsDao _clusterDetailsDao;
long _serverId;
@Inject
ManagedContext _managedContext;
List<Investigator> _investigators;
public List<Investigator> getInvestigators() {
return _investigators;
@ -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,10 +796,19 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
@Override
public void run() {
ServerContexts.registerSystemContext();
try {
s_logger.info("Starting work");
while (!_stopped) {
_managedContext.runWithContext(new Runnable() {
@Override
public void run() {
runWithContext();
}
});
}
s_logger.info("Time to go home!");
}
private void runWithContext() {
HaWorkVO work = null;
try {
s_logger.trace("Checking the database");
@ -806,10 +818,10 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
synchronized (this) {
wait(_timeToSleep);
}
continue;
return;
} catch (final InterruptedException e) {
s_logger.info("Interrupted");
continue;
return;
}
}
@ -829,7 +841,7 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
nextTime = destroyVM(work);
} else {
assert false : "How did we get here with " + wt.toString();
continue;
return;
}
if (nextTime == null) {
@ -854,11 +866,6 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
}
}
}
s_logger.info("Time to go home!");
} finally {
ServerContexts.unregisterSystemContext();
}
}
public synchronized void wakup() {
notifyAll();

View File

@ -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)) {

View File

@ -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);

View File

@ -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<DomainRouterVO> 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,9 +1276,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
}
@Override
public void run() {
ServerContexts.registerSystemContext();
try {
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.
@ -1320,20 +1314,16 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
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<DomainRouterVO> 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();
}
}
}

View File

@ -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 {

View File

@ -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<Long> _disabledVms = Collections.newSetFromMap(new ConcurrentHashMap<Long, Boolean>());
private boolean _schedulerDisabled = false;
@ -68,7 +73,12 @@ public class SecurityGroupManagerImpl2 extends SecurityGroupManagerImpl{
public void run() {
while (true) {
try{
_managedContext.runWithContext(new Runnable() {
@Override
public void run() {
work();
}
});
} catch (final Throwable th) {
s_logger.error("SG Work: Caught this throwable, ", th);
}

View File

@ -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) {

View File

@ -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<ProjectInvitationVO> invitationsToExpire = _projectInvitationDao.listInvitationsToExpire(_invitationTimeOut);

View File

@ -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<DomainVO> domains = _domainDao.findImmediateChildrenForParent(DomainVO.ROOT_DOMAIN);

View File

@ -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) {

View File

@ -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...");

View File

@ -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.");

View File

@ -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();
}
}

View File

@ -33,11 +33,11 @@ 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.ServerContexts;
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.ManagedContextTimerTask;
import com.cloud.api.ApiDispatcher;
import com.cloud.api.ApiGsonHelper;
@ -371,17 +371,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();
}
}
};

View File

@ -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();
}
}

View File

@ -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 {

View File

@ -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) {

View File

@ -50,9 +50,9 @@ import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
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 +1492,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 +1577,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);

View File

@ -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<T> {
}
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();
}
}

View File

@ -61,7 +61,6 @@ import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.context.ServerContexts;
import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
@ -72,6 +71,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 +1708,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 +1747,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
} finally {
scanLock.releaseRef();
ServerContexts.unregisterSystemContext();
}
}

View File

@ -35,10 +35,10 @@ 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.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.usage.UsageTypes;
import org.springframework.stereotype.Component;
import com.cloud.alert.AlertManager;
@ -279,7 +279,17 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna
return true;
}
@Override
public void run() {
new ManagedContextRunnable() {
@Override
protected void runInContext() {
runInContext();
}
};
}
protected void runInContext() {
if (s_logger.isInfoEnabled()) {
s_logger.info("starting usage job...");
}
@ -1651,8 +1661,9 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna
m_usageVMSnapshotDao.persist(vsVO);
}
private class Heartbeat implements Runnable {
public void run() {
private class Heartbeat extends ManagedContextRunnable {
@Override
protected void runInContext() {
Transaction usageTxn = Transaction.open(Transaction.USAGE_DB);
try {
if(!m_heartbeatLock.lock(3)) { // 3 second timeout
@ -1757,8 +1768,9 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna
}
}
private class SanityCheck implements Runnable {
public void run() {
private class SanityCheck extends ManagedContextRunnable {
@Override
protected void runInContext() {
UsageSanityChecker usc = new UsageSanityChecker();
try {
String errors = usc.runSanityCheck();

View File

@ -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) {

View File

@ -27,6 +27,11 @@
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-framework-managed-context</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
@ -35,6 +40,14 @@
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>

View File

@ -23,6 +23,8 @@ import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
import org.apache.log4j.Logger;
public class VmwareContextPool {
@ -117,9 +119,9 @@ public class VmwareContextPool {
}
private TimerTask getTimerTask() {
return new TimerTask() {
return new ManagedContextTimerTask() {
@Override
public void run() {
protected void runInContext() {
try {
// doIdleCheck();