Refactor listSnapshots to new API framework. Also some minor code cleanup.

This commit is contained in:
Kris McQueen 2010-09-07 18:41:52 -07:00
parent 3b703c76cf
commit 614c3fa502
5 changed files with 258 additions and 167 deletions

View File

@ -20,43 +20,26 @@ package com.cloud.api.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.api.BaseCmd;
import com.cloud.api.BaseListCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.SnapshotResponse;
import com.cloud.async.AsyncJobVO;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.server.Criteria;
import com.cloud.serializer.SerializerHelper;
import com.cloud.storage.Snapshot;
import com.cloud.storage.Snapshot.SnapshotType;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.VolumeVO;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
public class ListSnapshotsCmd extends BaseCmd {
@Implementation(method="listSnapshots")
public class ListSnapshotsCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListSnapshotsCmd.class.getName());
private static final String s_name = "listsnapshotsresponse";
private static final List<Pair<Enum, Boolean>> s_properties = new ArrayList<Pair<Enum, Boolean>>();
static {
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ACCOUNT, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.DOMAIN_ID, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ID, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.INTERVAL_TYPE, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.NAME, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.SNAPSHOT_TYPE, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.VOLUME_ID, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.KEYWORD, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.PAGE, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.PAGESIZE, Boolean.FALSE));
}
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
@ -119,115 +102,46 @@ public class ListSnapshotsCmd extends BaseCmd {
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getName() {
return s_name;
}
public List<Pair<Enum, Boolean>> getProperties() {
return s_properties;
}
@Override
public List<Pair<String, Object>> execute(Map<String, Object> params) {
Long volumeId = (Long)params.get(BaseCmd.Properties.VOLUME_ID.getName());
String name = (String)params.get(BaseCmd.Properties.NAME.getName());
Long id = (Long)params.get(BaseCmd.Properties.ID.getName());
String interval = (String)params.get(BaseCmd.Properties.INTERVAL_TYPE.getName());
String snapshotType = (String)params.get(BaseCmd.Properties.SNAPSHOT_TYPE.getName());
Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName());
String accountName = (String)params.get(BaseCmd.Properties.ACCOUNT.getName());
Long domainId = (Long)params.get(BaseCmd.Properties.DOMAIN_ID.getName());
String keyword = (String)params.get(BaseCmd.Properties.KEYWORD.getName());
Integer page = (Integer)params.get(BaseCmd.Properties.PAGE.getName());
Integer pageSize = (Integer)params.get(BaseCmd.Properties.PAGESIZE.getName());
//Verify parameters
if(volumeId != null){
VolumeVO volume = getManagementServer().findAnyVolumeById(volumeId);
if (volume == null) {
throw new ServerApiException (BaseCmd.SNAPSHOT_INVALID_PARAM_ERROR, "unable to find a volume with id " + volumeId);
}
checkAccountPermissions(params, volume.getAccountId(), volume.getDomainId(), "volume", volumeId);
}
Long accountId = null;
if ((account == null) || isAdmin(account.getType())) {
if(account != null && account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)
accountId = account.getId();
if (domainId != null && accountName != null) {
Account userAccount = getManagementServer().findAccountByName(accountName, domainId);
if (userAccount != null) {
accountId = userAccount.getId();
}
@Override @SuppressWarnings("unchecked")
public String getResponse() {
List<SnapshotVO> snapshots = (List<SnapshotVO>)getResponseObject();
List<SnapshotResponse> response = new ArrayList<SnapshotResponse>();
for (Snapshot snapshot : snapshots) {
SnapshotResponse snapshotResponse = new SnapshotResponse();
snapshotResponse.setId(snapshot.getId());
Account acct = getManagementServer().findAccountById(Long.valueOf(snapshot.getAccountId()));
if (acct != null) {
snapshotResponse.setAccountName(acct.getAccountName());
snapshotResponse.setDomainId(acct.getDomainId());
snapshotResponse.setDomain(getManagementServer().findDomainIdById(acct.getDomainId()).getName());
}
} else {
accountId = account.getId();
VolumeVO volume = getManagementServer().findAnyVolumeById(snapshot.getVolumeId());
String snapshotTypeStr = SnapshotType.values()[snapshot.getSnapshotType()].name();
snapshotResponse.setSnapshotType(snapshotTypeStr);
snapshotResponse.setVolumeId(snapshot.getVolumeId());
snapshotResponse.setVolumeName(volume.getName());
snapshotResponse.setVolumeType(volume.getVolumeType().name());
snapshotResponse.setCreated(snapshot.getCreated());
snapshotResponse.setName(snapshot.getName());
AsyncJobVO asyncJob = getManagementServer().findInstancePendingAsyncJob("snapshot", snapshot.getId());
if (asyncJob != null) {
snapshotResponse.setJobId(asyncJob.getId());
snapshotResponse.setJobStatus(asyncJob.getStatus());
}
snapshotResponse.setIntervalType(getManagementServer().getSnapshotIntervalTypes(snapshot.getId()));
response.add(snapshotResponse);
}
Long startIndex = Long.valueOf(0);
int pageSizeNum = 50;
if (pageSize != null) {
pageSizeNum = pageSize.intValue();
}
if (page != null) {
int pageNum = page.intValue();
if (pageNum > 0) {
startIndex = Long.valueOf(pageSizeNum * (pageNum-1));
}
}
Criteria c = new Criteria("created", Boolean.FALSE, startIndex, Long.valueOf(pageSizeNum));
c.addCriteria(Criteria.VOLUMEID, volumeId);
c.addCriteria(Criteria.TYPE, snapshotType); // I don't want to create a new Criteria called SNAPSHOT_TYPE
c.addCriteria(Criteria.NAME, name);
c.addCriteria(Criteria.ID, id);
c.addCriteria(Criteria.KEYWORD, keyword);
c.addCriteria(Criteria.ACCOUNTID, accountId);
List<SnapshotVO> snapshots = null;
try {
snapshots = getManagementServer().listSnapshots(c, interval);
} catch (InvalidParameterValueException e) {
throw new ServerApiException(SNAPSHOT_INVALID_PARAM_ERROR, e.getMessage());
}
if (snapshots == null) {
throw new ServerApiException(BaseCmd.SNAPSHOT_LIST_ERROR, "unable to find snapshots for volume with id " + volumeId);
}
Object[] snapshotTag = new Object[snapshots.size()];
int i = 0;
for (Snapshot snapshot : snapshots) {
List<Pair<String, Object>> snapshotData = new ArrayList<Pair<String, Object>>();
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.ID.getName(), snapshot.getId().toString()));
Account acct = getManagementServer().findAccountById(Long.valueOf(snapshot.getAccountId()));
if (acct != null) {
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.ACCOUNT.getName(), acct.getAccountName()));
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.DOMAIN_ID.getName(), acct.getDomainId().toString()));
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.DOMAIN.getName(), getManagementServer().findDomainIdById(acct.getDomainId()).getName()));
}
volumeId = snapshot.getVolumeId();
VolumeVO volume = getManagementServer().findAnyVolumeById(volumeId);
String snapshotTypeStr = SnapshotType.values()[snapshot.getSnapshotType()].name();
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.SNAPSHOT_TYPE.getName(), snapshotTypeStr));
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.VOLUME_ID.getName(), volumeId));
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.VOLUME_NAME.getName(), volume.getName()));
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.VOLUME_TYPE.getName(), volume.getVolumeType()));
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.CREATED.getName(), getDateString(snapshot.getCreated())));
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.NAME.getName(), snapshot.getName()));
AsyncJobVO asyncJob = getManagementServer().findInstancePendingAsyncJob("snapshot", snapshot.getId());
if(asyncJob != null) {
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.JOB_ID.getName(), asyncJob.getId().toString()));
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.JOB_STATUS.getName(), String.valueOf(asyncJob.getStatus())));
}
snapshotData.add(new Pair<String, Object>(BaseCmd.Properties.INTERVAL_TYPE.getName(), getManagementServer().getSnapshotIntervalTypes(snapshot.getId())));
snapshotTag[i++] = snapshotData;
}
List<Pair<String, Object>> returnTags = new ArrayList<Pair<String, Object>>();
Pair<String, Object> snapshotTags = new Pair<String, Object>("snapshot", snapshotTag);
returnTags.add(snapshotTags);
return returnTags;
return SerializerHelper.toSerializedString(response);
}
}

View File

@ -0,0 +1,151 @@
package com.cloud.api.response;
import java.util.Date;
import com.cloud.api.ResponseObject;
import com.cloud.serializer.Param;
public class SnapshotResponse implements ResponseObject {
@Param(name="id")
private Long id;
@Param(name="account")
private String accountName;
@Param(name="domainid")
private Long domainId;
@Param(name="domain")
private String domain;
@Param(name="snapshottype")
private String snapshotType;
@Param(name="volumeid")
private Long volumeId;
@Param(name="volumename")
private String volumeName;
@Param(name="volumetype")
private String volumeType;
@Param(name="created")
private Date created;
@Param(name="name")
private String name;
@Param(name="jobid")
private Long jobId;
@Param(name="jobstatus")
private Integer jobStatus;
@Param(name="intervaltype")
private String intervalType;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public Long getDomainId() {
return domainId;
}
public void setDomainId(Long domainId) {
this.domainId = domainId;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public String getSnapshotType() {
return snapshotType;
}
public void setSnapshotType(String snapshotType) {
this.snapshotType = snapshotType;
}
public Long getVolumeId() {
return volumeId;
}
public void setVolumeId(Long volumeId) {
this.volumeId = volumeId;
}
public String getVolumeName() {
return volumeName;
}
public void setVolumeName(String volumeName) {
this.volumeName = volumeName;
}
public String getVolumeType() {
return volumeType;
}
public void setVolumeType(String volumeType) {
this.volumeType = volumeType;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getJobId() {
return jobId;
}
public void setJobId(Long jobId) {
this.jobId = jobId;
}
public Integer getJobStatus() {
return jobStatus;
}
public void setJobStatus(Integer jobStatus) {
this.jobStatus = jobStatus;
}
public String getIntervalType() {
return intervalType;
}
public void setIntervalType(String intervalType) {
this.intervalType = intervalType;
}
}

View File

@ -54,6 +54,7 @@ import com.cloud.api.commands.ListPreallocatedLunsCmd;
import com.cloud.api.commands.ListPublicIpAddressesCmd;
import com.cloud.api.commands.ListRoutersCmd;
import com.cloud.api.commands.ListServiceOfferingsCmd;
import com.cloud.api.commands.ListSnapshotsCmd;
import com.cloud.api.commands.ListTemplatesCmd;
import com.cloud.api.commands.LockAccountCmd;
import com.cloud.api.commands.LockUserCmd;
@ -1565,11 +1566,11 @@ public interface ManagementServer {
/**
* List all snapshots of a disk volume. Optionaly lists snapshots created by specified interval
* @param c the search criteria (order by, limit, etc.)
* @param cmd the command containing the search criteria (order by, limit, etc.)
* @return list of snapshots
* @throws InvalidParameterValueException
*/
List<SnapshotVO> listSnapshots(Criteria c, String interval) throws InvalidParameterValueException;
List<SnapshotVO> listSnapshots(ListSnapshotsCmd cmd) throws InvalidParameterValueException;
/**
* find a single snapshot by id
@ -1801,11 +1802,6 @@ public interface ManagementServer {
*/
long updateLoadBalancerRuleAsync(long userId, long accountId, long loadBalancerId, String name, String description, String privatePort, String algorithm);
// void assignToLoadBalancer(long userId, long loadBalancerId, List<Long> instanceIds) throws NetworkRuleConflictException, InternalErrorException, PermissionDeniedException, InvalidParameterValueException;
// long assignToLoadBalancerAsync(long userId, long loadBalancerId, List<Long> instanceIds, Map<String, String> params);
// boolean removeFromLoadBalancer(long userId, long loadBalancerId, List<Long> instanceIds) throws InvalidParameterValueException;
// long removeFromLoadBalancerAsync(long userId, long loadBalancerId, List<Long> instanceIds);
String[] getApiConfig();
StoragePoolVO findPoolById(Long id);
List<? extends StoragePoolVO> searchForStoragePools(Criteria c);

View File

@ -91,6 +91,7 @@ import com.cloud.api.commands.ListPreallocatedLunsCmd;
import com.cloud.api.commands.ListPublicIpAddressesCmd;
import com.cloud.api.commands.ListRoutersCmd;
import com.cloud.api.commands.ListServiceOfferingsCmd;
import com.cloud.api.commands.ListSnapshotsCmd;
import com.cloud.api.commands.ListTemplatesCmd;
import com.cloud.api.commands.LockAccountCmd;
import com.cloud.api.commands.LockUserCmd;
@ -6584,43 +6585,54 @@ public class ManagementServerImpl implements ManagementServer {
public SnapshotVO createTemplateSnapshot(Long userId, long volumeId) {
return _vmMgr.createTemplateSnapshot(userId, volumeId);
}
@Override
public boolean destroyTemplateSnapshot(Long userId, long snapshotId) {
return _vmMgr.destroyTemplateSnapshot(userId, snapshotId);
}
// @Override
// public long deleteSnapshotAsync(long userId, long snapshotId) {
// Snapshot snapshot = findSnapshotById(snapshotId);
// long volumeId = snapshot.getVolumeId();
// List<SnapshotPolicyVO> policies = _snapMgr.listPoliciesforSnapshot(snapshotId);
//
// // Return the job id of the last destroySnapshotAsync job which actually destroys the snapshot.
// // The rest of the async jobs just update the db and don't really do any meaningful thing.
// long finalJobId = 0;
// for (SnapshotPolicyVO policy : policies) {
// finalJobId = _snapMgr.destroySnapshotAsync(userId, volumeId, snapshotId, policy.getId());
// }
// return finalJobId;
// }
@Override
public List<SnapshotVO> listSnapshots(Criteria c, String interval) throws InvalidParameterValueException {
Filter searchFilter = new Filter(SnapshotVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit());
public List<SnapshotVO> listSnapshots(ListSnapshotsCmd cmd) throws InvalidParameterValueException {
Long volumeId = cmd.getVolumeId();
// Verify parameters
if(volumeId != null){
VolumeVO volume = _volumeDao.findById(volumeId);
if (volume == null) {
throw new InvalidParameterValueException("unable to find a volume with id " + volumeId);
}
checkAccountPermissions(volume.getAccountId(), volume.getDomainId(), "volume", volumeId);
}
Account account = (Account)UserContext.current().getAccountObject();
Long domainId = cmd.getDomainId();
String accountName = cmd.getAccountName();
Long accountId = null;
if ((account == null) || isAdmin(account.getType())) {
if(account != null && account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)
accountId = account.getId();
if (domainId != null && accountName != null) {
Account userAccount = _accountDao.findActiveAccount(accountName, domainId);
if (userAccount != null) {
accountId = userAccount.getId();
}
}
} else {
accountId = account.getId();
}
Filter searchFilter = new Filter(SnapshotVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
SearchCriteria<SnapshotVO> sc = _snapshotDao.createSearchCriteria();
Object volumeId = c.getCriteria(Criteria.VOLUMEID);
Object name = c.getCriteria(Criteria.NAME);
Object id = c.getCriteria(Criteria.ID);
Object keyword = c.getCriteria(Criteria.KEYWORD);
Object accountId = c.getCriteria(Criteria.ACCOUNTID);
Object snapshotTypeStr = c.getCriteria(Criteria.TYPE);
Object name = cmd.getSnapshotName();
Object id = cmd.getId();
Object keyword = cmd.getKeyword();
Object snapshotTypeStr = cmd.getSnapshotType();
String interval = cmd.getIntervalType();
sc.addAnd("status", SearchCriteria.Op.EQ, Snapshot.Status.BackedUp);
if(volumeId != null){
if (volumeId != null) {
sc.addAnd("volumeId", SearchCriteria.Op.EQ, volumeId);
}
@ -6649,12 +6661,12 @@ public class ManagementServerImpl implements ManagementServer {
throw new InvalidParameterValueException("Unsupported snapshot type " + snapshotTypeStr);
}
sc.addAnd("snapshotType", SearchCriteria.Op.EQ, snapshotType.ordinal());
}
else {
} else {
// Show only MANUAL and RECURRING snapshot types
sc.addAnd("snapshotType", SearchCriteria.Op.NEQ, Snapshot.SnapshotType.TEMPLATE.ordinal());
}
if(interval != null && volumeId != null) {
if (interval != null && volumeId != null) {
IntervalType intervalType = DateUtil.IntervalType.getIntervalType(interval);
if(intervalType == null) {
throw new InvalidParameterValueException("Unsupported interval type " + intervalType);
@ -8554,5 +8566,23 @@ public class ManagementServerImpl implements ManagementServer {
return deleteUserInternal(userId);
}
private Long checkAccountPermissions(long targetAccountId, long targetDomainId, String targetDesc, long targetId) throws ServerApiException {
Long accountId = null;
Account account = (Account)UserContext.current().getAccountObject();
if (account != null) {
if (!isAdmin(account.getType())) {
if (account.getId().longValue() != targetAccountId) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find a " + targetDesc + " with id " + targetId + " for this account");
}
} else if (!_domainDao.isChildDomain(account.getDomainId(), targetDomainId)) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to perform operation for " + targetDesc + " with id " + targetId + ", permission denied.");
}
accountId = account.getId();
}
return accountId;
}
}

View File

@ -780,7 +780,7 @@ public class SnapshotManagerImpl implements SnapshotManager {
}
private Long checkAccountPermissions(long targetAccountId,long targetDomainId,String targetDesc,long targetId) throws ServerApiException {
private Long checkAccountPermissions(long targetAccountId, long targetDomainId, String targetDesc, long targetId) throws ServerApiException {
Long accountId = null;
Account account = (Account)UserContext.current().getAccountObject();
@ -797,7 +797,7 @@ public class SnapshotManagerImpl implements SnapshotManager {
return accountId;
}
private static boolean isAdmin(short accountType) {
return ((accountType == Account.ACCOUNT_TYPE_ADMIN) ||
(accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) ||