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;
>>>
>>>
>>>
>>>
>

Reply via email to