FR17: 1. Add timeout to the volume stats command

2. When a unknown command is received return a BadCommand from request processor
This commit is contained in:
Abhinandan Prateek 2017-05-29 11:39:05 +05:30
parent 8f7428837e
commit 5ecba59cb7
6 changed files with 67 additions and 15 deletions

View File

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

View File

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

View File

@ -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<Integer> StatsTimeout = new ConfigKey<Integer>("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<String, VolumeStatsEntry> volumeStatsByUuid = _userVmMgr.getVolumeStatistics(pool.getClusterId(), pool.getUuid(), pool.getPoolType(), volumeLocators);
HashMap<String, VolumeStatsEntry> 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
};
}
}

View File

@ -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<Boolean> EnableDynamicallyScaleVm = new ConfigKey<Boolean>("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<Long, List<VmDiskStatsEntry>> getVmDiskStatistics(long hostId, String hostName, List<Long> vmIds);
HashMap<String, VolumeStatsEntry> getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List<String> volumeLocator);
HashMap<String, VolumeStatsEntry> getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List<String> 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<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse)
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams,
String deploymentPlannerToUse) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
boolean upgradeVirtualMachine(Long id, Long serviceOfferingId, Map<String, String> customParameters) throws ResourceUnavailableException,
ConcurrentOperationException, ManagementServerException,
VirtualMachineMigrationException;
boolean upgradeVirtualMachine(Long id, Long serviceOfferingId, Map<String, String> 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.

View File

@ -1565,10 +1565,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
@Override
public HashMap<String, VolumeStatsEntry> getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List<String> volumeUuids) {
public HashMap<String, VolumeStatsEntry> getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List<String> volumeLocator, int timeout) {
List<HostVO> 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();

View File

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