From 614c3fa50286e850a44c31f96b84dcfdbaf0df59 Mon Sep 17 00:00:00 2001 From: Kris McQueen Date: Tue, 7 Sep 2010 18:41:52 -0700 Subject: [PATCH] Refactor listSnapshots to new API framework. Also some minor code cleanup. --- .../cloud/api/commands/ListSnapshotsCmd.java | 168 +++++------------- .../cloud/api/response/SnapshotResponse.java | 151 ++++++++++++++++ .../com/cloud/server/ManagementServer.java | 10 +- .../cloud/server/ManagementServerImpl.java | 92 ++++++---- .../storage/snapshot/SnapshotManagerImpl.java | 4 +- 5 files changed, 258 insertions(+), 167 deletions(-) create mode 100644 server/src/com/cloud/api/response/SnapshotResponse.java diff --git a/server/src/com/cloud/api/commands/ListSnapshotsCmd.java b/server/src/com/cloud/api/commands/ListSnapshotsCmd.java index 8773eeed488..521651389e9 100644 --- a/server/src/com/cloud/api/commands/ListSnapshotsCmd.java +++ b/server/src/com/cloud/api/commands/ListSnapshotsCmd.java @@ -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> s_properties = new ArrayList>(); - - static { - s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.DOMAIN_ID, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.ID, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.INTERVAL_TYPE, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.NAME, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.SNAPSHOT_TYPE, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.VOLUME_ID, Boolean.FALSE)); - - s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.KEYWORD, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.PAGE, Boolean.FALSE)); - s_properties.add(new Pair(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> getProperties() { - return s_properties; - } - - @Override - public List> execute(Map 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 snapshots = (List)getResponseObject(); + + List response = new ArrayList(); + 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 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> snapshotData = new ArrayList>(); - snapshotData.add(new Pair(BaseCmd.Properties.ID.getName(), snapshot.getId().toString())); - - Account acct = getManagementServer().findAccountById(Long.valueOf(snapshot.getAccountId())); - if (acct != null) { - snapshotData.add(new Pair(BaseCmd.Properties.ACCOUNT.getName(), acct.getAccountName())); - snapshotData.add(new Pair(BaseCmd.Properties.DOMAIN_ID.getName(), acct.getDomainId().toString())); - snapshotData.add(new Pair(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(BaseCmd.Properties.SNAPSHOT_TYPE.getName(), snapshotTypeStr)); - snapshotData.add(new Pair(BaseCmd.Properties.VOLUME_ID.getName(), volumeId)); - snapshotData.add(new Pair(BaseCmd.Properties.VOLUME_NAME.getName(), volume.getName())); - snapshotData.add(new Pair(BaseCmd.Properties.VOLUME_TYPE.getName(), volume.getVolumeType())); - snapshotData.add(new Pair(BaseCmd.Properties.CREATED.getName(), getDateString(snapshot.getCreated()))); - snapshotData.add(new Pair(BaseCmd.Properties.NAME.getName(), snapshot.getName())); - - AsyncJobVO asyncJob = getManagementServer().findInstancePendingAsyncJob("snapshot", snapshot.getId()); - if(asyncJob != null) { - snapshotData.add(new Pair(BaseCmd.Properties.JOB_ID.getName(), asyncJob.getId().toString())); - snapshotData.add(new Pair(BaseCmd.Properties.JOB_STATUS.getName(), String.valueOf(asyncJob.getStatus()))); - } - snapshotData.add(new Pair(BaseCmd.Properties.INTERVAL_TYPE.getName(), getManagementServer().getSnapshotIntervalTypes(snapshot.getId()))); - snapshotTag[i++] = snapshotData; - } - List> returnTags = new ArrayList>(); - Pair snapshotTags = new Pair("snapshot", snapshotTag); - returnTags.add(snapshotTags); - return returnTags; + return SerializerHelper.toSerializedString(response); } } diff --git a/server/src/com/cloud/api/response/SnapshotResponse.java b/server/src/com/cloud/api/response/SnapshotResponse.java new file mode 100644 index 00000000000..d1a9d3daf34 --- /dev/null +++ b/server/src/com/cloud/api/response/SnapshotResponse.java @@ -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; + } +} diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index bad3616cf49..d3774072fa8 100644 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -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 listSnapshots(Criteria c, String interval) throws InvalidParameterValueException; + List 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 instanceIds) throws NetworkRuleConflictException, InternalErrorException, PermissionDeniedException, InvalidParameterValueException; -// long assignToLoadBalancerAsync(long userId, long loadBalancerId, List instanceIds, Map params); -// boolean removeFromLoadBalancer(long userId, long loadBalancerId, List instanceIds) throws InvalidParameterValueException; -// long removeFromLoadBalancerAsync(long userId, long loadBalancerId, List instanceIds); - String[] getApiConfig(); StoragePoolVO findPoolById(Long id); List searchForStoragePools(Criteria c); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 3809fab0e54..e61bbea1b67 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -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 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 listSnapshots(Criteria c, String interval) throws InvalidParameterValueException { - Filter searchFilter = new Filter(SnapshotVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit()); + public List 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 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; + } } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 3a27cf877b8..80eaa8b4bfd 100644 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -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) ||