diff --git a/core/src/com/cloud/agent/api/AttachVolumeAnswer.java b/core/src/com/cloud/agent/api/AttachVolumeAnswer.java index 6b965b05043..ee38775f5d4 100644 --- a/core/src/com/cloud/agent/api/AttachVolumeAnswer.java +++ b/core/src/com/cloud/agent/api/AttachVolumeAnswer.java @@ -27,6 +27,12 @@ public class AttachVolumeAnswer extends Answer { this.deviceId = null; } + public AttachVolumeAnswer(AttachVolumeCommand cmd, Long deviceId) { + super(cmd); + this.deviceId = deviceId; + this.vdiUuid = ""; + } + public AttachVolumeAnswer(AttachVolumeCommand cmd, Long deviceId, String vdiUuid) { super(cmd); this.deviceId = deviceId; diff --git a/core/src/com/cloud/agent/api/AttachVolumeCommand.java b/core/src/com/cloud/agent/api/AttachVolumeCommand.java index 2eb503ab099..49b2a706b4b 100644 --- a/core/src/com/cloud/agent/api/AttachVolumeCommand.java +++ b/core/src/com/cloud/agent/api/AttachVolumeCommand.java @@ -19,57 +19,57 @@ package com.cloud.agent.api; import com.cloud.storage.Storage.StoragePoolType; public class AttachVolumeCommand extends Command { - private boolean attach; - private boolean _managed; - private String vmName; - private StoragePoolType pooltype; - private String volumePath; - private String volumeName; - private Long deviceId; - private String chainInfo; - private String poolUuid; - private String _storageHost; - private int _storagePort; - private String _iScsiName; - private String _chapInitiatorUsername; - private String _chapInitiatorPassword; - private String _chapTargetUsername; - private String _chapTargetPassword; - private Long bytesReadRate; - private Long bytesWriteRate; - private Long iopsReadRate; - private Long iopsWriteRate; + private boolean attach; + private boolean _managed; + private String vmName; + private StoragePoolType pooltype; + private String volumePath; + private String volumeName; + private Long deviceId; + private String chainInfo; + private String poolUuid; + private String _storageHost; + private int _storagePort; + private String _iScsiName; + private String _chapInitiatorUsername; + private String _chapInitiatorPassword; + private String _chapTargetUsername; + private String _chapTargetPassword; + private Long bytesReadRate; + private Long bytesWriteRate; + private Long iopsReadRate; + private Long iopsWriteRate; - protected AttachVolumeCommand() { - } + protected AttachVolumeCommand() { + } public AttachVolumeCommand(boolean attach, boolean managed, String vmName, StoragePoolType pooltype, String volumePath, String volumeName, Long deviceId, String chainInfo) { - this.attach = attach; - this._managed = managed; - this.vmName = vmName; - this.pooltype = pooltype; - this.volumePath = volumePath; - this.volumeName = volumeName; - this.deviceId = deviceId; - this.chainInfo = chainInfo; - } + this.attach = attach; + this._managed = managed; + this.vmName = vmName; + this.pooltype = pooltype; + this.volumePath = volumePath; + this.volumeName = volumeName; + this.deviceId = deviceId; + this.chainInfo = chainInfo; + } - @Override + @Override public boolean executeInSequence() { return true; } - public boolean getAttach() { - return attach; - } + public boolean getAttach() { + return attach; + } - public String getVmName() { - return vmName; - } + public String getVmName() { + return vmName; + } - public StoragePoolType getPooltype() { + public StoragePoolType getPooltype() { return pooltype; } @@ -77,13 +77,13 @@ public class AttachVolumeCommand extends Command { this.pooltype = pooltype; } - public String getVolumePath() { - return volumePath; - } + public String getVolumePath() { + return volumePath; + } - public String getVolumeName() { + public String getVolumeName() { return volumeName; - } + } public Long getDeviceId() { return deviceId; @@ -109,61 +109,61 @@ public class AttachVolumeCommand extends Command { _storageHost = storageHost; } - public String getStorageHost() { - return _storageHost; - } + public String getStorageHost() { + return _storageHost; + } - public void setStoragePort(int storagePort) { - _storagePort = storagePort; - } + public void setStoragePort(int storagePort) { + _storagePort = storagePort; + } - public int getStoragePort() { - return _storagePort; - } + public int getStoragePort() { + return _storagePort; + } - public boolean isManaged() { + public boolean isManaged() { return _managed; } - public void set_iScsiName(String iScsiName) { - this._iScsiName = iScsiName; - } + public void set_iScsiName(String iScsiName) { + this._iScsiName = iScsiName; + } - public String get_iScsiName() { - return _iScsiName; - } + public String get_iScsiName() { + return _iScsiName; + } - public void setChapInitiatorUsername(String chapInitiatorUsername) { - _chapInitiatorUsername = chapInitiatorUsername; - } + public void setChapInitiatorUsername(String chapInitiatorUsername) { + _chapInitiatorUsername = chapInitiatorUsername; + } - public String getChapInitiatorUsername() { - return _chapInitiatorUsername; - } + public String getChapInitiatorUsername() { + return _chapInitiatorUsername; + } - public void setChapInitiatorPassword(String chapInitiatorPassword) { - _chapInitiatorPassword = chapInitiatorPassword; - } + public void setChapInitiatorPassword(String chapInitiatorPassword) { + _chapInitiatorPassword = chapInitiatorPassword; + } - public String getChapInitiatorPassword() { - return _chapInitiatorPassword; - } + public String getChapInitiatorPassword() { + return _chapInitiatorPassword; + } - public void setChapTargetUsername(String chapTargetUsername) { - _chapTargetUsername = chapTargetUsername; - } + public void setChapTargetUsername(String chapTargetUsername) { + _chapTargetUsername = chapTargetUsername; + } - public String getChapTargetUsername() { - return _chapTargetUsername; - } + public String getChapTargetUsername() { + return _chapTargetUsername; + } - public void setChapTargetPassword(String chapTargetPassword) { - _chapTargetPassword = chapTargetPassword; - } + public void setChapTargetPassword(String chapTargetPassword) { + _chapTargetPassword = chapTargetPassword; + } - public String getChapTargetPassword() { - return _chapTargetPassword; - } + public String getChapTargetPassword() { + return _chapTargetPassword; + } public void setBytesReadRate(Long bytesReadRate) { this.bytesReadRate = bytesReadRate; diff --git a/core/test/org/apache/cloudstack/api/agent/test/AttachVolumeAnswerTest.java b/core/test/org/apache/cloudstack/api/agent/test/AttachVolumeAnswerTest.java index 9e43d9f1793..0b2bb1f4f3f 100644 --- a/core/test/org/apache/cloudstack/api/agent/test/AttachVolumeAnswerTest.java +++ b/core/test/org/apache/cloudstack/api/agent/test/AttachVolumeAnswerTest.java @@ -33,7 +33,7 @@ public class AttachVolumeAnswerTest { String results = ""; AttachVolumeAnswer ava2 = new AttachVolumeAnswer(avc, results); Long deviceId = 10L; - AttachVolumeAnswer ava3 = new AttachVolumeAnswer(avc, deviceId, ""); + AttachVolumeAnswer ava3 = new AttachVolumeAnswer(avc, deviceId); @Test public void testGetDeviceId() { diff --git a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java index d9656b4c138..8cbda146669 100755 --- a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java +++ b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java @@ -98,10 +98,10 @@ public class DiskOfferingVO implements DiskOffering { private Boolean customizedIops; @Column(name="min_iops") - Long minIops; + private Long minIops; @Column(name="max_iops") - Long maxIops; + private Long maxIops; @Column(name = "sort_key") int sortKey; diff --git a/engine/schema/src/com/cloud/storage/VolumeVO.java b/engine/schema/src/com/cloud/storage/VolumeVO.java index 7b54f3df538..bd57f105bdc 100755 --- a/engine/schema/src/com/cloud/storage/VolumeVO.java +++ b/engine/schema/src/com/cloud/storage/VolumeVO.java @@ -71,10 +71,10 @@ public class VolumeVO implements Volume { Long size; @Column(name = "min_iops") - Long minIops; + private Long minIops; @Column(name = "max_iops") - Long maxIops; + private Long maxIops; @Column(name = "folder") String folder; @@ -155,8 +155,9 @@ public class VolumeVO implements Volume { String reservationId; // Real Constructor - public VolumeVO(Type type, String name, long dcId, long domainId, long accountId, long diskOfferingId, long size, - Long minIops, Long maxIops, String iScsiName) { + public VolumeVO(Type type, String name, long dcId, long domainId, + long accountId, long diskOfferingId, long size, + Long minIops, Long maxIops, String iScsiName) { this.volumeType = type; this.name = name; this.dataCenterId = dcId; @@ -171,8 +172,10 @@ public class VolumeVO implements Volume { this.uuid = UUID.randomUUID().toString(); } - public VolumeVO(String name, long dcId, long podId, long accountId, long domainId, Long instanceId, String folder, String path, - long size, Long minIops, Long maxIops, String iScsiName, Volume.Type vType) { + public VolumeVO(String name, long dcId, long podId, long accountId, + long domainId, Long instanceId, String folder, String path, + long size, Long minIops, Long maxIops, String iScsiName, + Volume.Type vType) { this.name = name; this.accountId = accountId; this.domainId = domainId; @@ -191,6 +194,27 @@ public class VolumeVO implements Volume { this.uuid = UUID.randomUUID().toString(); } + public VolumeVO(String name, long dcId, long podId, long accountId, + long domainId, Long instanceId, String folder, String path, + long size, Volume.Type vType) { + this.name = name; + this.accountId = accountId; + this.domainId = domainId; + this.instanceId = instanceId; + this.folder = folder; + this.path = path; + this.size = size; + this.minIops = null; + this.maxIops = null; + this._iScsiName = null; + this.podId = podId; + this.dataCenterId = dcId; + this.volumeType = vType; + this.state = Volume.State.Allocated; + this.recreatable = false; + this.uuid = UUID.randomUUID().toString(); + } + // Copy Constructor public VolumeVO(Volume that) { this(that.getName(), that.getDataCenterId(), that.getPodId(), that.getAccountId(), that.getDomainId(), that.getInstanceId(), diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 372cc1bebfb..18707369975 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -3972,7 +3972,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa throw new Exception("Unable to create a dummy VM for volume creation"); } - vmMo.createDisk(volumeDatastorePath, (int)(dsMo.getSummary().getFreeSpace() / (1024L * 1024L)), + vmMo.createDisk(volumeDatastorePath, getMBsFromBytes(dsMo.getSummary().getFreeSpace()), morDs, vmMo.getScsiDeviceControllerKey()); vmMo.detachDisk(volumeDatastorePath, false); } @@ -5054,7 +5054,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa synchronized (this) { s_logger.info("Delete file if exists in datastore to clear the way for creating the volume. file: " + volumeDatastorePath); VmwareHelper.deleteVolumeVmdkFiles(dsMo, vmdkName, dcMo); - vmMo.createDisk(volumeDatastorePath, (int) (dskch.getSize() / (1024L * 1024L)), morDatastore, -1); + vmMo.createDisk(volumeDatastorePath, getMBsFromBytes(dskch.getSize()), morDatastore, -1); vmMo.detachDisk(volumeDatastorePath, false); } @@ -5113,7 +5113,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // s_logger.info("Delete file if exists in datastore to clear the way for creating the volume. file: " + volumeDatastorePath); VmwareHelper.deleteVolumeVmdkFiles(dsMo, volumeUuid.toString(), dcMo); - vmMo.createDisk(volumeDatastorePath, (int) (dskch.getSize() / (1024L * 1024L)), morDatastore, vmMo.getScsiDeviceControllerKey()); + vmMo.createDisk(volumeDatastorePath, getMBsFromBytes(dskch.getSize()), morDatastore, vmMo.getScsiDeviceControllerKey()); vmMo.detachDisk(volumeDatastorePath, false); } @@ -5137,6 +5137,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } + private static int getMBsFromBytes(long bytes) { + return (int)(bytes / (1024L * 1024L)); + } + protected VirtualMachineMO prepareVolumeHostDummyVm(VmwareHypervisorHost hyperHost, DatastoreMO dsMo, String vmName) throws Exception { assert (hyperHost != null); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index c8e00da1f19..1f4b4342f5c 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -6591,7 +6591,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected VDI handleSrAndVdiAttach(String iqn, String storageHostName, - String chapInitiatorName, String chapInitiatorPassword) throws Exception { + String chapInitiatorName, String chapInitiatorPassword) throws Types.XenAPIException, XmlRpcException { VDI vdi = null; Connection conn = getConnection(); @@ -6612,7 +6612,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vdir.virtualSize = sr.getPhysicalSize(conn) - sr.getPhysicalUtilisation(conn) - getMetadata(sr.getPhysicalSize(conn)); if (vdir.virtualSize < 0) { - throw new Exception("VDI virtual size cannot be less than 0."); + throw new CloudRuntimeException("VDI virtual size cannot be less than 0."); } vdi = VDI.create(conn, vdir); diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java index 329f27f7779..df77d15f4d9 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java @@ -36,6 +36,7 @@ import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.exception.StorageUnavailableException; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.VolumeVO; @@ -120,21 +121,16 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { private SolidFireUtil.SolidFireAccount createSolidFireAccount(String sfAccountName, SolidFireConnection sfConnection) { - try { - String mVip = sfConnection.getManagementVip(); - int mPort = sfConnection.getManagementPort(); - String clusterAdminUsername = sfConnection.getClusterAdminUsername(); - String clusterAdminPassword = sfConnection.getClusterAdminPassword(); + String mVip = sfConnection.getManagementVip(); + int mPort = sfConnection.getManagementPort(); + String clusterAdminUsername = sfConnection.getClusterAdminUsername(); + String clusterAdminPassword = sfConnection.getClusterAdminPassword(); - long accountNumber = SolidFireUtil.createSolidFireAccount(mVip, mPort, - clusterAdminUsername, clusterAdminPassword, sfAccountName); + long accountNumber = SolidFireUtil.createSolidFireAccount(mVip, mPort, + clusterAdminUsername, clusterAdminPassword, sfAccountName); - return SolidFireUtil.getSolidFireAccountById(mVip, mPort, - clusterAdminUsername, clusterAdminPassword, accountNumber); - } - catch (Exception ex) { - throw new IllegalArgumentException(ex.getMessage()); - } + return SolidFireUtil.getSolidFireAccountById(mVip, mPort, + clusterAdminUsername, clusterAdminPassword, accountNumber); } private void updateCsDbWithAccountInfo(long csAccountId, SolidFireUtil.SolidFireAccount sfAccount) { @@ -225,7 +221,6 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { } private SolidFireUtil.SolidFireVolume createSolidFireVolume(VolumeInfo volumeInfo, SolidFireConnection sfConnection) - throws StorageUnavailableException, Exception { String mVip = sfConnection.getManagementVip(); int mPort = sfConnection.getManagementPort(); @@ -248,11 +243,11 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { iops = new Iops(volumeInfo.getMinIops(), volumeInfo.getMaxIops()); } - long sfVolumeId = SolidFireUtil.createSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, - volumeInfo.getName(), sfAccountId, volumeInfo.getSize(), true, - iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops()); + long sfVolumeId = SolidFireUtil.createSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, + volumeInfo.getName(), sfAccountId, volumeInfo.getSize(), true, + iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops()); - return SolidFireUtil.getSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolumeId); + return SolidFireUtil.getSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolumeId); } private static class Iops @@ -261,14 +256,14 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { private final long _maxIops; private final long _burstIops; - public Iops(long minIops, long maxIops) throws Exception + public Iops(long minIops, long maxIops) throws IllegalArgumentException { if (minIops <= 0 || maxIops <= 0) { - throw new Exception("The 'Min IOPS' and 'Max IOPS' values must be greater than 0."); + throw new IllegalArgumentException("The 'Min IOPS' and 'Max IOPS' values must be greater than 0."); } if (minIops > maxIops) { - throw new Exception("The 'Min IOPS' value cannot exceed the 'Max IOPS' value."); + throw new IllegalArgumentException("The 'Min IOPS' value cannot exceed the 'Max IOPS' value."); } _minIops = minIops; @@ -299,7 +294,6 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { } private void deleteSolidFireVolume(VolumeInfo volumeInfo, SolidFireConnection sfConnection) - throws StorageUnavailableException, Exception { Long storagePoolId = volumeInfo.getPoolId(); @@ -318,15 +312,10 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { } private String getSfAccountName(String csAccountUuid, long csAccountId) { - return "CloudStack_" + csAccountUuid + "_" + getRandomNumber() + "_" + csAccountId; + return "CloudStack_" + csAccountUuid + "_" + csAccountId; } - private static long getRandomNumber() - { - return Math.round(Math.random() * 1000000000); - } - - private boolean sfAccountExists(String sfAccountName, SolidFireConnection sfConnection) throws Exception { + private boolean sfAccountExists(String sfAccountName, SolidFireConnection sfConnection) { String mVip = sfConnection.getManagementVip(); int mPort = sfConnection.getManagementPort(); String clusterAdminUsername = sfConnection.getClusterAdminUsername(); @@ -349,55 +338,43 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { String errMsg = null; if (dataObject.getType() == DataObjectType.VOLUME) { - try { - VolumeInfo volumeInfo = (VolumeInfo)dataObject; - AccountVO account = _accountDao.findById(volumeInfo.getAccountId()); - String sfAccountName = getSfAccountName(account.getUuid(), account.getAccountId()); + VolumeInfo volumeInfo = (VolumeInfo)dataObject; + AccountVO account = _accountDao.findById(volumeInfo.getAccountId()); + String sfAccountName = getSfAccountName(account.getUuid(), account.getAccountId()); - long storagePoolId = dataStore.getId(); - SolidFireConnection sfConnection = getSolidFireConnection(storagePoolId); + long storagePoolId = dataStore.getId(); + SolidFireConnection sfConnection = getSolidFireConnection(storagePoolId); - if (!sfAccountExists(sfAccountName, sfConnection)) { - SolidFireUtil.SolidFireAccount sfAccount = createSolidFireAccount(sfAccountName, - sfConnection); + if (!sfAccountExists(sfAccountName, sfConnection)) { + SolidFireUtil.SolidFireAccount sfAccount = createSolidFireAccount(sfAccountName, + sfConnection); - updateCsDbWithAccountInfo(account.getId(), sfAccount); - } - - SolidFireUtil.SolidFireVolume sfVolume = createSolidFireVolume(volumeInfo, sfConnection); - - iqn = sfVolume.getIqn(); - - VolumeVO volume = this._volumeDao.findById(volumeInfo.getId()); - - volume.set_iScsiName(iqn); - volume.setFolder(String.valueOf(sfVolume.getId())); - volume.setPoolType(StoragePoolType.IscsiLUN); - volume.setPoolId(storagePoolId); - - _volumeDao.update(volume.getId(), volume); - - StoragePoolVO storagePool = _storagePoolDao.findById(dataStore.getId()); - - long capacityBytes = storagePool.getCapacityBytes(); - long usedBytes = storagePool.getUsedBytes(); - - usedBytes += volumeInfo.getSize(); - - if (usedBytes > capacityBytes) { - usedBytes = capacityBytes; - } - - storagePool.setUsedBytes(usedBytes); - - _storagePoolDao.update(storagePoolId, storagePool); - } catch (StorageUnavailableException e) { - s_logger.error("Failed to create volume (StorageUnavailableException)", e); - errMsg = e.toString(); - } catch (Exception e) { - s_logger.error("Failed to create volume (Exception)", e); - errMsg = e.toString(); + updateCsDbWithAccountInfo(account.getId(), sfAccount); } + + SolidFireUtil.SolidFireVolume sfVolume = createSolidFireVolume(volumeInfo, sfConnection); + + iqn = sfVolume.getIqn(); + + VolumeVO volume = this._volumeDao.findById(volumeInfo.getId()); + + volume.set_iScsiName(iqn); + volume.setFolder(String.valueOf(sfVolume.getId())); + volume.setPoolType(StoragePoolType.IscsiLUN); + volume.setPoolId(storagePoolId); + + _volumeDao.update(volume.getId(), volume); + + StoragePoolVO storagePool = _storagePoolDao.findById(dataStore.getId()); + + long capacityBytes = storagePool.getCapacityBytes(); + long usedBytes = storagePool.getUsedBytes(); + + usedBytes += volumeInfo.getSize(); + + storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes); + + _storagePoolDao.update(storagePoolId, storagePool); } else { errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to createAsync"; @@ -412,7 +389,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { callback.complete(result); } - private void deleteSolidFireAccount(long sfAccountId, SolidFireConnection sfConnection) throws Exception { + private void deleteSolidFireAccount(long sfAccountId, SolidFireConnection sfConnection) { String mVip = sfConnection.getManagementVip(); int mPort = sfConnection.getManagementPort(); String clusterAdminUsername = sfConnection.getClusterAdminUsername(); @@ -433,7 +410,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { SolidFireUtil.deleteSolidFireAccount(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfAccountId); } - private boolean sfAccountHasVolume(long sfAccountId, SolidFireConnection sfConnection) throws Exception { + private boolean sfAccountHasVolume(long sfAccountId, SolidFireConnection sfConnection) { String mVip = sfConnection.getManagementVip(); int mPort = sfConnection.getManagementPort(); String clusterAdminUsername = sfConnection.getClusterAdminUsername(); @@ -459,48 +436,36 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { String errMsg = null; if (dataObject.getType() == DataObjectType.VOLUME) { - try { - VolumeInfo volumeInfo = (VolumeInfo)dataObject; - AccountVO account = _accountDao.findById(volumeInfo.getAccountId()); - AccountDetailVO accountDetails = _accountDetailsDao.findDetail(account.getAccountId(), SolidFireUtil.ACCOUNT_ID); - long sfAccountId = Long.parseLong(accountDetails.getValue()); + VolumeInfo volumeInfo = (VolumeInfo)dataObject; + AccountVO account = _accountDao.findById(volumeInfo.getAccountId()); + AccountDetailVO accountDetails = _accountDetailsDao.findDetail(account.getAccountId(), SolidFireUtil.ACCOUNT_ID); + long sfAccountId = Long.parseLong(accountDetails.getValue()); - long storagePoolId = dataStore.getId(); - SolidFireConnection sfConnection = getSolidFireConnection(storagePoolId); + long storagePoolId = dataStore.getId(); + SolidFireConnection sfConnection = getSolidFireConnection(storagePoolId); - deleteSolidFireVolume(volumeInfo, sfConnection); + deleteSolidFireVolume(volumeInfo, sfConnection); - _volumeDao.deleteVolumesByInstance(volumeInfo.getId()); + _volumeDao.deleteVolumesByInstance(volumeInfo.getId()); - if (!sfAccountHasVolume(sfAccountId, sfConnection)) { - // delete the account from the SolidFire SAN - deleteSolidFireAccount(sfAccountId, sfConnection); + if (!sfAccountHasVolume(sfAccountId, sfConnection)) { + // delete the account from the SolidFire SAN + deleteSolidFireAccount(sfAccountId, sfConnection); - // delete the info in the account_details table - // that's related to the SolidFire account - _accountDetailsDao.deleteDetails(account.getAccountId()); - } - - StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId); - - long usedBytes = storagePool.getUsedBytes(); - - usedBytes -= volumeInfo.getSize(); - - if (usedBytes < 0) { - usedBytes = 0; - } - - storagePool.setUsedBytes(usedBytes); - - _storagePoolDao.update(storagePoolId, storagePool); - } catch (StorageUnavailableException e) { - s_logger.error("Failed to create volume (StorageUnavailableException)", e); - errMsg = e.toString(); - } catch (Exception e) { - s_logger.error("Failed to create volume (Exception)", e); - errMsg = e.toString(); + // delete the info in the account_details table + // that's related to the SolidFire account + _accountDetailsDao.deleteDetails(account.getAccountId()); } + + StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId); + + long usedBytes = storagePool.getUsedBytes(); + + usedBytes -= volumeInfo.getSize(); + + storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes); + + _storagePoolDao.update(storagePoolId, storagePool); } else { errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to deleteAsync"; @@ -515,6 +480,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { @Override public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { + throw new UnsupportedOperationException(); } @Override @@ -524,13 +490,16 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { @Override public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { + throw new UnsupportedOperationException(); } @Override public void resize(DataObject data, AsyncCompletionCallback callback) { + throw new UnsupportedOperationException(); } @Override public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { + throw new UnsupportedOperationException(); } } diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java index 28864ea801e..9c784ba023a 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java @@ -35,12 +35,11 @@ import com.cloud.utils.component.ComponentContext; @Component public class SolidfirePrimaryDataStoreProvider implements PrimaryDataStoreProvider { - protected DataStoreLifeCycle lifecycle; - protected PrimaryDataStoreDriver driver; - protected HypervisorHostListener listener; + private DataStoreLifeCycle lifecycle; + private PrimaryDataStoreDriver driver; + private HypervisorHostListener listener; SolidfirePrimaryDataStoreProvider() { - } @Override diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java index 26766e8dd70..3570dc0414c 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java @@ -18,7 +18,10 @@ package org.apache.cloudstack.storage.datastore.util; import java.io.BufferedReader; import java.io.InputStreamReader; +import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.net.URI; +import java.net.URISyntaxException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; @@ -35,6 +38,7 @@ import org.apache.http.HttpResponse; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.ClientProtocolException; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; @@ -42,12 +46,13 @@ import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.BasicClientConnectionManager; +import com.cloud.utils.exception.CloudRuntimeException; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class SolidFireUtil { - public static final String PROVIDER_NAME = "SolidFire"; + public static final String PROVIDER_NAME = "SolidFire"; public static final String MANAGEMENT_VIP = "mVip"; public static final String STORAGE_VIP = "sVip"; @@ -66,38 +71,38 @@ public class SolidFireUtil public static final String CHAP_TARGET_USERNAME = "chapTargetUsername"; public static final String CHAP_TARGET_SECRET = "chapTargetSecret"; - public static long createSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, - String strSfVolumeName, long lSfAccountId, long lTotalSize, boolean bEnable512e, - long lMinIops, long lMaxIops, long lBurstIops) throws Exception - { - final Gson gson = new GsonBuilder().create(); - - VolumeToCreate volumeToCreate = new VolumeToCreate(strSfVolumeName, lSfAccountId, lTotalSize, bEnable512e, - lMinIops, lMaxIops, lBurstIops); - - String strVolumeToCreateJson = gson.toJson(volumeToCreate); - - String strVolumeCreateResultJson = executeJsonRpc(strVolumeToCreateJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); - - VolumeCreateResult volumeCreateResult = gson.fromJson(strVolumeCreateResultJson, VolumeCreateResult.class); - - verifyResult(volumeCreateResult.result, strVolumeCreateResultJson, gson); - - return volumeCreateResult.result.volumeID; - } - - public static void deleteSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVolumeId) throws Exception - { - final Gson gson = new GsonBuilder().create(); - - VolumeToDelete volumeToDelete = new VolumeToDelete(lVolumeId); - - String strVolumeToDeleteJson = gson.toJson(volumeToDelete); - - executeJsonRpc(strVolumeToDeleteJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); - } + public static long createSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, + String strSfVolumeName, long lSfAccountId, long lTotalSize, boolean bEnable512e, + long lMinIops, long lMaxIops, long lBurstIops) + { + final Gson gson = new GsonBuilder().create(); - public static void purgeSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVolumeId) throws Exception + VolumeToCreate volumeToCreate = new VolumeToCreate(strSfVolumeName, lSfAccountId, lTotalSize, bEnable512e, + lMinIops, lMaxIops, lBurstIops); + + String strVolumeToCreateJson = gson.toJson(volumeToCreate); + + String strVolumeCreateResultJson = executeJsonRpc(strVolumeToCreateJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); + + VolumeCreateResult volumeCreateResult = gson.fromJson(strVolumeCreateResultJson, VolumeCreateResult.class); + + verifyResult(volumeCreateResult.result, strVolumeCreateResultJson, gson); + + return volumeCreateResult.result.volumeID; + } + + public static void deleteSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVolumeId) + { + final Gson gson = new GsonBuilder().create(); + + VolumeToDelete volumeToDelete = new VolumeToDelete(lVolumeId); + + String strVolumeToDeleteJson = gson.toJson(volumeToDelete); + + executeJsonRpc(strVolumeToDeleteJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); + } + + public static void purgeSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVolumeId) { final Gson gson = new GsonBuilder().create(); @@ -108,31 +113,31 @@ public class SolidFireUtil executeJsonRpc(strVolumeToPurgeJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); } - public static SolidFireVolume getSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVolumeId) throws Exception - { - final Gson gson = new GsonBuilder().create(); - - VolumeToGet volumeToGet = new VolumeToGet(lVolumeId); - - String strVolumeToGetJson = gson.toJson(volumeToGet); - - String strVolumeGetResultJson = executeJsonRpc(strVolumeToGetJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); - - VolumeGetResult volumeGetResult = gson.fromJson(strVolumeGetResultJson, VolumeGetResult.class); - - verifyResult(volumeGetResult.result, strVolumeGetResultJson, gson); - - String strVolumeName = getVolumeName(volumeGetResult, lVolumeId); - String strVolumeIqn = getVolumeIqn(volumeGetResult, lVolumeId); - long lAccountId = getVolumeAccountId(volumeGetResult, lVolumeId); - String strVolumeStatus = getVolumeStatus(volumeGetResult, lVolumeId); - - return new SolidFireVolume(lVolumeId, strVolumeName, strVolumeIqn, lAccountId, strVolumeStatus); - } + public static SolidFireVolume getSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVolumeId) + { + final Gson gson = new GsonBuilder().create(); - public static List getSolidFireVolumesForAccountId(String strSfMvip, int iSfPort, - String strSfAdmin, String strSfPassword, long lAccountId) throws Exception - { + VolumeToGet volumeToGet = new VolumeToGet(lVolumeId); + + String strVolumeToGetJson = gson.toJson(volumeToGet); + + String strVolumeGetResultJson = executeJsonRpc(strVolumeToGetJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); + + VolumeGetResult volumeGetResult = gson.fromJson(strVolumeGetResultJson, VolumeGetResult.class); + + verifyResult(volumeGetResult.result, strVolumeGetResultJson, gson); + + String strVolumeName = getVolumeName(volumeGetResult, lVolumeId); + String strVolumeIqn = getVolumeIqn(volumeGetResult, lVolumeId); + long lAccountId = getVolumeAccountId(volumeGetResult, lVolumeId); + String strVolumeStatus = getVolumeStatus(volumeGetResult, lVolumeId); + + return new SolidFireVolume(lVolumeId, strVolumeName, strVolumeIqn, lAccountId, strVolumeStatus); + } + + public static List getSolidFireVolumesForAccountId(String strSfMvip, int iSfPort, + String strSfAdmin, String strSfPassword, long lAccountId) + { final Gson gson = new GsonBuilder().create(); VolumesToGetForAccount volumesToGetForAccount = new VolumesToGetForAccount(lAccountId); @@ -157,130 +162,135 @@ public class SolidFireUtil private static final String ACTIVE = "active"; - public static class SolidFireVolume - { - private final long _id; - private final String _name; - private final String _iqn; - private final long _accountId; - private final String _status; - - public SolidFireVolume(long id, String name, String iqn, - long accountId, String status) - { - _id = id; - _name = name; - _iqn = "/" + iqn + "/0"; - _accountId = accountId; - _status = status; - } - - public long getId() - { - return _id; - } - - public String getName() - { - return _name; - } - - public String getIqn() - { - return _iqn; - } - - public long getAccountId() - { - return _accountId; - } - - public boolean isActive() - { - return ACTIVE.equalsIgnoreCase(_status); - } - - @Override - public int hashCode() { - return (int)_id; + public static class SolidFireVolume + { + private final long _id; + private final String _name; + private final String _iqn; + private final long _accountId; + private final String _status; + + public SolidFireVolume(long id, String name, String iqn, + long accountId, String status) + { + _id = id; + _name = name; + _iqn = "/" + iqn + "/0"; + _accountId = accountId; + _status = status; } - + + public long getId() + { + return _id; + } + + public String getName() + { + return _name; + } + + public String getIqn() + { + return _iqn; + } + + public long getAccountId() + { + return _accountId; + } + + public boolean isActive() + { + return ACTIVE.equalsIgnoreCase(_status); + } + + @Override + public int hashCode() { + return _iqn.hashCode(); + } + @Override public String toString() { return _name; } - + @Override public boolean equals(Object obj) { - if (!(obj instanceof SolidFireVolume)) { + if (obj == null) { return false; } - + + if (!obj.getClass().equals(SolidFireVolume.class)) { + return false; + } + SolidFireVolume sfv = (SolidFireVolume)obj; - + if (_id == sfv._id && _name.equals(sfv._name) && - _iqn.equals(sfv._iqn) && isActive() == sfv.isActive()) { + _iqn.equals(sfv._iqn) && _accountId == sfv._accountId && + isActive() == sfv.isActive()) { return true; } - + return false; } } - - public static long createSolidFireAccount(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, - String strAccountName) throws Exception - { - final Gson gson = new GsonBuilder().create(); - - AccountToAdd accountToAdd = new AccountToAdd(strAccountName); - - String strAccountAddJson = gson.toJson(accountToAdd); - - String strAccountAddResultJson = executeJsonRpc(strAccountAddJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); - - AccountAddResult accountAddResult = gson.fromJson(strAccountAddResultJson, AccountAddResult.class); - - verifyResult(accountAddResult.result, strAccountAddResultJson, gson); - - return accountAddResult.result.accountID; - } - - public static void deleteSolidFireAccount(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, - long lAccountId) throws Exception - { - final Gson gson = new GsonBuilder().create(); - - AccountToRemove accountToRemove = new AccountToRemove(lAccountId); - - String strAccountToRemoveJson = gson.toJson(accountToRemove); - - executeJsonRpc(strAccountToRemoveJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); - } - - public static SolidFireAccount getSolidFireAccountById(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, - long lSfAccountId) throws Exception - { - final Gson gson = new GsonBuilder().create(); - - AccountToGetById accountToGetById = new AccountToGetById(lSfAccountId); - - String strAccountToGetByIdJson = gson.toJson(accountToGetById); - - String strAccountGetByIdResultJson = executeJsonRpc(strAccountToGetByIdJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); - - AccountGetResult accountGetByIdResult = gson.fromJson(strAccountGetByIdResultJson, AccountGetResult.class); - - verifyResult(accountGetByIdResult.result, strAccountGetByIdResultJson, gson); - - String strSfAccountName = accountGetByIdResult.result.account.username; - String strSfAccountInitiatorSecret = accountGetByIdResult.result.account.initiatorSecret; - String strSfAccountTargetSecret = accountGetByIdResult.result.account.targetSecret; - - return new SolidFireAccount(lSfAccountId, strSfAccountName, strSfAccountInitiatorSecret, strSfAccountTargetSecret); - } - public static SolidFireAccount getSolidFireAccountByName(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, - String strSfAccountName) throws Exception + public static long createSolidFireAccount(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, + String strAccountName) + { + final Gson gson = new GsonBuilder().create(); + + AccountToAdd accountToAdd = new AccountToAdd(strAccountName); + + String strAccountAddJson = gson.toJson(accountToAdd); + + String strAccountAddResultJson = executeJsonRpc(strAccountAddJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); + + AccountAddResult accountAddResult = gson.fromJson(strAccountAddResultJson, AccountAddResult.class); + + verifyResult(accountAddResult.result, strAccountAddResultJson, gson); + + return accountAddResult.result.accountID; + } + + public static void deleteSolidFireAccount(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, + long lAccountId) + { + final Gson gson = new GsonBuilder().create(); + + AccountToRemove accountToRemove = new AccountToRemove(lAccountId); + + String strAccountToRemoveJson = gson.toJson(accountToRemove); + + executeJsonRpc(strAccountToRemoveJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); + } + + public static SolidFireAccount getSolidFireAccountById(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, + long lSfAccountId) + { + final Gson gson = new GsonBuilder().create(); + + AccountToGetById accountToGetById = new AccountToGetById(lSfAccountId); + + String strAccountToGetByIdJson = gson.toJson(accountToGetById); + + String strAccountGetByIdResultJson = executeJsonRpc(strAccountToGetByIdJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); + + AccountGetResult accountGetByIdResult = gson.fromJson(strAccountGetByIdResultJson, AccountGetResult.class); + + verifyResult(accountGetByIdResult.result, strAccountGetByIdResultJson, gson); + + String strSfAccountName = accountGetByIdResult.result.account.username; + String strSfAccountInitiatorSecret = accountGetByIdResult.result.account.initiatorSecret; + String strSfAccountTargetSecret = accountGetByIdResult.result.account.targetSecret; + + return new SolidFireAccount(lSfAccountId, strSfAccountName, strSfAccountInitiatorSecret, strSfAccountTargetSecret); + } + + public static SolidFireAccount getSolidFireAccountByName(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, + String strSfAccountName) { final Gson gson = new GsonBuilder().create(); @@ -300,71 +310,75 @@ public class SolidFireUtil return new SolidFireAccount(lSfAccountId, strSfAccountName, strSfAccountInitiatorSecret, strSfAccountTargetSecret); } - - public static class SolidFireAccount - { - private final long _id; - private final String _name; - private final String _initiatorSecret; - private final String _targetSecret; - - public SolidFireAccount(long id, String name, String initiatorSecret, String targetSecret) - { - _id = id; - _name = name; - _initiatorSecret = initiatorSecret; - _targetSecret = targetSecret; - } - - public long getId() - { - return _id; - } - - public String getName() - { - return _name; - } - - public String getInitiatorSecret() - { - return _initiatorSecret; - } - - public String getTargetSecret() - { - return _targetSecret; - } - - @Override - public int hashCode() { - return (int)_id; - } - - @Override - public String toString() { - return _name; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof SolidFireAccount)) { - return false; - } - - SolidFireAccount sfa = (SolidFireAccount)obj; - - if (_id == sfa._id && _name.equals(sfa._name) && - _initiatorSecret.equals(sfa._initiatorSecret) && - _targetSecret.equals(sfa._targetSecret)) { - return true; - } - - return false; - } - } - public static List getDeletedVolumes(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword) throws Exception + public static class SolidFireAccount + { + private final long _id; + private final String _name; + private final String _initiatorSecret; + private final String _targetSecret; + + public SolidFireAccount(long id, String name, String initiatorSecret, String targetSecret) + { + _id = id; + _name = name; + _initiatorSecret = initiatorSecret; + _targetSecret = targetSecret; + } + + public long getId() + { + return _id; + } + + public String getName() + { + return _name; + } + + public String getInitiatorSecret() + { + return _initiatorSecret; + } + + public String getTargetSecret() + { + return _targetSecret; + } + + @Override + public int hashCode() { + return (_id + _name).hashCode(); + } + + @Override + public String toString() { + return _name; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + + if (!obj.getClass().equals(SolidFireAccount.class)) { + return false; + } + + SolidFireAccount sfa = (SolidFireAccount)obj; + + if (_id == sfa._id && _name.equals(sfa._name) && + _initiatorSecret.equals(sfa._initiatorSecret) && + _targetSecret.equals(sfa._targetSecret)) { + return true; + } + + return false; + } + } + + public static List getDeletedVolumes(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword) { final Gson gson = new GsonBuilder().create(); @@ -387,104 +401,104 @@ public class SolidFireUtil return deletedVolumes; } - - public static long createSolidFireVag(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, String strVagName) throws Exception - { - final Gson gson = new GsonBuilder().create(); - - VagToCreate vagToCreate = new VagToCreate(strVagName); - - String strVagCreateJson = gson.toJson(vagToCreate); - - String strVagCreateResultJson = executeJsonRpc(strVagCreateJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); - - VagCreateResult vagCreateResult = gson.fromJson(strVagCreateResultJson, VagCreateResult.class); - - verifyResult(vagCreateResult.result, strVagCreateResultJson, gson); - - return vagCreateResult.result.volumeAccessGroupID; - } - - public static void deleteSolidFireVag(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVagId) throws Exception - { - final Gson gson = new GsonBuilder().create(); - - VagToDelete vagToDelete = new VagToDelete(lVagId); - - String strVagToDeleteJson = gson.toJson(vagToDelete); - - executeJsonRpc(strVagToDeleteJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); - } - - @SuppressWarnings("unused") - private static final class VolumeToCreate - { - private final String method = "CreateVolume"; - private final VolumeToCreateParams params; - - private VolumeToCreate(final String strVolumeName, final long lAccountId, final long lTotalSize, - final boolean bEnable512e, final long lMinIOPS, final long lMaxIOPS, final long lBurstIOPS) - { - params = new VolumeToCreateParams(strVolumeName, lAccountId, lTotalSize, bEnable512e, - lMinIOPS, lMaxIOPS, lBurstIOPS); - } - - private static final class VolumeToCreateParams - { - private final String name; - private final long accountID; - private final long totalSize; - private final boolean enable512e; - private final VolumeToCreateParamsQoS qos; - - private VolumeToCreateParams(final String strVolumeName, final long lAccountId, final long lTotalSize, - final boolean bEnable512e, final long lMinIOPS, final long lMaxIOPS, final long lBurstIOPS) - { - name = strVolumeName; - accountID = lAccountId; - totalSize = lTotalSize; - enable512e = bEnable512e; - - qos = new VolumeToCreateParamsQoS(lMinIOPS, lMaxIOPS, lBurstIOPS); - } - - private static final class VolumeToCreateParamsQoS - { - private final long minIOPS; - private final long maxIOPS; - private final long burstIOPS; - - private VolumeToCreateParamsQoS(final long lMinIOPS, final long lMaxIOPS, final long lBurstIOPS) - { - minIOPS = lMinIOPS; - maxIOPS = lMaxIOPS; - burstIOPS = lBurstIOPS; - } - } - } - } - - @SuppressWarnings("unused") - private static final class VolumeToDelete - { - private final String method = "DeleteVolume"; - private final VolumeToDeleteParams params; - - private VolumeToDelete(final long lVolumeId) - { - params = new VolumeToDeleteParams(lVolumeId); - } - - private static final class VolumeToDeleteParams - { - private long volumeID; - - private VolumeToDeleteParams(final long lVolumeId) - { - volumeID = lVolumeId; - } - } - } + + public static long createSolidFireVag(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, String strVagName) + { + final Gson gson = new GsonBuilder().create(); + + VagToCreate vagToCreate = new VagToCreate(strVagName); + + String strVagCreateJson = gson.toJson(vagToCreate); + + String strVagCreateResultJson = executeJsonRpc(strVagCreateJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); + + VagCreateResult vagCreateResult = gson.fromJson(strVagCreateResultJson, VagCreateResult.class); + + verifyResult(vagCreateResult.result, strVagCreateResultJson, gson); + + return vagCreateResult.result.volumeAccessGroupID; + } + + public static void deleteSolidFireVag(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVagId) + { + final Gson gson = new GsonBuilder().create(); + + VagToDelete vagToDelete = new VagToDelete(lVagId); + + String strVagToDeleteJson = gson.toJson(vagToDelete); + + executeJsonRpc(strVagToDeleteJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword); + } + + @SuppressWarnings("unused") + private static final class VolumeToCreate + { + private final String method = "CreateVolume"; + private final VolumeToCreateParams params; + + private VolumeToCreate(final String strVolumeName, final long lAccountId, final long lTotalSize, + final boolean bEnable512e, final long lMinIOPS, final long lMaxIOPS, final long lBurstIOPS) + { + params = new VolumeToCreateParams(strVolumeName, lAccountId, lTotalSize, bEnable512e, + lMinIOPS, lMaxIOPS, lBurstIOPS); + } + + private static final class VolumeToCreateParams + { + private final String name; + private final long accountID; + private final long totalSize; + private final boolean enable512e; + private final VolumeToCreateParamsQoS qos; + + private VolumeToCreateParams(final String strVolumeName, final long lAccountId, final long lTotalSize, + final boolean bEnable512e, final long lMinIOPS, final long lMaxIOPS, final long lBurstIOPS) + { + name = strVolumeName; + accountID = lAccountId; + totalSize = lTotalSize; + enable512e = bEnable512e; + + qos = new VolumeToCreateParamsQoS(lMinIOPS, lMaxIOPS, lBurstIOPS); + } + + private static final class VolumeToCreateParamsQoS + { + private final long minIOPS; + private final long maxIOPS; + private final long burstIOPS; + + private VolumeToCreateParamsQoS(final long lMinIOPS, final long lMaxIOPS, final long lBurstIOPS) + { + minIOPS = lMinIOPS; + maxIOPS = lMaxIOPS; + burstIOPS = lBurstIOPS; + } + } + } + } + + @SuppressWarnings("unused") + private static final class VolumeToDelete + { + private final String method = "DeleteVolume"; + private final VolumeToDeleteParams params; + + private VolumeToDelete(final long lVolumeId) + { + params = new VolumeToDeleteParams(lVolumeId); + } + + private static final class VolumeToDeleteParams + { + private long volumeID; + + private VolumeToDeleteParams(final long lVolumeId) + { + volumeID = lVolumeId; + } + } + } @SuppressWarnings("unused") private static final class ListDeletedVolumes @@ -514,29 +528,29 @@ public class SolidFireUtil } } - @SuppressWarnings("unused") - private static final class VolumeToGet - { - private final String method = "ListActiveVolumes"; - private final VolumeToGetParams params; - - private VolumeToGet(final long lVolumeId) - { - params = new VolumeToGetParams(lVolumeId); - } - - private static final class VolumeToGetParams - { - private final long startVolumeID; - private final long limit = 1; - - private VolumeToGetParams(final long lVolumeId) - { - startVolumeID = lVolumeId; - } - } - } - + @SuppressWarnings("unused") + private static final class VolumeToGet + { + private final String method = "ListActiveVolumes"; + private final VolumeToGetParams params; + + private VolumeToGet(final long lVolumeId) + { + params = new VolumeToGetParams(lVolumeId); + } + + private static final class VolumeToGetParams + { + private final long startVolumeID; + private final long limit = 1; + + private VolumeToGetParams(final long lVolumeId) + { + startVolumeID = lVolumeId; + } + } + } + @SuppressWarnings("unused") private static final class VolumesToGetForAccount { @@ -559,76 +573,76 @@ public class SolidFireUtil } } - @SuppressWarnings("unused") - private static final class AccountToAdd - { - private final String method = "AddAccount"; - private final AccountToAddParams params; - - private AccountToAdd(final String strAccountName) - { - params = new AccountToAddParams(strAccountName); - } - - private static final class AccountToAddParams - { - private final String username; - - private AccountToAddParams(final String strAccountName) - { - username = strAccountName; - } - } - } - - @SuppressWarnings("unused") - private static final class AccountToRemove - { - private final String method = "RemoveAccount"; - private final AccountToRemoveParams params; - - private AccountToRemove(final long lAccountId) - { - params = new AccountToRemoveParams(lAccountId); - } - - private static final class AccountToRemoveParams - { - private long accountID; - - private AccountToRemoveParams(final long lAccountId) - { - accountID = lAccountId; - } - } - } - - @SuppressWarnings("unused") - private static final class AccountToGetById - { - private final String method = "GetAccountByID"; - private final AccountToGetByIdParams params; - - private AccountToGetById(final long lAccountId) - { - params = new AccountToGetByIdParams(lAccountId); - } - - private static final class AccountToGetByIdParams - { - private final long accountID; - - private AccountToGetByIdParams(final long lAccountId) - { - accountID = lAccountId; - } - } - } - + @SuppressWarnings("unused") + private static final class AccountToAdd + { + private final String method = "AddAccount"; + private final AccountToAddParams params; + + private AccountToAdd(final String strAccountName) + { + params = new AccountToAddParams(strAccountName); + } + + private static final class AccountToAddParams + { + private final String username; + + private AccountToAddParams(final String strAccountName) + { + username = strAccountName; + } + } + } + + @SuppressWarnings("unused") + private static final class AccountToRemove + { + private final String method = "RemoveAccount"; + private final AccountToRemoveParams params; + + private AccountToRemove(final long lAccountId) + { + params = new AccountToRemoveParams(lAccountId); + } + + private static final class AccountToRemoveParams + { + private long accountID; + + private AccountToRemoveParams(final long lAccountId) + { + accountID = lAccountId; + } + } + } + + @SuppressWarnings("unused") + private static final class AccountToGetById + { + private final String method = "GetAccountByID"; + private final AccountToGetByIdParams params; + + private AccountToGetById(final long lAccountId) + { + params = new AccountToGetByIdParams(lAccountId); + } + + private static final class AccountToGetByIdParams + { + private final long accountID; + + private AccountToGetByIdParams(final long lAccountId) + { + accountID = lAccountId; + } + } + } + @SuppressWarnings("unused") private static final class AccountToGetByName { - private final String method = "GetAccountName"; + private final String method = "GetAccountByName"; private final AccountToGetByNameParams params; private AccountToGetByName(final String strUsername) @@ -647,251 +661,271 @@ public class SolidFireUtil } } - @SuppressWarnings("unused") - private static final class VagToCreate - { - private final String method = "CreateVolumeAccessGroup"; - private final VagToCreateParams params; - - private VagToCreate(final String strVagName) - { - params = new VagToCreateParams(strVagName); - } - - private static final class VagToCreateParams - { - private final String name; - - private VagToCreateParams(final String strVagName) - { - name = strVagName; - } - } - } - - @SuppressWarnings("unused") - private static final class VagToDelete - { - private final String method = "DeleteVolumeAccessGroup"; - private final VagToDeleteParams params; - - private VagToDelete(final long lVagId) - { - params = new VagToDeleteParams(lVagId); - } - - private static final class VagToDeleteParams - { - private long volumeAccessGroupID; - - private VagToDeleteParams(final long lVagId) - { - volumeAccessGroupID = lVagId; - } - } - } - - private static final class VolumeCreateResult - { - private Result result; - - private static final class Result - { - private long volumeID; - } - } - - private static final class VolumeGetResult - { - private Result result; - - private static final class Result - { - private Volume[] volumes; - - private static final class Volume - { - private long volumeID; - private String name; - private String iqn; - private long accountID; - private String status; - } - } - } - - private static final class AccountAddResult - { - private Result result; - - private static final class Result - { - private long accountID; - } - } - - private static final class AccountGetResult - { - private Result result; - - private static final class Result - { - private Account account; - - private static final class Account - { - private long accountID; - private String username; - private String initiatorSecret; - private String targetSecret; - } - } - } - - private static final class VagCreateResult - { - private Result result; - - private static final class Result - { - private long volumeAccessGroupID; - } - } - - private static final class JsonError - { - private Error error; - - private static final class Error - { - private String message; - } - } - - private static DefaultHttpClient getHttpClient(int iPort) throws NoSuchAlgorithmException, KeyManagementException { - SSLContext sslContext = SSLContext.getInstance("SSL"); - X509TrustManager tm = new X509TrustManager() { - public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { + @SuppressWarnings("unused") + private static final class VagToCreate + { + private final String method = "CreateVolumeAccessGroup"; + private final VagToCreateParams params; + + private VagToCreate(final String strVagName) + { + params = new VagToCreateParams(strVagName); + } + + private static final class VagToCreateParams + { + private final String name; + + private VagToCreateParams(final String strVagName) + { + name = strVagName; + } + } + } + + @SuppressWarnings("unused") + private static final class VagToDelete + { + private final String method = "DeleteVolumeAccessGroup"; + private final VagToDeleteParams params; + + private VagToDelete(final long lVagId) + { + params = new VagToDeleteParams(lVagId); + } + + private static final class VagToDeleteParams + { + private long volumeAccessGroupID; + + private VagToDeleteParams(final long lVagId) + { + volumeAccessGroupID = lVagId; + } + } + } + + private static final class VolumeCreateResult + { + private Result result; + + private static final class Result + { + private long volumeID; + } + } + + private static final class VolumeGetResult + { + private Result result; + + private static final class Result + { + private Volume[] volumes; + + private static final class Volume + { + private long volumeID; + private String name; + private String iqn; + private long accountID; + private String status; + } + } + } + + private static final class AccountAddResult + { + private Result result; + + private static final class Result + { + private long accountID; + } + } + + private static final class AccountGetResult + { + private Result result; + + private static final class Result + { + private Account account; + + private static final class Account + { + private long accountID; + private String username; + private String initiatorSecret; + private String targetSecret; + } + } + } + + private static final class VagCreateResult + { + private Result result; + + private static final class Result + { + private long volumeAccessGroupID; + } + } + + private static final class JsonError + { + private Error error; + + private static final class Error + { + private String message; + } + } + + private static DefaultHttpClient getHttpClient(int iPort) { + try { + SSLContext sslContext = SSLContext.getInstance("SSL"); + X509TrustManager tm = new X509TrustManager() { + public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { + } + + public X509Certificate[] getAcceptedIssuers() { + return null; + } + }; + + sslContext.init(null, new TrustManager[] { tm }, new SecureRandom()); + + SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + SchemeRegistry registry = new SchemeRegistry(); + + registry.register(new Scheme("https", iPort, socketFactory)); + + BasicClientConnectionManager mgr = new BasicClientConnectionManager(registry); + DefaultHttpClient client = new DefaultHttpClient(); + + return new DefaultHttpClient(mgr, client.getParams()); + } + catch (NoSuchAlgorithmException ex) { + throw new CloudRuntimeException(ex.getMessage()); + } + catch (KeyManagementException ex) { + throw new CloudRuntimeException(ex.getMessage()); + } + } + + private static String executeJsonRpc(String strJsonToExecute, String strMvip, int iPort, + String strAdmin, String strPassword) + { + DefaultHttpClient httpClient = null; + StringBuilder sb = new StringBuilder(); + + try + { + StringEntity input = new StringEntity(strJsonToExecute); + + input.setContentType("application/json"); + + httpClient = getHttpClient(iPort); + + URI uri = new URI("https://" + strMvip + ":" + iPort + "/json-rpc/1.0"); + AuthScope authScope = new AuthScope(uri.getHost(), uri.getPort(), AuthScope.ANY_SCHEME); + UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(strAdmin, strPassword); + + httpClient.getCredentialsProvider().setCredentials(authScope, credentials); + + HttpPost postRequest = new HttpPost(uri); + + postRequest.setEntity(input); + + HttpResponse response = httpClient.execute(postRequest); + + if (!isSuccess(response.getStatusLine().getStatusCode())) + { + throw new CloudRuntimeException("Failed on JSON-RPC API call. HTTP error code = " + response.getStatusLine().getStatusCode()); } - public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { - } + BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); - public X509Certificate[] getAcceptedIssuers() { - return null; - } - }; - - sslContext.init(null, new TrustManager[] { tm }, new SecureRandom()); - - SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - SchemeRegistry registry = new SchemeRegistry(); - - registry.register(new Scheme("https", iPort, socketFactory)); - - BasicClientConnectionManager mgr = new BasicClientConnectionManager(registry); - DefaultHttpClient client = new DefaultHttpClient(); - - return new DefaultHttpClient(mgr, client.getParams()); - } - - private static String executeJsonRpc(String strJsonToExecute, String strMvip, int iPort, - String strAdmin, String strPassword) throws Exception - { - DefaultHttpClient httpClient = null; - StringBuilder sb = new StringBuilder(); - - try - { - StringEntity input = new StringEntity(strJsonToExecute); - - input.setContentType("application/json"); - - httpClient = getHttpClient(iPort); - - URI uri = new URI("https://" + strMvip + ":" + iPort + "/json-rpc/1.0"); - AuthScope authScope = new AuthScope(uri.getHost(), uri.getPort(), AuthScope.ANY_SCHEME); - UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(strAdmin, strPassword); - - httpClient.getCredentialsProvider().setCredentials(authScope, credentials); - - HttpPost postRequest = new HttpPost(uri); - - postRequest.setEntity(input); - - HttpResponse response = httpClient.execute(postRequest); - - if (!isSuccess(response.getStatusLine().getStatusCode())) - { - throw new RuntimeException("Failed on JSON-RPC API call. HTTP error code = " + response.getStatusLine().getStatusCode()); - } - - BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); - - String strOutput; - - - while ((strOutput = br.readLine()) != null) - { - sb.append(strOutput); - } - } finally { - if (httpClient != null) { - try { - httpClient.getConnectionManager().shutdown(); - } catch (Throwable t) {} - } - } - - return sb.toString(); - } - - private static boolean isSuccess(int iCode) { - return iCode >= 200 && iCode < 300; - } - - private static void verifyResult(Object obj, String strJson, Gson gson) throws IllegalStateException - { - if (obj != null) - { - return; - } - - JsonError jsonError = gson.fromJson(strJson, JsonError.class); - - if (jsonError != null) - { - throw new IllegalStateException(jsonError.error.message); - } - - throw new IllegalStateException("Problem with the following JSON: " + strJson); - } - - private static String getVolumeName(VolumeGetResult volumeGetResult, long lVolumeId) throws Exception - { - if (volumeGetResult.result.volumes != null && volumeGetResult.result.volumes.length == 1 && - volumeGetResult.result.volumes[0].volumeID == lVolumeId) - { - return volumeGetResult.result.volumes[0].name; - } - - throw new Exception("Could not determine the name of the volume, " + - "but the volume was created with an ID of " + lVolumeId + "."); - } - - private static String getVolumeIqn(VolumeGetResult volumeGetResult, long lVolumeId) throws Exception - { - if (volumeGetResult.result.volumes != null && volumeGetResult.result.volumes.length == 1 && - volumeGetResult.result.volumes[0].volumeID == lVolumeId) - { - return volumeGetResult.result.volumes[0].iqn; - } - - throw new Exception("Could not determine the IQN of the volume, " + - "but the volume was created with an ID of " + lVolumeId + "."); - } + String strOutput; - private static long getVolumeAccountId(VolumeGetResult volumeGetResult, long lVolumeId) throws Exception + while ((strOutput = br.readLine()) != null) + { + sb.append(strOutput); + } + } + catch (UnsupportedEncodingException ex) { + throw new CloudRuntimeException(ex.getMessage()); + } + catch (ClientProtocolException ex) { + throw new CloudRuntimeException(ex.getMessage()); + } + catch (IOException ex) { + throw new CloudRuntimeException(ex.getMessage()); + } + catch (URISyntaxException ex) { + throw new CloudRuntimeException(ex.getMessage()); + } + finally { + if (httpClient != null) { + try { + httpClient.getConnectionManager().shutdown(); + } catch (Exception t) {} + } + } + + return sb.toString(); + } + + private static boolean isSuccess(int iCode) { + return iCode >= 200 && iCode < 300; + } + + private static void verifyResult(Object obj, String strJson, Gson gson) throws IllegalStateException + { + if (obj != null) + { + return; + } + + JsonError jsonError = gson.fromJson(strJson, JsonError.class); + + if (jsonError != null) + { + throw new IllegalStateException(jsonError.error.message); + } + + throw new IllegalStateException("Problem with the following JSON: " + strJson); + } + + private static String getVolumeName(VolumeGetResult volumeGetResult, long lVolumeId) + { + if (volumeGetResult.result.volumes != null && volumeGetResult.result.volumes.length == 1 && + volumeGetResult.result.volumes[0].volumeID == lVolumeId) + { + return volumeGetResult.result.volumes[0].name; + } + + throw new CloudRuntimeException("Could not determine the name of the volume, " + + "but the volume was created with an ID of " + lVolumeId + "."); + } + + private static String getVolumeIqn(VolumeGetResult volumeGetResult, long lVolumeId) + { + if (volumeGetResult.result.volumes != null && volumeGetResult.result.volumes.length == 1 && + volumeGetResult.result.volumes[0].volumeID == lVolumeId) + { + return volumeGetResult.result.volumes[0].iqn; + } + + throw new CloudRuntimeException("Could not determine the IQN of the volume, " + + "but the volume was created with an ID of " + lVolumeId + "."); + } + + private static long getVolumeAccountId(VolumeGetResult volumeGetResult, long lVolumeId) { if (volumeGetResult.result.volumes != null && volumeGetResult.result.volumes.length == 1 && volumeGetResult.result.volumes[0].volumeID == lVolumeId) @@ -899,11 +933,11 @@ public class SolidFireUtil return volumeGetResult.result.volumes[0].accountID; } - throw new Exception("Could not determine the volume's account ID, " + + throw new CloudRuntimeException("Could not determine the volume's account ID, " + "but the volume was created with an ID of " + lVolumeId + "."); } - private static String getVolumeStatus(VolumeGetResult volumeGetResult, long lVolumeId) throws Exception + private static String getVolumeStatus(VolumeGetResult volumeGetResult, long lVolumeId) { if (volumeGetResult.result.volumes != null && volumeGetResult.result.volumes.length == 1 && volumeGetResult.result.volumes[0].volumeID == lVolumeId) @@ -911,7 +945,7 @@ public class SolidFireUtil return volumeGetResult.result.volumes[0].status; } - throw new Exception("Could not determine the status of the volume, " + + throw new CloudRuntimeException("Could not determine the status of the volume, " + "but the volume was created with an ID of " + lVolumeId + "."); } } diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 4b76dff5d5f..c2678fc6f9e 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -740,7 +740,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { txn.start(); VolumeVO volume = new VolumeVO(volumeName, zoneId, -1, -1, -1, - new Long(-1), null, null, 0, null, null, null, Volume.Type.DATADISK); + new Long(-1), null, null, 0, Volume.Type.DATADISK); volume.setPoolId(null); volume.setDataCenterId(zoneId); volume.setPodId(null); @@ -1012,7 +1012,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { txn.start(); VolumeVO volume = new VolumeVO(userSpecifiedName, -1, -1, -1, -1, - new Long(-1), null, null, 0, null, null, null, Volume.Type.DATADISK); + new Long(-1), null, null, 0, Volume.Type.DATADISK); volume.setPoolId(null); volume.setDataCenterId(zoneId); volume.setPodId(null);