Return-Path: X-Original-To: apmail-incubator-cloudstack-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-cloudstack-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 3AE45DAD0 for ; Tue, 18 Dec 2012 06:03:57 +0000 (UTC) Received: (qmail 15025 invoked by uid 500); 18 Dec 2012 06:03:57 -0000 Delivered-To: apmail-incubator-cloudstack-commits-archive@incubator.apache.org Received: (qmail 14782 invoked by uid 500); 18 Dec 2012 06:03:56 -0000 Mailing-List: contact cloudstack-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: cloudstack-dev@incubator.apache.org Delivered-To: mailing list cloudstack-commits@incubator.apache.org Received: (qmail 14577 invoked by uid 99); 18 Dec 2012 06:03:52 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 18 Dec 2012 06:03:52 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 5DDE981E326; Tue, 18 Dec 2012 06:03:52 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: bhaisaab@apache.org To: cloudstack-commits@incubator.apache.org X-Mailer: ASF-Git Admin Mailer Subject: [1/3] git commit: api: Fix ApiServer's handle() which runs on integration.api.port Message-Id: <20121218060352.5DDE981E326@tyr.zones.apache.org> Date: Tue, 18 Dec 2012 06:03:52 +0000 (UTC) Updated Branches: refs/heads/api_refactoring de8aa8654 -> d54d8cbcd api: Fix ApiServer's handle() which runs on integration.api.port - Fix URI parsing using apache hc - Remove bloated c-like parsing code - Fix param processing - TODO: To use Guava's multimap Signed-off-by: Rohit Yadav Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/d54d8cbc Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/d54d8cbc Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/d54d8cbc Branch: refs/heads/api_refactoring Commit: d54d8cbcd7913bcc2c82a5fa64042849753e026a Parents: 5572707 Author: Rohit Yadav Authored: Mon Dec 17 20:51:51 2012 -0800 Committer: Rohit Yadav Committed: Mon Dec 17 20:51:51 2012 -0800 ---------------------------------------------------------------------- server/src/com/cloud/api/ApiServer.java | 61 +++++++++++++------------ 1 files changed, 32 insertions(+), 29 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d54d8cbc/server/src/com/cloud/api/ApiServer.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index bb2044f..b440f17 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -23,6 +23,8 @@ import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URLDecoder; import java.net.URLEncoder; import java.security.SecureRandom; @@ -53,12 +55,14 @@ import org.apache.cloudstack.api.command.user.event.ListEventsCmd; import org.apache.cloudstack.api.command.user.vm.ListVMsCmd; import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd; import org.apache.commons.codec.binary.Base64; +import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.ConnectionClosedException; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpServerConnection; import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.impl.DefaultHttpServerConnection; @@ -187,7 +191,6 @@ public class ApiServer implements HttpRequestHandler { } encodeApiResponse = Boolean.valueOf(configDao.getValue(Config.EncodeApiResponse.key())); - String jsonType = configDao.getValue(Config.JavaScriptDefaultContentType.key()); if (jsonType != null) { jsonContentType = jsonType; @@ -199,10 +202,14 @@ public class ApiServer implements HttpRequestHandler { } } + // NOTE: handle() only handles over the wire (OTW) requests from integration.api.port 8096 + // If integration api port is not configured, actual OTW requests will be received by ApiServlet @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { - // get some information for the access log... + public void handle(HttpRequest request, HttpResponse response, HttpContext context) + throws HttpException, IOException { + + // Create StringBuffer to log information in access log StringBuffer sb = new StringBuffer(); HttpServerConnection connObj = (HttpServerConnection) context.getAttribute("http.connection"); if (connObj instanceof SocketHttpServerConnection) { @@ -212,40 +219,31 @@ public class ApiServer implements HttpRequestHandler { sb.append(request.getRequestLine()); try { - String uri = request.getRequestLine().getUri(); - int requestParamsStartIndex = uri.indexOf('?'); - if (requestParamsStartIndex >= 0) { - uri = uri.substring(requestParamsStartIndex + 1); - } - - String[] paramArray = uri.split("&"); - if (paramArray.length < 1) { - s_logger.info("no parameters received for request: " + uri + ", aborting..."); - return; + List paramList = null; + try { + paramList = URLEncodedUtils.parse(new URI(request.getRequestLine().getUri()), "UTF-8"); + } catch (URISyntaxException e) { + s_logger.error("Error parsing url request", e); } + // Use Multimap as the parameter map should be in the form (name=String, value=String[]) + // So parameter values are stored in a list for the same name key + // APITODO: Use Guava's (import com.google.common.collect.Multimap;) + // (Immutable)Multimap paramMultiMap = HashMultimap.create(); + // Map> parameterMap = paramMultiMap.asMap(); Map parameterMap = new HashMap(); - - String responseType = BaseCmd.RESPONSE_TYPE_XML; - for (String paramEntry : paramArray) { - String[] paramValue = paramEntry.split("="); - if (paramValue.length != 2) { - s_logger.info("malformed parameter: " + paramEntry + ", skipping"); + String responseType = BaseCmd.RESPONSE_TYPE_JSON; + for (NameValuePair param : paramList) { + if (param.getName().equalsIgnoreCase("response")) { + responseType = param.getValue(); continue; } - if ("response".equalsIgnoreCase(paramValue[0])) { - responseType = paramValue[1]; - } else { - // according to the servlet spec, the parameter map should be in the form (name=String, - // value=String[]), so - // parameter values will be stored in an array - parameterMap.put(/* name */paramValue[0], /* value */new String[] { paramValue[1] }); - } + parameterMap.put(param.getName(), new String[] { param.getValue() }); } - // Check responseType, if not among valid types, fallback to XML + // Check responseType, if not among valid types, fallback to JSON if (!(responseType.equals(BaseCmd.RESPONSE_TYPE_JSON) || responseType.equals(BaseCmd.RESPONSE_TYPE_XML))) - responseType = BaseCmd.RESPONSE_TYPE_XML; + responseType = BaseCmd.RESPONSE_TYPE_JSON; try { // always trust commands from API port, user context will always be UID_SYSTEM/ACCOUNT_ID_SYSTEM @@ -379,6 +377,11 @@ public class ApiServer implements HttpRequestHandler { UserContext ctx = UserContext.current(); Long callerUserId = ctx.getCallerUserId(); Account caller = ctx.getCaller(); + + // Queue command based on Cmd super class: + // BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned. + // BaseAsyncCreateCmd: cmd params are processed and create() is called, then same workflow as BaseAsyncCmd. + // BaseAsyncCmd: cmd is processed and submitted as an AsyncJob, job related info is serialized and returned. if (cmdObj instanceof BaseAsyncCmd) { Long objectId = null; String objectEntityTable = null;