From 61676ff3ea20276115a3bc10c5e20f5a883c79d3 Mon Sep 17 00:00:00 2001 From: Kelven Yang Date: Thu, 14 Jul 2011 18:11:32 -0700 Subject: [PATCH] Make cluster request timeout to be configurable --- .../cluster/ClusterServiceServletAdapter.java | 37 +++++++++---- .../cluster/ClusterServiceServletImpl.java | 53 ++++++++++--------- .../src/com/cloud/configuration/Config.java | 3 +- setup/db/db/data-217to218.sql | 5 -- setup/db/db/schema-227to228.sql | 7 ++- 5 files changed, 64 insertions(+), 41 deletions(-) diff --git a/server/src/com/cloud/cluster/ClusterServiceServletAdapter.java b/server/src/com/cloud/cluster/ClusterServiceServletAdapter.java index 813cc123a80..e8364dcf987 100644 --- a/server/src/com/cloud/cluster/ClusterServiceServletAdapter.java +++ b/server/src/com/cloud/cluster/ClusterServiceServletAdapter.java @@ -32,6 +32,8 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.cluster.dao.ManagementServerHostDao; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.PropertiesUtil; import com.cloud.utils.component.ComponentLocator; @@ -40,15 +42,21 @@ import com.cloud.utils.component.ComponentLocator; public class ClusterServiceServletAdapter implements ClusterServiceAdapter { private static final Logger s_logger = Logger.getLogger(ClusterServiceServletAdapter.class); - private static final int DEFAULT_SERVICE_PORT = 9090; + private static final int DEFAULT_SERVICE_PORT = 9090; + private static final int DEFAULT_REQUEST_TIMEOUT = 300; // 300 seconds - private ClusterManager manager; + private ClusterManager _manager; + + private ManagementServerHostDao _mshostDao; + + private ConfigurationDao _configDao; - private ManagementServerHostDao _mshostDao; private ClusterServiceServletContainer _servletContainer; private String _name; - private int _clusterServicePort = DEFAULT_SERVICE_PORT; + private int _clusterServicePort = DEFAULT_SERVICE_PORT; + + private int _clusterRequestTimeoutSeconds = DEFAULT_REQUEST_TIMEOUT; @Override public ClusterService getPeerService(String strPeer) throws RemoteException { @@ -63,7 +71,7 @@ public class ClusterServiceServletAdapter implements ClusterServiceAdapter { if(serviceUrl == null) return null; - return new ClusterServiceServletImpl(serviceUrl); + return new ClusterServiceServletImpl(serviceUrl, _clusterRequestTimeoutSeconds); } @Override @@ -111,7 +119,7 @@ public class ClusterServiceServletAdapter implements ClusterServiceAdapter { @Override public boolean start() { _servletContainer = new ClusterServiceServletContainer(); - _servletContainer.start(new ClusterServiceServletHttpHandler(manager), _clusterServicePort); + _servletContainer.start(new ClusterServiceServletHttpHandler(_manager), _clusterServicePort); return true; } @@ -128,13 +136,24 @@ public class ClusterServiceServletAdapter implements ClusterServiceAdapter { ComponentLocator locator = ComponentLocator.getCurrentLocator(); - manager = locator.getManager(ClusterManager.class); - if(manager == null) + _manager = locator.getManager(ClusterManager.class); + if(_manager == null) throw new ConfigurationException("Unable to get " + ClusterManager.class.getName()); _mshostDao = locator.getDao(ManagementServerHostDao.class); if(_mshostDao == null) throw new ConfigurationException("Unable to get " + ManagementServerHostDao.class.getName()); + + if(_mshostDao == null) + throw new ConfigurationException("Unable to get " + ManagementServerHostDao.class.getName()); + + _configDao = locator.getDao(ConfigurationDao.class); + if(_configDao == null) + throw new ConfigurationException("Unable to get " + ConfigurationDao.class.getName()); + + String value = _configDao.getValue(Config.ClusterMessageTimeOutSeconds.key()); + _clusterRequestTimeoutSeconds = NumbersUtil.parseInt(value, DEFAULT_REQUEST_TIMEOUT); + s_logger.info("Configure cluster request time out. timeout: " + _clusterRequestTimeoutSeconds + " seconds"); File dbPropsFile = PropertiesUtil.findConfigFile("db.properties"); Properties dbProps = new Properties(); @@ -145,7 +164,7 @@ public class ClusterServiceServletAdapter implements ClusterServiceAdapter { } catch (IOException e) { throw new ConfigurationException("Unable to load db.properties content"); } - + _clusterServicePort = NumbersUtil.parseInt(dbProps.getProperty("cluster.servlet.port"), DEFAULT_SERVICE_PORT); if(s_logger.isInfoEnabled()) s_logger.info("Cluster servlet port : " + _clusterServicePort); diff --git a/server/src/com/cloud/cluster/ClusterServiceServletImpl.java b/server/src/com/cloud/cluster/ClusterServiceServletImpl.java index 0d1ca84f45b..ce65fe18e87 100644 --- a/server/src/com/cloud/cluster/ClusterServiceServletImpl.java +++ b/server/src/com/cloud/cluster/ClusterServiceServletImpl.java @@ -34,30 +34,33 @@ import com.google.gson.Gson; public class ClusterServiceServletImpl implements ClusterService { private static final long serialVersionUID = 4574025200012566153L; private static final Logger s_logger = Logger.getLogger(ClusterServiceServletImpl.class); - private static int HTTP_DATA_TIMEOUT = 60000; - private String serviceUrl; + private String _serviceUrl; - private final Gson gson; + private final Gson _gson; + private int _requestTimeoutSeconds; public ClusterServiceServletImpl() { - gson = GsonHelper.getGson(); + _gson = GsonHelper.getGson(); } - public ClusterServiceServletImpl(String serviceUrl) { - this.serviceUrl = serviceUrl; + public ClusterServiceServletImpl(String serviceUrl, int requestTimeoutSeconds) { + s_logger.info("Setup cluster service servlet. service url: " + serviceUrl + ", request timeout: " + requestTimeoutSeconds + " seconds"); + + this._serviceUrl = serviceUrl; + this._requestTimeoutSeconds = requestTimeoutSeconds; - gson = GsonHelper.getGson(); + _gson = GsonHelper.getGson(); } @Override public String execute(String callingPeer, long agentId, String gsonPackage, boolean stopOnError) throws RemoteException { if(s_logger.isDebugEnabled()) { - s_logger.debug("Post (sync-call) " + gsonPackage + " to " + serviceUrl + " for agent " + agentId + " from " + callingPeer); + s_logger.debug("Post (sync-call) " + gsonPackage + " to " + _serviceUrl + " for agent " + agentId + " from " + callingPeer); } HttpClient client = getHttpClient(); - PostMethod method = new PostMethod(serviceUrl); + PostMethod method = new PostMethod(_serviceUrl); method.addParameter("method", Integer.toString(RemoteMethodConstants.METHOD_EXECUTE)); method.addParameter("agentId", Long.toString(agentId)); @@ -71,11 +74,11 @@ public class ClusterServiceServletImpl implements ClusterService { public long executeAsync(String callingPeer, long agentId, String gsonPackage, boolean stopOnError) throws RemoteException { if(s_logger.isDebugEnabled()) { - s_logger.debug("Post (Async-call) " + gsonPackage + " to " + serviceUrl + " for agent " + agentId + " from " + callingPeer); + s_logger.debug("Post (Async-call) " + gsonPackage + " to " + _serviceUrl + " for agent " + agentId + " from " + callingPeer); } HttpClient client = getHttpClient(); - PostMethod method = new PostMethod(serviceUrl); + PostMethod method = new PostMethod(_serviceUrl); method.addParameter("method", Integer.toString(RemoteMethodConstants.METHOD_EXECUTE_ASYNC)); method.addParameter("agentId", Long.toString(agentId)); @@ -85,15 +88,15 @@ public class ClusterServiceServletImpl implements ClusterService { String result = executePostMethod(client, method); if(result == null) { - s_logger.error("Empty return from remote async-execution on " + serviceUrl); - throw new RemoteException("Invalid result returned from async-execution on peer : " + serviceUrl); + s_logger.error("Empty return from remote async-execution on " + _serviceUrl); + throw new RemoteException("Invalid result returned from async-execution on peer : " + _serviceUrl); } try { - return gson.fromJson(result, Long.class); + return _gson.fromJson(result, Long.class); } catch(Throwable e) { s_logger.error("Unable to parse executeAsync return : " + result); - throw new RemoteException("Invalid result returned from async-execution on peer : " + serviceUrl); + throw new RemoteException("Invalid result returned from async-execution on peer : " + _serviceUrl); } } @@ -105,7 +108,7 @@ public class ClusterServiceServletImpl implements ClusterService { + ", seq: " + seq + ", gsonPackage: " + gsonPackage); } HttpClient client = getHttpClient(); - PostMethod method = new PostMethod(serviceUrl); + PostMethod method = new PostMethod(_serviceUrl); method.addParameter("method", Integer.toString(RemoteMethodConstants.METHOD_ASYNC_RESULT)); method.addParameter("agentId", Long.toString(agentId)); @@ -130,11 +133,11 @@ public class ClusterServiceServletImpl implements ClusterService { @Override public boolean ping(String callingPeer) throws RemoteException { if(s_logger.isDebugEnabled()) { - s_logger.debug("Ping at " + serviceUrl); + s_logger.debug("Ping at " + _serviceUrl); } HttpClient client = getHttpClient(); - PostMethod method = new PostMethod(serviceUrl); + PostMethod method = new PostMethod(_serviceUrl); method.addParameter("method", Integer.toString(RemoteMethodConstants.METHOD_PING)); method.addParameter("callingPeer", callingPeer); @@ -154,20 +157,20 @@ public class ClusterServiceServletImpl implements ClusterService { if(response == HttpStatus.SC_OK) { result = method.getResponseBodyAsString(); if(s_logger.isDebugEnabled()) { - s_logger.debug("POST " + serviceUrl + " response :" + result + ", responding time: " + s_logger.debug("POST " + _serviceUrl + " response :" + result + ", responding time: " + (System.currentTimeMillis() - startTick) + " ms"); } } else { s_logger.error("Invalid response code : " + response + ", from : " - + serviceUrl + ", method : " + method.getParameter("method") + + _serviceUrl + ", method : " + method.getParameter("method") + " responding time: " + (System.currentTimeMillis() - startTick)); } } catch (HttpException e) { - s_logger.error("HttpException from : " + serviceUrl + ", method : " + method.getParameter("method")); + s_logger.error("HttpException from : " + _serviceUrl + ", method : " + method.getParameter("method")); } catch (IOException e) { - s_logger.error("IOException from : " + serviceUrl + ", method : " + method.getParameter("method")); + s_logger.error("IOException from : " + _serviceUrl + ", method : " + method.getParameter("method")); } catch(Throwable e) { - s_logger.error("Exception from : " + serviceUrl + ", method : " + method.getParameter("method") + ", exception :", e); + s_logger.error("Exception from : " + _serviceUrl + ", method : " + method.getParameter("method") + ", exception :", e); } return result; @@ -176,7 +179,7 @@ public class ClusterServiceServletImpl implements ClusterService { private HttpClient getHttpClient() { HttpClient client = new HttpClient(); HttpClientParams clientParams = new HttpClientParams(); - clientParams.setSoTimeout(HTTP_DATA_TIMEOUT); + clientParams.setSoTimeout(this._requestTimeoutSeconds * 1000); client.setParams(clientParams); return client; @@ -184,7 +187,7 @@ public class ClusterServiceServletImpl implements ClusterService { // for test purpose only public static void main(String[] args) { - ClusterServiceServletImpl service = new ClusterServiceServletImpl("http://localhost:9090/clusterservice"); + ClusterServiceServletImpl service = new ClusterServiceServletImpl("http://localhost:9090/clusterservice", 300); try { String result = service.execute("test", 1, "{ p1:v1, p2:v2 }", true); System.out.println(result); diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index e19bb6606c9..63729a58937 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -236,8 +236,9 @@ public enum Config { AgentLbEnable("Advanced", ClusterManager.class, Boolean.class, "agent.lb.enabled", "true", "If agent load balancing enabled in cluster setup", null), SubDomainNetworkAccess("Advanced", NetworkManager.class, Boolean.class, "allow.subdomain.network.access", "true", "Allow subdomains to use networks dedicated to their parent domain(s)", null), - EncodeApiResponse("Advanced", ManagementServer.class, Boolean.class, "encode.api.response", "false", "Do UTF-8 encoding for the api response, false by default", null); + EncodeApiResponse("Advanced", ManagementServer.class, Boolean.class, "encode.api.response", "false", "Do UTF-8 encoding for the api response, false by default", null), + ClusterMessageTimeOutSeconds("Advanced", ManagementServer.class, Integer.class, "cluster.message.timeout.seconds", "300", "Time (in seconds) to wait before a inter-management server message post times out.", null); private final String _category; private final Class _componentClass; diff --git a/setup/db/db/data-217to218.sql b/setup/db/db/data-217to218.sql index b17774ab7b6..3aea09eea9e 100755 --- a/setup/db/db/data-217to218.sql +++ b/setup/db/db/data-217to218.sql @@ -1,8 +1,3 @@ INSERT INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'default.page.size', '500', 'Default page size for API list* commands'); DELETE FROM `cloud`.`op_host_capacity` WHERE `capacity_type` in (2,6); -INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.management.portgroup', 'Management Network', 'Specify the management network name(for ESXi hosts)'); -INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.additional.vnc.portrange.start', '59000', 'Start port number of additional VNC port range'); -INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.additional.vnc.portrange.size', '1000', 'Start port number of additional VNC port range'); -INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Console Proxy', 'DEFAULT', 'AgentManager', 'consoleproxy.management.state', 'Auto', 'console proxy service management state'); -INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Console Proxy', 'DEFAULT', 'AgentManager', 'consoleproxy.management.state.last', 'Auto', 'last console proxy service management state'); diff --git a/setup/db/db/schema-227to228.sql b/setup/db/db/schema-227to228.sql index e41fc1adb89..5a0cb1e5522 100644 --- a/setup/db/db/schema-227to228.sql +++ b/setup/db/db/schema-227to228.sql @@ -139,4 +139,9 @@ CREATE INDEX `i_op_lock__mac_ip_thread` on `op_lock` (`mac`, `ip`, `thread`); UPDATE `cloud`.`mshost` set removed=NULL where removed IS NOT NULL; - +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.management.portgroup', 'Management Network', 'Specify the management network name(for ESXi hosts)'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.additional.vnc.portrange.start', '59000', 'Start port number of additional VNC port range'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.additional.vnc.portrange.size', '1000', 'Start port number of additional VNC port range'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Console Proxy', 'DEFAULT', 'AgentManager', 'consoleproxy.management.state', 'Auto', 'console proxy service management state'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Console Proxy', 'DEFAULT', 'AgentManager', 'consoleproxy.management.state.last', 'Auto', 'last console proxy service management state'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'cluster.message.timeout.seconds', '300', 'Time (in seconds) to wait before a inter-management server message post times out.');