From 580bf857ff41cd6bff36f8cfdb8e821d7978598d Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Wed, 2 Jan 2013 18:34:54 -0800 Subject: [PATCH] server: ApiServer inits with processing cmd classes to fill apiname:class mapping - Add maven dependency reflections (wtfl license, apl compliant) - Use reflections to recurse and get apiname:class mapping Signed-off-by: Rohit Yadav --- server/pom.xml | 5 +++ server/src/com/cloud/api/ApiServer.java | 43 ++++++++++++++----------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/server/pom.xml b/server/pom.xml index c253e43acc7..1fd18319823 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -79,6 +79,11 @@ tests test + + org.reflections + reflections + 0.9.8 + install diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 5ee7c356aba..b853094dd6c 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -119,10 +119,8 @@ import com.cloud.user.User; import com.cloud.user.UserAccount; import com.cloud.user.UserContext; import com.cloud.user.UserVO; -import com.cloud.utils.IdentityProxy; import com.cloud.utils.Pair; import com.cloud.utils.component.Adapters; -import com.cloud.utils.PropertiesUtil; import com.cloud.utils.StringUtils; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; @@ -133,6 +131,8 @@ import com.cloud.utils.exception.CSExceptionErrorCode; import com.cloud.uuididentity.dao.IdentityDao; import com.cloud.acl.APIAccessChecker; +import org.reflections.Reflections; + public class ApiServer implements HttpRequestHandler { private static final Logger s_logger = Logger.getLogger(ApiServer.class.getName()); private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName()); @@ -152,6 +152,7 @@ public class ApiServer implements HttpRequestHandler { private static int _workerCount = 0; private static ApiServer s_instance = null; private static final DateFormat _dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + private Map> _apiNameCmdClassMap = new HashMap>(); private static ExecutorService _executor = new ThreadPoolExecutor(10, 150, 60, TimeUnit.SECONDS, new LinkedBlockingQueue(), new NamedThreadFactory("ApiServer")); @@ -199,6 +200,19 @@ public class ApiServer implements HttpRequestHandler { } } + // Populate api name and cmd class mappings + Reflections reflections = new Reflections("org.apache.cloudstack"); + Set> cmdClasses = reflections.getTypesAnnotatedWith(APICommand.class); + reflections = new Reflections("com.cloud.api"); + cmdClasses.addAll(reflections.getTypesAnnotatedWith(APICommand.class)); + for(Class cmdClass: cmdClasses) { + String apiName = cmdClass.getAnnotation(APICommand.class).name(); + if (_apiNameCmdClassMap.containsKey(apiName)) { + s_logger.error("Cmd class " + cmdClass.getName() + " conflicts on apiname" + apiName); + } + _apiNameCmdClassMap.put(apiName, cmdClass); + } + encodeApiResponse = Boolean.valueOf(configDao.getValue(Config.EncodeApiResponse.key())); String jsonType = configDao.getValue(Config.JavaScriptDefaultContentType.key()); if (jsonType != null) { @@ -322,9 +336,8 @@ public class ApiServer implements HttpRequestHandler { paramMap.put(key, decodedValue); } - String cmdClassName = getCmdClassName(command[0]); - if (cmdClassName != null) { - Class cmdClass = Class.forName(cmdClassName); + Class cmdClass = getCmdClass(command[0]); + if (cmdClass != null) { BaseCmd cmdObj = (BaseCmd) cmdClass.newInstance(); cmdObj.setFullUrlParams(paramMap); cmdObj.setResponseType(responseType); @@ -795,15 +808,8 @@ public class ApiServer implements HttpRequestHandler { return true; } - private String getCmdClassName(String cmdName) { - String cmdClassName = null; - for (APIAccessChecker apiChecker : _apiAccessCheckers){ - cmdClassName = apiChecker.getApiCommands().getProperty(cmdName); - // Break on the first non-null value - if (cmdClassName != null) - return cmdClassName; - } - return null; + private Class getCmdClass(String cmdName) { + return _apiNameCmdClassMap.get(cmdName); } // FIXME: rather than isError, we might was to pass in the status code to give more flexibility @@ -939,7 +945,7 @@ public class ApiServer implements HttpRequestHandler { public String getSerializedApiError(int errorCode, String errorText, Map apiCommandParams, String responseType, Exception ex) { String responseName = null; - String cmdClassName = null; + Class cmdClass = null; String responseText = null; try { @@ -950,10 +956,9 @@ public class ApiServer implements HttpRequestHandler { // cmd name can be null when "command" parameter is missing in the request if (cmdObj != null) { String cmdName = ((String[]) cmdObj)[0]; - cmdClassName = getCmdClassName(cmdName); - if (cmdClassName != null) { - Class claz = Class.forName(cmdClassName); - responseName = ((BaseCmd) claz.newInstance()).getCommandName(); + cmdClass = getCmdClass(cmdName); + if (cmdClass != null) { + responseName = ((BaseCmd) cmdClass.newInstance()).getCommandName(); } else { responseName = "errorresponse"; }