Updated Branches: refs/heads/events-framework b03744ab0 -> 4cbe8a479
add state machine to Snapshot object Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/4cbe8a47 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/4cbe8a47 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/4cbe8a47 Branch: refs/heads/events-framework Commit: 4cbe8a479ff5659e7f955cd2a87b23d53452d633 Parents: db2ba81 Author: Murali Reddy <[email protected]> Authored: Mon Jan 28 20:45:56 2013 +0530 Committer: Murali Reddy <[email protected]> Committed: Mon Jan 28 20:45:56 2013 +0530 ---------------------------------------------------------------------- api/src/com/cloud/storage/Snapshot.java | 39 +++- .../cloudstack/api/response/SnapshotResponse.java | 12 +- core/src/com/cloud/storage/SnapshotVO.java | 26 +-- server/src/com/cloud/api/ApiDBUtils.java | 207 ++------------- server/src/com/cloud/api/ApiResponseHelper.java | 191 ++------------ .../src/com/cloud/storage/StorageManagerImpl.java | 6 +- server/src/com/cloud/storage/dao/SnapshotDao.java | 13 +- .../src/com/cloud/storage/dao/SnapshotDaoImpl.java | 49 ++-- .../storage/snapshot/SnapshotManagerImpl.java | 94 ++++--- server/src/com/cloud/vm/UserVmManagerImpl.java | 4 +- .../test/com/cloud/snapshot/SnapshotDaoTest.java | 9 +- 11 files changed, 193 insertions(+), 457 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4cbe8a47/api/src/com/cloud/storage/Snapshot.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/storage/Snapshot.java b/api/src/com/cloud/storage/Snapshot.java index 99bdee6..97fa9b9 100644 --- a/api/src/com/cloud/storage/Snapshot.java +++ b/api/src/com/cloud/storage/Snapshot.java @@ -16,14 +16,16 @@ // under the License. package com.cloud.storage; -import java.util.Date; - -import org.apache.cloudstack.acl.ControlledEntity; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.utils.fsm.StateMachine2; +import com.cloud.utils.fsm.StateObject; +import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; -public interface Snapshot extends ControlledEntity, Identity, InternalIdentity { +import java.util.Date; + +public interface Snapshot extends ControlledEntity, Identity, InternalIdentity, StateObject<Snapshot.State> { public enum Type { MANUAL, RECURRING, @@ -51,13 +53,29 @@ public interface Snapshot extends ControlledEntity, Identity, InternalIdentity { } } - public enum Status { + public enum State { Creating, CreatedOnPrimary, BackingUp, BackedUp, Error; + private final static StateMachine2<State, Event, Snapshot> s_fsm = new StateMachine2<State, Event, Snapshot>(); + + public static StateMachine2<State, Event, Snapshot> getStateMachine() { + return s_fsm; + } + + static { + s_fsm.addTransition(Creating, Event.CreateRequested, Creating); + s_fsm.addTransition(Creating, Event.OperationSucceeded, CreatedOnPrimary); + s_fsm.addTransition(Creating, Event.OperationFailed, Error); + s_fsm.addTransition(CreatedOnPrimary, Event.BackupToSecondary, BackingUp); + s_fsm.addTransition(CreatedOnPrimary, Event.OperationFailed, Error); + s_fsm.addTransition(BackingUp, Event.OperationSucceeded, BackedUp); + s_fsm.addTransition(BackingUp, Event.OperationFailed, Error); + } + public String toString() { return this.name(); } @@ -67,6 +85,15 @@ public interface Snapshot extends ControlledEntity, Identity, InternalIdentity { } } + enum Event { + CreateRequested, + CreatedOnPrimary, + BackupToSecondary, + BackedupToSecondary, + OperationSucceeded, + OperationFailed + } + public static final long MANUAL_POLICY_ID = 0L; long getAccountId(); @@ -81,7 +108,7 @@ public interface Snapshot extends ControlledEntity, Identity, InternalIdentity { Type getType(); - Status getStatus(); + State getState(); HypervisorType getHypervisorType(); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4cbe8a47/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java index 8ea0d7f..58b7cf1 100644 --- a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java @@ -16,16 +16,16 @@ // under the License. package org.apache.cloudstack.api.response; -import java.util.Date; -import java.util.List; - -import org.apache.cloudstack.api.ApiConstants; import com.cloud.serializer.Param; import com.cloud.storage.Snapshot; import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; import org.apache.cloudstack.api.EntityReference; +import java.util.Date; +import java.util.List; + @EntityReference(value=Snapshot.class) @SuppressWarnings("unused") public class SnapshotResponse extends BaseResponse implements ControlledEntityResponse { @@ -81,7 +81,7 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe @SerializedName(ApiConstants.STATE) @Param(description = "the state of the snapshot. BackedUp means that snapshot is ready to be used; Creating - the snapshot is being allocated on the primary storage; BackingUp - the snapshot is being backed up on secondary storage") - private Snapshot.Status state; + private Snapshot.State state; @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with snapshot", responseObject = ResourceTagResponse.class) private List<ResourceTagResponse> tags; @@ -149,7 +149,7 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe this.intervalType = intervalType; } - public void setState(Snapshot.Status state) { + public void setState(Snapshot.State state) { this.state = state; } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4cbe8a47/core/src/com/cloud/storage/SnapshotVO.java ---------------------------------------------------------------------- diff --git a/core/src/com/cloud/storage/SnapshotVO.java b/core/src/com/cloud/storage/SnapshotVO.java index e5e3650..c1c5f21 100644 --- a/core/src/com/cloud/storage/SnapshotVO.java +++ b/core/src/com/cloud/storage/SnapshotVO.java @@ -16,23 +16,13 @@ // under the License. package com.cloud.storage; -import java.util.Date; -import java.util.UUID; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; - -import org.apache.cloudstack.api.Identity; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.db.GenericDao; import com.google.gson.annotations.Expose; -import org.apache.cloudstack.api.InternalIdentity; + +import javax.persistence.*; +import java.util.Date; +import java.util.UUID; @Entity @Table(name="snapshots") @@ -69,7 +59,7 @@ public class SnapshotVO implements Snapshot { @Expose @Column(name="status", updatable = true, nullable=false) @Enumerated(value=EnumType.STRING) - private Status status; + private State status; @Column(name="snapshot_type") short snapshotType; @@ -127,7 +117,7 @@ public class SnapshotVO implements Snapshot { this.snapshotType = snapshotType; this.typeDescription = typeDescription; this.size = size; - this.status = Status.Creating; + this.status = State.Creating; this.prevSnapshotId = 0; this.hypervisorType = hypervisorType; this.version = "2.2"; @@ -252,11 +242,11 @@ public class SnapshotVO implements Snapshot { } @Override - public Status getStatus() { + public State getState() { return status; } - public void setStatus(Status status) { + public void setStatus(State status) { this.status = status; } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4cbe8a47/server/src/com/cloud/api/ApiDBUtils.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 0b08b26..143e280 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -16,68 +16,8 @@ // under the License. package com.cloud.api; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.cloudstack.api.ApiConstants.HostDetails; -import org.apache.cloudstack.api.ApiConstants.VMDetails; -import org.apache.cloudstack.api.response.AccountResponse; -import org.apache.cloudstack.api.response.AsyncJobResponse; -import org.apache.cloudstack.api.response.DiskOfferingResponse; -import org.apache.cloudstack.api.response.DomainRouterResponse; -import org.apache.cloudstack.api.response.EventResponse; -import org.apache.cloudstack.api.response.HostResponse; -import org.apache.cloudstack.api.response.InstanceGroupResponse; -import org.apache.cloudstack.api.response.ProjectAccountResponse; -import org.apache.cloudstack.api.response.ProjectInvitationResponse; -import org.apache.cloudstack.api.response.ProjectResponse; -import org.apache.cloudstack.api.response.ResourceTagResponse; -import org.apache.cloudstack.api.response.SecurityGroupResponse; -import org.apache.cloudstack.api.response.ServiceOfferingResponse; -import org.apache.cloudstack.api.response.StoragePoolResponse; -import org.apache.cloudstack.api.response.UserResponse; -import org.apache.cloudstack.api.response.UserVmResponse; -import org.apache.cloudstack.api.response.VolumeResponse; -import org.apache.cloudstack.api.response.ZoneResponse; - -import com.cloud.api.query.dao.AccountJoinDao; -import com.cloud.api.query.dao.AsyncJobJoinDao; -import com.cloud.api.query.dao.DataCenterJoinDao; -import com.cloud.api.query.dao.DiskOfferingJoinDao; -import com.cloud.api.query.dao.DomainRouterJoinDao; -import com.cloud.api.query.dao.HostJoinDao; -import com.cloud.api.query.dao.InstanceGroupJoinDao; -import com.cloud.api.query.dao.ProjectAccountJoinDao; -import com.cloud.api.query.dao.ProjectInvitationJoinDao; -import com.cloud.api.query.dao.ProjectJoinDao; -import com.cloud.api.query.dao.ResourceTagJoinDao; -import com.cloud.api.query.dao.SecurityGroupJoinDao; -import com.cloud.api.query.dao.ServiceOfferingJoinDao; -import com.cloud.api.query.dao.StoragePoolJoinDao; -import com.cloud.api.query.dao.UserAccountJoinDao; -import com.cloud.api.query.dao.UserVmJoinDao; -import com.cloud.api.query.dao.VolumeJoinDao; -import com.cloud.api.query.vo.AccountJoinVO; -import com.cloud.api.query.vo.AsyncJobJoinVO; -import com.cloud.api.query.vo.DataCenterJoinVO; -import com.cloud.api.query.vo.DiskOfferingJoinVO; -import com.cloud.api.query.vo.DomainRouterJoinVO; -import com.cloud.api.query.vo.EventJoinVO; -import com.cloud.api.query.vo.HostJoinVO; -import com.cloud.api.query.vo.InstanceGroupJoinVO; -import com.cloud.api.query.vo.ProjectAccountJoinVO; -import com.cloud.api.query.vo.ProjectInvitationJoinVO; -import com.cloud.api.query.vo.ProjectJoinVO; -import com.cloud.api.query.vo.ResourceTagJoinVO; -import com.cloud.api.query.vo.SecurityGroupJoinVO; -import com.cloud.api.query.vo.ServiceOfferingJoinVO; -import com.cloud.api.query.vo.StoragePoolJoinVO; -import com.cloud.api.query.vo.UserAccountJoinVO; -import com.cloud.api.query.vo.UserVmJoinVO; -import com.cloud.api.query.vo.VolumeJoinVO; +import com.cloud.api.query.dao.*; +import com.cloud.api.query.vo.*; import com.cloud.async.AsyncJob; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; @@ -89,18 +29,8 @@ import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationService; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.AccountVlanMapVO; -import com.cloud.dc.ClusterVO; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; -import com.cloud.dc.Vlan; -import com.cloud.dc.VlanVO; -import com.cloud.dc.dao.AccountVlanMapDao; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.HostPodDao; -import com.cloud.dc.dao.VlanDao; +import com.cloud.dc.*; +import com.cloud.dc.dao.*; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.Event; @@ -112,65 +42,23 @@ import com.cloud.host.HostStats; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.IPAddressVO; -import com.cloud.network.IpAddress; -import com.cloud.network.LoadBalancerVO; -import com.cloud.network.Network; +import com.cloud.network.*; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; -import com.cloud.network.NetworkDomainVO; -import com.cloud.network.NetworkManager; -import com.cloud.network.NetworkModel; -import com.cloud.network.NetworkProfile; -import com.cloud.network.NetworkRuleConfigVO; -import com.cloud.network.NetworkVO; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.PhysicalNetworkVO; -import com.cloud.network.Site2SiteVpnGatewayVO; -import com.cloud.network.Site2SiteCustomerGatewayVO; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.as.AutoScalePolicy; -import com.cloud.network.as.AutoScalePolicyConditionMapVO; -import com.cloud.network.as.AutoScalePolicyVO; -import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO; -import com.cloud.network.as.AutoScaleVmGroupVO; -import com.cloud.network.as.AutoScaleVmProfileVO; -import com.cloud.network.as.ConditionVO; -import com.cloud.network.as.CounterVO; -import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao; -import com.cloud.network.as.dao.AutoScalePolicyDao; -import com.cloud.network.as.dao.AutoScaleVmGroupDao; -import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao; -import com.cloud.network.as.dao.AutoScaleVmProfileDao; -import com.cloud.network.as.dao.ConditionDao; -import com.cloud.network.as.dao.CounterDao; -import com.cloud.network.dao.FirewallRulesCidrsDao; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.LoadBalancerDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.PhysicalNetworkDao; -import com.cloud.network.dao.NetworkDomainDao; -import com.cloud.network.dao.NetworkRuleConfigDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; -import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao; -import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; -import com.cloud.network.dao.Site2SiteVpnGatewayDao; -import com.cloud.network.dao.Site2SiteCustomerGatewayDao; +import com.cloud.network.as.*; +import com.cloud.network.as.dao.*; +import com.cloud.network.dao.*; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.SecurityGroupVO; import com.cloud.network.security.dao.SecurityGroupDao; -import com.cloud.network.vpc.StaticRouteVO; -import com.cloud.network.vpc.VpcGatewayVO; -import com.cloud.network.vpc.VpcManager; -import com.cloud.network.vpc.VpcOffering; -import com.cloud.network.vpc.VpcVO; +import com.cloud.network.vpc.*; import com.cloud.network.vpc.dao.StaticRouteDao; +import com.cloud.network.vpc.dao.VpcDao; import com.cloud.network.vpc.dao.VpcGatewayDao; import com.cloud.network.vpc.dao.VpcOfferingDao; import com.cloud.offering.DiskOffering; @@ -183,57 +71,16 @@ import com.cloud.projects.ProjectAccount; import com.cloud.projects.ProjectInvitation; import com.cloud.projects.ProjectService; import com.cloud.resource.ResourceManager; -import com.cloud.server.Criteria; -import com.cloud.server.ManagementServer; -import com.cloud.server.ResourceTag; +import com.cloud.server.*; import com.cloud.server.ResourceTag.TaggedResourceType; -import com.cloud.server.StatsCollector; -import com.cloud.server.TaggedResourceService; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.GuestOS; -import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.Snapshot; -import com.cloud.storage.SnapshotVO; +import com.cloud.storage.*; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.StorageStats; -import com.cloud.storage.UploadVO; -import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateS3VO; -import com.cloud.storage.VMTemplateSwiftVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; import com.cloud.storage.Volume.Type; -import com.cloud.storage.VolumeHostVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.GuestOSCategoryDao; -import com.cloud.storage.dao.GuestOSDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.SnapshotPolicyDao; -import com.cloud.storage.dao.StoragePoolDao; -import com.cloud.storage.dao.UploadDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateDetailsDao; -import com.cloud.storage.dao.VMTemplateHostDao; -import com.cloud.storage.dao.VMTemplateS3Dao; -import com.cloud.storage.dao.VMTemplateSwiftDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.dao.*; import com.cloud.storage.snapshot.SnapshotPolicy; -import com.cloud.user.Account; -import com.cloud.user.AccountDetailsDao; -import com.cloud.user.AccountVO; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.SSHKeyPairVO; -import com.cloud.user.User; -import com.cloud.user.UserAccount; -import com.cloud.user.UserStatisticsVO; -import com.cloud.user.UserVO; +import com.cloud.user.*; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.SSHKeyPairDao; import com.cloud.user.dao.UserDao; @@ -242,23 +89,13 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentLocator; -import com.cloud.vm.ConsoleProxyVO; -import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.InstanceGroup; -import com.cloud.vm.InstanceGroupVO; -import com.cloud.vm.NicProfile; -import com.cloud.vm.UserVmDetailVO; -import com.cloud.vm.UserVmManager; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VmStats; -import com.cloud.vm.dao.ConsoleProxyDao; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.dao.UserVmDetailsDao; -import com.cloud.vm.dao.VMInstanceDao; -import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.vm.*; +import com.cloud.vm.dao.*; +import org.apache.cloudstack.api.ApiConstants.HostDetails; +import org.apache.cloudstack.api.ApiConstants.VMDetails; +import org.apache.cloudstack.api.response.*; + +import java.util.*; public class ApiDBUtils { private static ManagementServer _ms; @@ -699,7 +536,7 @@ public class ApiDBUtils { public static Snapshot findSnapshotById(long snapshotId) { SnapshotVO snapshot = _snapshotDao.findById(snapshotId); - if (snapshot != null && snapshot.getRemoved() == null && snapshot.getStatus() == Snapshot.Status.BackedUp) { + if (snapshot != null && snapshot.getRemoved() == null && snapshot.getState() == Snapshot.State.BackedUp) { return snapshot; } else { return null; http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4cbe8a47/server/src/com/cloud/api/ApiResponseHelper.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 1c8849a..3c80a68 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -16,125 +16,9 @@ // under the License. package com.cloud.api; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; - -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.ResponseGenerator; -import org.apache.log4j.Logger; - -import org.apache.cloudstack.acl.ControlledEntity; -import org.apache.cloudstack.acl.ControlledEntity.ACLType; -import org.apache.cloudstack.api.ApiConstants.HostDetails; -import org.apache.cloudstack.api.ApiConstants.VMDetails; -import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; -import org.apache.cloudstack.api.response.AccountResponse; - import com.cloud.api.query.ViewResponseHelper; -import com.cloud.api.query.vo.AccountJoinVO; -import com.cloud.api.query.vo.AsyncJobJoinVO; -import com.cloud.api.query.vo.ControlledViewEntity; -import com.cloud.api.query.vo.DataCenterJoinVO; -import com.cloud.api.query.vo.DiskOfferingJoinVO; -import com.cloud.api.query.vo.DomainRouterJoinVO; -import com.cloud.api.query.vo.EventJoinVO; -import com.cloud.api.query.vo.HostJoinVO; -import com.cloud.api.query.vo.InstanceGroupJoinVO; -import com.cloud.api.query.vo.ProjectAccountJoinVO; -import com.cloud.api.query.vo.ProjectInvitationJoinVO; -import com.cloud.api.query.vo.ProjectJoinVO; -import com.cloud.api.query.vo.ResourceTagJoinVO; -import com.cloud.api.query.vo.SecurityGroupJoinVO; -import com.cloud.api.query.vo.ServiceOfferingJoinVO; -import com.cloud.api.query.vo.StoragePoolJoinVO; -import com.cloud.api.query.vo.UserAccountJoinVO; -import com.cloud.api.query.vo.UserVmJoinVO; -import com.cloud.api.query.vo.VolumeJoinVO; +import com.cloud.api.query.vo.*; import com.cloud.api.response.ApiResponseSerializer; -import org.apache.cloudstack.api.response.AsyncJobResponse; -import org.apache.cloudstack.api.response.AutoScalePolicyResponse; -import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse; -import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse; -import org.apache.cloudstack.api.response.CapabilityResponse; -import org.apache.cloudstack.api.response.CapacityResponse; -import org.apache.cloudstack.api.response.ClusterResponse; -import org.apache.cloudstack.api.response.ConditionResponse; -import org.apache.cloudstack.api.response.ConfigurationResponse; -import org.apache.cloudstack.api.response.ControlledEntityResponse; -import org.apache.cloudstack.api.response.CounterResponse; -import org.apache.cloudstack.api.response.CreateCmdResponse; -import org.apache.cloudstack.api.response.DiskOfferingResponse; -import org.apache.cloudstack.api.response.DomainResponse; -import org.apache.cloudstack.api.response.DomainRouterResponse; -import org.apache.cloudstack.api.response.EventResponse; -import org.apache.cloudstack.api.response.ExtractResponse; -import org.apache.cloudstack.api.response.FirewallResponse; -import org.apache.cloudstack.api.response.FirewallRuleResponse; -import org.apache.cloudstack.api.response.GuestOSResponse; -import org.apache.cloudstack.api.response.HostResponse; -import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse; -import org.apache.cloudstack.api.response.ControlledViewEntityResponse; -import org.apache.cloudstack.api.response.IPAddressResponse; -import org.apache.cloudstack.api.response.InstanceGroupResponse; -import org.apache.cloudstack.api.response.IpForwardingRuleResponse; -import org.apache.cloudstack.api.response.LBStickinessPolicyResponse; -import org.apache.cloudstack.api.response.LBStickinessResponse; -import org.apache.cloudstack.api.response.LDAPConfigResponse; -import org.apache.cloudstack.api.response.LoadBalancerResponse; -import org.apache.cloudstack.api.response.NetworkACLResponse; -import org.apache.cloudstack.api.response.NetworkOfferingResponse; -import org.apache.cloudstack.api.response.NetworkResponse; -import org.apache.cloudstack.api.response.PhysicalNetworkResponse; -import org.apache.cloudstack.api.response.PodResponse; -import org.apache.cloudstack.api.response.PrivateGatewayResponse; -import org.apache.cloudstack.api.response.ProjectAccountResponse; -import org.apache.cloudstack.api.response.ProjectInvitationResponse; -import org.apache.cloudstack.api.response.ProjectResponse; -import org.apache.cloudstack.api.response.ProviderResponse; -import org.apache.cloudstack.api.response.RemoteAccessVpnResponse; -import org.apache.cloudstack.api.response.ResourceCountResponse; -import org.apache.cloudstack.api.response.ResourceLimitResponse; -import org.apache.cloudstack.api.response.ResourceTagResponse; -import org.apache.cloudstack.api.response.SecurityGroupResponse; -import org.apache.cloudstack.api.response.SecurityGroupRuleResponse; -import org.apache.cloudstack.api.response.ServiceOfferingResponse; -import org.apache.cloudstack.api.response.ServiceResponse; -import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse; -import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse; -import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse; -import org.apache.cloudstack.api.response.SnapshotPolicyResponse; -import org.apache.cloudstack.api.response.SnapshotResponse; -import org.apache.cloudstack.api.response.SnapshotScheduleResponse; -import org.apache.cloudstack.api.response.StaticRouteResponse; -import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse; -import org.apache.cloudstack.api.response.StoragePoolResponse; -import org.apache.cloudstack.api.response.SwiftResponse; -import org.apache.cloudstack.api.response.SystemVmInstanceResponse; -import org.apache.cloudstack.api.response.SystemVmResponse; -import org.apache.cloudstack.api.response.TemplatePermissionsResponse; -import org.apache.cloudstack.api.response.TemplateResponse; -import org.apache.cloudstack.api.response.TrafficTypeResponse; -import org.apache.cloudstack.api.response.UserResponse; -import org.apache.cloudstack.api.response.UserVmResponse; -import org.apache.cloudstack.api.response.VirtualRouterProviderResponse; -import org.apache.cloudstack.api.response.VlanIpRangeResponse; -import org.apache.cloudstack.api.response.VolumeResponse; -import org.apache.cloudstack.api.response.VpcOfferingResponse; -import org.apache.cloudstack.api.response.VpcResponse; -import org.apache.cloudstack.api.response.VpnUsersResponse; -import org.apache.cloudstack.api.response.ZoneResponse; - -import org.apache.cloudstack.api.response.S3Response; import com.cloud.async.AsyncJob; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityVO; @@ -143,53 +27,21 @@ import com.cloud.configuration.Configuration; import com.cloud.configuration.Resource.ResourceOwnerType; import com.cloud.configuration.ResourceCount; import com.cloud.configuration.ResourceLimit; -import com.cloud.dc.ClusterVO; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; -import com.cloud.dc.Pod; -import com.cloud.dc.StorageNetworkIpRange; -import com.cloud.dc.Vlan; +import com.cloud.dc.*; import com.cloud.dc.Vlan.VlanType; -import com.cloud.dc.VlanVO; import com.cloud.domain.Domain; import com.cloud.event.Event; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.hypervisor.HypervisorCapabilities; -import com.cloud.network.IPAddressVO; -import com.cloud.network.IpAddress; -import com.cloud.network.Network; +import com.cloud.network.*; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; -import com.cloud.network.NetworkProfile; -import com.cloud.network.NetworkVO; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetwork; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.PhysicalNetworkTrafficType; -import com.cloud.network.PhysicalNetworkVO; -import com.cloud.network.RemoteAccessVpn; -import com.cloud.network.Site2SiteCustomerGateway; -import com.cloud.network.Site2SiteVpnConnection; -import com.cloud.network.Site2SiteVpnGateway; -import com.cloud.network.VirtualRouterProvider; -import com.cloud.network.VpnUser; -import com.cloud.network.as.AutoScalePolicy; -import com.cloud.network.as.AutoScaleVmGroup; -import com.cloud.network.as.AutoScaleVmProfile; -import com.cloud.network.as.AutoScaleVmProfileVO; -import com.cloud.network.as.Condition; -import com.cloud.network.as.ConditionVO; -import com.cloud.network.as.Counter; +import com.cloud.network.as.*; import com.cloud.network.router.VirtualRouter; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.FirewallRuleVO; -import com.cloud.network.rules.LoadBalancer; -import com.cloud.network.rules.PortForwardingRule; -import com.cloud.network.rules.StaticNatRule; -import com.cloud.network.rules.StickinessPolicy; +import com.cloud.network.rules.*; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityRule; import com.cloud.network.security.SecurityRule.SecurityRuleType; @@ -207,25 +59,11 @@ import com.cloud.projects.ProjectInvitation; import com.cloud.server.Criteria; import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.TaggedResourceType; -import com.cloud.storage.GuestOS; -import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.S3; -import com.cloud.storage.Snapshot; +import com.cloud.storage.*; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.StorageStats; -import com.cloud.storage.Swift; -import com.cloud.storage.UploadVO; -import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateS3VO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.VMTemplateSwiftVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; -import com.cloud.storage.VolumeVO; import com.cloud.storage.snapshot.SnapshotPolicy; import com.cloud.storage.snapshot.SnapshotSchedule; import com.cloud.template.VirtualMachineTemplate; @@ -242,6 +80,21 @@ import com.cloud.vm.InstanceGroup; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.Type; +import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.acl.ControlledEntity.ACLType; +import org.apache.cloudstack.api.ApiConstants.HostDetails; +import org.apache.cloudstack.api.ApiConstants.VMDetails; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.ResponseGenerator; +import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; +import org.apache.cloudstack.api.response.*; +import org.apache.log4j.Logger; + +import java.text.DecimalFormat; +import java.util.*; + +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; public class ApiResponseHelper implements ResponseGenerator { @@ -378,7 +231,7 @@ public class ApiResponseHelper implements ResponseGenerator { snapshotResponse.setCreated(snapshot.getCreated()); snapshotResponse.setName(snapshot.getName()); snapshotResponse.setIntervalType(ApiDBUtils.getSnapshotIntervalTypes(snapshot.getId())); - snapshotResponse.setState(snapshot.getStatus()); + snapshotResponse.setState(snapshot.getState()); //set tag information List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Snapshot, snapshot.getId()); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4cbe8a47/server/src/com/cloud/storage/StorageManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 9897fa1..e5b49d0 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1887,8 +1887,8 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag throw new InvalidParameterValueException("unable to find a snapshot with id " + snapshotId); } - if (snapshotCheck.getStatus() != Snapshot.Status.BackedUp) { - throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.Status.BackedUp + " state yet and can't be used for volume creation"); + if (snapshotCheck.getState() != Snapshot.State.BackedUp) { + throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.State.BackedUp + " state yet and can't be used for volume creation"); } diskOfferingId = snapshotCheck.getDiskOfferingId(); @@ -2393,7 +2393,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag } // remove snapshots in Error state - List<SnapshotVO> snapshots = _snapshotDao.listAllByStatus(Snapshot.Status.Error); + List<SnapshotVO> snapshots = _snapshotDao.listAllByStatus(Snapshot.State.Error); for (SnapshotVO snapshotVO : snapshots) { try{ _snapshotDao.expunge(snapshotVO.getId()); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4cbe8a47/server/src/com/cloud/storage/dao/SnapshotDao.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/storage/dao/SnapshotDao.java b/server/src/com/cloud/storage/dao/SnapshotDao.java index b32d278..3b961f6 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDao.java +++ b/server/src/com/cloud/storage/dao/SnapshotDao.java @@ -16,15 +16,16 @@ // under the License. package com.cloud.storage.dao; -import java.util.List; - import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot.Type; import com.cloud.storage.SnapshotVO; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDao; +import com.cloud.utils.fsm.StateDao; + +import java.util.List; -public interface SnapshotDao extends GenericDao<SnapshotVO, Long> { +public interface SnapshotDao extends GenericDao<SnapshotVO, Long>, StateDao<Snapshot.State, Snapshot.Event, Snapshot> { List<SnapshotVO> listByVolumeId(long volumeId); List<SnapshotVO> listByVolumeId(Filter filter, long volumeId); SnapshotVO findNextSnapshot(long parentSnapId); @@ -39,7 +40,7 @@ public interface SnapshotDao extends GenericDao<SnapshotVO, Long> { List<SnapshotVO> listByHostId(Filter filter, long hostId); List<SnapshotVO> listByHostId(long hostId); public Long countSnapshotsForAccount(long accountId); - List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.Status... status); - List<SnapshotVO> listByStatus(long volumeId, Snapshot.Status... status); - List<SnapshotVO> listAllByStatus(Snapshot.Status... status); + List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.State... status); + List<SnapshotVO> listByStatus(long volumeId, Snapshot.State... status); + List<SnapshotVO> listAllByStatus(Snapshot.State... status); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4cbe8a47/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java index 65e2f5f..011022e 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -16,33 +16,27 @@ // under the License. package com.cloud.storage.dao; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.util.List; - -import javax.ejb.Local; - -import org.apache.log4j.Logger; - import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.Snapshot; +import com.cloud.storage.Snapshot.Event; +import com.cloud.storage.Snapshot.State; import com.cloud.storage.Snapshot.Type; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.utils.component.ComponentLocator; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.*; import com.cloud.utils.db.JoinBuilder.JoinType; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; -import com.cloud.utils.db.Transaction; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.VMInstanceDaoImpl; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.List; @Local (value={SnapshotDao.class}) public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements SnapshotDao { @@ -113,7 +107,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements public List<SnapshotVO> listByHostId(Filter filter, long hostId ) { SearchCriteria<SnapshotVO> sc = HostIdSearch.create(); sc.setParameters("hostId", hostId); - sc.setParameters("status", Snapshot.Status.BackedUp); + sc.setParameters("status", Snapshot.State.BackedUp); return listBy(sc, filter); } @@ -145,7 +139,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements HostIdSearch = createSearchBuilder(); HostIdSearch.and("hostId", HostIdSearch.entity().getSecHostId(), SearchCriteria.Op.EQ); - HostIdSearch.and("status", HostIdSearch.entity().getStatus(), SearchCriteria.Op.EQ); + HostIdSearch.and("status", HostIdSearch.entity().getState(), SearchCriteria.Op.EQ); HostIdSearch.done(); VolumeIdTypeSearch = createSearchBuilder(); @@ -172,7 +166,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements StatusSearch = createSearchBuilder(); StatusSearch.and("volumeId", StatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); - StatusSearch.and("status", StatusSearch.entity().getStatus(), SearchCriteria.Op.IN); + StatusSearch.and("status", StatusSearch.entity().getState(), SearchCriteria.Op.IN); StatusSearch.done(); CountSnapshotsByAccount = createSearchBuilder(Long.class); @@ -182,7 +176,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements CountSnapshotsByAccount.done(); InstanceIdSearch = createSearchBuilder(); - InstanceIdSearch.and("status", InstanceIdSearch.entity().getStatus(), SearchCriteria.Op.IN); + InstanceIdSearch.and("status", InstanceIdSearch.entity().getState(), SearchCriteria.Op.IN); SearchBuilder<VMInstanceVO> instanceSearch = _instanceDao.createSearchBuilder(); instanceSearch.and("instanceId", instanceSearch.entity().getId(), SearchCriteria.Op.EQ); @@ -274,7 +268,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements } @Override - public List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.Status... status) { + public List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.State... status) { SearchCriteria<SnapshotVO> sc = this.InstanceIdSearch.create(); if (status != null && status.length != 0) { @@ -287,7 +281,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements } @Override - public List<SnapshotVO> listByStatus(long volumeId, Snapshot.Status... status) { + public List<SnapshotVO> listByStatus(long volumeId, Snapshot.State... status) { SearchCriteria<SnapshotVO> sc = this.StatusSearch.create(); sc.setParameters("volumeId", volumeId); sc.setParameters("status", (Object[])status); @@ -309,9 +303,20 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements } @Override - public List<SnapshotVO> listAllByStatus(Snapshot.Status... status) { + public List<SnapshotVO> listAllByStatus(Snapshot.State... status) { SearchCriteria<SnapshotVO> sc = this.StatusSearch.create(); sc.setParameters("status", (Object[])status); return listBy(sc, null); } + + @Override + public boolean updateState(State currentState, Event event, State nextState, Snapshot snapshot, Object data) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + SnapshotVO snapshotVO = (SnapshotVO)snapshot; + snapshotVO.setStatus(nextState); + super.update(snapshotVO.getId(), snapshotVO); + txn.commit(); + return true; + } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4cbe8a47/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index b7fcec7..9dc15a1 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -45,7 +45,6 @@ import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.resource.ResourceManager; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.*; -import com.cloud.storage.Snapshot.Status; import com.cloud.storage.Snapshot.Type; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.dao.*; @@ -66,6 +65,8 @@ import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.db.*; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.fsm.NoTransitionException; +import com.cloud.utils.fsm.StateMachine2; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; @@ -147,6 +148,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma private int _deltaSnapshotMax; private int _backupsnapshotwait; + private StateMachine2<Snapshot.State, Snapshot.Event, Snapshot> _snapshotFsm; + protected SearchBuilder<SnapshotVO> PolicySnapshotSearch; protected SearchBuilder<SnapshotPolicyVO> PoliciesForSnapSearch; @@ -211,6 +214,13 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (snapshot == null) { throw new CloudRuntimeException("Can not find snapshot " + snapshotId); } + + try { + stateTransitTo(snapshot, Snapshot.Event.CreateRequested); + } catch (NoTransitionException nte) { + s_logger.debug("Failed to update snapshot state due to " + nte.getMessage()); + } + // Send a ManageSnapshotCommand to the agent String vmName = _storageMgr.getVmNameOnVolume(volume); long volumeId = volume.getId(); @@ -241,14 +251,16 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (preSnapshotPath != null && preSnapshotPath.equals(answer.getSnapshotPath())) { // empty snapshot s_logger.debug("CreateSnapshot: this is empty snapshot "); - snapshot.setPath(preSnapshotPath); - snapshot.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId()); - snapshot.setSwiftId(preSnapshotVO.getSwiftId()); - - snapshot.setStatus(Snapshot.Status.BackedUp); - snapshot.setPrevSnapshotId(preId); - snapshot.setSecHostId(preSnapshotVO.getSecHostId()); - _snapshotDao.update(snapshotId, snapshot); + try { + snapshot.setPath(preSnapshotPath); + snapshot.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId()); + snapshot.setSwiftId(preSnapshotVO.getSwiftId()); + snapshot.setPrevSnapshotId(preId); + snapshot.setSecHostId(preSnapshotVO.getSecHostId()); + stateTransitTo(snapshot, Snapshot.Event.OperationSucceeded); + } catch (NoTransitionException nte) { + s_logger.debug("CreateSnapshot: failed to update state of snapshot due to " + nte.getMessage()); + } } else { long preSnapshotId = 0; @@ -298,6 +310,11 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (answer != null) { s_logger.error(answer.getDetails()); } + try { + stateTransitTo(snapshot, Snapshot.Event.OperationFailed); + } catch (NoTransitionException nte) { + s_logger.debug("Failed to update snapshot state due to " + nte.getMessage()); + } throw new CloudRuntimeException("Creating snapshot for volume " + volumeId + " on primary storage failed."); } @@ -362,7 +379,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } if(userVm.getHypervisorType() == HypervisorType.VMware || userVm.getHypervisorType() == HypervisorType.KVM) { - List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.Status.Creating, Snapshot.Status.CreatedOnPrimary, Snapshot.Status.BackingUp); + List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp); if(activeSnapshots.size() > 1) throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later"); } @@ -371,19 +388,15 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma snapshot = createSnapshotOnPrimary(volume, policyId, snapshotId); if (snapshot != null) { - if (snapshot.getStatus() == Snapshot.Status.CreatedOnPrimary) { + if (snapshot.getState() == Snapshot.State.CreatedOnPrimary) { backedUp = backupSnapshotToSecondaryStorage(snapshot); - } else if (snapshot.getStatus() == Snapshot.Status.BackedUp) { + } else if (snapshot.getState() == Snapshot.State.BackedUp) { // For empty snapshot we set status to BackedUp in createSnapshotOnPrimary backedUp = true; } else { - snapshot.setStatus(Status.Error); - _snapshotDao.update(snapshot.getId(), snapshot); throw new CloudRuntimeException("Failed to create snapshot: " + snapshot + " on primary storage"); } if (!backedUp) { - snapshot.setStatus(Status.Error); - _snapshotDao.update(snapshot.getId(), snapshot); throw new CloudRuntimeException("Created snapshot: " + snapshot + " on primary but failed to backup on secondary"); } } else { @@ -402,17 +415,9 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } if( !backedUp ) { - snapshot.setStatus(Status.Error); - _snapshotDao.update(snapshot.getId(), snapshot); } else { _resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot); } - } else { - snapshot = _snapshotDao.findById(snapshotId); - if (snapshot != null) { - snapshot.setStatus(Status.Error); - _snapshotDao.update(snapshotId, snapshot); - } } /* @@ -430,9 +435,12 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma private SnapshotVO updateDBOnCreate(Long id, String snapshotPath, long preSnapshotId) { SnapshotVO createdSnapshot = _snapshotDao.findByIdIncludingRemoved(id); createdSnapshot.setPath(snapshotPath); - createdSnapshot.setStatus(Snapshot.Status.CreatedOnPrimary); createdSnapshot.setPrevSnapshotId(preSnapshotId); - _snapshotDao.update(id, createdSnapshot); + try { + stateTransitTo(createdSnapshot, Snapshot.Event.OperationSucceeded); + } catch (NoTransitionException nte) { + s_logger.debug("Faile to update state of snapshot due to " + nte.getMessage()); + } return createdSnapshot; } @@ -574,9 +582,11 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma throw new CloudRuntimeException("Can not acquire lock for snapshot: " + ss); } try { - - snapshot.setStatus(Snapshot.Status.BackingUp); - _snapshotDao.update(snapshot.getId(), snapshot); + try { + stateTransitTo(snapshot, Snapshot.Event.BackupToSecondary); + } catch (NoTransitionException nte) { + s_logger.debug("Failed to update the state of snapshot while backing up snapshot"); + } long volumeId = snapshot.getVolumeId(); VolumeVO volume = _volsDao.lockRow(volumeId, true); @@ -657,10 +667,18 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (answer.isFull()) { snapshot.setPrevSnapshotId(0); } - snapshot.setStatus(Snapshot.Status.BackedUp); - _snapshotDao.update(snapshotId, snapshot); + try { + stateTransitTo(snapshot, Snapshot.Event.OperationSucceeded); + } catch (NoTransitionException nte) { + s_logger.debug("Failed to update the state of snapshot while backing up snapshot"); + } } else { + try { + stateTransitTo(snapshot, Snapshot.Event.OperationFailed); + } catch (NoTransitionException nte) { + s_logger.debug("Failed to update the state of snapshot while backing up snapshot"); + } s_logger.warn("Failed to back up snapshot on secondary storage, deleting the record from the DB"); _snapshotDao.remove(snapshotId); } @@ -739,7 +757,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma _accountMgr.checkAccess(caller, null, true, snapshotCheck); - if( !Status.BackedUp.equals(snapshotCheck.getStatus() ) ) { + if( !Snapshot.State.BackedUp.equals(snapshotCheck.getState() ) ) { throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status"); } @@ -764,7 +782,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma Transaction txn = Transaction.currentTxn(); txn.start(); _snapshotDao.remove(snapshotId); - if (snapshot.getStatus() == Snapshot.Status.BackedUp) { + if (snapshot.getState() == Snapshot.State.BackedUp) { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, 0L, snapshot.getClass().getName(), snapshot.getUuid()); @@ -919,7 +937,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma SearchBuilder<SnapshotVO> sb = _snapshotDao.createSearchBuilder(); _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); - sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ); + sb.and("status", sb.entity().getState(), SearchCriteria.Op.EQ); sb.and("volumeId", sb.entity().getVolumeId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); @@ -1405,6 +1423,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma s_logger.info("Snapshot Manager is configured."); + _snapshotFsm = Snapshot.State.getStateMachine(); + return true; } @@ -1491,11 +1511,15 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma @Override public boolean canOperateOnVolume(VolumeVO volume) { - List<SnapshotVO> snapshots = _snapshotDao.listByStatus(volume.getId(), Status.Creating, Status.CreatedOnPrimary, Status.BackingUp); + List<SnapshotVO> snapshots = _snapshotDao.listByStatus(volume.getId(), Snapshot.State.Creating, + Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp); if (snapshots.size() > 0) { return false; } return true; } + protected boolean stateTransitTo(Snapshot snapshot, Snapshot.Event e) throws NoTransitionException { + return _snapshotFsm.transitTo(snapshot, e, null, _snapshotDao); + } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4cbe8a47/server/src/com/cloud/vm/UserVmManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index a1227b2..68b2a29 100644 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1298,8 +1298,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager //check permissions _accountMgr.checkAccess(caller, null, true, snapshot); - if (snapshot.getStatus() != Snapshot.Status.BackedUp) { - throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.Status.BackedUp + " state yet and can't be used for template creation"); + if (snapshot.getState() != Snapshot.State.BackedUp) { + throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.State.BackedUp + " state yet and can't be used for template creation"); } /* http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/4cbe8a47/server/test/com/cloud/snapshot/SnapshotDaoTest.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/snapshot/SnapshotDaoTest.java b/server/test/com/cloud/snapshot/SnapshotDaoTest.java index c412f49..5dc9b91 100644 --- a/server/test/com/cloud/snapshot/SnapshotDaoTest.java +++ b/server/test/com/cloud/snapshot/SnapshotDaoTest.java @@ -16,24 +16,23 @@ // under the License. package com.cloud.snapshot; -import java.util.List; - import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.dao.SnapshotDaoImpl; import com.cloud.utils.component.ComponentLocator; - import junit.framework.Assert; import junit.framework.TestCase; +import java.util.List; + public class SnapshotDaoTest extends TestCase { public void testListBy() { SnapshotDaoImpl dao = ComponentLocator.inject(SnapshotDaoImpl.class); - List<SnapshotVO> snapshots = dao.listByInstanceId(3, Snapshot.Status.BackedUp); + List<SnapshotVO> snapshots = dao.listByInstanceId(3, Snapshot.State.BackedUp); for(SnapshotVO snapshot : snapshots) { - Assert.assertTrue(snapshot.getStatus() == Snapshot.Status.BackedUp); + Assert.assertTrue(snapshot.getState() == Snapshot.State.BackedUp); } } }
