On Wed, Jun 18, 2008 at 1:53 PM, Chris Chabot <[EMAIL PROTECTED]> wrote:
> Thanks for the heads up Cassie! > > I'm unavoidably tied up until mid friday, but i'll start banging on it as > soon as possible. First impression is very good though, way of dealing with > it looks sound and practical, and should be relatively trivial to add on the > php side too. > > Good job! > > Ps, just a thought that occurred to me: Since the spec doesn't yet mention > batching using the json format .. would we dare suggesting adding it to the > restful api properly or do we hide it in the not-documented cellar and save > the big coming out party for 0.9? lol, dunno. once we get both impls i figure we can throw it to the spec list and decide through mass discussion over there :) > > > -- Chris > > > On Jun 18, 2008, at 9:43 PM, Cassie wrote: > > Hey Chris and other php guys - I just wanted to alert you to the json >> batching stuff I wrote for the java restful server. This batching isn't in >> the spec (the spec has some crazy multi part thing that is super atom pub >> specific) so at this point it is just an extension so that the opensocial >> js >> apis can work better (because not batching is a regression). >> >> Lemme know what you think of the format - its pretty similar to what we >> had >> for the old json wire format. Once we clean this up we can propose it to >> the >> restful spec list as an alternative to the atomy batching. >> >> All input welcome! >> >> - Cassie >> >> >> On Wed, Jun 18, 2008 at 12:39 PM, <[EMAIL PROTECTED]> wrote: >> >> Author: doll >>> Date: Wed Jun 18 12:39:54 2008 >>> New Revision: 669268 >>> >>> URL: http://svn.apache.org/viewvc?rev=669268&view=rev >>> Log: >>> The dataservice rest impl now supports a jsonBatch format. This batch >>> format can now be optionally turned on in the restfulcontainer.js code. >>> >>> (As soon as php implements the batching stuff then we can remove the flag >>> and always use batching) >>> >>> >>> >>> Added: >>> >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/RequestItemTest.java >>> >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulBatchTest.java >>> Modified: >>> incubator/shindig/trunk/features/opensocial-current/restfulcontainer.js >>> >>> >>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/DataServiceServlet.java >>> >>> >>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/RequestItem.java >>> >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/DataServiceServletTest.java >>> >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulJsonPeopleTest.java >>> >>> Modified: >>> incubator/shindig/trunk/features/opensocial-current/restfulcontainer.js >>> URL: >>> >>> http://svn.apache.org/viewvc/incubator/shindig/trunk/features/opensocial-current/restfulcontainer.js?rev=669268&r1=669267&r2=669268&view=diff >>> >>> >>> ============================================================================== >>> --- >>> incubator/shindig/trunk/features/opensocial-current/restfulcontainer.js >>> (original) >>> +++ >>> incubator/shindig/trunk/features/opensocial-current/restfulcontainer.js >>> Wed Jun 18 12:39:54 2008 >>> @@ -38,6 +38,8 @@ >>> this.baseUrl_ = baseUrl; >>> >>> this.securityToken_ = shindig.auth.getSecurityToken(); >>> + >>> + this.useBatching_ = false; >>> }; >>> RestfulContainer.inherits(opensocial.Container); >>> >>> @@ -94,7 +96,6 @@ >>> var url = requestObject.request.url; >>> var separator = url.indexOf("?") != -1 ? "&" : "?"; >>> >>> - // TODO: Use batching instead of doing this one by one >>> gadgets.io.makeNonProxiedRequest( >>> baseUrl + url + separator + "st=" + st, >>> function(result) { >>> @@ -115,8 +116,61 @@ >>> } >>> >>> // may need multiple urls for one response but lets ignore that for now >>> - for (var i = 0; i < totalRequests; i++) { >>> - makeProxiedRequest(requestObjects[i], this.baseUrl_, >>> this.securityToken_); >>> + // TODO: Once both the php and java code decide on and implement >>> batching >>> + // the non-batching code should be deleted >>> + if (!this.useBatching_) { >>> + for (var i = 0; i < totalRequests; i++) { >>> + makeProxiedRequest(requestObjects[i], this.baseUrl_, >>> this.securityToken_); >>> + } >>> + >>> + } else { >>> + var jsonBatchData = {}; >>> + >>> + for (var j = 0; j < totalRequests; j++) { >>> + var requestObject = requestObjects[j]; >>> + >>> + jsonBatchData[requestObject.key] = {url : >>> requestObject.request.url, >>> + method : requestObject.request.method}; >>> + if (requestObject.request.postData) { >>> + jsonBatchData[requestObject.key].parameters = >>> requestObject.request.postData; >>> + } >>> + } >>> + >>> + // This is slightly different than jsonContainer >>> + var sendResponse = function(result) { >>> + result = result.data; >>> + >>> + if (!result || result['error']) { >>> + callback(new opensocial.DataResponse({}, true)); >>> + return; >>> + } >>> + >>> + var responses = result['responses'] || []; >>> + var globalError = false; >>> + >>> + var responseMap = {}; >>> + >>> + for (var k = 0; k < requestObjects.length; k++) { >>> + var request = requestObjects[k]; >>> + var response = responses[request.key]; >>> + >>> + var rawData = response['response']; >>> + var error = response['error']; >>> + var errorMessage = response['errorMessage']; >>> + >>> + var processedData = request.request.processResponse( >>> + request.request, rawData, error, errorMessage); >>> + globalError = globalError || processedData.hadError(); >>> + responseMap[request.key] = processedData; >>> + } >>> + >>> + var dataResponse = new opensocial.DataResponse(responseMap, >>> globalError); >>> + callback(dataResponse); >>> + }; >>> + >>> + // TODO: get the jsonbatch url from the container config >>> + new BatchRequest(this.baseUrl_ + "/jsonBatch", >>> gadgets.json.stringify(jsonBatchData), >>> + sendResponse, {'st' : shindig.auth.getSecurityToken()}).send(); >>> } >>> >>> }; >>> >>> Modified: >>> >>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/DataServiceServlet.java >>> URL: >>> >>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/DataServiceServlet.java?rev=669268&r1=669267&r2=669268&view=diff >>> >>> >>> ============================================================================== >>> --- >>> >>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/DataServiceServlet.java >>> (original) >>> +++ >>> >>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/DataServiceServlet.java >>> Wed Jun 18 12:39:54 2008 >>> @@ -17,28 +17,31 @@ >>> */ >>> package org.apache.shindig.social.dataservice; >>> >>> -import com.google.inject.Inject; >>> -import com.google.inject.Injector; >>> - >>> -import org.apache.shindig.common.SecurityTokenDecoder; >>> import org.apache.shindig.common.SecurityToken; >>> +import org.apache.shindig.common.SecurityTokenDecoder; >>> import org.apache.shindig.common.SecurityTokenException; >>> import org.apache.shindig.common.servlet.InjectedServlet; >>> +import org.apache.shindig.social.ResponseItem; >>> import org.apache.shindig.social.opensocial.util.BeanConverter; >>> import org.apache.shindig.social.opensocial.util.BeanJsonConverter; >>> import org.apache.shindig.social.opensocial.util.BeanXmlConverter; >>> -import org.apache.shindig.social.ResponseItem; >>> + >>> +import com.google.common.collect.Maps; >>> +import com.google.inject.Inject; >>> +import com.google.inject.Injector; >>> +import org.apache.commons.lang.StringUtils; >>> +import org.json.JSONException; >>> +import org.json.JSONObject; >>> >>> import javax.servlet.ServletException; >>> import javax.servlet.http.HttpServletRequest; >>> import javax.servlet.http.HttpServletResponse; >>> import java.io.IOException; >>> import java.io.PrintWriter; >>> +import java.util.Iterator; >>> import java.util.Map; >>> import java.util.logging.Logger; >>> >>> -import org.apache.commons.lang.StringUtils; >>> - >>> public class DataServiceServlet extends InjectedServlet { >>> >>> protected static final String X_HTTP_METHOD_OVERRIDE = >>> "X-HTTP-Method-Override"; >>> @@ -58,6 +61,7 @@ >>> private Map<String, Class<? extends DataRequestHandler>> handlers; >>> private BeanJsonConverter jsonConverter; >>> private BeanXmlConverter xmlConverter; >>> + private static final String JSON_BATCH_ROUTE = "jsonBatch"; >>> >>> @Inject >>> public void setHandlers(HandlerProvider handlers) { >>> @@ -65,8 +69,7 @@ >>> } >>> >>> @Inject >>> - public void setSecurityTokenDecoder(SecurityTokenDecoder >>> - securityTokenDecoder) { >>> + public void setSecurityTokenDecoder(SecurityTokenDecoder >>> securityTokenDecoder) { >>> this.securityTokenDecoder = securityTokenDecoder; >>> } >>> >>> @@ -102,12 +105,67 @@ >>> protected void doPost(HttpServletRequest servletRequest, >>> HttpServletResponse servletResponse) >>> throws ServletException, IOException { >>> - String path = servletRequest.getPathInfo(); >>> - logger.finest("Handling restful request for " + path); >>> + logger.finest("Handling restful request for " + >>> servletRequest.getPathInfo()); >>> >>> servletRequest.setCharacterEncoding("UTF-8"); >>> + SecurityToken token = getSecurityToken(servletRequest); >>> + BeanConverter converter = getConverterForRequest(servletRequest); >>> >>> - String route = getRouteFromParameter(path); >>> + if (isBatchUrl(servletRequest)) { >>> + try { >>> + handleBatchRequest(servletRequest, servletResponse, token, >>> converter); >>> + } catch (JSONException e) { >>> + throw new RuntimeException("Bad batch format", e); >>> + } >>> + } else { >>> + handleSingleRequest(servletRequest, servletResponse, token, >>> converter); >>> + } >>> + } >>> + >>> + private void handleSingleRequest(HttpServletRequest servletRequest, >>> + HttpServletResponse servletResponse, SecurityToken token, >>> + BeanConverter converter) throws IOException { >>> + String method = >>> getHttpMethodFromParameter(servletRequest.getMethod(), >>> + servletRequest.getParameter(X_HTTP_METHOD_OVERRIDE)); >>> + >>> + RequestItem requestItem = new RequestItem(servletRequest, token, >>> method); >>> + ResponseItem responseItem = getResponseItem(converter, requestItem); >>> + >>> + if (responseItem.getError() == null) { >>> + PrintWriter writer = servletResponse.getWriter(); >>> + >>> writer.write(converter.convertToString(responseItem.getResponse())); >>> + } else { >>> + >>> servletResponse.sendError(responseItem.getError().getHttpErrorCode(), >>> + responseItem.getErrorMessage()); >>> + } >>> + } >>> + >>> + private void handleBatchRequest(HttpServletRequest servletRequest, >>> + HttpServletResponse servletResponse, SecurityToken token, >>> + BeanConverter converter) throws IOException, JSONException { >>> + >>> + JSONObject requests = new >>> JSONObject(servletRequest.getParameter("request")); >>> + Map<String, ResponseItem> responses = Maps.newHashMap(); >>> + >>> + Iterator keys = requests.keys(); >>> + while (keys.hasNext()) { >>> + String key = (String) keys.next(); >>> + String request = requests.getString(key); >>> + >>> + RequestItem requestItem = converter.convertToObject(request, >>> RequestItem.class); >>> + requestItem.parseUrlParamsIntoParameters(); >>> + requestItem.setToken(token); >>> + >>> + responses.put(key, getResponseItem(converter, requestItem)); >>> + } >>> + >>> + PrintWriter writer = servletResponse.getWriter(); >>> + writer.write(converter.convertToString( >>> + Maps.immutableMap("error", false, "responses", responses))); >>> + } >>> + >>> + ResponseItem getResponseItem(BeanConverter converter, RequestItem >>> requestItem) { >>> + String route = getRouteFromParameter(requestItem.getUrl()); >>> Class<? extends DataRequestHandler> handlerClass = handlers.get(route); >>> >>> if (handlerClass == null) { >>> @@ -115,13 +173,12 @@ >>> } >>> >>> DataRequestHandler handler = injector.getInstance(handlerClass); >>> - BeanConverter converter = getConverterForRequest(servletRequest); >>> - // TODO: Move all conversions out of the handler up into the servlet >>> layer >>> handler.setConverter(converter); >>> >>> - String method = >>> getHttpMethodFromParameter(servletRequest.getMethod(), >>> - servletRequest.getParameter(X_HTTP_METHOD_OVERRIDE)); >>> + return handler.handleMethod(requestItem); >>> + } >>> >>> + SecurityToken getSecurityToken(HttpServletRequest servletRequest) { >>> SecurityToken token; >>> try { >>> token = >>> >>> securityTokenDecoder.createToken(servletRequest.getParameter(SECURITY_TOKEN_PARAM)); >>> @@ -129,20 +186,10 @@ >>> throw new RuntimeException( >>> "Implement error return for bad security token."); >>> } >>> - >>> - ResponseItem responseItem = handler.handleMethod( >>> - new RequestItem(servletRequest, token, method)); >>> - >>> - if (responseItem.getError() == null) { >>> - PrintWriter writer = servletResponse.getWriter(); >>> - >>> writer.write(converter.convertToString(responseItem.getResponse())); >>> - } else { >>> - >>> servletResponse.sendError(responseItem.getError().getHttpErrorCode(), >>> - responseItem.getErrorMessage()); >>> - } >>> + return token; >>> } >>> >>> - /*package-protected*/ BeanConverter >>> getConverterForRequest(HttpServletRequest servletRequest) { >>> + BeanConverter getConverterForRequest(HttpServletRequest >>> servletRequest) >>> { >>> String formatString = servletRequest.getParameter(FORMAT_PARAM); >>> if (!StringUtils.isBlank(formatString) && >>> formatString.equals(ATOM_FORMAT)) { >>> return xmlConverter; >>> @@ -150,8 +197,7 @@ >>> return jsonConverter; >>> } >>> >>> - /*package-protected*/ String getHttpMethodFromParameter(String method, >>> - String overrideParameter) { >>> + String getHttpMethodFromParameter(String method, String >>> overrideParameter) { >>> if (!StringUtils.isBlank(overrideParameter)) { >>> return overrideParameter; >>> } else { >>> @@ -159,11 +205,15 @@ >>> } >>> } >>> >>> - /*package-protected*/ String getRouteFromParameter(String pathInfo) { >>> + String getRouteFromParameter(String pathInfo) { >>> pathInfo = pathInfo.substring(1); >>> int indexOfNextPathSeparator = pathInfo.indexOf("/"); >>> return indexOfNextPathSeparator != -1 ? >>> pathInfo.substring(0, indexOfNextPathSeparator) : >>> pathInfo; >>> } >>> + >>> + boolean isBatchUrl(HttpServletRequest servletRequest) { >>> + return servletRequest.getPathInfo().endsWith(JSON_BATCH_ROUTE); >>> + } >>> } >>> >>> Modified: >>> >>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/RequestItem.java >>> URL: >>> >>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/RequestItem.java?rev=669268&r1=669267&r2=669268&view=diff >>> >>> >>> ============================================================================== >>> --- >>> >>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/RequestItem.java >>> (original) >>> +++ >>> >>> incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/dataservice/RequestItem.java >>> Wed Jun 18 12:39:54 2008 >>> @@ -34,6 +34,8 @@ >>> private Map<String, String> parameters; >>> private SecurityToken token; >>> >>> + public RequestItem() { } >>> + >>> public RequestItem(String url, Map<String, String> parameters, >>> SecurityToken token, >>> String method) { >>> this.url = url; >>> @@ -50,7 +52,7 @@ >>> Map<String, String> parameters = Maps.newHashMap(); >>> >>> Enumeration names = servletRequest.getParameterNames(); >>> - while(names.hasMoreElements()) { >>> + while (names.hasMoreElements()) { >>> String name = (String) names.nextElement(); >>> parameters.put(name, servletRequest.getParameter(name)); >>> } >>> @@ -58,6 +60,30 @@ >>> return parameters; >>> } >>> >>> + /* >>> + * Takes any url params out of the url and puts them into the param >>> map. >>> + * Usually the servlet request code does this for us but the batch >>> request calls have to do it >>> + * by hand. >>> + */ >>> + public void parseUrlParamsIntoParameters() { >>> + if (this.parameters == null) { >>> + this.parameters = Maps.newHashMap(); >>> + } >>> + >>> + String fullUrl = this.url; >>> + int queryParamIndex = fullUrl.indexOf("?"); >>> + >>> + if (queryParamIndex != -1) { >>> + this.url = fullUrl.substring(0, queryParamIndex); >>> + >>> + String queryParams = fullUrl.substring(queryParamIndex + 1); >>> + for (String param : queryParams.split("&")) { >>> + String[] paramPieces = param.split("=", 2); >>> + this.parameters.put(paramPieces[0], paramPieces.length == 2 ? >>> paramPieces[1] : ""); >>> + } >>> + } >>> + } >>> + >>> public String getUrl() { >>> return url; >>> } >>> >>> Modified: >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/DataServiceServletTest.java >>> URL: >>> >>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/DataServiceServletTest.java?rev=669268&r1=669267&r2=669268&view=diff >>> >>> >>> ============================================================================== >>> --- >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/DataServiceServletTest.java >>> (original) >>> +++ >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/DataServiceServletTest.java >>> Wed Jun 18 12:39:54 2008 >>> @@ -147,37 +147,24 @@ >>> } >>> >>> public void testInvalidRoute() throws Exception { >>> - req.setCharacterEncoding("UTF-8"); >>> - EasyMock.expect(req.getPathInfo()).andReturn("/ahhh!"); >>> - >>> - EasyMock.replay(req); >>> try { >>> - servlet.doPost(req, res); >>> + servlet.getResponseItem(null, new RequestItem("/ahhh!", null, >>> null, >>> null)); >>> fail("The route should not have found a valid handler."); >>> } catch (RuntimeException e) { >>> // Yea! >>> assertEquals("No handler for route: ahhh!", e.getMessage()); >>> } >>> - EasyMock.verify(req); >>> } >>> >>> public void testSecurityTokenException() throws Exception { >>> - req.setCharacterEncoding("UTF-8"); >>> - EasyMock.expect(req.getPathInfo()).andReturn("/" + >>> DataServiceServlet.APPDATA_ROUTE); >>> - EasyMock.expect(req.getMethod()).andReturn("POST"); >>> - >>> >>> EasyMock.expect(req.getParameter(DataServiceServlet.X_HTTP_METHOD_OVERRIDE)).andReturn("POST"); >>> - >>> >>> EasyMock.expect(req.getParameter(DataServiceServlet.FORMAT_PARAM)).andReturn(null); >>> - >>> String tokenString = "owner:viewer:app:container.com:foo:bar"; >>> >>> >>> EasyMock.expect(req.getParameter(DataServiceServlet.SECURITY_TOKEN_PARAM)) >>> .andReturn(tokenString); >>> EasyMock.expect(tokenDecoder.createToken(tokenString)).andThrow(new >>> SecurityTokenException("")); >>> >>> - setupInjector(); >>> - >>> - EasyMock.replay(req, tokenDecoder, injector); >>> + EasyMock.replay(req, tokenDecoder); >>> try { >>> - servlet.doPost(req, res); >>> + servlet.getSecurityToken(req); >>> fail("The route should have thrown an exception due to the invalid >>> security token."); >>> } catch (RuntimeException e) { >>> // Yea! >>> @@ -185,7 +172,7 @@ >>> // instead of just throwing an exception. >>> assertEquals("Implement error return for bad security token.", >>> e.getMessage()); >>> } >>> - EasyMock.verify(req, tokenDecoder, injector); >>> + EasyMock.verify(req, tokenDecoder); >>> } >>> >>> public void testGetHttpMethodFromParameter() throws Exception { >>> @@ -202,6 +189,20 @@ >>> assertEquals("path", servlet.getRouteFromParameter("/path/fun/yes")); >>> } >>> >>> + public void testIsBatchUrl() throws Exception { >>> + assertBatchUrl("/jsonBatch", true); >>> + assertBatchUrl("/path/to/the/jsonBatch", true); >>> + assertBatchUrl("/people/normalpath", false); >>> + } >>> + >>> + private void assertBatchUrl(String url, boolean isBatch) { >>> + EasyMock.expect(req.getPathInfo()).andReturn(url); >>> + EasyMock.replay(req); >>> + assertEquals(isBatch, servlet.isBatchUrl(req)); >>> + EasyMock.verify(req); >>> + EasyMock.reset(req); >>> + } >>> + >>> public void testGetConverterForRequest() throws Exception { >>> BeanJsonConverter json = new BeanJsonConverter(); >>> BeanXmlConverter xml = new BeanXmlConverter(); >>> >>> Added: >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/RequestItemTest.java >>> URL: >>> >>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/RequestItemTest.java?rev=669268&view=auto >>> >>> >>> ============================================================================== >>> --- >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/RequestItemTest.java >>> (added) >>> +++ >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/RequestItemTest.java >>> Wed Jun 18 12:39:54 2008 >>> @@ -0,0 +1,64 @@ >>> +/* >>> + * Licensed to the Apache Software Foundation (ASF) under one >>> + * or more contributor license agreements. See the NOTICE file >>> + * distributed with this work for additional information >>> + * regarding copyright ownership. The ASF licenses this file >>> + * to you under the Apache License, Version 2.0 (the >>> + * "License"); you may not use this file except in compliance >>> + * with the License. You may obtain a copy of the License at >>> + * >>> + * http://www.apache.org/licenses/LICENSE-2.0 >>> + * >>> + * Unless required by applicable law or agreed to in writing, >>> + * software distributed under the License is distributed on an >>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY >>> + * KIND, either express or implied. See the License for the >>> + * specific language governing permissions and limitations under the >>> License. >>> + */ >>> +package org.apache.shindig.social.dataservice; >>> + >>> +import org.apache.shindig.common.SecurityToken; >>> + >>> +import junit.framework.TestCase; >>> + >>> +import java.util.Map; >>> + >>> +import com.google.common.collect.Maps; >>> + >>> +public class RequestItemTest extends TestCase { >>> + >>> + public void testParseUrl() throws Exception { >>> + String path = "/people/john.doe/@self"; >>> + >>> + RequestItem request = new RequestItem(); >>> + request.setUrl(path + "?fields=huey,dewey,louie"); >>> + >>> + request.parseUrlParamsIntoParameters(); >>> + >>> + assertEquals(path, request.getUrl()); >>> + assertEquals("huey,dewey,louie", >>> request.getParameters().get("fields")); >>> + >>> + // Try it without any params >>> + request = new RequestItem(); >>> + request.setUrl(path); >>> + >>> + request.parseUrlParamsIntoParameters(); >>> + >>> + assertEquals(path, request.getUrl()); >>> + assertEquals(null, request.getParameters().get("fields")); >>> + } >>> + >>> + public void testBasicFunctions() throws Exception { >>> + String url = "url"; >>> + Map<String, String> params = Maps.newHashMap(); >>> + SecurityToken token = null; >>> + String method = "method"; >>> + RequestItem request = new RequestItem(url, params, token, method); >>> + >>> + assertEquals(url, request.getUrl()); >>> + assertEquals(params, request.getParameters()); >>> + assertEquals(token, request.getToken()); >>> + assertEquals(method, request.getMethod()); >>> + } >>> + >>> +} >>> \ No newline at end of file >>> >>> Added: >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulBatchTest.java >>> URL: >>> >>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulBatchTest.java?rev=669268&view=auto >>> >>> >>> ============================================================================== >>> --- >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulBatchTest.java >>> (added) >>> +++ >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulBatchTest.java >>> Wed Jun 18 12:39:54 2008 >>> @@ -0,0 +1,93 @@ >>> +/* >>> + * Licensed to the Apache Software Foundation (ASF) under one or more >>> + * contributor license agreements. The ASF licenses this file to You >>> + * under the Apache License, Version 2.0 (the "License"); you may not >>> + * use this file except in compliance with the License. >>> + * You may obtain a copy of the License at >>> + * >>> + * http://www.apache.org/licenses/LICENSE-2.0 >>> + * >>> + * Unless required by applicable law or agreed to in writing, software >>> + * distributed under the License is distributed on an "AS IS" BASIS, >>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >>> implied. >>> + * See the License for the specific language governing permissions and >>> + * limitations under the License. For additional information regarding >>> + * copyright in this work, please see the NOTICE file in the top level >>> + * directory of this distribution. >>> + */ >>> +package org.apache.shindig.social.dataservice.integration; >>> + >>> +import com.google.common.collect.Maps; >>> +import org.json.JSONObject; >>> +import org.junit.Test; >>> + >>> +import java.util.Map; >>> + >>> +public class RestfulBatchTest extends AbstractLargeRestfulTests { >>> + >>> + /** >>> + * Batch format: >>> + * POST to /jsonBatch >>> + * {request : >>> + * {friends : {url : /people/john.doe/@friends, method : GET}} >>> + * {john : {url : /people/john.doe/@self, method : GET}} >>> + * {updateData : {url : /appdata/john.doe/@self/appId, method : >>> POST, postData : {count : 1}}} >>> + * } >>> + * >>> + * >>> + * Expected response >>> + * >>> + * {error : false, >>> + * responses : { >>> + * {friends : {response : {<friend collection>}}} >>> + * {john : {response : {<john.doe>}}} >>> + * {updateData : {response : {}}} >>> + * } >>> + * >>> + * Each response can possibly have .error and .errorMessage properties >>> as well. >>> + * >>> + * @throws Exception if test encounters an error >>> + */ >>> + @Test >>> + public void testGetBatchRequest() throws Exception { >>> + Map<String, String> extraParams = Maps.newHashMap(); >>> + extraParams.put("request", "{" >>> + + "friends : {url : '/people/john.doe/@friends', method : >>> 'GET'}, >>> " >>> + + "john : {url : '/people/john.doe/@self', method : 'GET'}, " >>> + + "updateData : {url : '/appdata/john.doe/@self/a', method : >>> 'POST', parameters : {entry : {count : 1}}}" >>> + + "}"); >>> + >>> + String resp = getJsonResponse("jsonBatch", "POST", extraParams); >>> + JSONObject result = getJson(resp); >>> + >>> + assertEquals(false, result.getBoolean("error")); >>> + >>> + JSONObject jsonResponses = result.getJSONObject("responses"); >>> + assertEquals(3, jsonResponses.length()); >>> + >>> + // friends response >>> + JSONObject jsonFriends = jsonResponses.getJSONObject("friends"); >>> + assertFalse(jsonFriends.has("error")); >>> + assertFalse(jsonFriends.has("errorMessage")); >>> + >>> + JSONObject jsonFriendsResponse = >>> jsonFriends.getJSONObject("response"); >>> + assertEquals(2, jsonFriendsResponse.getInt("totalResults")); >>> + assertEquals(0, jsonFriendsResponse.getInt("startIndex")); >>> + >>> + // john.doe response >>> + JSONObject jsonJohn = jsonResponses.getJSONObject("john"); >>> + assertFalse(jsonJohn.has("error")); >>> + assertFalse(jsonJohn.has("errorMessage")); >>> + >>> + JSONObject jsonJohnResponse = jsonJohn.getJSONObject("response"); >>> + assertEquals("john.doe", jsonJohnResponse.getString("id")); >>> + assertEquals("John Doe", >>> jsonJohnResponse.getJSONObject("name").getString("unstructured")); >>> + >>> + // john.doe response >>> + JSONObject jsonData = jsonResponses.getJSONObject("updateData"); >>> + assertFalse(jsonData.has("error")); >>> + assertFalse(jsonData.has("errorMessage")); >>> + assertTrue(jsonData.has("response")); >>> + } >>> + >>> +} >>> \ No newline at end of file >>> >>> Modified: >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulJsonPeopleTest.java >>> URL: >>> >>> http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulJsonPeopleTest.java?rev=669268&r1=669267&r2=669268&view=diff >>> >>> >>> ============================================================================== >>> --- >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulJsonPeopleTest.java >>> (original) >>> +++ >>> >>> incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulJsonPeopleTest.java >>> Wed Jun 18 12:39:54 2008 >>> @@ -29,7 +29,6 @@ >>> import org.apache.shindig.social.opensocial.model.Url; >>> >>> import com.google.common.collect.Maps; >>> -import org.easymock.classextension.EasyMock; >>> import org.json.JSONArray; >>> import org.json.JSONException; >>> import org.json.JSONObject; >>> >>> >>> >>> >

