http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7fa1a86/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 1f625d3..824af6a 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -431,8 +431,8 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag } @Override - public boolean isLocalStorageActiveOnHost(Host host) { - List<StoragePoolHostVO> storagePoolHostRefs = _storagePoolHostDao.listByHostId(host.getId()); + public boolean isLocalStorageActiveOnHost(Long hostId) { + List<StoragePoolHostVO> storagePoolHostRefs = _storagePoolHostDao.listByHostId(hostId); for (StoragePoolHostVO storagePoolHostRef : storagePoolHostRefs) { StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolHostRef.getPoolId()); if (storagePool.getPoolType() == StoragePoolType.LVM || storagePool.getPoolType() == StoragePoolType.EXT) { @@ -652,7 +652,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag Pair<VolumeVO, String> volumeDetails = createVolumeFromSnapshot(volume, snapshot); if (volumeDetails != null) { createdVolume = volumeDetails.first(); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), createdVolume.getDataCenterId(), createdVolume.getId(), createdVolume.getName(), + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), createdVolume.getDataCenterId(), createdVolume.getId(), createdVolume.getName(), createdVolume.getDiskOfferingId(), null, createdVolume.getSize()); _usageEventDao.persist(usageEvent); } @@ -737,21 +737,21 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag @DB public VolumeVO copyVolumeFromSecToPrimary(VolumeVO volume, VMInstanceVO vm, VMTemplateVO template, DataCenterVO dc, HostPodVO pod, Long clusterId, ServiceOfferingVO offering, DiskOfferingVO diskOffering, List<StoragePoolVO> avoids, long size, HypervisorType hyperType) throws NoTransitionException { - + final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(avoids); DiskProfile dskCh = createDiskCharacteristics(volume, template, dc, diskOffering); dskCh.setHyperType(vm.getHypervisorType()); - // Find a suitable storage to create volume on + // Find a suitable storage to create volume on StoragePoolVO destPool = findStoragePool(dskCh, dc, pod, clusterId, null, vm, avoidPools); - - // Copy the volume from secondary storage to the destination storage pool + + // Copy the volume from secondary storage to the destination storage pool stateTransitTo(volume, Event.CopyRequested); VolumeHostVO volumeHostVO = _volumeHostDao.findByVolumeId(volume.getId()); HostVO secStorage = _hostDao.findById(volumeHostVO.getHostId()); String secondaryStorageURL = secStorage.getStorageUrl(); String[] volumePath = volumeHostVO.getInstallPath().split("/"); String volumeUUID = volumePath[volumePath.length - 1].split("\\.")[0]; - + CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), volumeUUID, destPool, secondaryStorageURL, false, _copyvolumewait); CopyVolumeAnswer cvAnswer; try { @@ -764,23 +764,23 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag if (cvAnswer == null || !cvAnswer.getResult()) { stateTransitTo(volume, Event.CopyFailed); throw new CloudRuntimeException("Failed to copy the volume from secondary storage to the destination primary storage pool."); - } + } Transaction txn = Transaction.currentTxn(); - txn.start(); + txn.start(); volume.setPath(cvAnswer.getVolumePath()); volume.setFolder(destPool.getPath()); volume.setPodId(destPool.getPodId()); - volume.setPoolId(destPool.getId()); + volume.setPoolId(destPool.getId()); volume.setPodId(destPool.getPodId()); - stateTransitTo(volume, Event.CopySucceeded); + stateTransitTo(volume, Event.CopySucceeded); UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), volume.getDiskOfferingId(), null, volume.getSize()); _usageEventDao.persist(usageEvent); _volumeHostDao.remove(volumeHostVO.getId()); txn.commit(); return volume; - + } - + @Override @DB public VolumeVO createVolume(VolumeVO volume, VMInstanceVO vm, VMTemplateVO template, DataCenterVO dc, HostPodVO pod, Long clusterId, ServiceOfferingVO offering, DiskOfferingVO diskOffering, @@ -975,7 +975,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag value = configDao.getValue(Config.RecreateSystemVmEnabled.key()); _recreateSystemVmEnabled = Boolean.parseBoolean(value); - + value = configDao.getValue(Config.StorageTemplateCleanupEnabled.key()); _templateCleanupEnabled = (value == null ? true : Boolean.parseBoolean(value)); @@ -1517,7 +1517,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag } if(sPool.getStatus() != StoragePoolStatus.Maintenance){ s_logger.warn("Unable to delete storage id: " + id +" due to it is not in Maintenance state"); - throw new InvalidParameterValueException("Unable to delete storage due to it is not in Maintenance state, id: " + id); + throw new InvalidParameterValueException("Unable to delete storage due to it is not in Maintenance state, id: " + id); } if (sPool.getPoolType().equals(StoragePoolType.LVM) || sPool.getPoolType().equals(StoragePoolType.EXT)) { s_logger.warn("Unable to delete local storage id:" + id); @@ -1546,7 +1546,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag " for this pool"); } } - + // First get the host_id from storage_pool_host_ref for given pool id StoragePoolVO lock = _storagePoolDao.acquireInLockTable(sPool.getId()); @@ -1740,10 +1740,10 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag return _volsDao.findById(volume.getId()); } - + /* * Upload the volume to secondary storage. - * + * */ @Override @DB @@ -1755,13 +1755,13 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag String volumeName = cmd.getVolumeName(); String url = cmd.getUrl(); String format = cmd.getFormat(); - + validateVolume(caller, ownerId, zoneId, volumeName, url, format); VolumeVO volume = persistVolume(caller, ownerId, zoneId, volumeName, url, cmd.getFormat()); _downloadMonitor.downloadVolumeToStorage(volume, zoneId, url, cmd.getChecksum(), ImageFormat.valueOf(format.toUpperCase())); - return volume; + return volume; } - + private boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format) throws ResourceAllocationException{ // permission check @@ -1769,7 +1769,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag // Check that the resource limit for volumes won't be exceeded _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.volume); - + // Verify that zone exists DataCenterVO zone = _dcDao.findById(zoneId); @@ -1781,22 +1781,22 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId); } - + if (url.toLowerCase().contains("file://")) { throw new InvalidParameterValueException("File:// type urls are currently unsupported"); } - + ImageFormat imgfmt = ImageFormat.valueOf(format.toUpperCase()); if (imgfmt == null) { throw new IllegalArgumentException("Image format is incorrect " + format + ". Supported formats are " + EnumUtils.listValues(ImageFormat.values())); } - + String userSpecifiedName = volumeName; if (userSpecifiedName == null) { userSpecifiedName = getRandomVolumeName(); } if((!url.toLowerCase().endsWith("vhd"))&&(!url.toLowerCase().endsWith("vhd.zip")) - &&(!url.toLowerCase().endsWith("vhd.bz2"))&&(!url.toLowerCase().endsWith("vhd.gz")) + &&(!url.toLowerCase().endsWith("vhd.bz2"))&&(!url.toLowerCase().endsWith("vhd.gz")) &&(!url.toLowerCase().endsWith("qcow2"))&&(!url.toLowerCase().endsWith("qcow2.zip")) &&(!url.toLowerCase().endsWith("qcow2.bz2"))&&(!url.toLowerCase().endsWith("qcow2.gz")) &&(!url.toLowerCase().endsWith("ova"))&&(!url.toLowerCase().endsWith("ova.zip")) @@ -1804,7 +1804,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag &&(!url.toLowerCase().endsWith("img"))&&(!url.toLowerCase().endsWith("raw"))){ throw new InvalidParameterValueException("Please specify a valid " + format.toLowerCase()); } - + if ((format.equalsIgnoreCase("vhd") && (!url.toLowerCase().endsWith(".vhd") && !url.toLowerCase().endsWith("vhd.zip") && !url.toLowerCase().endsWith("vhd.bz2") && !url.toLowerCase().endsWith("vhd.gz") )) || (format.equalsIgnoreCase("qcow2") && (!url.toLowerCase().endsWith(".qcow2") && !url.toLowerCase().endsWith("qcow2.zip") && !url.toLowerCase().endsWith("qcow2.bz2") && !url.toLowerCase().endsWith("qcow2.gz") )) || (format.equalsIgnoreCase("ova") && (!url.toLowerCase().endsWith(".ova") && !url.toLowerCase().endsWith("ova.zip") && !url.toLowerCase().endsWith("ova.bz2") && !url.toLowerCase().endsWith("ova.gz"))) @@ -1812,14 +1812,14 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag throw new InvalidParameterValueException("Please specify a valid URL. URL:" + url + " is an invalid for the format " + format.toLowerCase()); } validateUrl(url); - + return false; } - + private String validateUrl(String url){ try { URI uri = new URI(url); - if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("http") + if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("http") && !uri.getScheme().equalsIgnoreCase("https") && !uri.getScheme().equalsIgnoreCase("file"))) { throw new IllegalArgumentException("Unsupported scheme for url: " + url); } @@ -1840,16 +1840,16 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag } catch (UnknownHostException uhe) { throw new IllegalArgumentException("Unable to resolve " + host); } - + return uri.toString(); } catch (URISyntaxException e) { throw new IllegalArgumentException("Invalid URL " + url); } - + } - + private VolumeVO persistVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format) { - + Transaction txn = Transaction.currentTxn(); txn.start(); @@ -1860,7 +1860,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag volume.setAccountId(ownerId); volume.setDomainId(((caller == null) ? Domain.ROOT_DOMAIN : caller.getDomainId())); long diskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId(); - volume.setDiskOfferingId(diskOfferingId); + volume.setDiskOfferingId(diskOfferingId); //volume.setSize(size); volume.setInstanceId(null); volume.setUpdated(new Date()); @@ -1881,8 +1881,8 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag txn.commit(); return volume; } - - + + /* * Just allocate a volume in the database, don't send the createvolume cmd to hypervisor. The volume will be finally * created @@ -1984,7 +1984,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag * throw new UnsupportedServiceException("operation not supported, snapshot with id " + snapshotId + * " is created from ROOT volume"); * } - * + * */ } @@ -2189,7 +2189,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag s_logger.debug("Successfully set Capacity - " + totalOverProvCapacity + " for capacity type - " + capacityType + " , DataCenterId - " + storagePool.getDataCenterId() + ", HostOrPoolId - " + storagePool.getId() + ", PodId " + storagePool.getPodId()); } - + @Override public List<Long> getUpHostsInPool(long poolId) { SearchCriteria<Long> sc = UpHostsInPoolSearch.create(); @@ -2290,7 +2290,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag s_logger.warn("Unable to destroy " + vol.getId(), e); } } - + // remove snapshots in Error state List<SnapshotVO> snapshots = _snapshotDao.listAllByStatus(Snapshot.Status.Error); for (SnapshotVO snapshotVO : snapshots) { @@ -2300,7 +2300,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag s_logger.warn("Unable to destroy " + snapshotVO.getId(), e); } } - + } finally { scanLock.unlock(); } @@ -2439,7 +2439,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag s_logger.warn("problem cleaning up snapshots in secondary storage " + secondaryStorageHost, e2); } } - + //CleanUp volumes on Secondary Storage. for (HostVO secondaryStorageHost : secondaryStorageHosts) { try { @@ -2467,7 +2467,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag _volumeHostDao.remove(destroyedVolumeHostVO.getId()); } } - + }catch (Exception e2) { s_logger.warn("problem cleaning up volumes in secondary storage " + secondaryStorageHost, e2); } @@ -2899,14 +2899,14 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM."); } - // Check that volume is completely Uploaded + // Check that volume is completely Uploaded if (volume.getState() == Volume.State.UploadOp){ VolumeHostVO volumeHost = _volumeHostDao.findByVolumeId(volume.getId()); if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS){ throw new InvalidParameterValueException("Please specify a volume that is not uploading"); - } + } } - + // Check that the volume is not already destroyed if (volume.getState() != Volume.State.Destroy) { if (!destroyVolume(volume)) { @@ -3258,7 +3258,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag if (s_logger.isDebugEnabled()) { s_logger.debug("Checking if we need to prepare " + vols.size() + " volumes for " + vm); } - + boolean recreate = _recreateSystemVmEnabled; List<VolumeVO> recreateVols = new ArrayList<VolumeVO>(vols.size()); @@ -3270,7 +3270,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag } if (assignedPool == null && recreate) { assignedPool = _storagePoolDao.findById(vol.getPoolId()); - + } if (assignedPool != null || recreate) { Volume.State state = vol.getState(); @@ -3311,7 +3311,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); vm.addDisk(new VolumeTO(vol, pool)); } - + } } } else { @@ -3333,7 +3333,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag existingPool = _storagePoolDao.findById(vol.getPoolId()); s_logger.debug("existing pool: " + existingPool.getId()); } - + if (vol.getState() == Volume.State.Allocated || vol.getState() == Volume.State.Creating) { newVol = vol; } else { @@ -3422,7 +3422,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag if (toBeCreated.getTemplateId() != null) { template = _templateDao.findById(toBeCreated.getTemplateId()); } - + StoragePool pool = null; if (sPool != null) { pool = sPool; @@ -3506,27 +3506,27 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag if (s_logger.isDebugEnabled()) { s_logger.debug("Expunging " + vol); } - + //Find out if the volume is present on secondary storage VolumeHostVO volumeHost = _volumeHostDao.findByVolumeId(vol.getId()); if(volumeHost != null){ if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED){ HostVO ssHost = _hostDao.findById(volumeHost.getHostId()); - DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(ssHost.getStorageUrl(), volumeHost.getInstallPath()); + DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(ssHost.getStorageUrl(), volumeHost.getInstallPath()); Answer answer = _agentMgr.sendToSecStorage(ssHost, dtCommand); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " + volumeHost + " due to " + ((answer == null) ? "answer is null" : answer.getDetails())); return; } - }else if(volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS){ + }else if(volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS){ s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it."); throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded."); } _volumeHostDao.remove(volumeHost.getId()); _volumeDao.remove(vol.getId()); - return; + return; } - + String vmName = null; if (vol.getVolumeType() == Type.ROOT && vol.getInstanceId() != null) { VirtualMachine vm = _vmInstanceDao.findByIdIncludingRemoved(vol.getInstanceId()); @@ -3894,7 +3894,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag vmSearch.and("type", vmSearch.entity().getType(), SearchCriteria.Op.NIN); vmSearch.or("nulltype", vmSearch.entity().getType(), SearchCriteria.Op.NULL); sb.join("vmSearch", vmSearch, sb.entity().getInstanceId(), vmSearch.entity().getId(), JoinBuilder.JoinType.LEFTOUTER); - + if (tags != null && !tags.isEmpty()) { SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder(); for (int count=0; count < tags.size(); count++) { @@ -3924,7 +3924,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag } sc.setJoinParameters("diskOfferingSearch", "systemUse", 1); - + if (tags != null && !tags.isEmpty()) { int count = 0; sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Volume.toString()); @@ -3957,7 +3957,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag // Only return volumes that are not destroyed sc.setParameters("state", Volume.State.Destroy); - + Pair<List<VolumeVO>, Integer> volumes = _volumeDao.searchAndCount(sc, searchFilter); return new Pair<List<? extends Volume>, Integer>(volumes.first(), volumes.second()); @@ -3979,14 +3979,14 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag return null; } } - + @Override public HypervisorType getHypervisorTypeFromFormat(ImageFormat format) { - + if(format == null) { return HypervisorType.None; } - + if (format == ImageFormat.VHD) { return HypervisorType.XenServer; } else if (format == ImageFormat.OVA) { @@ -4075,5 +4075,5 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag } return true; } - + }
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7fa1a86/server/test/com/cloud/api/APITest.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/api/APITest.java b/server/test/com/cloud/api/APITest.java new file mode 100644 index 0000000..69c488f --- /dev/null +++ b/server/test/com/cloud/api/APITest.java @@ -0,0 +1,189 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.api; + +import java.io.BufferedReader; +import java.io.EOFException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.math.BigInteger; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Iterator; + +import com.cloud.utils.exception.CloudRuntimeException; +import com.google.gson.Gson; + +/** + * Base class for API Test + * + * @author Min Chen + * + */ +public abstract class APITest { + + protected String rootUrl = "http://localhost:8080/client/api"; + protected String sessionKey = null; + protected String cookieToSent = null; + + + /** + * Sending an api request through Http GET + * @param command command name + * @param params command query parameters in a HashMap + * @return http request response string + */ + protected String sendRequest(String command, HashMap<String, String> params){ + try { + // Construct query string + StringBuilder sBuilder = new StringBuilder(); + sBuilder.append("command="); + sBuilder.append(command); + if ( params != null && params.size() > 0){ + Iterator<String> keys = params.keySet().iterator(); + while (keys.hasNext()){ + String key = keys.next(); + sBuilder.append("&"); + sBuilder.append(key); + sBuilder.append("="); + sBuilder.append(URLEncoder.encode(params.get(key), "UTF-8")); + } + } + + // Construct request url + String reqUrl = rootUrl + "?" + sBuilder.toString(); + + // Send Http GET request + URL url = new URL(reqUrl); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + + if ( !command.equals("login") && cookieToSent != null){ + // add the cookie to a request + conn.setRequestProperty("Cookie", cookieToSent); + } + conn.connect(); + + + if ( command.equals("login")){ + // if it is login call, store cookie + String headerName=null; + for (int i=1; (headerName = conn.getHeaderFieldKey(i))!=null; i++) { + if (headerName.equals("Set-Cookie")) { + String cookie = conn.getHeaderField(i); + cookie = cookie.substring(0, cookie.indexOf(";")); + String cookieName = cookie.substring(0, cookie.indexOf("=")); + String cookieValue = cookie.substring(cookie.indexOf("=") + 1, cookie.length()); + cookieToSent = cookieName + "=" + cookieValue; + } + } + } + + // Get the response + StringBuilder response = new StringBuilder(); + BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String line; + try { + while ((line = rd.readLine()) != null) { + response.append(line); + } + } catch (EOFException ex) { + // ignore this exception + System.out.println("EOF exception due to java bug"); + } + rd.close(); + + + + return response.toString(); + + } catch (Exception e) { + throw new CloudRuntimeException("Problem with sending api request", e); + } + } + + protected String createMD5String(String password) { + MessageDigest md5; + try { + md5 = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + throw new CloudRuntimeException("Error", e); + } + + md5.reset(); + BigInteger pwInt = new BigInteger(1, md5.digest(password.getBytes())); + + // make sure our MD5 hash value is 32 digits long... + StringBuffer sb = new StringBuffer(); + String pwStr = pwInt.toString(16); + int padding = 32 - pwStr.length(); + for (int i = 0; i < padding; i++) { + sb.append('0'); + } + sb.append(pwStr); + return sb.toString(); + } + + + protected Object fromSerializedString(String result, Class<?> repCls) { + try { + if (result != null && !result.isEmpty()) { + + // get real content + int start = result.indexOf('{', result.indexOf('{') + 1); // find the second { + if ( start < 0 ){ + throw new CloudRuntimeException("Response format is wrong: " + result); + } + int end = result.lastIndexOf('}', result.lastIndexOf('}')-1); // find the second } backwards + if ( end < 0 ){ + throw new CloudRuntimeException("Response format is wrong: " + result); + } + String content = result.substring(start, end+1); + Gson gson = ApiGsonHelper.getBuilder().create(); + return gson.fromJson(content, repCls); + } + return null; + } catch (RuntimeException e) { + throw new CloudRuntimeException("Caught runtime exception when doing GSON deserialization on: " + result, e); + } + } + + /** + * Login call + * @param username user name + * @param password password (plain password, we will do MD5 hash here for you) + * @return login response string + */ + protected void login(String username, String password) + { + //String md5Psw = createMD5String(password); + // send login request + HashMap<String, String> params = new HashMap<String, String>(); + params.put("response", "json"); + params.put("username", username); + params.put("password", password); + String result = this.sendRequest("login", params); + LoginResponse loginResp = (LoginResponse)fromSerializedString(result, LoginResponse.class); + sessionKey = loginResp.getSessionkey(); + + } +} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7fa1a86/server/test/com/cloud/api/ListPerfTest.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/api/ListPerfTest.java b/server/test/com/cloud/api/ListPerfTest.java new file mode 100644 index 0000000..47abcae --- /dev/null +++ b/server/test/com/cloud/api/ListPerfTest.java @@ -0,0 +1,109 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.api; + +import java.util.HashMap; + +import org.junit.Before; +import org.junit.Test; + + +/** + * Test fixture to do performance test for list command + * Currently we commented out this test suite since it requires a real MS and Db running. + * + * @author Min Chen + * + */ +public class ListPerfTest extends APITest { + + + + @Before + public void setup(){ + // always login for each testcase + login("admin", "password"); + } + + @Test + public void testListVM(){ + // issue list VM calls + HashMap<String, String> params = new HashMap<String, String>(); + params.put("response", "json"); + params.put("listAll", "true"); + params.put("sessionkey", sessionKey); + long before = System.currentTimeMillis(); + String result = this.sendRequest("listVirtualMachines", params); + long after = System.currentTimeMillis(); + System.out.println("Time taken to list VM: " + (after - before) + " ms"); + + } + + @Test + public void testListVMXML(){ + // issue list VM calls + HashMap<String, String> params = new HashMap<String, String>(); + params.put("listAll", "true"); + params.put("sessionkey", sessionKey); + long before = System.currentTimeMillis(); + String result = this.sendRequest("listVirtualMachines", params); + long after = System.currentTimeMillis(); + System.out.println("Time taken to list VM: " + (after - before) + " ms"); + + } + + @Test + public void testListRouter(){ + // issue list VM calls + HashMap<String, String> params = new HashMap<String, String>(); + params.put("response", "json"); + params.put("listAll", "true"); + params.put("sessionkey", sessionKey); + long before = System.currentTimeMillis(); + String result = this.sendRequest("listRouters", params); + long after = System.currentTimeMillis(); + System.out.println("Time taken to list Routers: " + (after - before) + " ms"); + + } + + @Test + public void testListRouterXML(){ + // issue list VM calls + HashMap<String, String> params = new HashMap<String, String>(); + params.put("listAll", "true"); + params.put("sessionkey", sessionKey); + long before = System.currentTimeMillis(); + String result = this.sendRequest("listRouters", params); + long after = System.currentTimeMillis(); + System.out.println("Time taken to list Routers: " + (after - before) + " ms"); + + } + + @Test + public void testListHosts(){ + // issue list Hosts calls + HashMap<String, String> params = new HashMap<String, String>(); + params.put("response", "json"); + params.put("listAll", "true"); + params.put("sessionkey", sessionKey); + long before = System.currentTimeMillis(); + String result = this.sendRequest("listHosts", params); + long after = System.currentTimeMillis(); + System.out.println("Time taken to list Hosts: " + (after - before) + " ms"); + + } +} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7fa1a86/server/test/com/cloud/api/LoginResponse.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/api/LoginResponse.java b/server/test/com/cloud/api/LoginResponse.java new file mode 100644 index 0000000..097ae42 --- /dev/null +++ b/server/test/com/cloud/api/LoginResponse.java @@ -0,0 +1,142 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.api; + +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +/** + * Login Response object + * + * @author Min Chen + * + */ +public class LoginResponse extends BaseResponse { + + @SerializedName("timeout") + @Param(description = "session timeout period") + private String timeout; + + @SerializedName("sessionkey") + @Param(description = "login session key") + private String sessionkey; + + @SerializedName("username") + @Param(description = "login username") + private String username; + + @SerializedName("userid") + @Param(description = "login user internal uuid") + private String userid; + + @SerializedName("firstname") + @Param(description = "login user firstname") + private String firstname; + + @SerializedName("lastname") + @Param(description = "login user lastname") + private String lastname; + + @SerializedName("account") + @Param(description = "login user account type") + private String account; + + @SerializedName("domainid") + @Param(description = "login user domain id") + private String domainid; + + @SerializedName("type") + @Param(description = "login user type") + private int type; + + public String getTimeout() { + return timeout; + } + + public void setTimeout(String timeout) { + this.timeout = timeout; + } + + public String getSessionkey() { + return sessionkey; + } + + public void setSessionkey(String sessionkey) { + this.sessionkey = sessionkey; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUserid() { + return userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDomainid() { + return domainid; + } + + public void setDomainid(String domainid) { + this.domainid = domainid; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + + +}
