From 59a6e2157af1405e409cb956b37ed290358f073d Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 27 May 2011 19:44:19 -0400 Subject: [PATCH 01/65] fix user data, and template sync --- .../cloud/agent/vmdata/JettyVmDataServer.java | 16 +++++++++++++--- .../cloud/agent/manager/AgentManagerImpl.java | 4 +--- server/src/com/cloud/api/ApiDBUtils.java | 12 +++++++----- server/src/com/cloud/storage/StorageManager.java | 4 +++- .../com/cloud/storage/StorageManagerImpl.java | 12 ++++++++++++ 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java b/agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java index 38ebe1ac33d..df112a6a46f 100644 --- a/agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java +++ b/agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java @@ -21,6 +21,7 @@ package com.cloud.agent.vmdata; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; @@ -38,6 +39,7 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import org.mortbay.jetty.Connector; import org.mortbay.jetty.Handler; @@ -294,10 +296,18 @@ public class JettyVmDataServer implements VmDataServer { try { _fs.create(vmDataDir, item[1]); String vmDataFile = vmDataDir + File.separator + item[1]; + byte[] data; if (item[2] != null) { - BufferedWriter writer = new BufferedWriter(new FileWriter(vmDataFile)); - writer.write(item[2]); - writer.close(); + if (item[1].equals("userdata")) { + data = Base64.decodeBase64(item[2]); + } else { + data = item[2].getBytes(); + } + if (data != null && data.length > 0) { + FileOutputStream writer = new FileOutputStream(vmDataFile); + writer.write(data); + writer.close(); + } } } catch (IOException e) { s_logger.warn("Failed to write vm data item " + item[1], e); diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index 81f0a620c40..dc70480c90d 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -489,9 +489,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager { @Override public HostVO getSSAgent(HostVO ssHost) { if( ssHost.getType() == Host.Type.LocalSecondaryStorage ) { - if( ssHost.getStatus() == Status.Up ) { - return ssHost; - } + return ssHost; } else if ( ssHost.getType() == Host.Type.SecondaryStorage) { Long dcId = ssHost.getDataCenterId(); List ssAHosts = _hostDao.listBy(Host.Type.SecondaryStorageVM, dcId); diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 73bd4e2cc82..433b7ca0886 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -484,12 +484,14 @@ public class ApiDBUtils { if (vmTemplate.getHypervisorType() == HypervisorType.BareMetal) { return _templateHostDao.listByTemplateId(templateId); } else { - HostVO secondaryStorageHost = _storageMgr.getSecondaryStorageHost(zoneId); - if (secondaryStorageHost == null) { - return new ArrayList(); - } else { - return _templateHostDao.listByHostTemplate(secondaryStorageHost.getId(), templateId); + List templates = new ArrayList(); + List secondaryStorageHosts = _storageMgr.getSecondaryStorageHosts(zoneId); + if (!secondaryStorageHosts.isEmpty()) { + for (HostVO ssh : secondaryStorageHosts) { + templates.addAll(_templateHostDao.listByHostTemplate(ssh.getId(), templateId)); + } } + return templates; } } else { return _templateHostDao.listByOnlyTemplateId(templateId); diff --git a/server/src/com/cloud/storage/StorageManager.java b/server/src/com/cloud/storage/StorageManager.java index e1210cb5e42..5b4860788e5 100755 --- a/server/src/com/cloud/storage/StorageManager.java +++ b/server/src/com/cloud/storage/StorageManager.java @@ -195,5 +195,7 @@ public interface StorageManager extends Manager { boolean delPoolFromHost(long hostId); - HostVO getSecondaryStorageHost(long zoneId, long tmpltId); + HostVO getSecondaryStorageHost(long zoneId, long tmpltId); + + List getSecondaryStorageHosts(long zoneId); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index aabb44848e7..fe3795c857d 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -970,6 +970,18 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag int index = rn.nextInt(size); return hosts.get(index); } + + @Override + public List getSecondaryStorageHosts(long zoneId) { + List hosts = _hostDao.listSecondaryStorageHosts(zoneId); + if( hosts == null || hosts.size() == 0) { + hosts = _hostDao.listLocalSecondaryStorageHosts(zoneId); + if (hosts.isEmpty()) { + return new ArrayList(); + } + } + return hosts; + } @Override public String getStoragePoolTags(long poolId) { From baa638a352f5e2130562a7f0a079b4db56930048 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 27 May 2011 21:33:17 -0400 Subject: [PATCH 02/65] fix user data --- agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java b/agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java index df112a6a46f..8b8cbb3fcf7 100644 --- a/agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java +++ b/agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java @@ -298,7 +298,7 @@ public class JettyVmDataServer implements VmDataServer { String vmDataFile = vmDataDir + File.separator + item[1]; byte[] data; if (item[2] != null) { - if (item[1].equals("userdata")) { + if (item[1].equals("user-data")) { data = Base64.decodeBase64(item[2]); } else { data = item[2].getBytes(); From d006fd141ce5c87f99c286ddcdc06ccbeec44e7a Mon Sep 17 00:00:00 2001 From: Abhinandan Prateek Date: Mon, 30 May 2011 12:39:15 +0530 Subject: [PATCH 03/65] bug 9909: upload manager support multiple secondary storage --- .../resource/NfsSecondaryStorageResource.java | 4 +-- .../storage/upload/UploadMonitorImpl.java | 25 +++++++++++++------ .../cloud/template/TemplateManagerImpl.java | 18 +++++++++---- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 6f554d94553..04ba5353c63 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -539,8 +539,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S _params.put(StorageLayer.InstanceConfigKey, _storage); _dlMgr = new DownloadManagerImpl(); _dlMgr.configure("DownloadManager", _params); - //_upldMgr = new UploadManagerImpl(); - //_upldMgr.configure("UploadManager", params); + _upldMgr = new UploadManagerImpl(); + _upldMgr.configure("UploadManager", params); } catch (ConfigurationException e) { s_logger.warn("Caught problem while configuring DownloadManager", e); return false; diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 3b87f714fa9..3809701ad48 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -200,11 +200,20 @@ public class UploadMonitorImpl implements UploadMonitor { Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ; - //Check if ssvm is up - HostVO sserver = storageServers.get(0); - if(sserver.getStatus() != com.cloud.host.Status.Up){ - throw new CloudRuntimeException("Couldnt create extract link - Secondary Storage Vm is not up"); - } + List storageServerVMs = _serverDao.listByTypeDataCenter(Host.Type.SecondaryStorageVM, dataCenterId); + //Check if one ssvm is up + boolean no_vm_up = true; + HostVO use_ssvm = null; + for (HostVO ssvm: storageServerVMs){ + if(ssvm.getStatus() == com.cloud.host.Status.Up){ + no_vm_up = false; + use_ssvm = ssvm; + break; + } + } + if(no_vm_up){ + throw new CloudRuntimeException("Couldnt create extract link - Secondary Storage Vm is not up"); + } //Check if it already exists. List extractURLList = _uploadDao.listByTypeUploadStatus(template.getId(), type, UploadVO.Status.DOWNLOAD_URL_CREATED); @@ -213,7 +222,7 @@ public class UploadMonitorImpl implements UploadMonitor { } // It doesn't exist so create a DB entry. - UploadVO uploadTemplateObj = new UploadVO(sserver.getId(), template.getId(), new Date(), + UploadVO uploadTemplateObj = new UploadVO(use_ssvm.getId(), template.getId(), new Date(), Status.DOWNLOAD_URL_NOT_CREATED, 0, type, Mode.HTTP_DOWNLOAD); uploadTemplateObj.setInstallPath(vmTemplateHost.getInstallPath()); _uploadDao.persist(uploadTemplateObj); @@ -221,7 +230,7 @@ public class UploadMonitorImpl implements UploadMonitor { // Create Symlink at ssvm String uuid = UUID.randomUUID().toString() + ".vhd"; CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(vmTemplateHost.getInstallPath(), uuid); - long result = send(sserver.getId(), cmd, null); + long result = send(use_ssvm.getId(), cmd, null); if (result == -1){ errorString = "Unable to create a link for " +type+ " id:"+template.getId(); s_logger.error(errorString); @@ -230,7 +239,7 @@ public class UploadMonitorImpl implements UploadMonitor { //Construct actual URL locally now that the symlink exists at SSVM List ssVms = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running); - if (ssVms.size() > 0) { + if (ssVms.size() > 0) { SecondaryStorageVmVO ssVm = ssVms.get(0); if (ssVm.getPublicIpAddress() == null) { errorString = "A running secondary storage vm has a null public ip?"; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 32d9d4355d1..2388930c6c5 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -262,12 +262,20 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe } } - HostVO secondaryStorageHost = _storageMgr.getSecondaryStorageHost(zoneId); + List sservers = _storageMgr.getSecondaryStorageHosts(zoneId); + VMTemplateHostVO tmpltHostRef = null; - if (secondaryStorageHost != null) { - tmpltHostRef = _tmpltHostDao.findByHostTemplate(secondaryStorageHost.getId(), templateId); - if (tmpltHostRef != null && tmpltHostRef.getDownloadState() != com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - throw new InvalidParameterValueException("The " + desc + " has not been downloaded "); + if (sservers != null) { + for(HostVO secondaryStorageHost: sservers){ + tmpltHostRef = _tmpltHostDao.findByHostTemplate(secondaryStorageHost.getId(), templateId); + if (tmpltHostRef != null){ + if (tmpltHostRef.getDownloadState() != com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + throw new InvalidParameterValueException("The " + desc + " has not been downloaded "); + } + else { + break; + } + } } } From 024bd039dabd2dd90add381e17466e9d25a9bc10 Mon Sep 17 00:00:00 2001 From: nit Date: Mon, 30 May 2011 12:34:33 +0530 Subject: [PATCH 04/65] bug 9729 : Permission change - allow admin to use anybody's private template. status 9729: resolved fixed --- server/src/com/cloud/acl/DomainChecker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/acl/DomainChecker.java b/server/src/com/cloud/acl/DomainChecker.java index f6b39c4659b..b0978fdf76b 100755 --- a/server/src/com/cloud/acl/DomainChecker.java +++ b/server/src/com/cloud/acl/DomainChecker.java @@ -82,7 +82,7 @@ public class DomainChecker extends AdapterBase implements SecurityChecker { // validate that the template is usable by the account if (!template.isPublicTemplate()) { Account owner = _accountDao.findById(template.getAccountId()); - if (BaseCmd.isAdmin(owner.getType()) || (owner.getId() == caller.getId())) { + if (BaseCmd.isAdmin(caller.getType()) || (owner.getId() == caller.getId())) { return true; } From b5aeb6fa0e00d4b150ae94be8bb53cb35576868b Mon Sep 17 00:00:00 2001 From: Abhinandan Prateek Date: Tue, 31 May 2011 12:00:40 +0530 Subject: [PATCH 05/65] bug 9909: upload manager support multiple secondary storage --- .../storage/CreateEntityDownloadURLCommand.java | 17 +++++++++++++++++ .../storage/template/UploadManagerImpl.java | 5 ++--- .../cloud/storage/upload/UploadMonitorImpl.java | 4 ++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/api/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java b/api/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java index 376a94f302b..e7a2540df25 100755 --- a/api/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java +++ b/api/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java @@ -22,8 +22,16 @@ import com.cloud.agent.api.Command; public class CreateEntityDownloadURLCommand extends AbstractDownloadCommand { + public CreateEntityDownloadURLCommand(String parent, String installPath, String uuid) { // this constructor is for creating template download url + super(); + this.parent = parent; // parent is required as not the template can be child of one of many parents + this.installPath = installPath; + this.extractLinkUUID = uuid; + } + public CreateEntityDownloadURLCommand(String installPath, String uuid) { super(); + this.parent = parent; this.installPath = installPath; this.extractLinkUUID = uuid; } @@ -32,6 +40,7 @@ public class CreateEntityDownloadURLCommand extends AbstractDownloadCommand { } private String installPath; + private String parent; private String extractLinkUUID; @Override @@ -46,6 +55,14 @@ public class CreateEntityDownloadURLCommand extends AbstractDownloadCommand { public void setInstallPath(String installPath) { this.installPath = installPath; } + + public String getParent() { + return parent; + } + + public void setParent(String parent) { + this.parent = parent; + } public String getExtractLinkUUID() { return extractLinkUUID; diff --git a/core/src/com/cloud/storage/template/UploadManagerImpl.java b/core/src/com/cloud/storage/template/UploadManagerImpl.java index d559ae0b3a3..da88da86868 100755 --- a/core/src/com/cloud/storage/template/UploadManagerImpl.java +++ b/core/src/com/cloud/storage/template/UploadManagerImpl.java @@ -373,11 +373,10 @@ public class UploadManagerImpl implements UploadManager { } - // Create a symbolic link from the actual directory to the template location. The entity would be directly visible under /var/www/html/userdata - cmd.getInstallPath(); + // Create a symbolic link from the actual directory to the template location. The entity would be directly visible under /var/www/html/userdata/cmd.getInstallPath(); command = new Script("/bin/bash", s_logger); command.add("-c"); - command.add("ln -sf " + extractMountPoint + File.separator + cmd.getInstallPath() + " " + extractDir + uuid); + command.add("ln -sf /mnt/SecStorage/" + cmd.getParent() + File.separator + cmd.getInstallPath() + " " + extractDir + uuid); result = command.execute(); if (result != null) { String errorString = "Error in linking err=" + result; diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 3809701ad48..c5a1e1bb446 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -194,7 +194,7 @@ public class UploadMonitorImpl implements UploadMonitor { String errorString = ""; boolean success = false; List storageServers = _serverDao.listByTypeDataCenter(Host.Type.SecondaryStorage, dataCenterId); - if(storageServers == null ) { + if(storageServers == null || storageServers.size() == 0) { throw new CloudRuntimeException("No Storage Server found at the datacenter - " +dataCenterId); } @@ -229,7 +229,7 @@ public class UploadMonitorImpl implements UploadMonitor { try{ // Create Symlink at ssvm String uuid = UUID.randomUUID().toString() + ".vhd"; - CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(vmTemplateHost.getInstallPath(), uuid); + CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(storageServers.get(0).getParent(), vmTemplateHost.getInstallPath(), uuid); long result = send(use_ssvm.getId(), cmd, null); if (result == -1){ errorString = "Unable to create a link for " +type+ " id:"+template.getId(); From 6de2bef7cd1b118ae63bd217d9f50d7c7ee48d9a Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Tue, 31 May 2011 13:57:20 +0530 Subject: [PATCH 06/65] bug 9973: listReourceLimits A domain-admin of domain X can view Resource Limits from other domain adding additional checks, and moving old code to access checkers status 9973: resolved fixed --- .../com/cloud/user/AccountManagerImpl.java | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index ce0c677cf52..1cd22cec19c 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -511,23 +511,34 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag throw new InvalidParameterValueException("Failed to list limits for account " + accountName + " no domain id specified."); } - Account userAccount = _accountDao.findActiveAccount(accountName, domainId); + DomainVO domain = _domainDao.findById(domainId); + if (domain == null) { + throw new InvalidParameterValueException("Unable to find domain by id " + domainId); + } + Account userAccount = _accountDao.findActiveAccount(accountName, domainId); if (userAccount == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); - } else if (account != null - && (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || account.getType() == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN || account.getType() == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)) { - // If this is a non-root admin, make sure that the admin and the user account belong in the same domain or - // that the user account's domain is a child domain of the parent - if (account.getDomainId() != userAccount.getDomainId() && !_domainDao.isChildDomain(account.getDomainId(), userAccount.getDomainId())) { - throw new PermissionDeniedException("You do not have permission to access limits for this account: " + accountName); - } + } + + if (account != null) { + checkAccess(account, domain); } accountId = userAccount.getId(); domainId = null; } else if (domainId != null) { // Look up limits for the specified domain + + DomainVO domain = _domainDao.findById(domainId); + if (domain == null) { + throw new InvalidParameterValueException("Unable to find domain by id " + domainId); + } + + if (account != null) { + checkAccess(account, domain); + } + accountId = null; } else if (account == null) { // Look up limits for the ROOT domain From 67ff27496dd075e85640961ed5cc5445ba95eb0f Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Wed, 25 May 2011 16:58:12 -0700 Subject: [PATCH 07/65] tags added --- server/src/com/cloud/network/NetworkVO.java | 21 ++- setup/db/create-schema.sql | 2 +- utils/src/com/cloud/utils/db/Attribute.java | 74 ++++++----- .../com/cloud/utils/db/GenericDaoBase.java | 125 ++++++++++++++++-- .../src/com/cloud/utils/db/SqlGenerator.java | 47 ++++--- .../javax/persistence/ElementCollection.java | 13 +- 6 files changed, 205 insertions(+), 77 deletions(-) diff --git a/server/src/com/cloud/network/NetworkVO.java b/server/src/com/cloud/network/NetworkVO.java index ab760faacfe..af60f5e27b1 100644 --- a/server/src/com/cloud/network/NetworkVO.java +++ b/server/src/com/cloud/network/NetworkVO.java @@ -22,11 +22,15 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import javax.persistence.CollectionTable; import javax.persistence.Column; +import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import javax.persistence.FetchType; import javax.persistence.Id; +import javax.persistence.JoinColumn; import javax.persistence.Table; import javax.persistence.TableGenerator; import javax.persistence.Transient; @@ -34,7 +38,6 @@ import javax.persistence.Transient; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.dao.NetworkDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.GenericDao; import com.cloud.utils.net.NetUtils; @@ -73,7 +76,7 @@ public class NetworkVO implements Network { String displayText;; @Column(name="broadcast_uri") - URI broadcastUri; + URI broadcastUri; @Column(name="gateway") String gateway; @@ -132,7 +135,7 @@ public class NetworkVO implements Network { Date created; @Column(name="reservation_id") - String reservationId; + String reservationId; @Column(name="is_default") boolean isDefault; @@ -140,7 +143,9 @@ public class NetworkVO implements Network { @Column(name="is_security_group_enabled") boolean securityGroupEnabled; - @Transient + @ElementCollection(targetClass = String.class, fetch=FetchType.EAGER) + @Column(name="tag") + @CollectionTable(name="network_tags", joinColumns=@JoinColumn(name="network_id")) List tags; public NetworkVO() { @@ -408,7 +413,7 @@ public class NetworkVO implements Network { return isDefault; } - @Override + @Override public boolean isSecurityGroupEnabled() { return securityGroupEnabled; } @@ -464,10 +469,4 @@ public class NetworkVO implements Network { buf.append(id).append("|").append(trafficType.toString()).append("|").append(networkOfferingId).append("]"); return buf.toString(); } - - private static NetworkDao _networkDao = null; - static void init(NetworkDao networkDao) { - _networkDao = networkDao; - } - } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 3b6ab9132be..ffa7a5e4db4 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -197,7 +197,7 @@ CREATE TABLE `cloud`.`network_tags` ( `network_id` bigint unsigned NOT NULL COMMENT 'id of the network', `tag` varchar(255) NOT NULL COMMENT 'tag', PRIMARY KEY (`id`), - CONSTRAINT `fk_network_tags__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`), + CONSTRAINT `fk_network_tags__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, UNIQUE KEY(`network_id`, `tag`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/utils/src/com/cloud/utils/db/Attribute.java b/utils/src/com/cloud/utils/db/Attribute.java index aefb02dd139..ee13be3f42d 100755 --- a/utils/src/com/cloud/utils/db/Attribute.java +++ b/utils/src/com/cloud/utils/db/Attribute.java @@ -21,6 +21,7 @@ import java.lang.reflect.Field; import javax.persistence.AttributeOverride; import javax.persistence.Column; +import javax.persistence.ElementCollection; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -54,49 +55,50 @@ public class Attribute { CharDT(0x100000), StringDT(0x200000), IntegerDT(0x400000); - + int place; Flag(int place) { this.place = place; } - + public int place() { return place; } - + public boolean check(int value) { return (value & place) == place; } - + public int setTrue(int value) { return (value | place); } - + public int setFalse(int value) { return (value & ~place); } } - + protected String table; protected String columnName; protected Field field; protected int flags; protected Column column; - + protected Object attache; + public Attribute(Class clazz, AttributeOverride[] overrides, Field field, String tableName, boolean isEmbedded, boolean isId) { this.field = field; flags = 0; table = tableName; setupColumnInfo(clazz, overrides, tableName, isEmbedded, isId); } - + public Attribute(String table, String columnName) { this.table = table; this.columnName = columnName; this.field = null; this.column = null; } - + protected void setupColumnInfo(Class clazz, AttributeOverride[] overrides, String tableName, boolean isEmbedded, boolean isId) { flags = Flag.Selectable.setTrue(flags); GeneratedValue gv = field.getAnnotation(GeneratedValue.class); @@ -122,7 +124,7 @@ public class Attribute { if (isEmbedded) { flags = Flag.Embedded.setTrue(flags); } - + if (isId) { flags = Flag.Id.setTrue(flags); } else { @@ -143,6 +145,12 @@ public class Attribute { flags = Flag.Nullable.setTrue(flags); } } + ElementCollection ec = field.getAnnotation(ElementCollection.class); + if (ec != null) { + flags = Flag.Insertable.setFalse(flags); + flags = Flag.Selectable.setFalse(flags); + } + Temporal temporal = field.getAnnotation(Temporal.class); if (temporal != null) { if (temporal.value() == TemporalType.DATE) { @@ -153,50 +161,50 @@ public class Attribute { flags = Flag.TimeStamp.setTrue(flags); } } - + if (column != null && column.table().length() > 0) { table = column.table(); } - + columnName = DbUtil.getColumnName(field, overrides); } - + public final boolean isInsertable() { return Flag.Insertable.check(flags); } - + public final boolean isUpdatable() { return Flag.Updatable.check(flags); } - + public final boolean isNullable() { return Flag.Nullable.check(flags); } - + public final boolean isId() { return Flag.Id.check(flags); } - + public final boolean isSelectable() { return Flag.Selectable.check(flags); } - + public final boolean is(Flag flag) { return flag.check(flags); } - + public final void setTrue(Flag flag) { flags = flag.setTrue(flags); } - + public final void setFalse(Flag flag) { flags = flag.setFalse(flags); } - + public Field getField() { return field; } - + public Object get(Object entity) { try { return field.get(entity); @@ -205,23 +213,23 @@ public class Attribute { return null; } } - + @Override public int hashCode() { - return columnName.hashCode(); + return columnName.hashCode(); } - + @Override public boolean equals(Object obj) { - if (!(obj instanceof Attribute)) { - return false; - } - - Attribute that = (Attribute)obj; - - return columnName.equals(that.columnName) && table.equals(that.table); + if (!(obj instanceof Attribute)) { + return false; + } + + Attribute that = (Attribute)obj; + + return columnName.equals(that.columnName) && table.equals(that.table); } - + @Override public String toString() { return table + "." + columnName; diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java index 1be42c4f5d9..a350e8d8fd4 100755 --- a/utils/src/com/cloud/utils/db/GenericDaoBase.java +++ b/utils/src/com/cloud/utils/db/GenericDaoBase.java @@ -19,6 +19,7 @@ package com.cloud.utils.db; import java.io.Serializable; import java.io.UnsupportedEncodingException; +import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -36,6 +37,7 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; +import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -49,7 +51,6 @@ import javax.persistence.EmbeddedId; import javax.persistence.EntityExistsException; import javax.persistence.EnumType; import javax.persistence.Enumerated; -import javax.persistence.OneToMany; import javax.persistence.TableGenerator; import net.sf.cglib.proxy.Callback; @@ -72,6 +73,8 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; +import edu.emory.mathcs.backport.java.util.Collections; + /** * GenericDaoBase is a simple way to implement DAOs. It DOES NOT * support the full EJB3 spec. It borrows some of the annotations from @@ -135,7 +138,7 @@ public abstract class GenericDaoBase implements Gene protected Map _idAttributes; protected Map _tgs; protected final Map _allAttributes; - protected List _oneToManyAttributes; + protected List _ecAttributes; protected final Map, Attribute> _allColumns; protected Enhancer _enhancer; protected Factory _factory; @@ -224,7 +227,7 @@ public abstract class GenericDaoBase implements Gene _deleteSqls = generator.buildDeleteSqls(); _removed = generator.getRemovedAttribute(); _tgs = generator.getTableGenerators(); - _oneToManyAttributes = generator.getOneToManyAttributes(); + _ecAttributes = generator.getElementCollectionAttributes(); TableGenerator tg = this.getClass().getAnnotation(TableGenerator.class); if (tg != null) { @@ -261,6 +264,13 @@ public abstract class GenericDaoBase implements Gene for (final Pair deletSql : _deleteSqls) { s_logger.trace(deletSql.first()); } + + s_logger.trace("Collection SQLs"); + for (Attribute attr : _ecAttributes) { + EcInfo info = (EcInfo)attr.attache; + s_logger.trace(info.insertSql); + s_logger.trace(info.selectSql); + } } } @@ -610,7 +620,7 @@ public abstract class GenericDaoBase implements Gene return (M)new String(bytes, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new CloudRuntimeException("UnsupportedEncodingException exception while converting UTF-8 data"); - } + } } else { return null; } @@ -767,7 +777,7 @@ public abstract class GenericDaoBase implements Gene } final String sqlStr = pstmt.toString(); throw new CloudRuntimeException("DB Exception on: " + sqlStr, e); - } + } } @DB(txn=false) @@ -892,8 +902,8 @@ public abstract class GenericDaoBase implements Gene ResultSet rs = pstmt.executeQuery(); return rs.next() ? toEntityBean(rs, true) : null; } catch (SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + pstmt.toString(), e); - } + throw new CloudRuntimeException("DB Exception on: " + pstmt, e); + } } @Override @DB(txn=false) @@ -1212,6 +1222,30 @@ public abstract class GenericDaoBase implements Gene } } } + for (Attribute attr : _ecAttributes) { + EcInfo ec = (EcInfo)attr.attache; + Object obj; + try { + obj = attr.field.get(entity); + if (ec.rawClass != null) { + Enumeration en = Collections.enumeration((Collection)obj); + while (en.hasMoreElements()) { + pstmt = txn.prepareAutoCloseStatement(ec.insertSql); + if (ec.targetClass == Date.class) { + pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), (Date)en.nextElement())); + } else { + pstmt.setObject(1, en.nextElement()); + } + prepareAttribute(2, pstmt, _idAttributes.get(attr.table)[0], _idField.get(entity)); + pstmt.executeUpdate(); + } + } + } catch (IllegalArgumentException e) { + throw new CloudRuntimeException("Yikes! ", e); + } catch (IllegalAccessException e) { + throw new CloudRuntimeException("Yikes! ", e); + } + } txn.commit(); } catch (final SQLException e) { if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) { @@ -1235,7 +1269,7 @@ public abstract class GenericDaoBase implements Gene } else if (attr.is(Attribute.Flag.AutoGV)) { if (attr.columnName.equals(GenericDao.XID_COLUMN)) { return UUID.randomUUID().toString(); - } + } assert (false) : "Auto generation is not supported."; return null; } else if (attr.is(Attribute.Flag.SequenceGV)) { @@ -1268,7 +1302,7 @@ public abstract class GenericDaoBase implements Gene final Column column = attr.field.getAnnotation(Column.class); final int length = column != null ? column.length() : 255; - // to support generic localization, utilize MySql UTF-8 support + // to support generic localization, utilize MySql UTF-8 support if (length < str.length()) { try { pstmt.setBytes(j, str.substring(0, column.length()).getBytes("UTF-8")); @@ -1379,9 +1413,78 @@ public abstract class GenericDaoBase implements Gene for (int index = 1, max = meta.getColumnCount(); index <= max; index++) { setField(entity, result, meta, index); } - for (Attribute attr : _oneToManyAttributes) { - OneToMany otm = attr.field.getAnnotation(OneToMany.class); + for (Attribute attr : _ecAttributes) { + loadCollection(entity, attr); + } + } + @DB(txn = true) + @SuppressWarnings("unchecked") + protected void loadCollection(T entity, Attribute attr) { + EcInfo ec = (EcInfo)attr.attache; + + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + try { + pstmt = txn.prepareAutoCloseStatement(ec.selectSql); + pstmt.setObject(1, _idField.get(entity)); + ResultSet rs = pstmt.executeQuery(); + ArrayList lst = new ArrayList(); + if (ec.targetClass == Integer.class) { + while (rs.next()) { + lst.add(rs.getInt(1)); + } + } else if (ec.targetClass == Long.class) { + while (rs.next()) { + lst.add(rs.getLong(1)); + } + } else if (ec.targetClass == String.class) { + while (rs.next()) { + lst.add(rs.getString(1)); + } + } else if (ec.targetClass == Short.class) { + while (rs.next()) { + lst.add(rs.getShort(1)); + } + } else if (ec.targetClass == Date.class) { + while (rs.next()) { + lst.add(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(1))); + } + } else if (ec.targetClass == Boolean.class) { + while (rs.next()) { + lst.add(rs.getBoolean(1)); + } + } else { + assert (false) : "You'll need to add more classeses"; + } + + if (ec.rawClass == null) { + Object[] array = (Object[])Array.newInstance(ec.targetClass); + lst.toArray(array); + try { + attr.field.set(entity, array); + } catch (IllegalArgumentException e) { + throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e); + } catch (IllegalAccessException e) { + throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e); + } + } else { + try { + Collection coll = (Collection)ec.rawClass.newInstance(); + coll.addAll(lst); + attr.field.set(entity, coll); + } catch (IllegalAccessException e) { + throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e); + } catch (InstantiationException e) { + throw new CloudRuntimeException("Never should happen", e); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error executing " + pstmt, e); + } catch (IllegalArgumentException e) { + throw new CloudRuntimeException("Error executing " + pstmt, e); + } catch (IllegalAccessException e) { + throw new CloudRuntimeException("Error executing " + pstmt, e); } } diff --git a/utils/src/com/cloud/utils/db/SqlGenerator.java b/utils/src/com/cloud/utils/db/SqlGenerator.java index 9928dc1caec..d8be5c5e259 100755 --- a/utils/src/com/cloud/utils/db/SqlGenerator.java +++ b/utils/src/com/cloud/utils/db/SqlGenerator.java @@ -29,16 +29,16 @@ import java.util.List; import java.util.Map; import javax.persistence.AttributeOverride; -import javax.persistence.CascadeType; +import javax.persistence.CollectionTable; import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorType; import javax.persistence.DiscriminatorValue; +import javax.persistence.ElementCollection; import javax.persistence.Embeddable; import javax.persistence.Embedded; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.FetchType; -import javax.persistence.OneToMany; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.SecondaryTable; import javax.persistence.TableGenerator; @@ -54,13 +54,13 @@ public class SqlGenerator { ArrayList> _tables; LinkedHashMap> _ids; HashMap _generators; - ArrayList _otmAttrs; + ArrayList _ecAttrs; public SqlGenerator(Class clazz) { _clazz = clazz; _tables = new ArrayList>(); _attributes = new ArrayList(); - _otmAttrs = new ArrayList(); + _ecAttrs = new ArrayList(); _embeddeds = new ArrayList(); _ids = new LinkedHashMap>(); _generators = new HashMap(); @@ -68,6 +68,7 @@ public class SqlGenerator { buildAttributes(clazz, DbUtil.getTableName(clazz), DbUtil.getAttributeOverrides(clazz), false, false); assert (_tables.size() > 0) : "Did you forget to put @Entity on " + clazz.getName(); handleDaoAttributes(clazz); + findEcAttributes(); } protected boolean checkMethods(Class clazz, Map attrs) { @@ -140,27 +141,33 @@ public class SqlGenerator { attrs.add(attr); } - if (field.getAnnotation(OneToMany.class) != null) { - assert supportsOneToMany(field) : "Doesn't support One To Many"; - _otmAttrs.add(attr); - } else { - _attributes.add(attr); + _attributes.add(attr); + } + } + + protected void findEcAttributes() { + for (Attribute attr : _attributes) { + ElementCollection ec = attr.field.getAnnotation(ElementCollection.class); + if (ec != null) { + Attribute idAttr = _ids.get(attr.table).get(0); + assert supportsElementCollection(attr.field) : "Doesn't support ElementCollection for " + attr.field.getName(); + attr.attache = new EcInfo(attr, idAttr); + _ecAttrs.add(attr); } } } - protected boolean supportsOneToMany(Field field) { - OneToMany otm = field.getAnnotation(OneToMany.class); + protected boolean supportsElementCollection(Field field) { + ElementCollection otm = field.getAnnotation(ElementCollection.class); if (otm.fetch() == FetchType.LAZY) { - assert (false) : "Doesn't support laz fetch: " + field.getName(); - return false; + assert (false) : "Doesn't support laz fetch: " + field.getName(); + return false; } - for (CascadeType cascade : otm.cascade()) { - if (cascade == CascadeType.ALL || cascade == CascadeType.PERSIST || cascade == CascadeType.MERGE || cascade == CascadeType.REMOVE) { - assert (false) : "Doesn't support " + cascade + " for " + field.getName(); - return false; - } + CollectionTable ct = field.getAnnotation(CollectionTable.class); + if (ct == null) { + assert (false) : "No collection table sepcified for " + field.getName(); + return false; } return true; @@ -264,8 +271,8 @@ public class SqlGenerator { } } - public List getOneToManyAttributes() { - return _otmAttrs; + public List getElementCollectionAttributes() { + return _ecAttrs; } public Attribute findAttribute(String name) { diff --git a/utils/src/javax/persistence/ElementCollection.java b/utils/src/javax/persistence/ElementCollection.java index aaaa96edf25..622bab2fba8 100644 --- a/utils/src/javax/persistence/ElementCollection.java +++ b/utils/src/javax/persistence/ElementCollection.java @@ -17,6 +17,17 @@ */ package javax.persistence; -public interface ElementCollection { +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(value = { METHOD, FIELD }) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface ElementCollection { + FetchType fetch() default FetchType.LAZY; + + Class targetClass() default void.class; } From 0ab12edd6cd079a549f58992e75d14eb519a92b4 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Tue, 31 May 2011 09:25:30 -0700 Subject: [PATCH 08/65] network tagging changes --- .../com/cloud/agent/transport/Request.java | 5 + .../xen/resource/CitrixResourceBase.java | 225 +++++++----------- .../cloud/agent/transport/RequestTest.java | 7 + .../cloud/agent/manager/AgentManagerImpl.java | 2 +- .../cloud/storage/dao/StoragePoolDaoImpl.java | 6 +- .../com/cloud/vm/dao/ConsoleProxyDaoImpl.java | 6 +- .../com/cloud/vm/dao/DomainRouterDaoImpl.java | 4 +- .../vm/dao/SecondaryStorageVmDaoImpl.java | 52 ++-- .../com/cloud/utils/db/GenericDaoBase.java | 180 +++++++------- .../src/com/cloud/utils/db/UpdateBuilder.java | 34 ++- 10 files changed, 262 insertions(+), 259 deletions(-) diff --git a/core/src/com/cloud/agent/transport/Request.java b/core/src/com/cloud/agent/transport/Request.java index 79028e9e477..7c98bed15ca 100755 --- a/core/src/com/cloud/agent/transport/Request.java +++ b/core/src/com/cloud/agent/transport/Request.java @@ -301,6 +301,11 @@ public class Request { } } } + + @Override + public String toString() { + return log("", true, Level.DEBUG); + } protected String log(String msg, boolean logContent, Level level) { StringBuilder content = new StringBuilder(); diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 79d164a3890..0d873ee6a47 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -120,8 +120,8 @@ import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.UpdateHostPasswordCommand; +import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; @@ -302,7 +302,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (VmPowerState.HALTED.equals(vmRec.powerState) && vmRec.affinity.equals(host)) { try { - vm.destroy(conn); + vm.destroy(conn); } catch (Exception e) { s_logger.warn("Catch Exception " + e.getClass().getName() + ": unable to destroy VM " + vmRec.nameLabel + " due to " + e.toString()); success = false; @@ -318,7 +318,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe @Override public void disconnected() { - } + } protected Pair getVmByNameLabel(Connection conn, Host host, String nameLabel, boolean getRecord) throws XmlRpcException, XenAPIException { Set vms = host.getResidentVMs(conn); @@ -499,11 +499,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - Pair getNativeNetworkForTraffic(Connection conn, TrafficType type) throws XenAPIException, XmlRpcException { + Pair getNativeNetworkForTraffic(Connection conn, TrafficType type, String tag) throws XenAPIException, XmlRpcException { + if (tag != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Looking for network named " + tag); + } + Network network = getNetworkByName(conn, tag); + } + if (type == TrafficType.Guest) { return new Pair(Network.getByUuid(conn, _host.guestNetwork), _host.guestPif); } else if (type == TrafficType.Control) { - setupLinkLocalNetwork(conn); + setupLinkLocalNetwork(conn); return new Pair(Network.getByUuid(conn, _host.linkLocalNetwork), null); } else if (type == TrafficType.Management) { return new Pair(Network.getByUuid(conn, _host.privateNetwork), _host.privatePif); @@ -524,8 +531,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe * then you will get an expection that is "REQUIRED_NETWROK" when you start a * vm with this network. The soultion is, create a vif of dom0 and plug it in * network, xenserver will create the bridge on behalf of you - * @throws XmlRpcException - * @throws XenAPIException + * @throws XmlRpcException + * @throws XenAPIException */ private void enableXenServerNetwork(Connection conn, Network nw, String vifNameLabel, String networkDesc) throws XenAPIException, XmlRpcException { @@ -575,7 +582,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe enableXenServerNetwork(conn, vswitchNw, "vswitch", "vswicth network"); _host.vswitchNetwork = vswitchNw; - } + } return _host.vswitchNetwork; } catch (Exception e) { e.printStackTrace(); @@ -609,7 +616,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected Network getNetwork(Connection conn, NicTO nic) throws XenAPIException, XmlRpcException { - Pair network = getNativeNetworkForTraffic(conn, nic.getType()); + String[] tags = nic.getTags(); + Pair network = getNativeNetworkForTraffic(conn, nic.getType(), tags != null && tags.length > 0 ? tags[0] : null); if (nic.getBroadcastUri() != null && nic.getBroadcastUri().toString().contains("untagged")) { return network.first(); } else if (nic.getBroadcastType() == BroadcastDomainType.Vlan) { @@ -753,12 +761,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } else if (volume.getType() == Volume.Type.ROOT) { vbdr.mode = Types.VbdMode.RW; vbdr.type = Types.VbdType.DISK; - vbdr.unpluggable = false; + vbdr.unpluggable = false; } else { vbdr.mode = Types.VbdMode.RW; vbdr.type = Types.VbdType.DISK; vbdr.unpluggable = true; - } + } VBD vbd = VBD.create(conn, vbdr); if (s_logger.isDebugEnabled()) { @@ -774,7 +782,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe assert templates.size() == 1 : "Should only have 1 template but found " + templates.size(); VM template = templates.iterator().next(); - VM vm = template.createClone(conn, vmSpec.getName()); + VM vm = template.createClone(conn, vmSpec.getName()); VM.Record vmr = vm.getRecord(conn); if (s_logger.isDebugEnabled()) { s_logger.debug("Created VM " + vmr.uuid + " for " + vmSpec.getName()); @@ -931,7 +939,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if( _host.systemvmisouuid == null ) { throw new CloudRuntimeException("can not find systemvmiso"); - } + } } VBD.Record cdromVBDR = new VBD.Record(); @@ -961,7 +969,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String result = connect(conn, cmd.getName(), privateIp, cmdPort); if (result != null) { return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + "due to:" + result); - } + } } catch (Exception e) { return new CheckSshAnswer(cmd, e); } @@ -995,7 +1003,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe private void cleanUpTmpDomVif(Connection conn) { List vifs; - synchronized(_tmpDom0Vif) { + synchronized(_tmpDom0Vif) { vifs = _tmpDom0Vif; _tmpDom0Vif = new ArrayList(); } @@ -1018,8 +1026,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe public StartAnswer execute(StartCommand cmd) { Connection conn = getConnection(); VirtualMachineTO vmSpec = cmd.getVirtualMachine(); - String vmName = vmSpec.getName(); - State state = State.Stopped; + String vmName = vmSpec.getName(); + State state = State.Stopped; VM vm = null; try { @@ -1040,7 +1048,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe synchronized (_vms) { _vms.put(vmName, State.Starting); } - Host host = Host.getByUuid(conn, _host.uuid); + Host host = Host.getByUuid(conn, _host.uuid); vm = createVmFromTemplate(conn, vmSpec, host); for (VolumeTO disk : vmSpec.getDisks()) { @@ -1087,7 +1095,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } else { //For user vm, program the rules for each nic if the isolation uri scheme is ec2 NicTO[] nics = vmSpec.getNics(); - for (NicTO nic : nics) { + for (NicTO nic : nics) { if (nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { result = callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), "vmID", Long.toString(vmSpec.getId())); @@ -1095,10 +1103,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.warn("Failed to program default network rules for " + vmName+" on nic with ip:"+nic.getIp()+" mac:"+nic.getMac()); } else { s_logger.info("Programmed default network rules for " + vmName+" on nic with ip:"+nic.getIp()+" mac:"+nic.getMac()); - } + } } } - } + } } state = State.Running; @@ -1243,7 +1251,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe int i = 0; for (StaticNatRuleTO rule : cmd.getRules()) { //1:1 NAT needs instanceip;publicip;domrip;op - args += rule.revoked() ? " -D " : " -A "; + args += rule.revoked() ? " -D " : " -A "; args += " -l " + rule.getSrcIp(); args += " -r " + rule.getDstIp(); args += " -P " + rule.getProtocol().toLowerCase(); @@ -1543,7 +1551,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); try { - IpAddressTO[] ips = cmd.getIpAddresses(); + IpAddressTO[] ips = cmd.getIpAddresses(); for (IpAddressTO ip : ips) { assignPublicIpAddress(conn, routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getVlanId(), @@ -1676,16 +1684,16 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe hostStats.setCpuUtilization(hostStats.getCpuUtilization() + getDataAverage(dataNode, col, numRows)); } -/* +/* if (param.contains("loadavg")) { hostStats.setAverageLoad((hostStats.getAverageLoad() + getDataAverage(dataNode, col, numRows))); } -*/ +*/ } } // add the host cpu utilization -/* +/* if (hostStats.getNumCpus() != 0) { hostStats.setCpuUtilization(hostStats.getCpuUtilization() / hostStats.getNumCpus()); s_logger.debug("Host cpu utilization " + hostStats.getCpuUtilization()); @@ -1701,7 +1709,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe HashMap vmStatsNameMap = new HashMap(); if( vmNames.size() == 0 ) { return new GetVmStatsAnswer(cmd, vmStatsNameMap); - } + } try { // Determine the UUIDs of the requested VMs @@ -1799,8 +1807,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization()*100); - if(s_logger.isDebugEnabled()) - s_logger.debug("Vm cpu utilization " + vmStatsAnswer.getCPUUtilization()); + if(s_logger.isDebugEnabled()) { + s_logger.debug("Vm cpu utilization " + vmStatsAnswer.getCPUUtilization()); + } } return vmResponseMap; @@ -1912,7 +1921,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.warn("Found an invalid value (infinity/NaN) in getDataAverage(), numRows>0"); return dummy; } - } + } } @@ -2173,9 +2182,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe snapshotvdi.setNameLabel(conn, "Template " + cmd.getName()); tmpl.destroy(conn); poolsr.scan(conn); - try{ + try{ Thread.sleep(5000); - } catch (Exception e) { + } catch (Exception e) { } String parentuuid = getVhdParent(conn, pUuid, snapshotUuid, isISCSI); VDI parent = getVDIbyUuid(conn, parentuuid); @@ -2355,7 +2364,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe break; } } - vm.poolMigrate(conn, dsthost, new HashMap()); + vm.poolMigrate(conn, dsthost, new HashMap()); vm.setAffinity(conn, dsthost); state = State.Stopping; } @@ -2704,7 +2713,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if( System.currentTimeMillis() - beginTime > timeout){ String msg = "Async " + timeout/1000 + " seconds timeout for task " + task.toString(); s_logger.warn(msg); - task.cancel(c); + task.cancel(c); throw new Types.BadAsyncResult(msg); } } @@ -2750,7 +2759,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe try { task.destroy(conn); } catch (Exception e1) { - s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid +") due to " + e1.toString()); + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid +") due to " + e1.toString()); } } } @@ -2816,7 +2825,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe try { task.destroy(conn); } catch (Exception e1) { - s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid +") due to " + e1.toString()); + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid +") due to " + e1.toString()); } } } @@ -2846,7 +2855,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe try { task.destroy(conn); } catch (Exception e1) { - s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid +") due to " + e1.toString()); + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid +") due to " + e1.toString()); } } } @@ -2880,8 +2889,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe "op", "download", "hostname", swift.getHostName(), "account", swift.getAccount(), "username", swift.getUserName(), "token", swift.getToken(), "rfilename", rfilename, "lfilename", lfilename); - if( result != null && result.equals("true")) + if( result != null && result.equals("true")) { return true; + } } catch (Exception e) { s_logger.warn("swift download failed due to " + e.toString()); } @@ -2895,8 +2905,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe "op", "upload", "hostname", swift.getHostName(), "account", swift.getAccount(), "username", swift.getUserName(), "token", swift.getToken(), "rfilename", rfilename, "lfilename", lfilename); - if( result != null && result.equals("true")) + if( result != null && result.equals("true")) { return true; + } } catch (Exception e) { s_logger.warn("swift download failed due to " + e.toString()); } @@ -2909,8 +2920,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe result = callHostPlugin(conn, "swift", "swift", "op", "delete", "hostname", swift.getHostName(), "account", swift.getAccount(), "username", swift.getUserName(), "token", swift.getToken(), "rfilename", rfilename); - if( result != null && result.equals("true")) + if( result != null && result.equals("true")) { return true; + } } catch (Exception e) { s_logger.warn("swift download failed due to " + e.toString()); } @@ -3109,7 +3121,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } return new StopAnswer(cmd, "Stop VM " + vmName + " Succeed", 0, bytesSent, bytesRcvd); - } + } } catch (XenAPIException e) { String msg = "VM destroy failed in Stop " + vmName + " Command due to " + e.toString(); s_logger.warn(msg, e); @@ -3145,11 +3157,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } catch (XenAPIException e) { String msg = "getVdis can not get VPD due to " + e.toString(); - s_logger.warn(msg, e); + s_logger.warn(msg, e); } catch (XmlRpcException e) { String msg = "getVdis can not get VPD due to " + e.getMessage(); s_logger.warn(msg, e); - } + } return vdis; } @@ -3267,7 +3279,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return true; } - protected Nic getManageMentNetwork(Connection conn) throws XmlRpcException, XenAPIException { + protected Nic getManageMentNetwork(Connection conn) throws XmlRpcException, XenAPIException { PIF mgmtPif = null; PIF.Record mgmtPifRec = null; Host host = Host.getByUuid(conn, _host.uuid); @@ -3429,66 +3441,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } } - } + } return found; } - protected Network enableVlanNetwork(Connection conn, long tag, String pifUuid) throws XenAPIException, XmlRpcException { - // In XenServer, vlan is added by - // 1. creating a network. - // 2. creating a vlan associating network with the pif. - // We always create - // 1. a network with VLAN[vlan id in decimal] - // 2. a vlan associating the network created with the pif to private - // network. - Network vlanNetwork = null; - String name = "VLAN" + Long.toString(tag); - - synchronized (name.intern()) { - vlanNetwork = getNetworkByName(conn, name); - if (vlanNetwork == null) { // Can't find it, then create it. - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating VLAN network for " + tag + " on host " + _host.ip); - } - Network.Record nwr = new Network.Record(); - nwr.nameLabel = name; - nwr.bridge = name; - vlanNetwork = Network.create(conn, nwr); - } - - PIF nPif = PIF.getByUuid(conn, pifUuid); - PIF.Record nPifr = nPif.getRecord(conn); - - Network.Record vlanNetworkr = vlanNetwork.getRecord(conn); - if (vlanNetworkr.PIFs != null) { - for (PIF pif : vlanNetworkr.PIFs) { - PIF.Record pifr = pif.getRecord(conn); - if(pifr.host.equals(nPifr.host)) { - if (pifr.device.equals(nPifr.device) ) { - pif.plug(conn); - return vlanNetwork; - } else { - throw new CloudRuntimeException("Creating VLAN " + tag + " on " + nPifr.device + " failed due to this VLAN is already created on " + pifr.device); - } - - } - } - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating VLAN " + tag + " on host " + _host.ip + " on device " + nPifr.device); - } - VLAN vlan = VLAN.create(conn, nPif, tag, vlanNetwork); - PIF untaggedPif = vlan.getUntaggedPIF(conn); - if (!untaggedPif.getCurrentlyAttached(conn)) { - untaggedPif.plug(conn); - } - } - - return vlanNetwork; - } - protected Network enableVlanNetwork(Connection conn, long tag, Network network, String pifUuid) throws XenAPIException, XmlRpcException { // In XenServer, vlan is added by // 1. creating a network. @@ -3541,7 +3498,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected SR getLocalLVMSR(Connection conn) { - try { + try { Map map = SR.getAllRecords(conn); for (Map.Entry entry : map.entrySet()) { SR.Record srRec = entry.getValue(); @@ -3620,7 +3577,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.warn(" can not ping xenserver " + _host.uuid); return null; } - } + } HashMap newStates = sync(conn); if (newStates == null) { s_logger.warn("Unable to get current status from sync"); @@ -3678,7 +3635,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe break; } Nic privateNic = getManageMentNetwork(conn); - _privateNetworkName = privateNic.nr.nameLabel; + _privateNetworkName = privateNic.nr.nameLabel; _host.privatePif = privateNic.pr.uuid; _host.privateNetwork = privateNic.nr.uuid; @@ -3900,7 +3857,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String tag = it.next(); if (tag.startsWith("vmops-version-")) { if (tag.contains(version)) { - s_logger.info(logX(host, "Host " + hr.address + " is already setup.")); + s_logger.info(logX(host, "Host " + hr.address + " is already setup.")); return; } else { it.remove(); @@ -3911,7 +3868,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(hr.address, 22); try { sshConnection.connect(null, 60000, 60000); - if (!sshConnection.authenticateWithPassword(_username, _password.peek())) { + if (!sshConnection.authenticateWithPassword(_username, _password.peek())) { throw new CloudRuntimeException("Unable to authenticate"); } @@ -4070,7 +4027,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe PBD.Record pbdr = pbd.getRecord(conn); if (host.equals(pbdr.host)) { if (!pbdr.currentlyAttached) { - pbdPlug(conn, pbd, pbdr.uuid); + pbdPlug(conn, pbd, pbdr.uuid); } found = true; break; @@ -4081,7 +4038,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe pbdr.host = host; pbdr.uuid = ""; PBD pbd = PBD.create(conn, pbdr); - pbdPlug(conn, pbd, pbd.getUuid(conn)); + pbdPlug(conn, pbd, pbd.getUuid(conn)); } } else { for (PBD pbd : pbds) { @@ -4117,7 +4074,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String msg = "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath(); s_logger.warn(msg, e); return new Answer(cmd, false, msg); - } + } } @@ -4229,7 +4186,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } - protected boolean can_bridge_firewall(Connection conn) { + protected boolean can_bridge_firewall(Connection conn) { return Boolean.valueOf(callHostPlugin(conn, "vmops", "can_bridge_firewall", "host_uuid", _host.uuid, "instance", _instance)); } @@ -4369,7 +4326,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe _isOvs = true; Connection conn = getConnection(); - String bridge = "unkonwn"; + String bridge = "unkonwn"; try { Network nw = setupvSwitchNetwork(conn); bridge = nw.getBridge(conn); @@ -4383,7 +4340,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe _host.ip, bridge); } else { return new OvsCreateGreTunnelAnswer(cmd, true, result, _host.ip, bridge, Integer.parseInt(res[1])); - } + } } catch (Exception e) { e.printStackTrace(); } @@ -4456,7 +4413,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (_publicNetworkName != null) { details.put("public.network.device", _publicNetworkName); - } + } if (_guestNetworkName != null) { details.put("guest.network.device", _guestNetworkName); } @@ -4610,7 +4567,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe private void CheckXenHostInfo() throws ConfigurationException { Connection conn = _connPool.slaveConnect(_host.ip, _username, _password); - if( conn == null ) { + if( conn == null ) { throw new ConfigurationException("Can not create slave connection to " + _host.ip); } try { @@ -4630,7 +4587,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe throw new ConfigurationException(msg); } } finally { - try { + try { Session.localLogout(conn); } catch (Exception e) { } @@ -4674,7 +4631,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vdir = vdi.getRecord(conn); s_logger.debug("Succesfully created VDI for " + cmd + ". Uuid = " + vdir.uuid); - VolumeTO vol = new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), vdir.nameLabel, + VolumeTO vol = new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), vdir.nameLabel, pool.getPath(), vdir.uuid, vdir.virtualSize, null); return new CreateAnswer(cmd, vol); } catch (Exception e) { @@ -4731,7 +4688,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe SR sr = SR.create(conn, host, deviceConfig, new Long(0), name, uri.getHost() + uri.getPath(), SRType.NFS.toString(), "user", shared, new HashMap()); if( !checkSR(conn, sr) ) { throw new Exception("no attached PBD"); - } + } if (s_logger.isDebugEnabled()) { s_logger.debug(logX(sr, "Created a SR; UUID is " + sr.getUuid(conn) + " device config is " + deviceConfig)); } @@ -4850,7 +4807,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe continue; } if (target.equals(dc.get("target")) && targetiqn.equals(dc.get("targetIQN")) && lunid.equals(dc.get("lunid"))) { - throw new CloudRuntimeException("There is a SR using the same configuration target:" + dc.get("target") + ", targetIQN:" + throw new CloudRuntimeException("There is a SR using the same configuration target:" + dc.get("target") + ", targetIQN:" + dc.get("targetIQN") + ", lunid:" + dc.get("lunid") + " for pool " + pool.getUuid() + "on host:" + _host.uuid); } } @@ -4894,7 +4851,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.warn(msg, e); throw new CloudRuntimeException(msg, e); } - } + } deviceConfig.put("SCSIid", scsiid); String result = SR.probe(conn, host, deviceConfig, type , smConfig); @@ -4906,9 +4863,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe sr = SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), poolId, type, "user", true, smConfig); } else { - sr = SR.introduce(conn, pooluuid, pool.getUuid(), poolId, + sr = SR.introduce(conn, pooluuid, pool.getUuid(), poolId, type, "user", true, smConfig); - Pool.Record pRec = XenServerConnectionPool.getPoolRecord(conn); + Pool.Record pRec = XenServerConnectionPool.getPoolRecord(conn); PBD.Record rec = new PBD.Record(); rec.deviceConfig = deviceConfig; rec.host = pRec.master; @@ -4964,7 +4921,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (server.equals(dc.get("server")) && serverpath.equals(dc.get("serverpath"))) { - throw new CloudRuntimeException("There is a SR using the same configuration server:" + dc.get("server") + ", serverpath:" + throw new CloudRuntimeException("There is a SR using the same configuration server:" + dc.get("server") + ", serverpath:" + dc.get("serverpath") + " for pool " + pool.getUuid() + "on host:" + _host.uuid); } @@ -5035,7 +4992,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String volumeFolder = String.valueOf(cmd.getVolumeId()) + "/"; String mountpoint = remoteVolumesMountPath + volumeFolder; SR primaryStoragePool = getStorageRepository(conn, poolTO); - String srUuid = primaryStoragePool.getUuid(conn); + String srUuid = primaryStoragePool.getUuid(conn); if (toSecondaryStorage) { // Create the volume folder if (!createSecondaryStorageFolder(conn, remoteVolumesMountPath, volumeFolder)) { @@ -5058,7 +5015,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe removeSR(conn, secondaryStorage); } } else { - String uuid = copy_vhd_to_secondarystorage(conn, mountpoint, volumeUUID, srUuid); + String uuid = copy_vhd_to_secondarystorage(conn, mountpoint, volumeUUID, srUuid); return new CopyVolumeAnswer(cmd, true, null, null, uuid); } } else { @@ -5118,12 +5075,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if( deviceId != null ) { if( deviceId.longValue() == 3 ) { String msg = "Device 3 is reserved for CD-ROM, choose other device"; - return new AttachVolumeAnswer(cmd,msg); + return new AttachVolumeAnswer(cmd,msg); } if(isDeviceUsed(conn, vm, deviceId)) { String msg = "Device " + deviceId + " is used in VM " + vmName; return new AttachVolumeAnswer(cmd,msg); - } + } diskNumber = deviceId.toString(); } else { diskNumber = getUnusedDeviceNum(conn, vm); @@ -5474,7 +5431,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe result = postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUuid, userSpecifiedName, null, physicalSize, virtualSize, newTemplateId); if (!result) { throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + templatePath); - } + } installPath = installPath + "/" + tmpltFilename; return new CreatePrivateTemplateAnswer(cmd, true, null, installPath, virtualSize, physicalSize, tmpltUuid, ImageFormat.VHD); } catch (Exception e) { @@ -5512,7 +5469,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } return false; - } + } protected BackupSnapshotAnswer execute(final BackupSnapshotCommand cmd) { Connection conn = getConnection(); @@ -5540,7 +5497,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid); if ( prevBackupUuid != null ) { - try { + try { String snapshotPaUuid = getVhdParent(conn, psUuid, snapshotUuid, isISCSI); if( snapshotPaUuid != null ) { String snashotPaPaPaUuid = getVhdParent(conn, psUuid, snapshotPaUuid, isISCSI); @@ -5549,7 +5506,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe fullbackup = false; } } - } catch (Exception e) { + } catch (Exception e) { } } String filename = volumeId + "_" + cmd.getSnapshotId() + "_" + cmd.getSnapshotUuid(); @@ -5636,7 +5593,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe // Get the absolute path of the snapshot on the secondary storage. URI snapshotURI = new URI(secondaryStoragePoolURL + "/snapshots/" + accountId + "/" + volumeId ); String snapshotPath = snapshotURI.getHost() + ":" + snapshotURI.getPath() + "/" + backedUpSnapshotUuid + ".vhd"; - String srUuid = primaryStorageSR.getUuid(conn); + String srUuid = primaryStorageSR.getUuid(conn); volumeUUID = copy_vhd_from_secondarystorage(conn, snapshotPath, srUuid); result = true; } catch (XenAPIException e) { @@ -5935,10 +5892,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } return success; - } + } protected String getVhdParent(Connection conn, String primaryStorageSRUuid, String snapshotUuid, Boolean isISCSI) { - String parentUuid = callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, + String parentUuid = callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", isISCSI.toString()); if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) { @@ -6058,7 +6015,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } catch (XenAPIException e) { String msg = "Unable to eject host " + _host.uuid + " due to " + e.toString(); - s_logger.warn(msg); + s_logger.warn(msg); host.destroy(conn); } return new Answer(cmd); @@ -6070,7 +6027,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String msg = "Exception Unable to destroy host " + _host.uuid + " in xenserver database due to " + e.getMessage(); s_logger.warn(msg, e); return new Answer(cmd, false, msg); - } + } } private Answer execute(CleanupNetworkRulesCmd cmd) { diff --git a/core/test/com/cloud/agent/transport/RequestTest.java b/core/test/com/cloud/agent/transport/RequestTest.java index 150a29f67d7..0198444fbff 100644 --- a/core/test/com/cloud/agent/transport/RequestTest.java +++ b/core/test/com/cloud/agent/transport/RequestTest.java @@ -42,8 +42,13 @@ public class RequestTest extends TestCase { private static final Logger s_logger = Logger.getLogger(RequestTest.class); public void testSerDeser() { + s_logger.info("Testing serializing and deserializing works as expected"); + + s_logger.info("UpdateHostPasswordCommand should have two parameters that doesn't show in logging"); UpdateHostPasswordCommand cmd1 = new UpdateHostPasswordCommand("abc", "def"); + s_logger.info("SecStorageFirewallCfgCommand has a context map that shouldn't show up in debug level"); SecStorageFirewallCfgCommand cmd2 = new SecStorageFirewallCfgCommand(); + s_logger.info("GetHostStatsCommand should not show up at all in debug level"); GetHostStatsCommand cmd3 = new GetHostStatsCommand("hostguid", "hostname", 101); cmd2.addPortConfig("abc", "24", true, "eth0"); cmd2.addPortConfig("127.0.0.1", "44", false, "eth1"); @@ -113,6 +118,7 @@ public class RequestTest extends TestCase { } public void testDownload() { + s_logger.info("Testing Download answer"); VMTemplateVO template = new VMTemplateVO(1, "templatename", ImageFormat.QCOW2, true, true, true, TemplateType.USER, "url", true, 32, 1, "chksum", "displayText", true, 30, true, HypervisorType.KVM); DownloadCommand cmd = new DownloadCommand("secUrl", template, 30000000l); @@ -128,6 +134,7 @@ public class RequestTest extends TestCase { } public void testLogging() { + s_logger.info("Testing Logging"); GetHostStatsCommand cmd3 = new GetHostStatsCommand("hostguid", "hostname", 101); Request sreq = new Request(2, 3, new Command[] { cmd3 }, true, true); sreq.setSequence(1); diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index dc70480c90d..896e125ac4b 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -2153,7 +2153,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager { Response response = null; if (attache == null) { - s_logger.debug("Processing sequence " + request.getSequence() + ": Processing " + request.toString()); + request.logD("Processing the first command "); if (!(cmd instanceof StartupCommand)) { s_logger.warn("Throwing away a request because it came through as the first command on a connect: " + request.toString()); return; diff --git a/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java b/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java index 8ec1e6948ab..a22f07435c8 100644 --- a/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java +++ b/server/src/com/cloud/storage/dao/StoragePoolDaoImpl.java @@ -280,7 +280,7 @@ public class StoragePoolDaoImpl extends GenericDaoBase imp sql.delete(sql.length() - 4, sql.length()); sql.append(DetailsSqlSuffix); Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = s_initStmt; + PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql.toString()); int i = 1; @@ -297,7 +297,7 @@ public class StoragePoolDaoImpl extends GenericDaoBase imp } return pools; } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); + throw new CloudRuntimeException("Unable to execute " + pstmt, e); } } @@ -351,7 +351,7 @@ public class StoragePoolDaoImpl extends GenericDaoBase imp while (rs.next()) { tags.add(rs.getString("name")); - } + } return tags; } catch (SQLException e) { throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); diff --git a/server/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java b/server/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java index 401d004dc52..d4e81c51fec 100644 --- a/server/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java +++ b/server/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java @@ -137,7 +137,7 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase im HostUpSearch = createSearchBuilder(); HostUpSearch.and("host", HostUpSearch.entity().getHostId(), SearchCriteria.Op.EQ); HostUpSearch.and("states", HostUpSearch.entity().getState(), SearchCriteria.Op.NIN); - HostUpSearch.done(); + HostUpSearch.done(); StateChangeSearch = createSearchBuilder(); StateChangeSearch.and("id", StateChangeSearch.entity().getId(), SearchCriteria.Op.EQ); @@ -171,7 +171,7 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase im UpdateBuilder ub = getUpdateBuilder(proxy); ub.set(proxy, "state", State.Destroyed); ub.set(proxy, "privateIpAddress", null); - update(id, ub); + update(id, ub, proxy); boolean result = super.remove(id); txn.commit(); @@ -204,7 +204,7 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase im public List listUpByHostId(long hostId) { SearchCriteria sc = HostUpSearch.create(); sc.setParameters("host", hostId); - sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging}); + sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging}); return listBy(sc); } diff --git a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index 8d6f311183f..68c873008d8 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -29,9 +29,9 @@ import com.cloud.network.dao.NetworkDaoImpl; import com.cloud.network.router.VirtualRouter.Role; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.db.UpdateBuilder; @@ -83,7 +83,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im router.setPublicIpAddress(null); UpdateBuilder ub = getUpdateBuilder(router); ub.set(router, "state", State.Destroyed); - update(id, ub); + update(id, ub, router); boolean result = super.remove(id); txn.commit(); diff --git a/server/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java b/server/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java index 3d33a4b8704..c890993451c 100644 --- a/server/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java +++ b/server/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java @@ -113,7 +113,7 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase sc = DataCenterStatusSearch.create(); sc.setParameters("states", (Object[])states); sc.setParameters("dc", dataCenterId); - if(role != null) - sc.setParameters("role", role); + if(role != null) { + sc.setParameters("role", role); + } return listBy(sc); } @@ -134,8 +135,9 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase getSecStorageVmListInStates(SecondaryStorageVm.Role role, State... states) { SearchCriteria sc = StateSearch.create(); sc.setParameters("states", (Object[])states); - if(role != null) - sc.setParameters("role", role); + if(role != null) { + sc.setParameters("role", role); + } return listBy(sc); } @@ -144,8 +146,9 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase listByHostId(SecondaryStorageVm.Role role, long hostId) { SearchCriteria sc = HostSearch.create(); sc.setParameters("host", hostId); - if(role != null) - sc.setParameters("role", role); + if(role != null) { + sc.setParameters("role", role); + } return listBy(sc); } @@ -153,9 +156,10 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase listUpByHostId(SecondaryStorageVm.Role role, long hostId) { SearchCriteria sc = HostUpSearch.create(); sc.setParameters("host", hostId); - sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging}); - if(role != null) - sc.setParameters("role", role); + sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging}); + if(role != null) { + sc.setParameters("role", role); + } return listBy(sc); } @@ -166,12 +170,13 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase listByZoneId(SecondaryStorageVm.Role role, long zoneId) { SearchCriteria sc = ZoneSearch.create(); sc.setParameters("zone", zoneId); - if(role != null) - sc.setParameters("role", role); + if(role != null) { + sc.setParameters("role", role); + } return listBy(sc); } @@ -219,8 +225,9 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase sc = LastHostSearch.create(); sc.setParameters("lastHost", hostId); sc.setParameters("state", State.Stopped); - if(role != null) - sc.setParameters("role", role); + if(role != null) { + sc.setParameters("role", role); + } return listBy(sc); } @@ -233,10 +240,11 @@ public class SecondaryStorageVmDaoImpl extends GenericDaoBase implements Gene protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT"); - protected final static Map, GenericDao> s_daoMaps = new HashMap, GenericDao>(71); + protected final static Map, GenericDao> s_daoMaps = new ConcurrentHashMap, GenericDao>(71); protected Class _entityBeanType; protected String _table; @@ -135,10 +136,10 @@ public abstract class GenericDaoBase implements Gene protected Pair _removed; protected Pair _removeSql; protected List> _deleteSqls; - protected Map _idAttributes; - protected Map _tgs; + protected final Map _idAttributes; + protected final Map _tgs; protected final Map _allAttributes; - protected List _ecAttributes; + protected final List _ecAttributes; protected final Map, Attribute> _allColumns; protected Enhancer _enhancer; protected Factory _factory; @@ -153,21 +154,6 @@ public abstract class GenericDaoBase implements Gene protected static final SequenceFetcher s_seqFetcher = SequenceFetcher.getInstance(); - protected static PreparedStatement s_initStmt; - static { - Connection conn = Transaction.getStandaloneConnection(); - try { - s_initStmt = conn.prepareStatement("SELECT 1"); - } catch (final SQLException e) { - } finally { - try { - conn.close(); - } catch (SQLException e) { - } - } - - } - protected String _name; public static GenericDao getDao(Class entityType) { @@ -238,7 +224,7 @@ public abstract class GenericDaoBase implements Gene _tgs.put(tg.name(), tg); } - Callback[] callbacks = new Callback[] { NoOp.INSTANCE, new UpdateBuilder(_allAttributes) }; + Callback[] callbacks = new Callback[] { NoOp.INSTANCE, new UpdateBuilder(this) }; _enhancer = new Enhancer(); _enhancer.setSuperclass(_entityBeanType); @@ -248,7 +234,7 @@ public abstract class GenericDaoBase implements Gene _searchEnhancer = new Enhancer(); _searchEnhancer.setSuperclass(_entityBeanType); - _searchEnhancer.setCallback(new UpdateBuilder(_allAttributes)); + _searchEnhancer.setCallback(new UpdateBuilder(this)); if (s_logger.isTraceEnabled()) { s_logger.trace("Select SQL: " + _partialSelectSql.first().toString()); @@ -277,7 +263,7 @@ public abstract class GenericDaoBase implements Gene @Override @DB(txn=false) @SuppressWarnings("unchecked") public T createForUpdate(final ID id) { - final T entity = (T)_factory.newInstance(new Callback[] {NoOp.INSTANCE, new UpdateBuilder(_allAttributes)}); + final T entity = (T)_factory.newInstance(new Callback[] {NoOp.INSTANCE, new UpdateBuilder(this)}); if (id != null) { try { _idField.set(entity, id); @@ -355,7 +341,7 @@ public abstract class GenericDaoBase implements Gene final String sql = str.toString(); - PreparedStatement pstmt = s_initStmt; + PreparedStatement pstmt = null; final List result = new ArrayList(); try { pstmt = txn.prepareAutoCloseStatement(sql); @@ -385,9 +371,9 @@ public abstract class GenericDaoBase implements Gene } return result; } catch (final SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + pstmt.toString(), e); + throw new CloudRuntimeException("DB Exception on: " + pstmt, e); } catch (final Throwable e) { - throw new CloudRuntimeException("Caught: " + pstmt.toString(), e); + throw new CloudRuntimeException("Caught: " + pstmt, e); } } @@ -417,7 +403,7 @@ public abstract class GenericDaoBase implements Gene final String sql = str.toString(); final Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = s_initStmt; + PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql); int i = 0; @@ -457,9 +443,9 @@ public abstract class GenericDaoBase implements Gene return results; } catch (final SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + pstmt.toString(), e); + throw new CloudRuntimeException("DB Exception on: " + pstmt, e); } catch (final Throwable e) { - throw new CloudRuntimeException("Caught: " + pstmt.toString(), e); + throw new CloudRuntimeException("Caught: " + pstmt, e); } } @@ -718,26 +704,38 @@ public abstract class GenericDaoBase implements Gene } if (s_logger.isTraceEnabled()) { - s_logger.trace("join search statement is " + pstmt.toString()); + s_logger.trace("join search statement is " + pstmt); } return count; } - @DB(txn=false) - protected int update(final ID id, final UpdateBuilder ub) { - SearchCriteria sc = createSearchCriteria(); - sc.addAnd(_idAttributes.get(_table)[0], SearchCriteria.Op.EQ, id); - int rowsUpdated = update(ub, sc, null); + protected int update(ID id, UpdateBuilder ub, T entity) { if (_cache != null) { _cache.remove(id); } + SearchCriteria sc = createSearchCriteria(); + sc.addAnd(_idAttributes.get(_table)[0], SearchCriteria.Op.EQ, id); + Transaction txn = Transaction.currentTxn(); + txn.start(); + + int rowsUpdated = update(ub, sc, null); + + try { + if (ub.getCollectionChanges() != null) { + insertElementCollection(entity, _idAttributes.get(_table)[0], id, ub.getCollectionChanges()); + } + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to persist element collection", e); + } + txn.commit(); + return rowsUpdated; } // @Override - public int update(final UpdateBuilder ub, final SearchCriteria sc, Integer rows) { + public int update(UpdateBuilder ub, final SearchCriteria sc, Integer rows) { StringBuilder sql = null; - PreparedStatement pstmt = s_initStmt; + PreparedStatement pstmt = null; final Transaction txn = Transaction.currentTxn(); try { final String searchClause = sc.getWhereClause(); @@ -775,8 +773,7 @@ public abstract class GenericDaoBase implements Gene if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) { throw new EntityExistsException("Entity already exists ", e); } - final String sqlStr = pstmt.toString(); - throw new CloudRuntimeException("DB Exception on: " + sqlStr, e); + throw new CloudRuntimeException("DB Exception on: " + pstmt, e); } } @@ -891,7 +888,7 @@ public abstract class GenericDaoBase implements Gene sql.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE); } Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = s_initStmt; + PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql.toString()); @@ -996,7 +993,7 @@ public abstract class GenericDaoBase implements Gene protected List executeList(final String sql, final Object... params) { final Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = s_initStmt; + PreparedStatement pstmt = null; final List result = new ArrayList(); try { pstmt = txn.prepareAutoCloseStatement(sql); @@ -1011,9 +1008,9 @@ public abstract class GenericDaoBase implements Gene } return result; } catch (final SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + pstmt.toString(), e); + throw new CloudRuntimeException("DB Exception on: " + pstmt, e); } catch (final Throwable e) { - throw new CloudRuntimeException("Caught: " + pstmt.toString(), e); + throw new CloudRuntimeException("Caught: " + pstmt, e); } } @@ -1038,7 +1035,7 @@ public abstract class GenericDaoBase implements Gene @Override public boolean expunge(final ID id) { final Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = s_initStmt; + PreparedStatement pstmt = null; String sql = null; try { txn.start(); @@ -1060,8 +1057,7 @@ public abstract class GenericDaoBase implements Gene } return true; } catch (final SQLException e) { - final String sqlStr = pstmt.toString(); - throw new CloudRuntimeException("DB Exception on: " + sqlStr, e); + throw new CloudRuntimeException("DB Exception on: " + pstmt, e); } } @@ -1079,7 +1075,7 @@ public abstract class GenericDaoBase implements Gene final String sql = str.toString(); final Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = s_initStmt; + PreparedStatement pstmt = null; try { pstmt = txn.prepareAutoCloseStatement(sql); int i = 0; @@ -1088,9 +1084,9 @@ public abstract class GenericDaoBase implements Gene } return pstmt.executeUpdate(); } catch (final SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + pstmt.toString(), e); + throw new CloudRuntimeException("DB Exception on: " + pstmt, e); } catch (final Throwable e) { - throw new CloudRuntimeException("Caught: " + pstmt.toString(), e); + throw new CloudRuntimeException("Caught: " + pstmt, e); } } @@ -1149,11 +1145,11 @@ public abstract class GenericDaoBase implements Gene } @Override @DB(txn=false) - public boolean update(final ID id, final T entity) { + public boolean update(ID id, T entity) { assert Enhancer.isEnhanced(entity.getClass()) : "Entity is not generated by this dao"; - final UpdateBuilder ub = getUpdateBuilder(entity); - final boolean result = update(id, ub) != 0; + UpdateBuilder ub = getUpdateBuilder(entity); + boolean result = update(id, ub, entity) != 0; return result; } @@ -1189,7 +1185,7 @@ public abstract class GenericDaoBase implements Gene ID id = null; final Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = s_initStmt; + PreparedStatement pstmt = null; String sql = null; try { txn.start(); @@ -1222,43 +1218,63 @@ public abstract class GenericDaoBase implements Gene } } } + HashMap ecAttributes = new HashMap(); for (Attribute attr : _ecAttributes) { - EcInfo ec = (EcInfo)attr.attache; - Object obj; - try { - obj = attr.field.get(entity); - if (ec.rawClass != null) { - Enumeration en = Collections.enumeration((Collection)obj); - while (en.hasMoreElements()) { - pstmt = txn.prepareAutoCloseStatement(ec.insertSql); - if (ec.targetClass == Date.class) { - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), (Date)en.nextElement())); - } else { - pstmt.setObject(1, en.nextElement()); - } - prepareAttribute(2, pstmt, _idAttributes.get(attr.table)[0], _idField.get(entity)); - pstmt.executeUpdate(); - } - } - } catch (IllegalArgumentException e) { - throw new CloudRuntimeException("Yikes! ", e); - } catch (IllegalAccessException e) { - throw new CloudRuntimeException("Yikes! ", e); + Object ec = attr.field.get(entity); + if (ec != null) { + ecAttributes.put(attr, ec); } } + + insertElementCollection(entity, _idAttributes.get(_table)[0], id, ecAttributes); txn.commit(); } catch (final SQLException e) { if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) { throw new EntityExistsException("Entity already exists: ", e); } else { - final String sqlStr = pstmt.toString(); - throw new CloudRuntimeException("DB Exception on: " + sqlStr, e); + throw new CloudRuntimeException("DB Exception on: " + pstmt, e); } + } catch (IllegalArgumentException e) { + throw new CloudRuntimeException("Problem with getting the ec attribute ", e); + } catch (IllegalAccessException e) { + throw new CloudRuntimeException("Problem with getting the ec attribute ", e); } return _idField != null ? findByIdIncludingRemoved(id) : null; } + protected void insertElementCollection(T entity, Attribute idAttribute, ID id, Map ecAttributes) throws SQLException { + Transaction txn = Transaction.currentTxn(); + txn.start(); + for (Map.Entry entry : ecAttributes.entrySet()) { + Attribute attr = entry.getKey(); + Object obj = entry.getValue(); + + EcInfo ec = (EcInfo)attr.attache; + Enumeration en = null; + if (ec.rawClass == null) { + en = Collections.enumeration(Arrays.asList((Object[])obj)); + } else { + en = Collections.enumeration((Collection)obj); + } + PreparedStatement pstmt = txn.prepareAutoCloseStatement(ec.clearSql); + prepareAttribute(1, pstmt, idAttribute, id); + pstmt.executeUpdate(); + + while (en.hasMoreElements()) { + pstmt = txn.prepareAutoCloseStatement(ec.insertSql); + if (ec.targetClass == Date.class) { + pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), (Date)en.nextElement())); + } else { + pstmt.setObject(1, en.nextElement()); + } + prepareAttribute(2, pstmt, idAttribute, id); + pstmt.executeUpdate(); + } + } + txn.commit(); + } + @DB(txn=false) protected Object generateValue(final Attribute attr) { if (attr.is(Attribute.Flag.Created) || attr.is(Attribute.Flag.Removed)) { @@ -1392,7 +1408,7 @@ public abstract class GenericDaoBase implements Gene @SuppressWarnings("unchecked") @DB(txn=false) protected T toEntityBean(final ResultSet result, final boolean cache) throws SQLException { - final T entity = (T)_factory.newInstance(new Callback[] {NoOp.INSTANCE, new UpdateBuilder(_allAttributes)}); + final T entity = (T)_factory.newInstance(new Callback[] {NoOp.INSTANCE, new UpdateBuilder(this)}); toEntityBean(result, entity); @@ -1496,7 +1512,7 @@ public abstract class GenericDaoBase implements Gene final StringBuilder sql = new StringBuilder("DELETE FROM "); sql.append(_table).append(" WHERE ").append(_removed.first()).append(" IS NOT NULL"); final Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = s_initStmt; + PreparedStatement pstmt = null; try { txn.start(); pstmt = txn.prepareAutoCloseStatement(sql.toString()); @@ -1504,8 +1520,7 @@ public abstract class GenericDaoBase implements Gene pstmt.executeUpdate(); txn.commit(); } catch (final SQLException e) { - final String sqlStr = pstmt.toString(); - throw new CloudRuntimeException("DB Exception on " + sqlStr, e); + throw new CloudRuntimeException("DB Exception on " + pstmt, e); } } @@ -1523,7 +1538,7 @@ public abstract class GenericDaoBase implements Gene } final Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = s_initStmt; + PreparedStatement pstmt = null; try { txn.start(); @@ -1541,8 +1556,7 @@ public abstract class GenericDaoBase implements Gene } return result > 0; } catch (final SQLException e) { - final String sqlStr = pstmt.toString(); - throw new CloudRuntimeException("DB Exception on: " + sqlStr, e); + throw new CloudRuntimeException("DB Exception on: " + pstmt, e); } } diff --git a/utils/src/com/cloud/utils/db/UpdateBuilder.java b/utils/src/com/cloud/utils/db/UpdateBuilder.java index 4ea4b0ae791..3ce48b912ff 100755 --- a/utils/src/com/cloud/utils/db/UpdateBuilder.java +++ b/utils/src/com/cloud/utils/db/UpdateBuilder.java @@ -29,11 +29,12 @@ import com.cloud.utils.Ternary; import com.cloud.utils.exception.CloudRuntimeException; public class UpdateBuilder implements MethodInterceptor { - protected final Map _attrs; protected Map> _changes; + protected HashMap _collectionChanges; + protected GenericDaoBase _dao; - protected UpdateBuilder(Map attrs) { - _attrs = attrs; + protected UpdateBuilder(GenericDaoBase dao) { + _dao = dao; _changes = new HashMap>(); } @@ -47,7 +48,7 @@ public class UpdateBuilder implements MethodInterceptor { makeIncrChange(name, args); } else if (name.startsWith("decr")) { makeDecrChange(name, args); - } + } return methodProxy.invokeSuper(object, args); } @@ -58,25 +59,32 @@ public class UpdateBuilder implements MethodInterceptor { } protected Attribute makeChange(String field, Object value) { - Attribute attr = _attrs.get(field); + Attribute attr = _dao._allAttributes.get(field); assert (attr == null || attr.isUpdatable()) : "Updating an attribute that's not updatable: " + field; if (attr != null) { - _changes.put(field, new Ternary(attr, null, value)); + if (attr.attache == null) { + _changes.put(field, new Ternary(attr, null, value)); + } else { + if (_collectionChanges == null) { + _collectionChanges = new HashMap(); + } + _collectionChanges.put(attr, value); + } } return attr; } protected void makeIncrChange(String method, Object[] args) { String field = methodToField(method, 4); - Attribute attr = _attrs.get(field); + Attribute attr = _dao._allAttributes.get(field); assert (attr != null && attr.isUpdatable()) : "Updating an attribute that's not updatable: " + field; incr(attr, args == null || args.length == 0 ? 1 : args[0]); } protected void makeDecrChange(String method, Object[] args) { String field = methodToField(method, 4); - Attribute attr = _attrs.get(field); + Attribute attr = _dao._allAttributes.get(field); assert (attr != null && attr.isUpdatable()) : "Updating an attribute that's not updatable: " + field; decr(attr, args == null || args.length == 0 ? 1 : args[0]); } @@ -107,19 +115,23 @@ public class UpdateBuilder implements MethodInterceptor { } public boolean hasChanges() { - return _changes.size() != 0; + return (_changes.size() + (_collectionChanges != null ? _collectionChanges.size() : 0)) != 0; } public boolean has(String name) { return _changes.containsKey(name); } - public Object get(String name) { - return _changes.get(name).second(); + public Map getCollectionChanges() { + return _collectionChanges; } protected void clear() { _changes.clear(); + if (_collectionChanges != null) { + _collectionChanges.clear(); + _collectionChanges = null; + } } public StringBuilder toSql(String tables) { From 7c74c3a51d28e1ba6027325ef77d32519e48360c Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Tue, 31 May 2011 09:48:16 -0700 Subject: [PATCH 09/65] bug 9651: network tagging changes working now --- .../utils/component/ComponentLocator.java | 83 ++++++++++--------- .../com/cloud/utils/db/GenericDaoBase.java | 16 +++- utils/src/com/cloud/utils/db/Transaction.java | 10 +-- 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/utils/src/com/cloud/utils/component/ComponentLocator.java b/utils/src/com/cloud/utils/component/ComponentLocator.java index a709a02fa5f..8ac6dcc8eba 100755 --- a/utils/src/com/cloud/utils/component/ComponentLocator.java +++ b/utils/src/com/cloud/utils/component/ComponentLocator.java @@ -90,6 +90,7 @@ public class ComponentLocator implements ComponentLocatorMBean { protected static Callback[] s_callbacks = new Callback[] { NoOp.INSTANCE, new DatabaseCallback()}; protected static CallbackFilter s_callbackFilter = new DatabaseCallbackFilter(); protected static final List> s_interceptors = new ArrayList>(); + protected static CleanupThread s_janitor = null; protected HashMap> _adapterMap; protected HashMap> _managerMap; @@ -99,12 +100,18 @@ public class ComponentLocator implements ComponentLocatorMBean { protected HashMap, Class> _factories; static { - Runtime.getRuntime().addShutdownHook(new CleanupThread()); + if (s_janitor == null) { + s_janitor = new CleanupThread(); + Runtime.getRuntime().addShutdownHook(new CleanupThread()); + } } public ComponentLocator(String server) { _serverName = server; - Runtime.getRuntime().addShutdownHook(new CleanupThread()); + if (s_janitor == null) { + s_janitor = new CleanupThread(); + Runtime.getRuntime().addShutdownHook(new CleanupThread()); + } } public String getLocatorName() { @@ -237,7 +244,7 @@ public class ComponentLocator implements ComponentLocatorMBean { if (singleton.state == Singleton.State.Instantiated) { inject(info.clazz, info.instance); singleton.state = Singleton.State.Injected; - } + } if (singleton.state == Singleton.State.Injected) { if (!info.instance.configure(info.name, info.params)) { s_logger.error("Unable to configure DAO: " + info.name); @@ -398,7 +405,7 @@ public class ComponentLocator implements ComponentLocatorMBean { System.exit(1); } s.state = Singleton.State.Configured; - } + } } else { s_logger.info("Configuring Manager: " + info.name); try { @@ -526,7 +533,7 @@ public class ComponentLocator implements ComponentLocatorMBean { s_logger.info("Injecting singleton Adapter: " + info.getName()); inject(info.clazz, info.instance); singleton.state = Singleton.State.Injected; - } + } if (singleton.state == Singleton.State.Injected) { s_logger.info("Configuring singleton Adapter: " + info.getName()); if (!info.instance.configure(info.name, info.params)) { @@ -551,7 +558,7 @@ public class ComponentLocator implements ComponentLocatorMBean { s_logger.error("Unable to configure adapter: " + info.name, e); System.exit(1); } - } + } } } @@ -1015,43 +1022,45 @@ public class ComponentLocator implements ComponentLocatorMBean { protected static class CleanupThread extends Thread { @Override - public synchronized void run() { - for (ComponentLocator locator : s_locators.values()) { - Iterator> itAdapters = locator._adapterMap.values().iterator(); - while (itAdapters.hasNext()) { - Adapters adapters = itAdapters.next(); - itAdapters.remove(); - for (ComponentInfo adapter : adapters._infos) { - if (adapter.singleton) { - Singleton singleton = s_singletons.get(adapter.clazz); - if (singleton.state == Singleton.State.Started) { + public void run() { + synchronized (CleanupThread.class) { + for (ComponentLocator locator : s_locators.values()) { + Iterator> itAdapters = locator._adapterMap.values().iterator(); + while (itAdapters.hasNext()) { + Adapters adapters = itAdapters.next(); + itAdapters.remove(); + for (ComponentInfo adapter : adapters._infos) { + if (adapter.singleton) { + Singleton singleton = s_singletons.get(adapter.clazz); + if (singleton.state == Singleton.State.Started) { + s_logger.info("Asking " + adapter.getName() + " to shutdown."); + adapter.instance.stop(); + singleton.state = Singleton.State.Stopped; + } else { + s_logger.debug("Skippng " + adapter.getName() + " because it has already stopped"); + } + } else { s_logger.info("Asking " + adapter.getName() + " to shutdown."); adapter.instance.stop(); - singleton.state = Singleton.State.Stopped; - } else { - s_logger.debug("Skippng " + adapter.getName() + " because it has already stopped"); } - } else { - s_logger.info("Asking " + adapter.getName() + " to shutdown."); - adapter.instance.stop(); } } } - } - - for (ComponentLocator locator : s_locators.values()) { - Iterator> itManagers = locator._managerMap.values().iterator(); - while (itManagers.hasNext()) { - ComponentInfo manager = itManagers.next(); - itManagers.remove(); - if (manager.singleton == true) { - Singleton singleton = s_singletons.get(manager.clazz); - if (singleton != null && singleton.state == Singleton.State.Started) { - s_logger.info("Asking Manager " + manager.getName() + " to shutdown."); - manager.instance.stop(); - singleton.state = Singleton.State.Stopped; - } else { - s_logger.info("Skipping Manager " + manager.getName() + " because it is not in a state to shutdown."); + + for (ComponentLocator locator : s_locators.values()) { + Iterator> itManagers = locator._managerMap.values().iterator(); + while (itManagers.hasNext()) { + ComponentInfo manager = itManagers.next(); + itManagers.remove(); + if (manager.singleton == true) { + Singleton singleton = s_singletons.get(manager.clazz); + if (singleton != null && singleton.state == Singleton.State.Started) { + s_logger.info("Asking Manager " + manager.getName() + " to shutdown."); + manager.instance.stop(); + singleton.state = Singleton.State.Stopped; + } else { + s_logger.info("Skipping Manager " + manager.getName() + " because it is not in a state to shutdown."); + } } } } diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java index 8b1f14e8f5b..2a31e6f84c6 100755 --- a/utils/src/com/cloud/utils/db/GenericDaoBase.java +++ b/utils/src/com/cloud/utils/db/GenericDaoBase.java @@ -1440,11 +1440,12 @@ public abstract class GenericDaoBase implements Gene EcInfo ec = (EcInfo)attr.attache; Transaction txn = Transaction.currentTxn(); + ResultSet rs = null; PreparedStatement pstmt = null; try { - pstmt = txn.prepareAutoCloseStatement(ec.selectSql); + pstmt = txn.prepareStatement(ec.selectSql); pstmt.setObject(1, _idField.get(entity)); - ResultSet rs = pstmt.executeQuery(); + rs = pstmt.executeQuery(); ArrayList lst = new ArrayList(); if (ec.targetClass == Integer.class) { while (rs.next()) { @@ -1501,6 +1502,17 @@ public abstract class GenericDaoBase implements Gene throw new CloudRuntimeException("Error executing " + pstmt, e); } catch (IllegalAccessException e) { throw new CloudRuntimeException("Error executing " + pstmt, e); + } finally { + try { + if (rs != null) { + rs.close(); + } + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + s_logger.error("Why are we getting an exception at close? ", e); + } } } diff --git a/utils/src/com/cloud/utils/db/Transaction.java b/utils/src/com/cloud/utils/db/Transaction.java index 1ad60816d95..5d846bd8bd7 100755 --- a/utils/src/com/cloud/utils/db/Transaction.java +++ b/utils/src/com/cloud/utils/db/Transaction.java @@ -109,7 +109,7 @@ public class Transaction { // Usage of this transaction setup should be limited, it will always open a new transaction context regardless of whether or not there is other // transaction context in the stack. It is used in special use cases that we want to control DB connection explicitly and in the mean time utilize // the existing DAO features - // + // public static Transaction openNew(final String name, Connection conn) { assert(conn != null); Transaction txn = new Transaction(name, false, CONNECTED_DB); @@ -191,7 +191,7 @@ public class Transaction { s_logger.warn("Unexpected exception: ", e); return null; } - } + } protected void attach(TransactionAttachment value) { _stack.push(new StackElement(ATTACHMENT, value)); @@ -452,7 +452,6 @@ public class Transaction { * @throws SQLException */ public Connection getConnection() throws SQLException { - closePreviousStatement(); if (_conn == null) { if (s_logger.isTraceEnabled()) { s_logger.trace("conn: Creating a DB connection with " + (_txn ? " txn: " : " no txn: ") + buildName()); @@ -653,8 +652,9 @@ public class Transaction { try { s_logger.trace("conn: Closing DB connection"); - if(this._dbId != CONNECTED_DB) - _conn.close(); + if(this._dbId != CONNECTED_DB) { + _conn.close(); + } _conn = null; } catch (final SQLException e) { From 8754f8fab8225b524398b7cc891593e8ef298a63 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Tue, 31 May 2011 10:27:50 -0700 Subject: [PATCH 10/65] bug 9651: checked in missing files --- .../com/cloud/network/dao/NetworkDaoTest.java | 57 ++++++++++ utils/src/com/cloud/utils/db/EcInfo.java | 107 ++++++++++++++++++ .../javax/persistence/CollectionTable.java | 39 +++++++ .../cloud/utils/db/ElementCollectionTest.java | 56 +++++++++ 4 files changed, 259 insertions(+) create mode 100644 server/test/com/cloud/network/dao/NetworkDaoTest.java create mode 100644 utils/src/com/cloud/utils/db/EcInfo.java create mode 100644 utils/src/javax/persistence/CollectionTable.java create mode 100644 utils/test/com/cloud/utils/db/ElementCollectionTest.java diff --git a/server/test/com/cloud/network/dao/NetworkDaoTest.java b/server/test/com/cloud/network/dao/NetworkDaoTest.java new file mode 100644 index 00000000000..1d51fc45433 --- /dev/null +++ b/server/test/com/cloud/network/dao/NetworkDaoTest.java @@ -0,0 +1,57 @@ +package com.cloud.network.dao; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.cloud.network.Network.GuestIpType; +import com.cloud.network.NetworkVO; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.Mode; +import com.cloud.network.Networks.TrafficType; +import com.cloud.utils.component.ComponentLocator; + + +public class NetworkDaoTest extends TestCase { + public void testTags() { + NetworkDaoImpl dao = ComponentLocator.inject(NetworkDaoImpl.class); + + dao.expunge(1001l); + NetworkVO network = new NetworkVO(1001, TrafficType.Control, GuestIpType.Direct, Mode.Dhcp, BroadcastDomainType.Native, 1, 1, 1, 1, 1001, "Name", "DisplayText", false, true); + network.setGuruName("guru_name"); + List tags = new ArrayList(); + + tags.add("a"); + tags.add("b"); + network.setTags(tags); + + network = dao.persist(network); + List saveTags = network.getTags(); + assert(saveTags.size() == 2 && saveTags.contains("a") && saveTags.contains("b")); + + NetworkVO retrieved = dao.findById(1001l); + List retrievedTags = retrieved.getTags(); + assert(retrievedTags.size() == 2 && retrievedTags.contains("a") && retrievedTags.contains("b")); + + List updateTags = new ArrayList(); + updateTags.add("e"); + updateTags.add("f"); + retrieved.setTags(updateTags); + dao.update(retrieved.getId(), retrieved); + + retrieved = dao.findById(1001l); + retrievedTags = retrieved.getTags(); + assert(retrievedTags.size() == 2 && retrievedTags.contains("e") && retrievedTags.contains("f")); + + + dao.expunge(1001l); + } + + public void testListBy() { + NetworkDaoImpl dao = ComponentLocator.inject(NetworkDaoImpl.class); + + dao.listBy(1l, 1l, 1l, "192.168.192.0/24"); + } + +} diff --git a/utils/src/com/cloud/utils/db/EcInfo.java b/utils/src/com/cloud/utils/db/EcInfo.java new file mode 100644 index 00000000000..cdbeb2441fa --- /dev/null +++ b/utils/src/com/cloud/utils/db/EcInfo.java @@ -0,0 +1,107 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.utils.db; + +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CollectionTable; +import javax.persistence.ElementCollection; +import javax.persistence.JoinColumn; + +import com.cloud.utils.exception.CloudRuntimeException; + +public class EcInfo { + protected String insertSql; + protected String selectSql; + protected String clearSql; + protected Class targetClass; + protected Class rawClass; + + public EcInfo(Attribute attr, Attribute idAttr) { + attr.attache = this; + ElementCollection ec = attr.field.getAnnotation(ElementCollection.class); + targetClass = ec.targetClass(); + Class type = attr.field.getType(); + if (type.isArray()) { + rawClass = null; + } else { + ParameterizedType pType = (ParameterizedType)attr.field.getGenericType(); + Type rawType = pType.getRawType(); + Class rawClazz = (Class)rawType; + try { + if (!Modifier.isAbstract(rawClazz.getModifiers()) && !rawClazz.isInterface() && rawClazz.getConstructors().length != 0 && rawClazz.getConstructor() != null) { + rawClass = rawClazz; + } else if (Set.class == rawClazz) { + rawClass = HashSet.class; + } else if (List.class == rawClazz) { + rawClass = ArrayList.class; + } else if (Collection.class == Collection.class) { + rawClass = ArrayList.class; + } else { + assert (false) : " We don't know how to create this calss " + rawType.toString() + " for " + attr.field.getName(); + } + } catch (NoSuchMethodException e) { + throw new CloudRuntimeException("Write your own support for " + rawClazz + " defined by " + attr.field.getName()); + } + } + + CollectionTable ct = attr.field.getAnnotation(CollectionTable.class); + assert (ct.name().length() > 0) : "Please sepcify the table for " + attr.field.getName(); + StringBuilder selectBuf = new StringBuilder("SELECT "); + StringBuilder insertBuf = new StringBuilder("INSERT INTO "); + StringBuilder clearBuf = new StringBuilder("DELETE FROM "); + + clearBuf.append(ct.name()).append(" WHERE "); + selectBuf.append(attr.columnName); + selectBuf.append(" FROM ").append(ct.name()).append(", ").append(attr.table); + selectBuf.append(" WHERE "); + + insertBuf.append(ct.name()).append("("); + StringBuilder valuesBuf = new StringBuilder("SELECT "); + + for (JoinColumn jc : ct.joinColumns()) { + selectBuf.append(ct.name()).append(".").append(jc.name()).append("="); + if (jc.referencedColumnName().length() == 0) { + selectBuf.append(idAttr.table).append(".").append(idAttr.columnName); + valuesBuf.append(idAttr.table).append(".").append(idAttr.columnName); + clearBuf.append(ct.name()).append(".").append(jc.name()).append("=?"); + } else { + selectBuf.append(attr.table).append(".").append(jc.referencedColumnName()); + valuesBuf.append(attr.table).append(".").append(jc.referencedColumnName()).append(","); + } + selectBuf.append(" AND "); + insertBuf.append(jc.name()).append(", "); + valuesBuf.append(", "); + } + + selectSql = selectBuf.append(idAttr.table).append(".").append(idAttr.columnName).append("=?").toString(); + insertBuf.append(attr.columnName).append(") "); + valuesBuf.append("? FROM ").append(attr.table); + valuesBuf.append(" WHERE ").append(idAttr.table).append(".").append(idAttr.columnName).append("=?"); + + insertSql = insertBuf.append(valuesBuf).toString(); + clearSql = clearBuf.toString(); + } +} diff --git a/utils/src/javax/persistence/CollectionTable.java b/utils/src/javax/persistence/CollectionTable.java new file mode 100644 index 00000000000..2b6ab84816d --- /dev/null +++ b/utils/src/javax/persistence/CollectionTable.java @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package javax.persistence; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(value = { METHOD, FIELD }) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface CollectionTable { + String catalog() default ""; + + JoinColumn[] joinColumns() default {}; + + String name() default ""; + + String schema() default ""; + + UniqueConstraint[] uniqueConstraints() default {}; +} diff --git a/utils/test/com/cloud/utils/db/ElementCollectionTest.java b/utils/test/com/cloud/utils/db/ElementCollectionTest.java new file mode 100644 index 00000000000..c1e766f17fb --- /dev/null +++ b/utils/test/com/cloud/utils/db/ElementCollectionTest.java @@ -0,0 +1,56 @@ +package com.cloud.utils.db; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import junit.framework.TestCase; + +import org.apache.log4j.Logger; + + +public class ElementCollectionTest extends TestCase { + static final Logger s_logger = Logger.getLogger(ElementCollectionTest.class); + ArrayList ar = null; + List lst = null; + Collection coll = null; + String[] array = null; + + public void testArrayList() throws Exception { + Field[] fields = this.getClass().getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers())) { + continue; + } + Class type1 = field.getType(); + Object collection = null; + if (!type1.isArray()) { + ParameterizedType type = (ParameterizedType)field.getGenericType(); + Type rawType = type.getRawType(); + Class rawClazz = (Class)rawType; + if (!Modifier.isAbstract(rawClazz.getModifiers()) && !rawClazz.isInterface() && rawClazz.getConstructors().length != 0 && rawClazz.getConstructor() != null) { + collection = rawClazz.newInstance(); + } + + if (collection == null) { + if (Collection.class.isAssignableFrom(rawClazz)) { + collection = new ArrayList(); + } else if (Set.class.isAssignableFrom(rawClazz)) { + collection = new HashSet(); + } + } + } else { + collection = Array.newInstance(String.class, 1); + } + field.set(this, collection); + assert (field.get(this) != null); + } + } +} From 3b9c9815c8eaea7723678ba137746b84351c8bb3 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 31 May 2011 12:04:08 -0700 Subject: [PATCH 11/65] bug 7553: listServiceOfferings API has a new parameter "issystem" now. Change UI to call "listServiceOfferings&issystem=false" for listing non-system service offerings. --- ui/scripts/cloud.core.init.js | 4 ++-- ui/scripts/cloud.core.instance.js | 2 +- ui/scripts/cloud.core.iso.js | 2 +- ui/scripts/cloud.core.template.js | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ui/scripts/cloud.core.init.js b/ui/scripts/cloud.core.init.js index f6c7b9f768a..4d65e2b8614 100644 --- a/ui/scripts/cloud.core.init.js +++ b/ui/scripts/cloud.core.init.js @@ -235,9 +235,9 @@ $(document).ready(function() { bindAndListMidMenuItems($("#leftmenu_submenu_systemvm"), "listSystemVms", systemVmGetSearchParams, "listsystemvmsresponse", "systemvm", "jsp/systemvm.jsp", afterLoadSystemVmJSP, systemvmToMidmenu, systemvmToRightPanel, getMidmenuId, false); //configuration - bindAndListMidMenuItems($("#leftmenu_service_offering"), "listServiceOfferings", serviceOfferingGetSearchParams, "listserviceofferingsresponse", "serviceoffering", "jsp/serviceoffering.jsp", afterLoadServiceOfferingJSP, serviceOfferingToMidmenu, serviceOfferingToRightPanel, getMidmenuId, false); + bindAndListMidMenuItems($("#leftmenu_service_offering"), "listServiceOfferings&issystem=false", serviceOfferingGetSearchParams, "listserviceofferingsresponse", "serviceoffering", "jsp/serviceoffering.jsp", afterLoadServiceOfferingJSP, serviceOfferingToMidmenu, serviceOfferingToRightPanel, getMidmenuId, false); bindAndListMidMenuItems($("#leftmenu_disk_offering"), "listDiskOfferings", diskOfferingGetSearchParams, "listdiskofferingsresponse", "diskoffering", "jsp/diskoffering.jsp", afterLoadDiskOfferingJSP, diskOfferingToMidmenu, diskOfferingToRightPanel, getMidmenuId, false); - bindAndListMidMenuItems($("#leftmenu_network_offering"), "listNetworkOfferings&&guestiptype=Virtual", networkOfferingGetSearchParams, "listnetworkofferingsresponse", "networkoffering", "jsp/networkoffering.jsp", afterLoadNetworkOfferingJSP, networkOfferingToMidmenu, networkOfferingToRightPanel, getMidmenuId, false); + bindAndListMidMenuItems($("#leftmenu_network_offering"), "listNetworkOfferings&guestiptype=Virtual", networkOfferingGetSearchParams, "listnetworkofferingsresponse", "networkoffering", "jsp/networkoffering.jsp", afterLoadNetworkOfferingJSP, networkOfferingToMidmenu, networkOfferingToRightPanel, getMidmenuId, false); } $("#leftmenu_global_setting").bind("click", function(event) { diff --git a/ui/scripts/cloud.core.instance.js b/ui/scripts/cloud.core.instance.js index 80080608d59..2a2589a907e 100644 --- a/ui/scripts/cloud.core.instance.js +++ b/ui/scripts/cloud.core.instance.js @@ -399,7 +399,7 @@ function initVMWizard() { }); $.ajax({ - data: createURL("command=listServiceOfferings"), + data: createURL("command=listServiceOfferings&issystem=false"), dataType: "json", async: false, success: function(json) { diff --git a/ui/scripts/cloud.core.iso.js b/ui/scripts/cloud.core.iso.js index d7038ec50a2..12d8a5fe352 100644 --- a/ui/scripts/cloud.core.iso.js +++ b/ui/scripts/cloud.core.iso.js @@ -249,7 +249,7 @@ function initCreateVmFromIsoDialog() { var $dialogCreateVmFromIso = $("#dialog_create_vm_from_iso"); $.ajax({ - data: createURL("command=listServiceOfferings"), + data: createURL("command=listServiceOfferings&issystem=false"), dataType: "json", success: function(json) { var items = json.listserviceofferingsresponse.serviceoffering; diff --git a/ui/scripts/cloud.core.template.js b/ui/scripts/cloud.core.template.js index f93146daf58..943cfe08770 100644 --- a/ui/scripts/cloud.core.template.js +++ b/ui/scripts/cloud.core.template.js @@ -148,7 +148,7 @@ function afterLoadTemplateJSP() { var $midmenuItem1 = beforeAddingMidMenuItem() ; $.ajax({ - data: createURL("command=registerTemplate&name="+todb(name)+"&displayText="+todb(desc)+"&url="+todb(url)+"&zoneid="+zoneId+"&ispublic="+isPublic+moreCriteria.join("")+"&format="+format+"&passwordEnabled="+password+"&osTypeId="+osType+"&hypervisor="+hypervisor+"&response=json"), + data: createURL("command=registerTemplate&name="+todb(name)+"&displayText="+todb(desc)+"&url="+todb(url)+"&zoneid="+zoneId+"&ispublic="+isPublic+moreCriteria.join("")+"&format="+format+"&passwordEnabled="+password+"&osTypeId="+osType+"&hypervisor="+hypervisor+""), dataType: "json", success: function(json) { var items = json.registertemplateresponse.template; @@ -233,7 +233,7 @@ function afterLoadTemplateJSP() { //zone dropdown (end) $.ajax({ - data: createURL("command=listOsTypes&response=json"), + data: createURL("command=listOsTypes"), dataType: "json", async: false, success: function(json) { @@ -253,7 +253,7 @@ function afterLoadTemplateJSP() { }); $.ajax({ - data: createURL("command=listServiceOfferings&response=json"), + data: createURL("command=listServiceOfferings&issystem=false"), dataType: "json", success: function(json) { var items = json.listserviceofferingsresponse.serviceoffering; @@ -266,7 +266,7 @@ function afterLoadTemplateJSP() { }); $.ajax({ - data: createURL("command=listDiskOfferings&response=json"), + data: createURL("command=listDiskOfferings"), dataType: "json", success: function(json) { var items = json.listdiskofferingsresponse.diskoffering; From 04e0800f7f0d7de173936843130fb191518f2fc6 Mon Sep 17 00:00:00 2001 From: anthony Date: Tue, 31 May 2011 11:52:18 -0700 Subject: [PATCH 12/65] when deleting volume, also delete snapshots for this volume in primary storage --- .../com/cloud/hypervisor/xen/resource/CitrixResourceBase.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 0d873ee6a47..7bda6c9ee3b 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -4970,6 +4970,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } try { + Set snapshots = vdi.getSnapshots(conn); + for( VDI snapshot: snapshots ) { + snapshot.destroy(conn); + } vdi.destroy(conn); } catch (Exception e) { String msg = "VDI destroy for " + volumeUUID + " failed due to " + e.toString(); From 5a052dba740588b5b671ecb126b56f3f9825a496 Mon Sep 17 00:00:00 2001 From: anthony Date: Tue, 31 May 2011 12:09:39 -0700 Subject: [PATCH 13/65] do NOT list secondary storage VM host in UI --- server/src/com/cloud/server/ManagementServerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 8194cc7eab0..c47e8c87c35 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1307,7 +1307,7 @@ public class ManagementServerImpl implements ManagementServer { sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%"); } if (type != null) { - sc.addAnd("type", SearchCriteria.Op.LIKE, "%" + type + "%"); + sc.addAnd("type", SearchCriteria.Op.LIKE, "%" + type); } if (state != null) { sc.addAnd("status", SearchCriteria.Op.EQ, state); From 69cab811aa78f316add3955e0d36134267857207 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 31 May 2011 13:22:58 -0700 Subject: [PATCH 14/65] bug 7553: cloudStack - add files for new page "System Service Offering". --- .../classes/resources/messages.properties | 2 + ui/index.jsp | 17 +- ui/jsp/systemserviceoffering.jsp | 309 ++++++++++++++ ui/scripts/cloud.core.init.js | 1 + .../cloud.core.systemserviceoffering.js | 395 ++++++++++++++++++ 5 files changed, 723 insertions(+), 1 deletion(-) create mode 100644 ui/jsp/systemserviceoffering.jsp create mode 100644 ui/scripts/cloud.core.systemserviceoffering.js diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 2201e48afe9..5de1b1b07fe 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -429,6 +429,7 @@ label.menu.physical.resources=Physical Resources label.menu.running.instances=Running Instances label.menu.security.groups=Security Groups label.menu.service.offerings=Service Offerings +label.menu.system.service.offerings=System Service Offerings label.menu.snapshots=Snapshots label.menu.stopped.instances=Stopped Instances label.menu.storage=Storage @@ -541,6 +542,7 @@ label.security.groups=Security Groups label.sent=Sent label.server=Server label.service.offering=Service Offering +label.system.service.offering=System Service Offering label.session.expired=Session Expired label.shared=Shared label.size=Size diff --git a/ui/index.jsp b/ui/index.jsp index f09613bcb3a..8286c509ff0 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -44,7 +44,8 @@ - + + @@ -718,6 +719,20 @@ +
+
+
+
+
+ + +
+
+
+ + + +
diff --git a/ui/jsp/systemserviceoffering.jsp b/ui/jsp/systemserviceoffering.jsp new file mode 100644 index 00000000000..1f36cfdc9c2 --- /dev/null +++ b/ui/jsp/systemserviceoffering.jsp @@ -0,0 +1,309 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> + + + + + + + +
+ +
+
+ +

+ +

+
+
+ +
+
+
+
+
+ +
+
+
+
(title)
+ +
+
+
+

+

+
+
+
+
+
+ :
+
+
+
+
+
+
+
+
+
+ :
+
+
+
+
+ + +
+
+
+
+
+ :
+
+
+
+
+ + +
+
+
+
+
+ :
+
+
+
+
+
+
+
+
+
+ :
+
+
+
+
+
+
+
+
+
+ :
+
+
+
+
+
+
+
+
+
+ :
+
+
+
+
+
+
+ +
+
+
+ :
+
+
+
+
+
+
+ +
+
+
+ :
+
+
+
+
+
+
+ +
+
+
+ :
+
+
+
+
+ +
+
+ +
+
+
+ :
+
+
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ Add Service Offering
+ +
+
+
+ + + + + + +
+ + + +
\ No newline at end of file diff --git a/ui/scripts/cloud.core.init.js b/ui/scripts/cloud.core.init.js index 4d65e2b8614..86d1cb0dcdd 100644 --- a/ui/scripts/cloud.core.init.js +++ b/ui/scripts/cloud.core.init.js @@ -236,6 +236,7 @@ $(document).ready(function() { //configuration bindAndListMidMenuItems($("#leftmenu_service_offering"), "listServiceOfferings&issystem=false", serviceOfferingGetSearchParams, "listserviceofferingsresponse", "serviceoffering", "jsp/serviceoffering.jsp", afterLoadServiceOfferingJSP, serviceOfferingToMidmenu, serviceOfferingToRightPanel, getMidmenuId, false); + bindAndListMidMenuItems($("#leftmenu_service_offering"), "listServiceOfferings&issystem=true", systemServiceOfferingGetSearchParams, "listserviceofferingsresponse", "serviceoffering", "jsp/serviceoffering.jsp", afterLoadServiceOfferingJSP, serviceOfferingToMidmenu, serviceOfferingToRightPanel, getMidmenuId, false); bindAndListMidMenuItems($("#leftmenu_disk_offering"), "listDiskOfferings", diskOfferingGetSearchParams, "listdiskofferingsresponse", "diskoffering", "jsp/diskoffering.jsp", afterLoadDiskOfferingJSP, diskOfferingToMidmenu, diskOfferingToRightPanel, getMidmenuId, false); bindAndListMidMenuItems($("#leftmenu_network_offering"), "listNetworkOfferings&guestiptype=Virtual", networkOfferingGetSearchParams, "listnetworkofferingsresponse", "networkoffering", "jsp/networkoffering.jsp", afterLoadNetworkOfferingJSP, networkOfferingToMidmenu, networkOfferingToRightPanel, getMidmenuId, false); } diff --git a/ui/scripts/cloud.core.systemserviceoffering.js b/ui/scripts/cloud.core.systemserviceoffering.js new file mode 100644 index 00000000000..f1025d97df8 --- /dev/null +++ b/ui/scripts/cloud.core.systemserviceoffering.js @@ -0,0 +1,395 @@ + /** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +function systemServiceOfferingGetSearchParams() { + var moreCriteria = []; + + var searchInput = $("#basic_search").find("#search_input").val(); + if (searchInput != null && searchInput.length > 0) { + moreCriteria.push("&keyword="+todb(searchInput)); + } + + var $advancedSearchPopup = getAdvancedSearchPopupInSearchContainer(); + if ($advancedSearchPopup.length > 0 && $advancedSearchPopup.css("display") != "none" ) { + if ($advancedSearchPopup.find("#adv_search_domain_li").css("display") != "none" + && $advancedSearchPopup.find("#domain").hasClass("textwatermark") == false) { + var domainName = $advancedSearchPopup.find("#domain").val(); + if (domainName != null && domainName.length > 0) { + var domainId; + if(autoCompleteDomains != null && autoCompleteDomains.length > 0) { + for(var i=0; i < autoCompleteDomains.length; i++) { + if(fromdb(autoCompleteDomains[i].name).toLowerCase() == domainName.toLowerCase()) { + domainId = autoCompleteDomains[i].id; + break; + } + } + } + if(domainId == null) { + showError(false, $advancedSearchPopup.find("#domain"), $advancedSearchPopup.find("#domain_errormsg"), g_dictionary["label.not.found"]); + } + else { //e.g. domainId == 5 (number) + showError(true, $advancedSearchPopup.find("#domain"), $advancedSearchPopup.find("#domain_errormsg"), null) + moreCriteria.push("&domainid="+todb(domainId)); + } + } + } + } + + return moreCriteria.join(""); +} + +function afterLoadSystemServiceOfferingJSP() { + initAddSystemServiceOfferingDialog(); + + $readonlyFields = $("#tab_content_details").find("#name, #displaytext"); + $editFields = $("#tab_content_details").find("#name_edit, #displaytext_edit"); +} + +function initAddSystemServiceOfferingDialog() { + initDialog("dialog_add_service"); + + var $dialogAddService = $("#dialog_add_service"); + $dialogAddService.find("#public_dropdown").unbind("change").bind("change", function(event) { + if($(this).val() == "true") { //public zone + $dialogAddService.find("#domain_container").hide(); + } + else { //private zone + $dialogAddService.find("#domain_container").show(); + } + return false; + }); + + applyAutoCompleteToDomainField($dialogAddService.find("#domain")); + + $("#add_systemserviceoffering_button").unbind("click").bind("click", function(event) { + $dialogAddService.find("#add_service_name").val(""); + $dialogAddService.find("#add_service_display").val(""); + $dialogAddService.find("#add_service_cpucore").val(""); + $dialogAddService.find("#add_service_cpu").val(""); + $dialogAddService.find("#add_service_memory").val(""); + $dialogAddService.find("#add_service_offerha").val("false"); + + $dialogAddService + .dialog('option', 'buttons', { + "Add": function() { + var $thisDialog = $(this); + + // validate values + var isValid = true; + isValid &= validateString("Name", $thisDialog.find("#add_service_name"), $thisDialog.find("#add_service_name_errormsg")); + isValid &= validateString("Display Text", $thisDialog.find("#add_service_display"), $thisDialog.find("#add_service_display_errormsg")); + isValid &= validateInteger("# of CPU Core", $thisDialog.find("#add_service_cpucore"), $thisDialog.find("#add_service_cpucore_errormsg"), 1, 1000); + isValid &= validateInteger("CPU", $thisDialog.find("#add_service_cpu"), $thisDialog.find("#add_service_cpu_errormsg"), 100, 100000); + isValid &= validateInteger("Memory", $thisDialog.find("#add_service_memory"), $thisDialog.find("#add_service_memory_errormsg"), 64, 1000000); + isValid &= validateString("Tags", $thisDialog.find("#add_service_tags"), $thisDialog.find("#add_service_tags_errormsg"), true); //optional + + if($thisDialog.find("#domain_container").css("display") != "none") { + isValid &= validateString("Domain", $thisDialog.find("#domain"), $thisDialog.find("#domain_errormsg"), false); //required + var domainName = $thisDialog.find("#domain").val(); + var domainId; + if(domainName != null && domainName.length > 0) { + if(autoCompleteDomains != null && autoCompleteDomains.length > 0) { + for(var i=0; i < autoCompleteDomains.length; i++) { + if(fromdb(autoCompleteDomains[i].name).toLowerCase() == domainName.toLowerCase()) { + domainId = autoCompleteDomains[i].id; + break; + } + } + } + if(domainId == null) { + showError(false, $thisDialog.find("#domain"), $thisDialog.find("#domain_errormsg"), g_dictionary["label.not.found"]); + isValid &= false; + } + } + } + + if (!isValid) + return; + $thisDialog.dialog("close"); + + var $midmenuItem1 = beforeAddingMidMenuItem() ; + + var array1 = []; + var name = $thisDialog.find("#add_service_name").val(); + array1.push("&name="+todb(name)); + + var display = $thisDialog.find("#add_service_display").val(); + array1.push("&displayText="+todb(display)); + + var storagetype = $thisDialog.find("#add_service_storagetype").val(); + array1.push("&storageType="+storagetype); + + var core = $thisDialog.find("#add_service_cpucore").val(); + array1.push("&cpuNumber="+core); + + var cpu = $thisDialog.find("#add_service_cpu").val(); + array1.push("&cpuSpeed="+cpu); + + var memory = $thisDialog.find("#add_service_memory").val(); + array1.push("&memory="+memory); + + var offerha = $thisDialog.find("#add_service_offerha").val(); + array1.push("&offerha="+offerha); + + var tags = $thisDialog.find("#add_service_tags").val(); + if(tags != null && tags.length > 0) + array1.push("&tags="+todb(tags)); + + if($thisDialog.find("#cpu_cap_dropdown_container").css("display") != "none") { + array1.push("&limitcpuuse="+$thisDialog.find("#cpu_cap_dropdown").val()); + } + + if($thisDialog.find("#domain_container").css("display") != "none") { + array1.push("&domainid="+domainId); + } + + $.ajax({ + data: createURL("command=createServiceOffering"+array1.join("")), + dataType: "json", + success: function(json) { + var item = json.createserviceofferingresponse.serviceoffering; + systemServiceOfferingToMidmenu(item, $midmenuItem1); + bindClickToMidMenu($midmenuItem1, systemServiceOfferingToRightPanel, getMidmenuId); + afterAddingMidMenuItem($midmenuItem1, true); + + }, + error: function(XMLHttpResponse) { + handleError(XMLHttpResponse, function() { + afterAddingMidMenuItem($midmenuItem1, false, parseXMLHttpResponse(XMLHttpResponse)); + }); + } + }); + }, + "Cancel": function() { + $(this).dialog("close"); + } + }).dialog("open"); + return false; + }); +} + +function doEditSystemServiceOffering($actionLink, $detailsTab, $midmenuItem1) { + $readonlyFields.hide(); + $editFields.show(); + $detailsTab.find("#cancel_button, #save_button").show(); + + $detailsTab.find("#cancel_button").unbind("click").bind("click", function(event){ + cancelEditMode($detailsTab); + return false; + }); + $detailsTab.find("#save_button").unbind("click").bind("click", function(event){ + doEditSystemServiceOffering2($actionLink, $detailsTab, $midmenuItem1, $readonlyFields, $editFields); + return false; + }); +} + +function doEditSystemServiceOffering2($actionLink, $detailsTab, $midmenuItem1, $readonlyFields, $editFields) { + var jsonObj = $midmenuItem1.data("jsonObj"); + var id = jsonObj.id; + + // validate values + var isValid = true; + isValid &= validateString("Name", $detailsTab.find("#name_edit"), $detailsTab.find("#name_edit_errormsg"), true); + isValid &= validateString("Display Text", $detailsTab.find("#displaytext_edit"), $detailsTab.find("#displaytext_edit_errormsg"), true); + if (!isValid) + return; + + var array1 = []; + var name = $detailsTab.find("#name_edit").val(); + array1.push("&name="+todb(name)); + var displaytext = $detailsTab.find("#displaytext_edit").val(); + array1.push("&displayText="+todb(displaytext)); + var offerha = $detailsTab.find("#offerha_edit").val(); + array1.push("&offerha="+offerha); + + var tags = $detailsTab.find("#tags_edit").val(); + array1.push("&tags="+todb(tags)); + + var domainid = $detailsTab.find("#domain_edit").val(); + array1.push("&domainid="+todb(domainid)); + + $.ajax({ + data: createURL("command=updateServiceOffering&id="+id+array1.join("")), + dataType: "json", + success: function(json) { + var jsonObj = json.updateserviceofferingresponse.serviceoffering; + systemServiceOfferingToMidmenu(jsonObj, $midmenuItem1); + systemServiceOfferingToRightPanel($midmenuItem1); + + $editFields.hide(); + $readonlyFields.show(); + $("#save_button, #cancel_button").hide(); + } + }); +} + +function doDeleteSystemServiceOffering($actionLink, $detailsTab, $midmenuItem1) { + var jsonObj = $midmenuItem1.data("jsonObj"); + var id = jsonObj.id; + + $("#dialog_confirmation") + .text(dictionary["message.action.delete.service.offering"]) + .dialog('option', 'buttons', { + "Confirm": function() { + $(this).dialog("close"); + var apiCommand = "command=deleteServiceOffering&id="+id; + doActionToTab(id, $actionLink, apiCommand, $midmenuItem1, $detailsTab); + }, + "Cancel": function() { + $(this).dialog("close"); + } + }).dialog("open"); +} + +function systemServiceOfferingToMidmenu(jsonObj, $midmenuItem1) { + $midmenuItem1.attr("id", getMidmenuId(jsonObj)); + $midmenuItem1.data("jsonObj", jsonObj); + + var $iconContainer = $midmenuItem1.find("#icon_container").show(); + $iconContainer.find("#icon").attr("src", "images/midmenuicon_system_serviceoffering.png"); + + var firstRowText = fromdb(jsonObj.name); + $midmenuItem1.find("#first_row").text(firstRowText); + $midmenuItem1.find("#first_row_container").attr("title", firstRowText); + + var secondRowText = jsonObj.cpunumber + " x " + convertHz(jsonObj.cpuspeed); + $midmenuItem1.find("#second_row").text(secondRowText); + $midmenuItem1.find("#second_row_container").attr("title", secondRowText); +} + +function systemServiceOfferingToRightPanel($midmenuItem1) { + copyActionInfoFromMidMenuToRightPanel($midmenuItem1); + $("#right_panel_content").data("$midmenuItem1", $midmenuItem1); + systemServiceOfferingJsonToDetailsTab(); +} + +function systemServiceOfferingJsonToDetailsTab() { + var $midmenuItem1 = $("#right_panel_content").data("$midmenuItem1"); + if($midmenuItem1 == null) { + systemServiceOfferingClearDetailsTab(); + return; + } + + var jsonObj = $midmenuItem1.data("jsonObj"); + if(jsonObj == null) { + systemServiceOfferingClearDetailsTab(); + return; + } + + var $thisTab = $("#right_panel_content #tab_content_details"); + $thisTab.find("#tab_container").hide(); + $thisTab.find("#tab_spinning_wheel").show(); + + var id = jsonObj.id; + + $.ajax({ + data: createURL("command=listServiceOfferings&id="+id), + dataType: "json", + async: false, + success: function(json) { + var items = json.listserviceofferingsresponse.serviceoffering; + if(items != null && items.length > 0) { + jsonObj = items[0]; + $midmenuItem1.data("jsonObj", jsonObj); + } + } + }); + + $thisTab.find("#id").text(fromdb(jsonObj.id)); + + $thisTab.find("#grid_header_title").text(fromdb(jsonObj.name)); + $thisTab.find("#name").text(fromdb(jsonObj.name)); + $thisTab.find("#name_edit").val(fromdb(jsonObj.name)); + + $thisTab.find("#displaytext").text(fromdb(jsonObj.displaytext)); + $thisTab.find("#displaytext_edit").val(fromdb(jsonObj.displaytext)); + + $thisTab.find("#storagetype").text(fromdb(jsonObj.storagetype)); + $thisTab.find("#cpu").text(jsonObj.cpunumber + " x " + convertHz(jsonObj.cpuspeed)); + $thisTab.find("#memory").text(convertBytes(parseInt(jsonObj.memory)*1024*1024)); + + setBooleanReadField(jsonObj.offerha, $thisTab.find("#offerha")); + setBooleanEditField(jsonObj.offerha, $thisTab.find("#offerha_edit")); + + setBooleanReadField(jsonObj.limitcpuuse, $thisTab.find("#limitcpuuse")); + + $thisTab.find("#tags").text(fromdb(jsonObj.tags)); + $thisTab.find("#tags_edit").val(fromdb(jsonObj.tags)); + + $thisTab.find("#domain").text(fromdb(jsonObj.domain)); + $thisTab.find("#domain_edit").val(fromdb(jsonObj.domainid)); + + setDateField(jsonObj.created, $thisTab.find("#created")); + + //actions *** + var $actionMenu = $("#right_panel_content #tab_content_details #action_link #action_menu"); + $actionMenu.find("#action_list").empty(); + buildActionLinkForTab("label.action.edit.service.offering", systemServiceOfferingActionMap, $actionMenu, $midmenuItem1, $thisTab); + buildActionLinkForTab("label.action.delete.service.offering", systemServiceOfferingActionMap, $actionMenu, $midmenuItem1, $thisTab); + + $thisTab.find("#tab_spinning_wheel").hide(); + $thisTab.find("#tab_container").show(); +} + +function systemServiceOfferingClearRightPanel() { + systemServiceOfferingClearDetailsTab(); +} + +function systemServiceOfferingClearDetailsTab() { + var $thisTab = $("#right_panel_content #tab_content_details"); + $thisTab.find("#id").text(""); + $thisTab.find("#grid_header_title").text(""); + $thisTab.find("#name").text(""); + $thisTab.find("#name_edit").val(""); + $thisTab.find("#displaytext").text(""); + $thisTab.find("#displaytext_edit").val(""); + $thisTab.find("#storagetype").text(""); + $thisTab.find("#cpu").text(""); + $thisTab.find("#memory").text(""); + $thisTab.find("#offerha").text(""); + $thisTab.find("#offerha_edit").val(""); + $thisTab.find("#tags").text(""); + $thisTab.find("#domain").text(""); + $thisTab.find("#domain_edit").val(""); + $thisTab.find("#created").text(""); + + var $actionMenu = $("#right_panel_content #tab_content_details #action_link #action_menu"); + $actionMenu.find("#action_list").empty(); + $actionMenu.find("#action_list").append($("#no_available_actions").clone().show()); +} + +var systemServiceOfferingActionMap = { + "label.action.edit.service.offering": { + dialogBeforeActionFn: doEditSystemServiceOffering + }, + "label.action.delete.service.offering": { + api: "deleteServiceOffering", + isAsyncJob: false, + dialogBeforeActionFn : doDeleteSystemServiceOffering, + inProcessText: "label.action.delete.service.offering.processing", + afterActionSeccessFn: function(json, $midmenuItem1, id) { + $midmenuItem1.slideUp("slow", function() { + $(this).remove(); + if(id.toString() == $("#right_panel_content").find("#tab_content_details").find("#id").text()) { + clearRightPanel(); + systemServiceOfferingClearRightPanel(); + } + }); + } + } +} \ No newline at end of file From c2b5b2ef952740d241d68ded995df412d1edbf18 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 31 May 2011 14:20:52 -0700 Subject: [PATCH 15/65] bug 7553: cloudStack - System Service Offering - correct left menu clicking. --- ui/scripts/cloud.core.init.js | 2 +- ui/scripts/cloud.core.serviceoffering.js | 3 ++- ui/scripts/cloud.core.systemserviceoffering.js | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ui/scripts/cloud.core.init.js b/ui/scripts/cloud.core.init.js index 86d1cb0dcdd..03f38ce2e43 100644 --- a/ui/scripts/cloud.core.init.js +++ b/ui/scripts/cloud.core.init.js @@ -236,7 +236,7 @@ $(document).ready(function() { //configuration bindAndListMidMenuItems($("#leftmenu_service_offering"), "listServiceOfferings&issystem=false", serviceOfferingGetSearchParams, "listserviceofferingsresponse", "serviceoffering", "jsp/serviceoffering.jsp", afterLoadServiceOfferingJSP, serviceOfferingToMidmenu, serviceOfferingToRightPanel, getMidmenuId, false); - bindAndListMidMenuItems($("#leftmenu_service_offering"), "listServiceOfferings&issystem=true", systemServiceOfferingGetSearchParams, "listserviceofferingsresponse", "serviceoffering", "jsp/serviceoffering.jsp", afterLoadServiceOfferingJSP, serviceOfferingToMidmenu, serviceOfferingToRightPanel, getMidmenuId, false); + bindAndListMidMenuItems($("#leftmenu_system_service_offering"), "listServiceOfferings&issystem=true", systemServiceOfferingGetSearchParams, "listserviceofferingsresponse", "serviceoffering", "jsp/serviceoffering.jsp", afterLoadServiceOfferingJSP, serviceOfferingToMidmenu, serviceOfferingToRightPanel, getMidmenuId, false); bindAndListMidMenuItems($("#leftmenu_disk_offering"), "listDiskOfferings", diskOfferingGetSearchParams, "listdiskofferingsresponse", "diskoffering", "jsp/diskoffering.jsp", afterLoadDiskOfferingJSP, diskOfferingToMidmenu, diskOfferingToRightPanel, getMidmenuId, false); bindAndListMidMenuItems($("#leftmenu_network_offering"), "listNetworkOfferings&guestiptype=Virtual", networkOfferingGetSearchParams, "listnetworkofferingsresponse", "networkoffering", "jsp/networkoffering.jsp", afterLoadNetworkOfferingJSP, networkOfferingToMidmenu, networkOfferingToRightPanel, getMidmenuId, false); } diff --git a/ui/scripts/cloud.core.serviceoffering.js b/ui/scripts/cloud.core.serviceoffering.js index 8da1185d0b9..f3f7241ccb7 100644 --- a/ui/scripts/cloud.core.serviceoffering.js +++ b/ui/scripts/cloud.core.serviceoffering.js @@ -362,7 +362,8 @@ function serviceOfferingClearDetailsTab() { $thisTab.find("#cpu").text(""); $thisTab.find("#memory").text(""); $thisTab.find("#offerha").text(""); - $thisTab.find("#offerha_edit").val(""); + $thisTab.find("#offerha_edit").val(""); + $thisTab.find("#limitcpuuse").text(""); $thisTab.find("#tags").text(""); $thisTab.find("#domain").text(""); $thisTab.find("#domain_edit").val(""); diff --git a/ui/scripts/cloud.core.systemserviceoffering.js b/ui/scripts/cloud.core.systemserviceoffering.js index f1025d97df8..8969bd7febd 100644 --- a/ui/scripts/cloud.core.systemserviceoffering.js +++ b/ui/scripts/cloud.core.systemserviceoffering.js @@ -362,7 +362,8 @@ function systemServiceOfferingClearDetailsTab() { $thisTab.find("#cpu").text(""); $thisTab.find("#memory").text(""); $thisTab.find("#offerha").text(""); - $thisTab.find("#offerha_edit").val(""); + $thisTab.find("#offerha_edit").val(""); + $thisTab.find("#limitcpuuse").text(""); $thisTab.find("#tags").text(""); $thisTab.find("#domain").text(""); $thisTab.find("#domain_edit").val(""); From a690d6169d9dff5b03a0848184266805eb1aed29 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 31 May 2011 14:44:22 -0700 Subject: [PATCH 16/65] bug 7553: fix a server-side bug - listServiceOffering API didn't take in "issystem" parameter. --- api/src/com/cloud/api/commands/ListServiceOfferingsCmd.java | 1 - server/src/com/cloud/server/ManagementServerImpl.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/api/src/com/cloud/api/commands/ListServiceOfferingsCmd.java b/api/src/com/cloud/api/commands/ListServiceOfferingsCmd.java index 320f21434e4..69d5c9a5931 100644 --- a/api/src/com/cloud/api/commands/ListServiceOfferingsCmd.java +++ b/api/src/com/cloud/api/commands/ListServiceOfferingsCmd.java @@ -26,7 +26,6 @@ import com.cloud.api.ApiConstants; import com.cloud.api.BaseListCmd; import com.cloud.api.Implementation; import com.cloud.api.Parameter; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.response.ListResponse; import com.cloud.api.response.ServiceOfferingResponse; import com.cloud.offering.ServiceOffering; diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index c47e8c87c35..fecd4d0f12b 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1061,7 +1061,7 @@ public class ManagementServerImpl implements ManagementServer { if (name != null) { sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%"); } - sc.addAnd("systemUse", SearchCriteria.Op.EQ, false); + sc.addAnd("systemUse", SearchCriteria.Op.EQ, issystem); return _offeringsDao.search(sc, searchFilter); From 997ef3768f8d1c36e8b5ff675695a2ec20048fa0 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 31 May 2011 15:59:17 -0700 Subject: [PATCH 17/65] bug 7553: cloudStack - System Service Offering - implement Add System Service Offering action. --- .../classes/resources/messages.properties | 1 + ui/jsp/systemserviceoffering.jsp | 12 ++++---- ui/scripts/cloud.core.init.js | 2 +- ui/scripts/cloud.core.serviceoffering.js | 2 +- .../cloud.core.systemserviceoffering.js | 28 +++++++++---------- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 5de1b1b07fe..2fed7b1c504 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -210,6 +210,7 @@ label.add.primary.storage=Add Primary Storage label.add.secondary.storage=Add Secondary Storage label.add.security.group=Add Security Group label.add.service.offering=Add Service Offering +label.add.system.service.offering=Add System Service Offering label.add.template=Add Template label.add.user=Add User label.add.vlan=Add VLAN diff --git a/ui/jsp/systemserviceoffering.jsp b/ui/jsp/systemserviceoffering.jsp index 1f36cfdc9c2..3521e55dd46 100644 --- a/ui/jsp/systemserviceoffering.jsp +++ b/ui/jsp/systemserviceoffering.jsp @@ -20,7 +20,7 @@ dictionary = {

- +

@@ -191,20 +191,20 @@ dictionary = {
-
+
- Add Service Offering
+ Add System Service Offering
- - -
+
:
diff --git a/ui/scripts/cloud.core.network.js b/ui/scripts/cloud.core.network.js index 9d909340ecc..abb5ad9da2d 100644 --- a/ui/scripts/cloud.core.network.js +++ b/ui/scripts/cloud.core.network.js @@ -89,8 +89,8 @@ function afterLoadNetworkJSP($leftmenuItem1) { networkPopulateMiddleMenu($leftmenuItem1); bindAddNetworkButton(); - $readonlyFields = $("#direct_network_page").find("#tab_content_details").find("#name, #displaytext"); - $editFields = $("#direct_network_page").find("#tab_content_details").find("#name_edit, #displaytext_edit"); + $readonlyFields = $("#direct_network_page").find("#tab_content_details").find("#name, #displaytext, #tags"); + $editFields = $("#direct_network_page").find("#tab_content_details").find("#name_edit, #displaytext_edit, #tags_edit"); } function networkPopulateMiddleMenu($leftmenuItem1) { @@ -1070,7 +1070,8 @@ function directNetworkJsonToDetailsTab() { $thisTab.find("#vlan").text(fromdb(jsonObj.vlan)); $thisTab.find("#gateway").text(fromdb(jsonObj.gateway)); $thisTab.find("#netmask").text(fromdb(jsonObj.netmask)); - + $thisTab.find("#tags").text(fromdb(jsonObj.tags)); + $thisTab.find("#tags_edit").val(fromdb(jsonObj.tags)); $thisTab.find("#domain").text(fromdb(jsonObj.domain)); //might be null $thisTab.find("#account").text(fromdb(jsonObj.account)); //might be null @@ -1079,7 +1080,8 @@ function directNetworkJsonToDetailsTab() { bindActionLink($actionLink); var $actionMenu = $actionLink.find("#action_menu"); - $actionMenu.find("#action_list").empty(); + $actionMenu.find("#action_list").empty(); + buildActionLinkForTab("label.action.edit.network", directNetworkActionMap, $actionMenu, $midmenuItem1, $thisTab); buildActionLinkForTab("label.action.delete.network", directNetworkActionMap, $actionMenu, $midmenuItem1, $thisTab); @@ -1092,11 +1094,15 @@ function directNetworkJsonClearDetailsTab() { $thisTab.find("#grid_header_title").text(""); $thisTab.find("#id").text(""); $thisTab.find("#name").text(""); - $thisTab.find("#displaytext").text(""); + $thisTab.find("#name_edit").val(""); + $thisTab.find("#displaytext").text(""); + $thisTab.find("#displaytext_edit").val(""); $thisTab.find("#default").text(""); $thisTab.find("#vlan").text(""); $thisTab.find("#gateway").text(""); - $thisTab.find("#netmask").text(""); + $thisTab.find("#netmask").text(""); + $thisTab.find("#tags").text(""); + $thisTab.find("#tags_edit").val(""); $thisTab.find("#domain").text(""); $thisTab.find("#account").text(""); @@ -1525,7 +1531,10 @@ function doEditDirectNetwork2($actionLink, $detailsTab, $midmenuItem1, $readonly var displaytext = $detailsTab.find("#displaytext_edit").val(); array1.push("&displayText="+todb(displaytext)); - + + var tags = $detailsTab.find("#tags_edit").val(); + array1.push("&tags="+todb(tags)); + $.ajax({ data: createURL("command=updateNetwork&id="+id+array1.join("")), dataType: "json", From 9ec9d745143e0d2c8200dccb29b4733c51000ec0 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 2 Jun 2011 12:33:32 -0400 Subject: [PATCH 48/65] zone can be deleted now --- .../configuration/ConfigurationManagerImpl.java | 5 ++--- server/src/com/cloud/dc/DataCenterVO.java | 11 ++++++++++- .../src/com/cloud/dc/dao/DataCenterDaoImpl.java | 15 +++++++++++++++ setup/db/create-schema.sql | 3 ++- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 804ea1826ea..da346ef3732 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -1065,11 +1065,10 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura List networks = _networkDao.listByZoneIncludingRemoved(zoneId); if (networks != null && !networks.isEmpty()) { for (NetworkVO network : networks) { - _networkDao.expunge(network.getId()); + _networkDao.remove(network.getId()); } } - - success = _zoneDao.expunge(zoneId); + success = _zoneDao.remove(zoneId); txn.commit(); diff --git a/server/src/com/cloud/dc/DataCenterVO.java b/server/src/com/cloud/dc/DataCenterVO.java index 63f58951172..950abfd619b 100644 --- a/server/src/com/cloud/dc/DataCenterVO.java +++ b/server/src/com/cloud/dc/DataCenterVO.java @@ -18,6 +18,7 @@ package com.cloud.dc; +import java.util.Date; import java.util.Map; import javax.persistence.Column; @@ -34,6 +35,7 @@ import javax.persistence.Transient; import com.cloud.network.Network.Provider; import com.cloud.org.Grouping; import com.cloud.utils.NumbersUtil; +import com.cloud.utils.db.GenericDao; @Entity @Table(name="data_center") @@ -111,6 +113,9 @@ public class DataCenterVO implements DataCenter { @Column(name="zone_token") private String zoneToken; + + @Column(name=GenericDao.REMOVED_COLUMN) + private Date removed; // This is a delayed load value. If the value is null, // then this field has not been loaded yet. @@ -397,5 +402,9 @@ public class DataCenterVO implements DataCenter { public void setZoneToken(String zoneToken) { this.zoneToken = zoneToken; - } + } + + public Date getRemoved() { + return removed; + } } diff --git a/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java b/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java index 1957098e6e7..1cca111a85c 100644 --- a/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java +++ b/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java @@ -32,6 +32,7 @@ import com.cloud.dc.DataCenterIpAddressVO; import com.cloud.dc.DataCenterLinkLocalIpAddressVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.DataCenterVnetVO; +import com.cloud.dc.HostPodVO; import com.cloud.dc.PodVlanVO; import com.cloud.org.Grouping; import com.cloud.utils.NumbersUtil; @@ -355,4 +356,18 @@ public class DataCenterDaoImpl extends GenericDaoBase implem } return result; } + + @Override + public boolean remove(Long id) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + DataCenterVO zone = createForUpdate(); + zone.setName(null); + + update(id, zone); + + boolean result = super.remove(id); + txn.commit(); + return result; + } } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index ffa7a5e4db4..d4466d16d47 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -280,7 +280,7 @@ CREATE TABLE `cloud`.`cluster` ( `allocation_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this cluster enabled for allocation for new resources', `removed` datetime COMMENT 'date removed if not null', PRIMARY KEY (`id`), - CONSTRAINT `fk_cluster__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `cloud`.`data_center`(`id`), + CONSTRAINT `fk_cluster__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `cloud`.`data_center`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_cluster__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `cloud`.`host_pod_ref`(`id`), UNIQUE `i_cluster__pod_id__name`(`pod_id`, `name`), INDEX `i_cluster__allocation_state`(`allocation_state`) @@ -490,6 +490,7 @@ CREATE TABLE `cloud`.`data_center` ( `is_security_group_enabled` tinyint NOT NULL DEFAULT 0 COMMENT '1: enabled, 0: not', `allocation_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this data center enabled for allocation for new resources', `zone_token` varchar(255), + `removed` datetime COMMENT 'date removed if not null', PRIMARY KEY (`id`), CONSTRAINT `fk_data_center__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`), INDEX `i_data_center__domain_id`(`domain_id`), From b449b1e408b591f58eebcf08e79e1853c18de36b Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 2 Jun 2011 13:41:35 -0400 Subject: [PATCH 49/65] add on delete cascade for networks table --- setup/db/create-schema.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index d4466d16d47..0804c2a68d0 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -185,7 +185,7 @@ CREATE TABLE `cloud`.`networks` ( `is_security_group_enabled` tinyint NOT NULL DEFAULT 0 COMMENT '1: enabled, 0: not', PRIMARY KEY (`id`), CONSTRAINT `fk_networks__network_offering_id` FOREIGN KEY (`network_offering_id`) REFERENCES `network_offerings`(`id`), - CONSTRAINT `fk_networks__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`), + CONSTRAINT `fk_networks__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_networks__related` FOREIGN KEY(`related`) REFERENCES `networks`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_networks__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), CONSTRAINT `fk_networks__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), From 87b4b993c7dd4c62ad427b4dd84ee6e382f6ee4c Mon Sep 17 00:00:00 2001 From: will Date: Thu, 2 Jun 2011 13:53:35 -0700 Subject: [PATCH 50/65] bug 10090: encoded the endpoint as well as the username for the accounts in the register callback response --- .../cloud/servlet/RegisterCompleteServlet.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/server/src/com/cloud/servlet/RegisterCompleteServlet.java b/server/src/com/cloud/servlet/RegisterCompleteServlet.java index 63b7af6fd16..c5b4e49ffda 100644 --- a/server/src/com/cloud/servlet/RegisterCompleteServlet.java +++ b/server/src/com/cloud/servlet/RegisterCompleteServlet.java @@ -18,6 +18,7 @@ package com.cloud.servlet; +import java.net.URLEncoder; import java.util.List; import javax.servlet.ServletContextEvent; @@ -86,6 +87,7 @@ public class RegisterCompleteServlet extends HttpServlet implements ServletConte statusCode = 503; responseMessage = "{ \"registration_info\" : { \"errorcode\" : \"503\", \"errortext\" : \"Missing token\" } }"; } else { + s_logger.info("Attempting to register user account with token = "+registrationToken); User resourceAdminUser = _accountSvc.getActiveUserByRegistrationToken(registrationToken); if (resourceAdminUser != null) { if(!resourceAdminUser.isRegistered()){ @@ -101,12 +103,12 @@ public class RegisterCompleteServlet extends HttpServlet implements ServletConte Configuration config = _configDao.findByName("endpointe.url"); StringBuffer sb = new StringBuffer(); - sb.append("{ \"registration_info\" : { \"endpoint_url\" : \""+config.getValue()+"\", "); + sb.append("{ \"registration_info\" : { \"endpoint_url\" : \""+encodeParam(config.getValue())+"\", "); sb.append("\"domain_id\" : \""+resourceAdminAccount.getDomainId()+"\", "); - sb.append("\"admin_account\" : \""+resourceAdminUser.getUsername()+"\", "); + sb.append("\"admin_account\" : \""+encodeParam(resourceAdminUser.getUsername())+"\", "); sb.append("\"admin_account_api_key\" : \""+resourceAdminUser.getApiKey()+"\", "); sb.append("\"admin_account_secret_key\" : \""+resourceAdminUser.getSecretKey()+"\", "); - sb.append("\"user_account\" : \""+rsUser.getUsername()+"\", "); + sb.append("\"user_account\" : \""+encodeParam(rsUser.getUsername())+"\", "); sb.append("\"user_account_api_key\" : \""+rsUser.getApiKey()+"\", "); sb.append("\"user_account_secret_key\" : \""+rsUser.getSecretKey()+"\" "); sb.append("} }"); @@ -125,4 +127,13 @@ public class RegisterCompleteServlet extends HttpServlet implements ServletConte s_logger.error("unknown exception writing register complete response", ex); } } + + private String encodeParam(String value) { + try { + return URLEncoder.encode(value, "UTF-8").replaceAll("\\+", "%20"); + } catch (Exception e) { + s_logger.warn("Unable to encode: " + value); + } + return value; + } } From 2a6215abcad08395f645d272662d8bf7f4481a25 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 2 Jun 2011 17:20:00 -0700 Subject: [PATCH 51/65] bug 9959: cloudStack - Add Network Device dialog, Add External Firewall dialog, Add External Load Balancer dialog - encode parameter values before passing them to API. --- ui/scripts/cloud.core.network.js | 12 ++++++------ ui/scripts/cloud.core.pod.js | 26 +++++++++++++------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/ui/scripts/cloud.core.network.js b/ui/scripts/cloud.core.network.js index abb5ad9da2d..deb6db2ed4c 100644 --- a/ui/scripts/cloud.core.network.js +++ b/ui/scripts/cloud.core.network.js @@ -724,13 +724,13 @@ function bindAddExternalFirewallButton() { var array1 = []; - array1.push("&zoneid=" + zoneObj.id); + array1.push("&zoneid=" + todb(zoneObj.id)); var username = $thisDialog.find("#username").val(); - array1.push("&username="+username); + array1.push("&username=" + todb(username)); var password = $thisDialog.find("#password").val(); - array1.push("&password="+password); + array1.push("&password=" + todb(password)); //*** construct URL (begin) *** var url = []; @@ -904,13 +904,13 @@ function bindAddLoadBalancerButton() { var array1 = []; - array1.push("&zoneid=" + zoneObj.id); + array1.push("&zoneid=" + todb(zoneObj.id)); var username = $thisDialog.find("#username").val(); - array1.push("&username="+username); + array1.push("&username=" + todb(username)); var password = $thisDialog.find("#password").val(); - array1.push("&password="+password); + array1.push("&password=" + todb(password)); //*** construct URL (begin) *** var url = []; diff --git a/ui/scripts/cloud.core.pod.js b/ui/scripts/cloud.core.pod.js index 4daa29b3ec8..7b84838e4d0 100644 --- a/ui/scripts/cloud.core.pod.js +++ b/ui/scripts/cloud.core.pod.js @@ -997,26 +997,26 @@ function bindAddNetworkDeviceButton($leftmenuItem1) { $thisDialog.find("#spinning_wheel").show(); var array1 = []; - array1.push("&networkdevicetype="+$thisDialog.find("#network_device_type").val()); - array1.push("&networkdeviceparameterlist[0].zoneid=" + zoneId); - array1.push("&networkdeviceparameterlist[0].podid=" + podId); - array1.push("&networkdeviceparameterlist[0].url="+$thisDialog.find("#url").val()); - array1.push("&networkdeviceparameterlist[0].username="+$thisDialog.find("#username").val()); - array1.push("&networkdeviceparameterlist[0].password="+$thisDialog.find("#password").val()); + array1.push("&networkdevicetype=" + todb($thisDialog.find("#network_device_type").val())); + array1.push("&networkdeviceparameterlist[0].zoneid=" + todb(zoneId)); + array1.push("&networkdeviceparameterlist[0].podid=" + todb(podId)); + array1.push("&networkdeviceparameterlist[0].url=" + todb($thisDialog.find("#url").val())); + array1.push("&networkdeviceparameterlist[0].username=" + todb($thisDialog.find("#username").val())); + array1.push("&networkdeviceparameterlist[0].password=" + todb($thisDialog.find("#password").val())); if($("#DHCP_server_type_container").css("display") != "none") - array1.push("&networkdeviceparameterlist[0].dhcpservertype=" + $thisDialog.find("#DHCP_server_type").val()); + array1.push("&networkdeviceparameterlist[0].dhcpservertype=" + todb($thisDialog.find("#DHCP_server_type").val())); if($("#Pxe_server_type_container").css("display") != "none") - array1.push("&networkdeviceparameterlist[0].pxeservertype=" + $thisDialog.find("#Pxe_server_type").val()); + array1.push("&networkdeviceparameterlist[0].pxeservertype=" + todb($thisDialog.find("#Pxe_server_type").val())); if($("#PING_storage_IP_container").css("display") != "none") - array1.push("&networkdeviceparameterlist[0].pingstorageserverip=" + $thisDialog.find("#PING_storage_IP").val()); + array1.push("&networkdeviceparameterlist[0].pingstorageserverip=" + todb($thisDialog.find("#PING_storage_IP").val())); if($("#PING_dir_container").css("display") != "none") - array1.push("&networkdeviceparameterlist[0].pingdir=" + $thisDialog.find("#PING_dir").val()); + array1.push("&networkdeviceparameterlist[0].pingdir=" + todb($thisDialog.find("#PING_dir").val())); if($("#TFTP_dir_container").css("display") != "none") - array1.push("&networkdeviceparameterlist[0].tftpdir=" + $thisDialog.find("#TFTP_dir").val()); + array1.push("&networkdeviceparameterlist[0].tftpdir=" + todb($thisDialog.find("#TFTP_dir").val())); if($("#PING_CIFS_username_container").css("display") != "none") - array1.push("&networkdeviceparameterlist[0].pingcifsusername=" + $thisDialog.find("#PING_CIFS_username").val()); + array1.push("&networkdeviceparameterlist[0].pingcifsusername=" + todb($thisDialog.find("#PING_CIFS_username").val())); if($("#PING_CIFS_password_container").css("display") != "none") - array1.push("&networkdeviceparameterlist[0].pingcifspassword=" + $thisDialog.find("#PING_CIFS_password").val()); + array1.push("&networkdeviceparameterlist[0].pingcifspassword=" + todb($thisDialog.find("#PING_CIFS_password").val())); $.ajax({ data: createURL("command=addNetworkDevice" + array1.join("")), From 87b3a326f3fae056870a65f75e4cc4ff8d4a005c Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 2 Jun 2011 19:27:54 -0700 Subject: [PATCH 52/65] bug 7194: cloudStack UI - IP Address page - create port forwarding rule - (1) split public port into public start port, public end port. (2) split private port into private start port, private end port. --- ui/jsp/ipaddress.jsp | 14 +++++- ui/scripts/cloud.core.ipaddress.js | 71 ++++++++++++++++-------------- 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/ui/jsp/ipaddress.jsp b/ui/jsp/ipaddress.jsp index 742383ac996..13515967e25 100644 --- a/ui/jsp/ipaddress.jsp +++ b/ui/jsp/ipaddress.jsp @@ -316,12 +316,22 @@ dictionary = {
- + + + - + + +
- + + + - + + +