From 80ef915fd528d27bad420cf07e7447494202a8e7 Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Thu, 26 Jun 2014 11:38:03 -0700 Subject: [PATCH] CLOUDSTACK-7000: ListSnapshotPolicy should list by policyid. Introduce updateSnapshotPolicy command (cherry picked from commit fce21439facea267d958d8939059ba65afb3578a) --- api/src/com/cloud/event/EventTypes.java | 7 +- .../storage/snapshot/SnapshotApiService.java | 3 + .../snapshot/ListSnapshotPoliciesCmd.java | 8 +- .../snapshot/UpdateSnapshotPolicyCmd.java | 133 ++++++++++++++++++ client/tomcatconf/commands.properties.in | 1 + .../cloud/storage/dao/SnapshotPolicyDao.java | 2 + .../storage/dao/SnapshotPolicyDaoImpl.java | 14 ++ .../src/com/cloud/api/ApiResponseHelper.java | 1 + .../cloud/server/ManagementServerImpl.java | 4 +- .../storage/snapshot/SnapshotManagerImpl.java | 36 ++++- 10 files changed, 203 insertions(+), 6 deletions(-) create mode 100644 api/src/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 0fa3cd5fd7f..5b9ea5c1a93 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -29,6 +29,7 @@ import com.cloud.network.vpc.NetworkACL; import com.cloud.network.vpc.NetworkACLItem; import com.cloud.network.Site2SiteVpnConnection; import com.cloud.server.ResourceTag; +import com.cloud.storage.snapshot.SnapshotPolicy; import com.cloud.vm.ConsoleProxy; import com.cloud.vm.SecondaryStorageVm; import org.apache.cloudstack.config.Configuration; @@ -630,9 +631,9 @@ public class EventTypes { // Snapshots entityEventDetails.put(EVENT_SNAPSHOT_CREATE, Snapshot.class); entityEventDetails.put(EVENT_SNAPSHOT_DELETE, Snapshot.class); - entityEventDetails.put(EVENT_SNAPSHOT_POLICY_CREATE, Snapshot.class); - entityEventDetails.put(EVENT_SNAPSHOT_POLICY_UPDATE, Snapshot.class); - entityEventDetails.put(EVENT_SNAPSHOT_POLICY_DELETE, Snapshot.class); + entityEventDetails.put(EVENT_SNAPSHOT_POLICY_CREATE, SnapshotPolicy.class); + entityEventDetails.put(EVENT_SNAPSHOT_POLICY_UPDATE, SnapshotPolicy.class); + entityEventDetails.put(EVENT_SNAPSHOT_POLICY_DELETE, SnapshotPolicy.class); // ISO entityEventDetails.put(EVENT_ISO_CREATE, "Iso"); diff --git a/api/src/com/cloud/storage/snapshot/SnapshotApiService.java b/api/src/com/cloud/storage/snapshot/SnapshotApiService.java index 91c08307bb8..0300980edb6 100644 --- a/api/src/com/cloud/storage/snapshot/SnapshotApiService.java +++ b/api/src/com/cloud/storage/snapshot/SnapshotApiService.java @@ -29,6 +29,7 @@ import com.cloud.storage.Snapshot; import com.cloud.storage.Volume; import com.cloud.user.Account; import com.cloud.utils.Pair; +import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd; public interface SnapshotApiService { @@ -106,4 +107,6 @@ public interface SnapshotApiService { Long getHostIdForSnapshotOperation(Volume vol); boolean revertSnapshot(Long snapshotId); + + SnapshotPolicy updateSnapshotPolicy(UpdateSnapshotPolicyCmd updateSnapshotPolicyCmd); } diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotPoliciesCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotPoliciesCmd.java index 749711f4150..282f82c36d7 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotPoliciesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotPoliciesCmd.java @@ -44,9 +44,12 @@ public class ListSnapshotPoliciesCmd extends BaseListCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "the ID of the disk volume") + @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, description = "the ID of the disk volume") private Long volumeId; + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = SnapshotPolicyResponse.class, description = "the ID of the snapshot policy") + private Long id; + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin}) private Boolean display; @@ -66,6 +69,9 @@ public class ListSnapshotPoliciesCmd extends BaseListCmd { return true; } + public Long getId() { + return id; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java new file mode 100644 index 00000000000..7181fd50d08 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java @@ -0,0 +1,133 @@ +package org.apache.cloudstack.api.command.user.snapshot; + +// 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. + +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.storage.Volume; +import com.cloud.storage.snapshot.SnapshotPolicy; +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.acl.SecurityChecker; +import org.apache.cloudstack.api.ACL; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCustomIdCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ResponseObject; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.SnapshotPolicyResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; + + +@APICommand(name = "updateSnapshotPolicy", description = "Updates the snapshot policy.", responseObject = SnapshotPolicyResponse.class, responseView = ResponseObject.ResponseView.Restricted, entityType = {Volume.class}, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class UpdateSnapshotPolicyCmd extends BaseAsyncCustomIdCmd { + public static final Logger s_logger = Logger.getLogger(UpdateSnapshotPolicyCmd.class.getName()); + private static final String s_name = "updatesnapshotpolicyresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @ACL(accessType = SecurityChecker.AccessType.OperateEntry) + @Parameter(name= ApiConstants.ID, type=CommandType.UUID, entityType=SnapshotPolicyResponse.class, description="the ID of the snapshot policy") + private Long id; + + @Parameter(name = ApiConstants.FOR_DISPLAY, + type = CommandType.BOOLEAN, + description = "an optional field, whether to the display the snapshot policy to the end user or not.", + since = "4.4", + authorized = {RoleType.Admin}) + private Boolean display; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public Boolean getDisplay() { + return display; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public Long getInstanceId() { + return getId(); + } + + @Override + public long getEntityOwnerId() { + + SnapshotPolicy policy = _entityMgr.findById(SnapshotPolicy.class, getId()); + if (policy == null) { + throw new InvalidParameterValueException("Invalid snapshot policy id was provided"); + } + Volume volume = _responseGenerator.findVolumeById(policy.getVolumeId()); + if (volume == null) { + throw new InvalidParameterValueException("Snapshot policy's volume id doesnt exist"); + }else{ + return volume.getAccountId(); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_SNAPSHOT_POLICY_UPDATE; + } + + @Override + public String getEventDescription() { + StringBuilder desc = new StringBuilder("Updating snapshot policy: "); + desc.append(getId()); + return desc.toString(); + } + + @Override + public void execute() { + CallContext.current().setEventDetails("SnapshotPolicy Id: " + getId()); + SnapshotPolicy result = _snapshotService.updateSnapshotPolicy(this); + if (result != null) { + SnapshotPolicyResponse response = _responseGenerator.createSnapshotPolicyResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update snapshot policy"); + } + } + + @Override + public void checkUuid() { + if (getCustomId() != null) { + _uuidMgr.checkUuid(getCustomId(), SnapshotPolicy.class); + } + } + +} \ No newline at end of file diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index d247aa03475..b9ac27b0bae 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -79,6 +79,7 @@ createSnapshot=15 listSnapshots=15 deleteSnapshot=15 createSnapshotPolicy=15 +updateSnapshotPolicy=15 deleteSnapshotPolicies=15 listSnapshotPolicies=15 revertSnapshot=15 diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java b/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java index 0e55c2a6a31..0ce2b170882 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java @@ -41,4 +41,6 @@ public interface SnapshotPolicyDao extends GenericDao { List listActivePolicies(); SnapshotPolicyVO findOneByVolume(long volumeId); + + Pair, Integer> listAndCountById(long id, boolean display, Filter filter); } diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java index 34478b4d873..033a82d5a6f 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java @@ -36,6 +36,7 @@ public class SnapshotPolicyDaoImpl extends GenericDaoBase VolumeIdSearch; private final SearchBuilder VolumeIdIntervalSearch; private final SearchBuilder ActivePolicySearch; + private final SearchBuilder SnapshotPolicySearch; @Override public SnapshotPolicyVO findOneByVolumeInterval(long volumeId, IntervalType intvType) { @@ -79,6 +80,14 @@ public class SnapshotPolicyDaoImpl extends GenericDaoBase, Integer> listAndCountById(long id, boolean display, Filter filter){ + SearchCriteria sc = SnapshotPolicySearch.create(); + sc.setParameters("id", id); + sc.setParameters("display", display); + return searchAndCount(sc, filter); + } + protected SnapshotPolicyDaoImpl() { VolumeIdSearch = createSearchBuilder(); VolumeIdSearch.and("volumeId", VolumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); @@ -94,6 +103,11 @@ public class SnapshotPolicyDaoImpl extends GenericDaoBase, Integer> listPoliciesforVolume(ListSnapshotPoliciesCmd cmd) { Long volumeId = cmd.getVolumeId(); boolean display = cmd.isDisplay(); + Long id = cmd.getId(); + Pair, Integer> result = null; + // TODO - Have a better way of doing this. + if(id != null){ + result = _snapshotPolicyDao.listAndCountById(id, display, null); + if(result != null && result.first() != null && !result.first().isEmpty()){ + SnapshotPolicyVO snapshotPolicy = result.first().get(0); + volumeId = snapshotPolicy.getId(); + } + } VolumeVO volume = _volsDao.findById(volumeId); if (volume == null) { throw new InvalidParameterValueException("Unable to find a volume with id " + volumeId); } _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume); - Pair, Integer> result = _snapshotPolicyDao.listAndCountByVolumeId(volumeId, display); + if(result != null) + return new Pair, Integer>(result.first(), result.second()); + result = _snapshotPolicyDao.listAndCountByVolumeId(volumeId, display); return new Pair, Integer>(result.first(), result.second()); }