Skip to content

Commit 43770e0

Browse files
author
Alena Prokharchyk
committed
CLOUDSTACK-4744: enhanced root admin API updateVolume with state/storageId parameters as a part of "Better control over first party objects" feature.
Also fixed existing bugs for the API: * corrected action event to be VOLUME.UPDATE (was VOLUME.ATTACH) * all parameters to update, should be optional - fixed that. If nothing is specified, the db object will remain with its original fields
1 parent b998fba commit 43770e0

5 files changed

Lines changed: 72 additions & 24 deletions

File tree

api/src/com/cloud/event/EventTypes.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ public class EventTypes {
188188
public static final String EVENT_VOLUME_DETAIL_UPDATE = "VOLUME.DETAIL.UPDATE";
189189
public static final String EVENT_VOLUME_DETAIL_ADD = "VOLUME.DETAIL.ADD";
190190
public static final String EVENT_VOLUME_DETAIL_REMOVE = "VOLUME.DETAIL.REMOVE";
191+
public static final String EVENT_VOLUME_UPDATE = "VOLUME.UPDATE";
192+
191193

192194
// Domains
193195
public static final String EVENT_DOMAIN_CREATE = "DOMAIN.CREATE";

api/src/com/cloud/storage/VolumeApiService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account acc
8484

8585
Snapshot allocSnapshot(Long volumeId, Long policyId)
8686
throws ResourceAllocationException;
87-
Volume updateVolume(UpdateVolumeCmd updateVolumeCmd);
87+
Volume updateVolume(long volumeId, String path, String state, Long storageId);
8888

8989
/**
9090
* Extracts the volume to a particular location.

api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,14 @@
2323
import org.apache.cloudstack.api.BaseAsyncCmd;
2424
import org.apache.cloudstack.api.Parameter;
2525
import org.apache.cloudstack.api.ServerApiException;
26-
import org.apache.cloudstack.api.response.UserVmResponse;
26+
import org.apache.cloudstack.api.response.StoragePoolResponse;
2727
import org.apache.cloudstack.api.response.VolumeResponse;
2828
import org.apache.cloudstack.context.CallContext;
29-
3029
import org.apache.log4j.Logger;
3130

3231
import com.cloud.event.EventTypes;
32+
import com.cloud.exception.InvalidParameterValueException;
3333
import com.cloud.storage.Volume;
34-
import com.cloud.user.Account;
3534

3635
@APICommand(name = "updateVolume", description="Updates the volume.", responseObject=VolumeResponse.class)
3736
public class UpdateVolumeCmd extends BaseAsyncCmd {
@@ -42,13 +41,18 @@ public class UpdateVolumeCmd extends BaseAsyncCmd {
4241
//////////////// API parameters /////////////////////
4342
/////////////////////////////////////////////////////
4443

45-
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class,
46-
required=true, description="the ID of the disk volume")
44+
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class, description="the ID of the disk volume")
4745
private Long id;
4846

49-
@Parameter(name=ApiConstants.PATH, type=CommandType.STRING,
50-
required=true, description="the path of the volume")
47+
@Parameter(name=ApiConstants.PATH, type=CommandType.STRING, description="The path of the volume")
5148
private String path;
49+
50+
@Parameter(name=ApiConstants.STORAGE_ID, type=CommandType.UUID, entityType=StoragePoolResponse.class,
51+
description="Destination storage pool UUID for the volume", since="4.3")
52+
private Long storageId;
53+
54+
@Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="The state of the volume", since="4.3")
55+
private String state;
5256

5357
/////////////////////////////////////////////////////
5458
/////////////////// Accessors ///////////////////////
@@ -61,6 +65,15 @@ public String getPath() {
6165
public Long getId() {
6266
return id;
6367
}
68+
69+
public Long getStorageId() {
70+
return storageId;
71+
}
72+
73+
public String getState() {
74+
return state;
75+
}
76+
6477

6578
/////////////////////////////////////////////////////
6679
/////////////// API Implementation///////////////////
@@ -83,25 +96,37 @@ public Long getInstanceId() {
8396
public long getEntityOwnerId() {
8497
Volume volume = _responseGenerator.findVolumeById(getId());
8598
if (volume == null) {
86-
return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
99+
throw new InvalidParameterValueException("Invalid volume id was provided");
87100
}
88101
return volume.getAccountId();
89102
}
90103

91104
@Override
92105
public String getEventType() {
93-
return EventTypes.EVENT_VOLUME_ATTACH;
106+
return EventTypes.EVENT_VOLUME_UPDATE;
94107
}
95108

96109
@Override
97110
public String getEventDescription() {
98-
return "adding detail to the volume: " + getId();
111+
StringBuffer desc = new StringBuffer();
112+
desc.append(" with");
113+
if (getPath() != null) {
114+
desc.append(" path " + getPath());
115+
}
116+
if (getStorageId() != null) {
117+
desc.append(", storage id " + getStorageId());
118+
}
119+
120+
if (getState() != null) {
121+
desc.append(", state " + getState());
122+
}
123+
return "Updating volume: " + getId() + desc.toString();
99124
}
100125

101126
@Override
102127
public void execute(){
103128
CallContext.current().setEventDetails("Volume Id: "+getId());
104-
Volume result = _volumeService.updateVolume(this);
129+
Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId());
105130
if (result != null) {
106131
VolumeResponse response = _responseGenerator.createVolumeResponse(result);
107132
response.setResponseName(getCommandName());

engine/schema/src/com/cloud/storage/VolumeVO.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.cloud.storage.Storage.StoragePoolType;
3636
import com.cloud.utils.NumbersUtil;
3737
import com.cloud.utils.db.GenericDao;
38+
import com.cloud.vm.VirtualMachine.State;
3839

3940
@Entity
4041
@Table(name = "volumes")
@@ -573,4 +574,10 @@ public Long getIsoId() {
573574
public void setIsoId(long isoId) {
574575
this.isoId =isoId;
575576
}
577+
578+
// don't use this directly, use volume state machine instead
579+
// This method is used by UpdateVolume as a part of "Better control over first class objects in CS"
580+
public void setState(State state) {
581+
this.state = state;
582+
}
576583
}

server/src/com/cloud/storage/VolumeApiServiceImpl.java

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,13 @@
2525

2626
import javax.inject.Inject;
2727

28-
import org.apache.log4j.Logger;
29-
3028
import org.apache.cloudstack.api.BaseCmd;
3129
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
3230
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
3331
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
3432
import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
3533
import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
3634
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
37-
import org.apache.cloudstack.api.command.user.volume.UpdateVolumeCmd;
3835
import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
3936
import org.apache.cloudstack.context.CallContext;
4037
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
@@ -67,6 +64,7 @@
6764
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
6865
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
6966
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
67+
import org.apache.log4j.Logger;
7068

7169
import com.cloud.agent.AgentManager;
7270
import com.cloud.agent.api.Answer;
@@ -1108,16 +1106,32 @@ public Volume attachVolumeToVM(AttachVolumeCmd command) {
11081106
}
11091107

11101108
@Override
1111-
public Volume updateVolume(UpdateVolumeCmd cmd) {
1112-
Long volumeId = cmd.getId();
1113-
String path = cmd.getPath();
1114-
1115-
if (path == null) {
1116-
throw new InvalidParameterValueException("Failed to update the volume as path was null");
1109+
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPDATE, eventDescription = "updating volume", async = true)
1110+
public Volume updateVolume(long volumeId, String path, String state, Long storageId) {
1111+
VolumeVO volume = _volumeDao.findById(volumeId);
1112+
1113+
if (path != null) {
1114+
volume.setPath(path);
11171115
}
1118-
1119-
VolumeVO volume = ApiDBUtils.findVolumeById(volumeId);
1120-
volume.setPath(path);
1116+
1117+
if (state != null) {
1118+
try {
1119+
Volume.State volumeState = Volume.State.valueOf(state);
1120+
volume.setState(volumeState);
1121+
}
1122+
catch(IllegalArgumentException ex) {
1123+
throw new InvalidParameterValueException("Invalid volume state specified");
1124+
}
1125+
}
1126+
1127+
if (storageId != null) {
1128+
StoragePool pool = _storagePoolDao.findById(storageId);
1129+
if (pool.getDataCenterId() != volume.getDataCenterId()) {
1130+
throw new InvalidParameterValueException("Invalid storageId specified; refers to the pool outside of the volume's zone");
1131+
}
1132+
volume.setPoolId(pool.getId());
1133+
}
1134+
11211135
_volumeDao.update(volumeId, volume);
11221136

11231137
return volume;

0 commit comments

Comments
 (0)