diff --git a/api/src/com/cloud/agent/api/BadCommand.java b/api/src/com/cloud/agent/api/BadCommand.java new file mode 100644 index 00000000000..55976f64185 --- /dev/null +++ b/api/src/com/cloud/agent/api/BadCommand.java @@ -0,0 +1,30 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class BadCommand extends Command { + + @Override + public boolean executeInSequence() { + // TODO Auto-generated method stub + return false; + } + + public BadCommand(){ + super(); + } +} diff --git a/core/src/com/cloud/agent/transport/Request.java b/core/src/com/cloud/agent/transport/Request.java index 3db9ae888ac..bf2823c361a 100755 --- a/core/src/com/cloud/agent/transport/Request.java +++ b/core/src/com/cloud/agent/transport/Request.java @@ -47,6 +47,7 @@ import com.google.gson.JsonSerializer; import com.google.gson.stream.JsonReader; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.BadCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig; import com.cloud.exception.UnsupportedVersionException; @@ -248,6 +249,8 @@ public class Request { JsonReader jsonReader = new JsonReader(reader); jsonReader.setLenient(true); _cmds = s_gson.fromJson(jsonReader, (Type)Command[].class); + } catch (JsonParseException e) { + _cmds = new Command[] { new BadCommand() }; } catch (RuntimeException e) { s_logger.error("Caught problem with " + _content, e); throw e; diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index fa0f3680048..330ea88616d 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -39,6 +39,8 @@ 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.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; @@ -119,7 +121,7 @@ import com.cloud.vm.dao.VMInstanceDao; * */ @Component -public class StatsCollector extends ManagerBase implements ComponentMethodInterceptable { +public class StatsCollector extends ManagerBase implements ComponentMethodInterceptable, Configurable { public static final Logger s_logger = Logger.getLogger(StatsCollector.class.getName()); @@ -198,6 +200,8 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds private boolean _dailyOrHourly = false; + public static final ConfigKey StatsTimeout = new ConfigKey("Advanced", Integer.class, "stats.timeout", "60000", + "The timeout for stats call in milli seconds.", true, ConfigKey.Scope.Cluster); //private final GlobalLock m_capacityCheckLock = GlobalLock.getInternLock("capacity.check"); public static StatsCollector getInstance() { @@ -225,7 +229,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc hostStatsInterval = NumbersUtil.parseLong(configs.get("host.stats.interval"), 60000L); hostAndVmStatsInterval = NumbersUtil.parseLong(configs.get("vm.stats.interval"), 60000L); storageStatsInterval = NumbersUtil.parseLong(configs.get("storage.stats.interval"), 60000L); - volumeStatsInterval = NumbersUtil.parseLong(configs.get("volume.stats.interval"), 60000L); + volumeStatsInterval = NumbersUtil.parseLong(configs.get("volume.stats.interval"), 600000L); autoScaleStatsInterval = NumbersUtil.parseLong(configs.get("autoscale.stats.interval"), 60000L); vmDiskStatsInterval = NumbersUtil.parseLong(configs.get("vm.disk.stats.interval"), 60000L); @@ -623,7 +627,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc } } try { - HashMap volumeStatsByUuid = _userVmMgr.getVolumeStatistics(pool.getClusterId(), pool.getUuid(), pool.getPoolType(), volumeLocators); + HashMap volumeStatsByUuid = _userVmMgr.getVolumeStatistics(pool.getClusterId(), pool.getUuid(), pool.getPoolType(), volumeLocators, StatsTimeout.value()); if (volumeStatsByUuid != null){ _volumeStats.putAll(volumeStatsByUuid); } @@ -999,4 +1003,16 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc public StorageStats getStoragePoolStats(long id) { return _storagePoolStats.get(id); } + + @Override + public String getConfigComponentName() { + return StatsCollector.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] { + StatsCollector.StatsTimeout + }; + } } diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index da644c7af2d..4649edefc93 100755 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -45,7 +45,7 @@ import com.cloud.utils.Pair; public interface UserVmManager extends UserVmService { static final String EnableDynamicallyScaleVmCK = "enable.dynamic.scale.vm"; static final ConfigKey EnableDynamicallyScaleVm = new ConfigKey("Advanced", Boolean.class, EnableDynamicallyScaleVmCK, "false", - "Enables/Disables dynamically scaling a vm", true, ConfigKey.Scope.Zone); + "Enables/Disables dynamically scaling a vm", true, ConfigKey.Scope.Zone); static final int MAX_USER_DATA_LENGTH_BYTES = 2048; @@ -80,7 +80,7 @@ public interface UserVmManager extends UserVmService { HashMap> getVmDiskStatistics(long hostId, String hostName, List vmIds); - HashMap getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List volumeLocator); + HashMap getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List volumeLocator, int timout); boolean deleteVmGroup(long groupId); @@ -92,19 +92,18 @@ public interface UserVmManager extends UserVmService { boolean expunge(UserVmVO vm, long callerUserId, Account caller); - Pair> startVirtualMachine(long vmId, Long hostId, Map additionalParams, String deploymentPlannerToUse) - throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + Pair> startVirtualMachine(long vmId, Long hostId, Map additionalParams, + String deploymentPlannerToUse) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; - boolean upgradeVirtualMachine(Long id, Long serviceOfferingId, Map customParameters) throws ResourceUnavailableException, - ConcurrentOperationException, ManagementServerException, - VirtualMachineMigrationException; + boolean upgradeVirtualMachine(Long id, Long serviceOfferingId, Map customParameters) + throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException; boolean setupVmForPvlan(boolean add, Long hostId, NicProfile nic); void collectVmDiskStatistics(UserVmVO userVm); - UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData, - Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName, String instanceName) throws ResourceUnavailableException, InsufficientCapacityException; + UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData, Boolean isDynamicallyScalable, + HTTPMethod httpMethod, String customId, String hostName, String instanceName) throws ResourceUnavailableException, InsufficientCapacityException; //the validateCustomParameters, save and remove CustomOfferingDetils functions can be removed from the interface once we can //find a common place for all the scaling and upgrading code of both user and systemvms. diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 89793c717d0..1c842e6a792 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1565,10 +1565,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } @Override - public HashMap getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List volumeUuids) { + public HashMap getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List volumeLocator, int timeout) { List neighbors = _resourceMgr.listHostsInClusterByStatus(clusterId, Status.Up); for (HostVO neighbor : neighbors) { - Answer answer = _agentMgr.easySend(neighbor.getId(), new GetVolumeStatsCommand(poolType, poolUuid, volumeUuids)); + GetVolumeStatsCommand cmd = new GetVolumeStatsCommand(poolType, poolUuid, volumeLocator); + if (timeout > 0) { + cmd.setWait(timeout/1000); + } + Answer answer = _agentMgr.easySend(neighbor.getId(), cmd); if (answer instanceof GetVolumeStatsAnswer){ GetVolumeStatsAnswer volstats = (GetVolumeStatsAnswer)answer; return volstats.getVolumeStats(); diff --git a/setup/db/db/schema-452to453.sql b/setup/db/db/schema-452to453.sql index 50e43875d8b..fa9f4a34b19 100644 --- a/setup/db/db/schema-452to453.sql +++ b/setup/db/db/schema-452to453.sql @@ -256,7 +256,7 @@ CREATE VIEW `cloud`.`host_view` AS and ha_config.resource_type='Host'; -INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Premium', 'DEFAULT', 'management-server', 'volume.stats.interval', '60000', 'Interval (in seconds) to report volume statistics', '60000', now(), NULL, NULL); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Premium', 'DEFAULT', 'management-server', 'volume.stats.interval', '600000', 'Interval (in milliseconds) to report volume statistics', '600000', now(), NULL, NULL); DROP VIEW IF EXISTS `cloud`.`volume_view`; CREATE VIEW `cloud`.`volume_view` AS