From 901f52eb99ea82effc8b50e6db8528ed42424681 Mon Sep 17 00:00:00 2001 From: Kris McQueen Date: Wed, 27 Oct 2010 17:16:28 -0700 Subject: [PATCH 1/5] bug 6782: incremental checkin for deleting an account. Since there was a change to findById to not find removed objects, these NPEs pop up from time to time where we expected to find the object previously and now it's not found. Since the account is getting deleted, do a findByIdIncludingRemoved to make sure the actual account object is retrieved. --- server/src/com/cloud/server/ManagementServerImpl.java | 2 +- server/src/com/cloud/user/AccountManagerImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index a454904c77d..b346e2fa274 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -821,7 +821,7 @@ public class ManagementServerImpl implements ManagementServer { s_logger.debug("Remove account " + accountId); } - AccountVO account = _accountDao.findById(accountId); + AccountVO account = _accountDao.findByIdIncludingRemoved(accountId); deleteAccount(account); EventUtils.saveEvent(Long.valueOf(1), Long.valueOf(1), EventVO.LEVEL_INFO, EventTypes.EVENT_USER_DELETE, "User " + username + " (id: " + userId + ") for accountId = " + accountId + " and domainId = " + userAccount.getDomainId() + " was deleted."); diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index e589b3bd2ce..05b2f75e68e 100644 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -125,7 +125,7 @@ public class AccountManagerImpl implements AccountManager { // on a per-domain basis, decrement the count // FIXME: can this decrement be done on the database side in a custom update statement? - Account account = _accountDao.findById(accountId); + Account account = _accountDao.findByIdIncludingRemoved(accountId); // find all accounts, even removed accounts if this happens to be for an account that's being deleted Long domainId = account.getDomainId(); while (domainId != null) { _resourceCountDao.updateDomainCount(domainId, type, false, numToDecrement); From 484f334d7aa3940035da2c29568990caeb5ff1f3 Mon Sep 17 00:00:00 2001 From: Kris McQueen Date: Wed, 27 Oct 2010 17:17:42 -0700 Subject: [PATCH 2/5] bug 6799: if there's an exception executing the Async command, create an error response with the appropriate information so that queryAsyncJobResult returns the relevant information status 6799: resolved fixed --- .../com/cloud/async/AsyncJobManagerImpl.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/async/AsyncJobManagerImpl.java b/server/src/com/cloud/async/AsyncJobManagerImpl.java index 2a496fc37a1..ec49a4296d5 100644 --- a/server/src/com/cloud/async/AsyncJobManagerImpl.java +++ b/server/src/com/cloud/async/AsyncJobManagerImpl.java @@ -38,6 +38,7 @@ import com.cloud.api.ApiDispatcher; import com.cloud.api.BaseAsyncCmd; import com.cloud.api.BaseCmd; import com.cloud.api.ServerApiException; +import com.cloud.api.response.ExceptionResponse; import com.cloud.async.dao.AsyncJobDao; import com.cloud.cluster.ClusterManager; import com.cloud.configuration.dao.ConfigurationDao; @@ -323,6 +324,7 @@ public class AsyncJobManagerImpl implements AsyncJobManager { public void run() { long jobId = 0; + BaseAsyncCmd cmdObj = null; Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { jobId = job.getId(); @@ -333,7 +335,7 @@ public class AsyncJobManagerImpl implements AsyncJobManager { } Class cmdClass = Class.forName(job.getCmd()); - BaseAsyncCmd cmdObj = (BaseAsyncCmd)cmdClass.newInstance(); + cmdObj = (BaseAsyncCmd)cmdClass.newInstance(); cmdObj.setAsyncJobManager(mgr); cmdObj.setJob(job); @@ -379,13 +381,25 @@ public class AsyncJobManagerImpl implements AsyncJobManager { } checkQueue(((AsyncCommandQueued)e).getQueue().getId()); } else { + String errorMsg = null; + int errorCode = BaseCmd.INTERNAL_ERROR; if (!(e instanceof ServerApiException)) { s_logger.error("Unexpected exception while executing " + job.getCmd(), e); + errorMsg = e.getMessage(); + } else { + ServerApiException sApiEx = (ServerApiException)e; + errorMsg = sApiEx.getDescription(); + errorCode = sApiEx.getErrorCode(); } + ExceptionResponse response = new ExceptionResponse(); + response.setErrorCode(errorCode); + response.setErrorText(errorMsg); + response.setResponseName((cmdObj == null) ? "unknowncommandresponse" : cmdObj.getName()); + // FIXME: setting resultCode to BaseCmd.INTERNAL_ERROR is not right, usually executors have their exception handling // and we need to preserve that as much as possible here - completeAsyncJob(jobId, AsyncJobResult.STATUS_FAILED, BaseCmd.INTERNAL_ERROR, e.getMessage()); + completeAsyncJob(jobId, AsyncJobResult.STATUS_FAILED, BaseCmd.INTERNAL_ERROR, response); // need to clean up any queue that happened as part of the dispatching and move on to the next item in the queue try { From 50c175d6c1d66b6d74dc6126d9e9f98ff36fe87b Mon Sep 17 00:00:00 2001 From: Kris McQueen Date: Wed, 27 Oct 2010 18:07:53 -0700 Subject: [PATCH 3/5] bug 6799: forgot to add the exception response in my commit for this bug... --- .../cloud/api/response/ExceptionResponse.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 server/src/com/cloud/api/response/ExceptionResponse.java diff --git a/server/src/com/cloud/api/response/ExceptionResponse.java b/server/src/com/cloud/api/response/ExceptionResponse.java new file mode 100644 index 00000000000..49542de481e --- /dev/null +++ b/server/src/com/cloud/api/response/ExceptionResponse.java @@ -0,0 +1,45 @@ +/** + * 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.api.response; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class ExceptionResponse extends BaseResponse { + @SerializedName("errorcode") @Param(description="numeric code associated with this error") + private Integer errorCode; + + @SerializedName("errortext") @Param(description="the text associated with this error") + private String errorText; + + public Integer getErrorCode() { + return errorCode; + } + + public void setErrorCode(Integer errorCode) { + this.errorCode = errorCode; + } + + public String getErrorText() { + return errorText; + } + + public void setErrorText(String errorText) { + this.errorText = errorText; + } +} From b4ef066846b6eb9d94204fb421ae9eccdbf914b8 Mon Sep 17 00:00:00 2001 From: Kris McQueen Date: Wed, 27 Oct 2010 18:23:18 -0700 Subject: [PATCH 4/5] bug 6782: fix NPEs associated with looking up the account after it's been deleted. When cleaning up the account, we delete the accountVO first, then stop/destroy VMs, routers, etc. During this cleanup, there are times when the account needs to be retrieved, and since it's been removed it has to be found by id 'including removed' in order to find it. status 6782: resolved fixed --- core/src/com/cloud/user/dao/AccountDaoImpl.java | 2 +- utils/src/com/cloud/utils/db/GenericDaoBase.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/com/cloud/user/dao/AccountDaoImpl.java b/core/src/com/cloud/user/dao/AccountDaoImpl.java index 1b60f22d2b4..5715ac58515 100644 --- a/core/src/com/cloud/user/dao/AccountDaoImpl.java +++ b/core/src/com/cloud/user/dao/AccountDaoImpl.java @@ -174,7 +174,7 @@ public class AccountDaoImpl extends GenericDaoBase implements A @Override public void markForCleanup(long accountId) { - AccountVO account = findById(accountId); + AccountVO account = findByIdIncludingRemoved(accountId); if (!account.getNeedsCleanup()) { account.setNeedsCleanup(true); update(accountId, account); diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java index 53df12503e4..236d49980bb 100755 --- a/utils/src/com/cloud/utils/db/GenericDaoBase.java +++ b/utils/src/com/cloud/utils/db/GenericDaoBase.java @@ -1137,7 +1137,7 @@ public abstract class GenericDaoBase implements Gene } } - return _idField != null ? findById(id) : null; + return _idField != null ? findByIdIncludingRemoved(id) : null; } @DB(txn=false) From 82b00343d69551cff8c1213bd4e8c829a345c891 Mon Sep 17 00:00:00 2001 From: NIKITA Date: Wed, 27 Oct 2010 18:29:01 -0700 Subject: [PATCH 5/5] Launch Test Provisioning tool button added to footer --- ui/new/css/main.css | 122 +++++++++++++++++----------- ui/new/images/test_provisioning.png | Bin 1142 -> 412 bytes ui/new/index.jsp | 7 +- 3 files changed, 78 insertions(+), 51 deletions(-) diff --git a/ui/new/css/main.css b/ui/new/css/main.css index aaf2cbbddc2..8967697836f 100644 --- a/ui/new/css/main.css +++ b/ui/new/css/main.css @@ -2012,48 +2012,7 @@ a:hover.search_button { padding:0; } -.actionsdropdown_boxlist { - width:197px; - height:auto; - float:left; - margin:0 0 5px 6px; - padding:0 0 10px 0; - list-style:none; -} -.actionsdropdown_boxlist li{ - width:194px; - height:auto; - float:left; - text-align:left; - background:#FFF url(../images/midmenu_hover.gif) repeat-x top left; - color:#CCC; - font-size:11px; - font-weight:normal; - margin:0 0 0 0; - padding:6px 0 5px 3px; - list-style:none; -} - -.actionsdropdown_boxlist li:hover{ - background:#e6e6e6 repeat top left; -} - -.actionsdropdown_boxlist a{ - text-decoration:none; - color:#2c8bbc; -} - - -.actionsdropdown_boxlist a:link, actionsdropdown_boxlist a:visited { - text-decoration:none; - color:#2c8bbc; -} - -.actionsdropdown_boxlist a:hover{ - text-decoration:none; - color:#2c8bbc; -} #contentwrapper{ height:100%; @@ -2740,19 +2699,43 @@ a:hover.search_button { padding:0; } -#footer p{ +.footer_testprovisiongtool{ width:auto; height:auto; float:left; - text-align:left; - font-size:11px; - font-weight:normal; - color:#c2c2c2; margin:9px 0 0 10px; display:inline; padding:0; } +.footer_testprovisiongtool_icon { + width:11px; + height:13px; + float:left; + background:url(../images/test_provisioning.png) no-repeat top left; + margin:0; + padding:0; +} +.footer_testprovisiongtool a{ + width:auto; + height:auto; + float:left; + text-decoration:none; + font-weight:normal; + color:#CCC; + margin:2px 0 0 7px; + display:inline; + padding:0; +} + +.footer_testprovisiongtool a:link, .footer_testprovisiongtool a:visited { + text-decoration:none; +} + +.footer_testprovisiongtool a:hover { + text-decoration:underline; +} + #footer span{ font-weight:bold; color:#CCC; @@ -3138,19 +3121,62 @@ a:hover.search_button { } .grid_actionsdropdown_box { - width:209px; + width:195px; height:auto; float:left; position:absolute; background:#FFF repeat top left; border:1px solid #CCC; top:18px; - right:1px; + right:0; margin:0; padding:0; z-index:1002; } +.actionsdropdown_boxlist { + width:183px; + height:auto; + float:left; + margin:0 0 5px 6px; + padding:0 0 10px 0; + list-style:none; +} + +.actionsdropdown_boxlist li{ + width:181px; + height:auto; + float:left; + text-align:left; + background:#FFF url(../images/midmenu_hover.gif) repeat-x top left; + color:#CCC; + font-size:11px; + font-weight:normal; + margin:0 0 0 0; + padding:6px 0 5px 3px; + list-style:none; +} + +.actionsdropdown_boxlist li:hover{ + background:#e6e6e6 repeat top left; +} + +.actionsdropdown_boxlist a{ + text-decoration:none; + color:#2c8bbc; +} + + +.actionsdropdown_boxlist a:link, actionsdropdown_boxlist a:visited { + text-decoration:none; + color:#2c8bbc; +} + +.actionsdropdown_boxlist a:hover{ + text-decoration:none; + color:#2c8bbc; +} + .dbrow { width:100%; height:44px; diff --git a/ui/new/images/test_provisioning.png b/ui/new/images/test_provisioning.png index b962f16bc052c251960647b4856d7e3c4be69c08..2e9f720942e02ed5350ebe9573a0935339b9ce05 100644 GIT binary patch delta 384 zcmV-`0e}AX2%G~UiBL{Q4GJ0x0000DNk~Le0000B0000D2nGNE0SNM>t&t%oe*r#8 zL_t(|+G6zc^ZU=s%gexEWo7jr2p9kYh#?{(;y=^Vr%xFG0*JxG!{fiLtu0uX(a_NF zKRY`+10y3N13&;VMn^~g|NHkZ!?$nW7#Km)c6N6Exw*L+m>8ho)2B}iEHE>F{`|=R z5I_vU!NFh-G6sn;y?y%@tOaBSe+YxvATbuOHXt~3=nx~!T#y(*04m5J1%McYf!XS@ zKk7ro|9`-nV1->Q2-`pi;~@|q5qX&znTbxQ>eXM&W`^!8%{ejL9e)*%z4vuI-0R!L z91&P+od*yRDn9}GAcGTtLKuctQE?*|aZI=K;z_@+P%q-orBKo|iL14)R-CieGw0NE zruSZAj5<*mV@SX+Pg`qF9zYP~(0f129pxhKc7&MVRQ3ns1oLMqFTiu9l$BD_1wrs; e0<=JIKsz5v)XI=|K|62&00005(BPe*_pw zL_t(|+G6la)cAb{YEf6rgPeEa<6%Xg3|`}XZS4-#WyfP#O2{&N2P^M|9d zqJrVXi4%q(F-EXJ}|JdvoZ<^3Lzx_01anhU}X67?+?SjzyBH8 zSXsf|5Qh3%8Hhpb&p`YTi0=Xf;EU{25CoziKC4n$(x0u{0X&|^uoKz=fA#fxT&fC(EK_A!E`EX^MREM>+ZKWF4d)z+ zqJXtlv68RdRd^H`y5Mov2K)i8bqyZ`A_3Z%|6##s^-1S=-;??h4BEJG}|^7 zp+IK`mt?zNl05u?83x{Y`6XB{Zb;?j=g|&^>(vU|wvF;U|El^kQAs)W+-gh8%>bW2l$Q2?IV(-~Fzk3t7=J&*zI1%r}#a(q6zZ$^JZ!Eo& z=H3F-P`G=?3?B6%e?VhZvy(6ogs1J&9~uP@z?p*yf@j{08{T;f-a#IL1TQ2QM0o?E zho-1hN@=@(ZFjLjo4U!Qlk8@uGxL4l`~txFfn4#5VPs`tLhJ1j@GEHJkCqrdqe?UDd823fBN*4UP;n3`M zyL>jA^+0Q-FlK2|MTtVlqHWtLnq9}CEwsXgroFo^nGl@8U_d&$aX*=SwcBlFu~@t~ zj#C(ul_f>{A_Y8yGNy_a;0JVk>%ipdc}0y@iwqT z!+?M8ylgWa4|o$iz(`tA%<@X(xS=zR5{cP)9^G_0bV58nw#lHzG4z9B{(MLOIIQ3A zpJY`4OBLkQMEjdLU*602B6Vu9u%_T=BseU6dCysHHWiq{ETIaCZ|BxURlJkr*F@4N mw?2a0`q&H6kSk>`eE%CXz-s>HIL9{t0000