Bug 13127: API error text refer to database ids instead of uuids

Description:

	Adding a new class AnnotationHelper, that provides routines
	to read annotations from a VO class.

	Cloudstack does the mapping between cloudstack java VO objects
	and the database tables using cglib. cglib creates proxy objects
	as the maps between VO objects and the database.  A VO (value
	object) class is populated after querying from the MYSQL database.

	Ideally, a getAnnotation() issued on a cglib proxy object should
	get a list of all the annotations in all classes in the inheritence
	chain. However, this functionality seems to be currently broken
	in cglib.  Hence, when querying for annotations given the object
	of a VO class, we need to get to the corresponding VO class of that
	cglib proxy class and issue a getAnnotation() on that class. To get
	the VO class, we simply need to get the super class of the proxy
	object. Also, we need to recurse to the root VO class in case the
	VO class extends another VO class.

	Note that the cache used by CS is ehcache.
This commit is contained in:
Vijayendra Bhamidipati 2012-03-08 16:38:54 -08:00
parent 6ff0a475d7
commit 6ac79c4be2
3 changed files with 91 additions and 2 deletions

View File

@ -28,12 +28,16 @@ import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.log4j.Logger;
import com.cloud.api.Identity;
import com.cloud.utils.db.GenericDao;
@Entity
@Table(name="domain")
public class DomainVO implements Domain, Identity {
public class DomainVO implements Domain, Identity {
public static final Logger s_logger = Logger.getLogger(DomainVO.class.getName());
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")

View File

@ -244,6 +244,7 @@ import com.cloud.vm.dao.SecondaryStorageVmDao;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.utils.exception.CSExceptionErrorCode;
import com.cloud.utils.AnnotationHelper;
import edu.emory.mathcs.backport.java.util.Arrays;
import edu.emory.mathcs.backport.java.util.Collections;
@ -1838,7 +1839,13 @@ public class ManagementServerImpl implements ManagementServer {
if (!domains.isEmpty() && !sameDomain) {
InvalidParameterValueException ex = new InvalidParameterValueException("Failed to update specified domain id with name '" + domainName + "' since it already exists in the system");
ex.addProxyObject("domain", domainId, "domainId");
// Get the domainVO object's table name.
String tablename = AnnotationHelper.getTableName(domain);
if (tablename != null) {
ex.addProxyObject(tablename, domainId, "domainId");
} else {
s_logger.info("\nCould not retrieve table name (annotation) from domainVO proxy cglib object\n");
}
throw ex;
}
}

View File

@ -0,0 +1,78 @@
/**
* * Copyright (C) 2012 Citrix Systems, 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 <http://www.gnu.org/licenses/>.
*
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.utils;
import javax.persistence.Table;
import org.apache.log4j.Logger;
import com.cloud.utils.exception.CSExceptionErrorCode;
public class AnnotationHelper extends Object {
// This class contains routines to help query annotation elements of objects.
// So add any annotation routines to this class.
public static final Logger s_logger = Logger.getLogger(AnnotationHelper.class.getName());
public static String getTableName(Object proxyObj) {
// Traverse to the base class of the VO class (which is the base class of the cglib proxy object's class).
// The cglib class is generated by cglib during runtime.
Class<?> curClass = proxyObj.getClass();
if (curClass == null) {
s_logger.info("\nCould not retrieve class information for proxy object\n");
return null;
}
while (curClass.getSuperclass() != null && curClass.getSuperclass().getName() != "java.lang.Object") {
curClass = curClass.getSuperclass();
}
// At this point, curClass is the root base class of proxyObj's class, and curClass is not java.lang.Object.
Table tabObj = (Table)curClass.getAnnotation(Table.class);
if (tabObj == null) {
s_logger.info("\n" + curClass + "does not have a Table annotation\n");
return null;
}
return tabObj.name();
}
}