Author: johnh
Date: Tue Jul 20 23:07:55 2010
New Revision: 966049

URL: http://svn.apache.org/viewvc?rev=966049&view=rev
Log:
Update common container JSON-RPC endpoint for security token refresh.

Includes a bit of refactoring, and several new tests.

Patch provided by Michael Hermanto.


Modified:
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java
    
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java

Modified: 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java?rev=966049&r1=966048&r2=966049&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java
 Tue Jul 20 23:07:55 2010
@@ -18,17 +18,18 @@
  */
 package org.apache.shindig.gadgets.servlet;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
 import com.google.inject.Inject;
+
 import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.auth.SecurityTokenDecoder;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.gadgets.Gadget;
 import org.apache.shindig.gadgets.GadgetContext;
 import org.apache.shindig.gadgets.RenderingContext;
-import org.apache.shindig.gadgets.UserPrefs;
 import org.apache.shindig.gadgets.process.Processor;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
 import org.apache.shindig.gadgets.spec.ModulePrefs;
@@ -41,8 +42,6 @@ import org.apache.shindig.protocol.Proto
 import org.apache.shindig.protocol.RequestItem;
 import org.apache.shindig.protocol.Service;
 
-import javax.servlet.http.HttpServletResponse;
-import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
@@ -52,127 +51,194 @@ import java.util.concurrent.ExecutionExc
 import java.util.concurrent.ExecutorCompletionService;
 import java.util.concurrent.ExecutorService;
 
+import javax.servlet.http.HttpServletResponse;
+
 @Service(name = "gadgets")
 public class GadgetsHandler {
-  Set<String> ALL_METADATA_FIELDS = ImmutableSet.of("iframeUrl", "userPrefs", 
"modulePrefs", "views", "views.name", "views.type",
-      "views.type", "views.href", "views.quirks", "views.content", 
"views.preferredHeight", "views.preferredWidth",
+  @VisibleForTesting
+  static final String FAILURE_METADATA = "Failed to get gadget metadata.";
+  @VisibleForTesting
+  static final String FAILURE_TOKEN = "Failed to get gadget token.";
+
+  private static final Set<String> ALL_METADATA_FIELDS = ImmutableSet.of(
+      "iframeUrl", "userPrefs", "modulePrefs", "views", "views.name", 
"views.type",
+      "views.type", "views.href", "views.quirks", "views.content",
+      "views.preferredHeight", "views.preferredWidth",
       "views.needsUserPrefsSubstituted", "views.attributes");
-  Set<String> DEFAULT_METADATA_FIELDS = ImmutableSet.of("iframeUrl", 
"userPrefs", "modulePrefs", "views");
+  private static final Set<String> DEFAULT_METADATA_FIELDS = ImmutableSet.of(
+      "iframeUrl", "userPrefs", "modulePrefs", "views");
 
   protected final ExecutorService executor;
   protected final Processor processor;
   protected final IframeUriManager iframeUriManager;
+  protected final SecurityTokenDecoder securityTokenDecoder;
 
   @Inject
-  public GadgetsHandler(ExecutorService executor, Processor processor, 
IframeUriManager iframeUriManager) {
+  public GadgetsHandler(
+      ExecutorService executor,
+      Processor processor,
+      IframeUriManager iframeUriManager,
+      SecurityTokenDecoder securityTokenDecoder) {
     this.executor = executor;
     this.processor = processor;
     this.iframeUriManager = iframeUriManager;
+    this.securityTokenDecoder = securityTokenDecoder;
   }
 
-  @Operation(httpMethods = {"POST","GET"}, path = "/metadata/{view}")
-  public Map<String,MetadataGadgetSpec> metadata(BaseRequestItem request) 
throws ProtocolException {
-    Set<String> gadgetUrls = 
ImmutableSet.copyOf(request.getListParameter("ids"));
-
-    if (gadgetUrls.isEmpty())
-      return ImmutableMap.of();
+  @Operation(httpMethods = {"POST", "GET"}, path = "metadata.get")
+  public Map<String, MetadataResponse> metadata(BaseRequestItem request)
+      throws ProtocolException {
+    return new AbstractExecutor<MetadataResponse>() {
+      @Override
+      protected Callable<MetadataResponse> createJob(String url, 
BaseRequestItem request) {
+        return createMetadataJob(url, request);
+      }
+    }.execute(request);
+  }
 
-    Set<String> fields = request.getFields(DEFAULT_METADATA_FIELDS);
+  @Operation(httpMethods = {"POST", "GET"}, path = "token.get")
+  public Map<String, TokenResponse> token(BaseRequestItem request)
+      throws ProtocolException {
+    return new AbstractExecutor<TokenResponse>() {
+      @Override
+      protected Callable<TokenResponse> createJob(String url, BaseRequestItem 
request) {
+        return createTokenJob(url, request);
+      }
+    }.execute(request);
+  }
 
-    CompletionService<MetadataGadgetSpec> completionService =  new 
ExecutorCompletionService<MetadataGadgetSpec>(executor);
+  @Operation(httpMethods = "GET", path="/@metadata.supportedFields")
+  public Set<String> supportedFields(RequestItem request) {
+    return ALL_METADATA_FIELDS;
+  }
 
-    for (String gadgetUri : gadgetUrls) {
-      completionService.submit(createNewJob(new 
MetadataGadgetContext(gadgetUri,request), fields));
-    }
+  private abstract class AbstractExecutor<R extends BaseResponse> {
+    @SuppressWarnings("unchecked")
+    public Map<String, R> execute(BaseRequestItem request) {
+      Set<String> gadgetUrls = 
ImmutableSet.copyOf(request.getListParameter("ids"));
+      if (gadgetUrls.isEmpty()) {
+        return ImmutableMap.of();
+      }
 
-    int numJobs = gadgetUrls.size();
-    Map<String,MetadataGadgetSpec> response = Maps.newHashMap();
+      CompletionService<R> completionService = new 
ExecutorCompletionService<R>(executor);
+      for (String gadgetUrl : gadgetUrls) {
+        Callable<R> job = createJob(gadgetUrl, request);
+        completionService.submit(job);
+      }
 
-    while (numJobs > 0) {
-      try {
-        MetadataGadgetSpec spec = completionService.take().get();
-        response.put(spec.getUrl(), spec);
-      } catch (InterruptedException e) {
-        throw new 
ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Processing 
interrupted", e);
-      } catch (ExecutionException ee) {
-        if (!(ee.getCause() instanceof RpcException)) {
-          throw new 
ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Processing 
error", ee);
-        }
-        RpcException e = (RpcException)ee.getCause();
-        // Just one gadget failed; mark it as such.
-        GadgetContext context = e.getContext();
-        if (context != null) {
-          response.put(context.getUrl().toString(), new 
MetadataGadgetSpec().setError(e.getCause().getLocalizedMessage()));
+      ImmutableMap.Builder<String, R> builder = ImmutableMap.builder();
+      for (int numJobs = gadgetUrls.size(); numJobs > 0; numJobs--) {
+        R response;
+        try {
+          response = completionService.take().get();
+          builder.put(response.getUrl(), response);
+        } catch (InterruptedException e) {
+          throw new ProtocolException(
+              HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+              "Processing interrupted.", e);
+        } catch (ExecutionException e) {
+          if (!(e.getCause() instanceof RpcException)) {
+            throw new ProtocolException(
+                HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                "Processing error.", e);
+          }
+          RpcException cause = (RpcException) e.getCause();
+          GadgetContext context = cause.getContext();
+          if (context != null) {
+            String url = context.getUrl().toString();
+            R errorResponse = (R) new BaseResponse(url, cause.getMessage());
+            builder.put(url, errorResponse);
+          }
         }
-      } finally {
-        numJobs--;
       }
+      return builder.build();
     }
-    return response;
-  }
 
-  @Operation(httpMethods = "GET", path="/@supportedFields")
-  public Set<String> supportedFields(RequestItem request) {
-    return ALL_METADATA_FIELDS;
+    protected abstract Callable<R> createJob(String url, BaseRequestItem 
request);
   }
 
-  protected MetadataJob createNewJob(GadgetContext context, Set<String> 
fields) {
-    return new MetadataJob(context, fields);
+  // Hook to override in sub-class.
+  protected Callable<MetadataResponse> createMetadataJob(String url, 
BaseRequestItem request) {
+    final GadgetContext context = new MetadataGadgetContext(url, request);
+    final Set<String> fields = request.getFields(DEFAULT_METADATA_FIELDS);
+    return new Callable<MetadataResponse>() {
+      public MetadataResponse call() throws Exception {
+        try {
+          Gadget gadget = processor.process(context);
+          String iframeUrl = fields.contains("iframeUrl")
+              ? iframeUriManager.makeRenderingUri(gadget).toString() : null;
+          return new MetadataResponse(context.getUrl().toString(), 
gadget.getSpec(),
+              iframeUrl, fields);
+        } catch (Exception e) {
+          // Note: this error message is publicly visible in JSON-RPC response.
+          throw new RpcException(context, FAILURE_METADATA, e);
+        }
+      }
+    };
   }
 
-  protected class MetadataJob implements Callable<MetadataGadgetSpec> {
-    protected final GadgetContext context;
-    protected final Set<String> fields;
-
-    public MetadataJob(GadgetContext context, Set<String> fields) {
-      this.context = context;
-      this.fields = fields;
-    }
-
-    public MetadataGadgetSpec call() throws RpcException {
-      try {
-        Gadget gadget = processor.process(context);
-        String iframeUrl =  fields.contains("iframeUrl") ? 
iframeUriManager.makeRenderingUri(gadget).toString() : null;
-
-        FilteringGadgetSpec spec = new FilteringGadgetSpec(gadget.getSpec(), 
iframeUrl, fields);
-        spec.setUrl(context.getUrl().toString());
-        return spec;
-      } catch (Exception e) {
-        throw new RpcException(context, e);
+  // Hook to override in sub-class.
+  protected Callable<TokenResponse> createTokenJob(String url, BaseRequestItem 
request) {
+    final TokenGadgetContext context = new TokenGadgetContext(url, request);
+    return new Callable<TokenResponse>() {
+      public TokenResponse call() throws Exception {
+        try {
+          String token = securityTokenDecoder.encodeToken(context.getToken());
+          return new TokenResponse(context.getUrl().toString(), token);
+        } catch (Exception e) {
+          // Note: this error message is publicly visible in JSON-RPC response.
+          throw new RpcException(context, FAILURE_TOKEN, e);
+        }
       }
-    }
+    };
   }
 
   /**
-   * Localized implementation of GadgetContext that uses information from the 
request.
+   * Gadget context classes used to translate JSON BaseRequestItem into a
+   * more meaningful model objects that Java can work with.
    */
-  private static class MetadataGadgetContext extends GadgetContext {
-    final BaseRequestItem request;
-    final Uri uri;
-    final Locale locale;
-    final boolean ignoreCache;
-    final boolean debug;
-    final String container;
 
-    public MetadataGadgetContext(String uri, BaseRequestItem request) {
+  private abstract class AbstractGadgetContext extends GadgetContext {
+    protected final Uri uri;
+    protected final String container;
+    protected final BaseRequestItem request;
+
+    public AbstractGadgetContext(String url, BaseRequestItem request) {
+      this.uri = Uri.parse(Preconditions.checkNotNull(url));
       this.request = Preconditions.checkNotNull(request);
-      this.uri = Uri.parse(Preconditions.checkNotNull(uri));
+      this.container = 
Preconditions.checkNotNull(request.getParameter("container"));
+    }
 
+    @Override
+    public Uri getUrl() {
+      return uri;
+    }
+
+    @Override
+    public String getContainer() {
+      return container;
+    }
+
+    @Override
+    public RenderingContext getRenderingContext() {
+      return RenderingContext.METADATA;
+    }
+  }
+
+  protected class MetadataGadgetContext extends AbstractGadgetContext {
+    protected final Locale locale;
+    protected final boolean ignoreCache;
+    protected final boolean debug;
+
+    public MetadataGadgetContext(String url, BaseRequestItem request) {
+      super(url, request);
       String lang = request.getParameter("language");
       String country = request.getParameter("country");
-
       this.locale = (lang != null && country != null) ? new 
Locale(lang,country) :
                     (lang != null) ? new Locale(lang) :
                     GadgetSpec.DEFAULT_LOCALE;
-
       this.ignoreCache = Boolean.valueOf(request.getParameter("ignoreCache"));
       this.debug = Boolean.valueOf(request.getParameter("debug"));
-      this.container = request.getToken().getContainer();
-    }
-
-    @Override
-    public Uri getUrl() {
-      return uri;
     }
 
     @Override
@@ -186,21 +252,11 @@ public class GadgetsHandler {
     }
 
     @Override
-    public RenderingContext getRenderingContext() {
-      return RenderingContext.METADATA;
-    }
-
-    @Override
     public boolean getIgnoreCache() {
       return ignoreCache;
     }
 
     @Override
-    public String getContainer() {
-      return container;
-    }
-
-    @Override
     public boolean getDebug() {
       return debug;
     }
@@ -211,9 +267,14 @@ public class GadgetsHandler {
     }
 
     @Override
-    public UserPrefs getUserPrefs() {
-            // TODO
-      return new UserPrefs(Maps.<String,String>newHashMap());
+    public SecurityToken getToken() {
+      return request.getToken();
+    }
+  }
+
+  protected class TokenGadgetContext extends AbstractGadgetContext {
+    public TokenGadgetContext(String url, BaseRequestItem request) {
+      super(url, request);
     }
 
     @Override
@@ -222,9 +283,87 @@ public class GadgetsHandler {
     }
   }
 
+  /**
+   * Response classes to represent data structure returned in JSON to common
+   * container JS. They must be public for reflection to work.
+   */
 
-  // has to be public for reflection to work.
-  public static final class FilteringView {
+  public static class BaseResponse {
+    private final String url;
+    private final String error;
+
+    // Call this to indicate an error.
+    public BaseResponse(String url, String error) {
+      this.url = url;
+      this.error = error;
+    }
+
+    // Have sub-class call this to indicate a success response.
+    protected BaseResponse(String url) {
+      this(url, null);
+    }
+
+    public String getUrl() {
+      return url;
+    }
+
+    public String getError() {
+      return error;
+    }
+  }
+
+  public static class MetadataResponse extends BaseResponse {
+    private final GadgetSpec spec;
+    private final String iframeUrl;
+    private final Map<String, ViewResponse> views;
+    private final Set<String> fields;
+
+    public MetadataResponse(String url, GadgetSpec spec, String iframeUrl, 
Set<String> fields) {
+      super(url);
+      this.spec = spec;
+      this.iframeUrl = iframeUrl;
+      this.fields = fields;
+
+      // Do we need view data?
+      boolean viewsRequested = fields.contains("views");
+      for (String f: fields) {
+        if (f.startsWith("views")) {
+          viewsRequested = true;
+        }
+      }
+      if (viewsRequested) {
+        ImmutableMap.Builder<String, ViewResponse> builder = 
ImmutableMap.builder();
+        for (Map.Entry<String,View> entry : spec.getViews().entrySet()) {
+          builder.put(entry.getKey(), new ViewResponse(entry.getValue(), 
fields));
+        }
+        views = builder.build();
+      } else {
+        views = null;
+      }
+    }
+
+    public String getIframeUrl() {
+      return fields.contains("iframeUrl") ? iframeUrl : null;
+    }
+
+    public String getChecksum() {
+      return fields.contains("checksum") ? spec.getChecksum() : null;
+    }
+
+    public ModulePrefs getModulePrefs() {
+      return fields.contains("modulePrefs") ? spec.getModulePrefs() : null;
+    }
+
+    public Map<String, UserPref> getUserPrefs() {
+      return fields.contains("userPrefs") ? spec.getUserPrefs() : null;
+    }
+
+    public Map<String, ViewResponse> getViews() {
+      return views;
+    }
+  }
+
+  public static class ViewResponse {
     private final View view;
     private final Set<String> fields;
 
@@ -239,7 +378,7 @@ public class GadgetsHandler {
       return (fields.contains("views") || fields.contains(param)) ? item : 
null;
     }
 
-    public FilteringView(View view, Set<String> fields) {
+    public ViewResponse(View view, Set<String> fields) {
       this.view = view;
       this.fields = fields;
     }
@@ -281,75 +420,17 @@ public class GadgetsHandler {
     }
   }
 
-  // has to be public for reflection to work..
-  public static class MetadataGadgetSpec {
-    private String msg = null;
-    private String url = null;
-
-    public MetadataGadgetSpec setError(String msg) {
-      this.msg = msg;
-      return this;
-    }
-    public MetadataGadgetSpec setUrl(String url) {
-      this.url = url;
-      return this;
-    }
-    public String getError() {
-      return msg;  
-    }
-    public String getUrl() {
-      return url;
-    }
-  }
-  
-  // has to be public for reflection to work.
-  public static final class FilteringGadgetSpec extends MetadataGadgetSpec {
-    private final GadgetSpec spec;
-    private final String iframeUrl;
-    private final Map<String,FilteringView> views;
-    private final Set<String> fields;
-
-    public FilteringGadgetSpec(GadgetSpec spec, String iframeUrl, Set<String> 
fields) {
-      this.spec = Preconditions.checkNotNull(spec);
-      this.iframeUrl = iframeUrl; // can be null
-      this.fields = Preconditions.checkNotNull(fields);
-
-      // Do we need view data?
-      boolean viewsRequested = fields.contains("views");
-      for (String f: fields) {
-        if (f.startsWith("views")) {
-          viewsRequested = true;
-        }
-      }
-      if (viewsRequested) {
-        ImmutableMap.Builder<String,FilteringView> builder = 
ImmutableMap.builder();
-        for (Map.Entry<String,View> entry : spec.getViews().entrySet()) {
-          builder.put(entry.getKey(), new FilteringView(entry.getValue(), 
fields));
-        }
-        views = builder.build();
-      } else {
-        views = null;
-      }
-    }
-
-    public String getIframeUrl() {
-      return fields.contains("iframeUrl") ? iframeUrl : null;
-    }
+  public static class TokenResponse extends BaseResponse {
+    private final String token;
 
-    public String getChecksum() {
-      return fields.contains("checksum") ? spec.getChecksum() : null;
-    }
-
-    public ModulePrefs getModulePrefs() {
-      return fields.contains("modulePrefs") ? spec.getModulePrefs() : null;
+    public TokenResponse(String url, String token) {
+      super(url);
+      this.token = token;
     }
 
-    public Map<String,UserPref> getUserPrefs() {
-      return fields.contains("userPrefs") ? spec.getUserPrefs() : null;
-    }
-
-    public Map<String, FilteringView> getViews() {
-      return views;
+    public String getToken() {
+      return token;
     }
   }
+
 }
\ No newline at end of file

Modified: 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java?rev=966049&r1=966048&r2=966049&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java
 Tue Jul 20 23:07:55 2010
@@ -1,36 +1,33 @@
 /*
- * 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
+ * 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
+ * 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.
+ * 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.gadgets.servlet;
 
-import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
+
+import org.apache.shindig.auth.SecurityTokenDecoder;
+import org.apache.shindig.auth.SecurityTokenException;
 import org.apache.shindig.common.EasyMockTestCase;
 import org.apache.shindig.common.JsonAssert;
 import org.apache.shindig.common.testing.FakeGadgetToken;
 import org.apache.shindig.common.testing.TestExecutorService;
-import org.apache.shindig.common.uri.Uri;
-import org.apache.shindig.gadgets.http.HttpRequest;
-import org.apache.shindig.gadgets.http.RequestPipeline;
 import org.apache.shindig.gadgets.process.ProcessingException;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
 import org.apache.shindig.protocol.DefaultHandlerRegistry;
@@ -46,98 +43,111 @@ import org.json.JSONObject;
 import org.junit.Before;
 import org.junit.Test;
 
-import javax.servlet.http.HttpServletResponse;
-import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executors;
 
-import static org.easymock.EasyMock.expect;
+import javax.servlet.http.HttpServletResponse;
 
 public class GadgetsHandlerTest extends EasyMockTestCase {
-  private final RequestPipeline pipeline = mock(RequestPipeline.class);
+  private static final String GADGET1_URL = FakeProcessor.SPEC_URL.toString();
+  private static final String GADGET2_URL = FakeProcessor.SPEC_URL2 
.toString();
+  private static final String CONTAINER = "container";
+  private static final String TOKEN = "_nekot_";
+
   private final FakeProcessor processor = new FakeProcessor();
   private final FakeIframeUriManager urlGenerator = new FakeIframeUriManager();
-  private final Map<String,FormDataItem> emptyFormItems = 
Collections.emptyMap();
+  private final Map<String, FormDataItem> emptyFormItems = 
Collections.emptyMap();
 
+  private Injector injector;
   private BeanJsonConverter converter;
   private HandlerRegistry registry;
   private FakeGadgetToken token;
 
-
   @Before
   public void setUp() throws Exception {
-    Injector injector = Guice.createInjector();
+    injector = Guice.createInjector();
     converter = new BeanJsonConverter(injector);
-
-    GadgetsHandler gadgetsHandler = new GadgetsHandler(new 
TestExecutorService(),
-        processor,
-        urlGenerator);
-
-    registry = new DefaultHandlerRegistry(injector, converter,
-        new HandlerExecutionListener.NoOpHandler());
-    registry.addHandlers(ImmutableSet.<Object>of(gadgetsHandler));
-
     token = new FakeGadgetToken();
     token.setAppUrl("http://www.example.com/gadget.xml";);
-
   }
 
-  private JSONObject createContext(String lang, String country)
-      throws JSONException {
-    return new JSONObject().put("language", lang).put("country", country);
+  private void registerGadgetsHandler(SecurityTokenDecoder decoder) {
+    GadgetsHandler handler =
+        new GadgetsHandler(new TestExecutorService(), processor, urlGenerator, 
decoder);
+    registry = new DefaultHandlerRegistry(
+        injector, converter, new HandlerExecutionListener.NoOpHandler());
+    registry.addHandlers(ImmutableSet.<Object> of(handler));
   }
 
-  private JSONObject makeMetadataRequest(String lang, String country, 
Collection<String> uris) throws JSONException {
-    JSONObject req = new JSONObject()
-        .put("method", "gadgets.metadata")
-        .put("id", "req1")
-        .put("params", new JSONObject().put("ids", uris));
-
+  private JSONObject makeMetadataRequest(String lang, String country, 
String... uris)
+      throws JSONException {
+    JSONObject req =
+        new JSONObject().put("method", "gadgets.metadata").put("id", 
"req1").put("params",
+            new JSONObject().put("ids", 
ImmutableList.of(uris)).put("container", CONTAINER));
     if (lang != null) req.put("language", lang);
     if (country != null) req.put("country", country);
     return req;
   }
-  
+
+  private JSONObject makeTokenRequest(String... uris) throws JSONException {
+    JSONObject req =
+        new JSONObject().put("method", "gadgets.token").put("id", 
"req1").put("params",
+            new JSONObject().put("ids", 
ImmutableList.of(uris)).put("container", CONTAINER));
+    return req;
+  }
+
   @Test
   public void testMetadataEmptyRequest() throws Exception {
-    JSONObject emptyrequest = makeMetadataRequest(null, null, 
Collections.<String>emptyList());
-
-    RpcHandler operation = registry.getRpcHandler(emptyrequest);
+    registerGadgetsHandler(null);
+    JSONObject request = makeMetadataRequest(null, null);
+    RpcHandler operation = registry.getRpcHandler(request);
+    Object empty = operation.execute(emptyFormItems, token, converter).get();
+    JsonAssert.assertJsonEquals("{}", converter.convertToString(empty));
+  }
 
+  @Test
+  public void testTokenEmptyRequest() throws Exception {
+    registerGadgetsHandler(null);
+    JSONObject request = makeTokenRequest();
+    RpcHandler operation = registry.getRpcHandler(request);
     Object empty = operation.execute(emptyFormItems, token, converter).get();
     JsonAssert.assertJsonEquals("{}", converter.convertToString(empty));
   }
 
-  @Test(expected=ExecutionException.class)
+  @Test(expected = ExecutionException.class)
   public void testMetadataInvalidUrl() throws Exception {
-    JSONObject invalidRequest = makeMetadataRequest(null, null, 
ImmutableList.of("[moo]"));
-
-    RpcHandler operation = registry.getRpcHandler(invalidRequest);
+    registerGadgetsHandler(null);
+    JSONObject request = makeMetadataRequest(null, null, "[moo]");
+    RpcHandler operation = registry.getRpcHandler(request);
+    Object empty = operation.execute(emptyFormItems, token, converter).get();
+  }
 
+  @Test(expected = ExecutionException.class)
+  public void testTokenInvalidUrl() throws Exception {
+    registerGadgetsHandler(null);
+    JSONObject request = makeTokenRequest("[moo]");
+    RpcHandler operation = registry.getRpcHandler(request);
     Object empty = operation.execute(emptyFormItems, token, converter).get();
   }
 
   @Test
   public void testMetadataOneGadget() throws Exception {
-    JSONObject oneGadget = makeMetadataRequest(null, null, 
ImmutableList.of(FakeProcessor.SPEC_URL.toString()));
-
-    RpcHandler operation = registry.getRpcHandler(oneGadget);
-
+    registerGadgetsHandler(null);
+    JSONObject request = makeMetadataRequest(null, null, GADGET1_URL);
+    RpcHandler operation = registry.getRpcHandler(request);
     Object responseObj = operation.execute(emptyFormItems, token, 
converter).get();
     JSONObject response = new 
JSONObject(converter.convertToString(responseObj));
 
-    JSONObject gadget = 
response.getJSONObject(FakeProcessor.SPEC_URL.toString());
+    JSONObject gadget = response.getJSONObject(GADGET1_URL);
     assertEquals(FakeIframeUriManager.DEFAULT_IFRAME_URI.toString(), 
gadget.getString("iframeUrl"));
     assertEquals(FakeProcessor.SPEC_TITLE, 
gadget.getJSONObject("modulePrefs").getString("title"));
 
     JSONObject view = 
gadget.getJSONObject("views").getJSONObject(GadgetSpec.DEFAULT_VIEW);
     assertEquals(FakeProcessor.PREFERRED_HEIGHT, 
view.getInt("preferredHeight"));
     assertEquals(FakeProcessor.PREFERRED_WIDTH, view.getInt("preferredWidth"));
-    assertEquals(FakeProcessor.LINK_HREF, 
gadget.getJSONObject("modulePrefs").getJSONObject("links")
-        .getJSONObject(FakeProcessor.LINK_REL).getString("href"));
+    assertEquals(FakeProcessor.LINK_HREF, gadget.getJSONObject("modulePrefs")
+        
.getJSONObject("links").getJSONObject(FakeProcessor.LINK_REL).getString("href"));
 
     JSONObject userPrefs = gadget.getJSONObject("userPrefs");
     assertNotNull(userPrefs);
@@ -162,63 +172,105 @@ public class GadgetsHandlerTest extends 
   }
 
   @Test
-  public void testMetadataUnexpectedError() throws Exception {
-    JSONObject oneGadget = makeMetadataRequest(null, null, 
ImmutableList.of(FakeProcessor.SPEC_URL.toString()));
+  public void testTokenOneGadget() throws Exception {
+    SecurityTokenDecoder decoder = 
EasyMock.createMock(SecurityTokenDecoder.class);
+    EasyMock.expect(decoder.encodeToken(token)).andReturn(TOKEN);
+    replay(decoder);
+
+    registerGadgetsHandler(decoder);
+    JSONObject request = makeTokenRequest(GADGET1_URL);
+    RpcHandler operation = registry.getRpcHandler(request);
+    Object responseObj = operation.execute(emptyFormItems, token, 
converter).get();
+    JSONObject response = new 
JSONObject(converter.convertToString(responseObj));
 
-    urlGenerator.throwRandomFault = true;
+    JSONObject gadget = response.getJSONObject(GADGET1_URL);
+    assertEquals(TOKEN, gadget.getString("token"));
+    assertFalse(gadget.has("error"));
+  }
 
-    RpcHandler operation = registry.getRpcHandler(oneGadget);
+  @Test
+  public void testMetadataOneGadgetFailure() throws Exception {
+    registerGadgetsHandler(null);
+    JSONObject request = makeMetadataRequest(null, null, GADGET1_URL);
+    urlGenerator.throwRandomFault = true;
+    RpcHandler operation = registry.getRpcHandler(request);
     Object responseObj = operation.execute(emptyFormItems, token, 
converter).get();
     JSONObject response = new 
JSONObject(converter.convertToString(responseObj));
 
-    String actual = 
response.getJSONObject(FakeProcessor.SPEC_URL.toString()).getString("error");
-    assertEquals("BROKEN", actual);
+    JSONObject gadget = response.getJSONObject(GADGET1_URL);
+    assertEquals(GadgetsHandler.FAILURE_METADATA, gadget.getString("error"));
   }
 
   @Test
-  public void testMultipleGadgets() throws Exception {
-    JSONObject metadataRequest = makeMetadataRequest("en", "US",
-        ImmutableList.of(FakeProcessor.SPEC_URL.toString(),
-                         FakeProcessor.SPEC_URL2.toString()));
-
-    RpcHandler operation = registry.getRpcHandler(metadataRequest);
+  public void testTokenOneGadgetFailure() throws Exception {
+    SecurityTokenDecoder decoder = 
EasyMock.createMock(SecurityTokenDecoder.class);
+    EasyMock.expect(decoder.encodeToken(token)).andThrow(new 
SecurityTokenException("blah"));
+    replay(decoder);
+
+    registerGadgetsHandler(decoder);
+    JSONObject request = makeTokenRequest(GADGET1_URL);
+    RpcHandler operation = registry.getRpcHandler(request);
     Object responseObj = operation.execute(emptyFormItems, token, 
converter).get();
     JSONObject response = new 
JSONObject(converter.convertToString(responseObj));
 
-    JSONObject gadget;
+    JSONObject gadget = response.getJSONObject(GADGET1_URL);
+    assertFalse(gadget.has("token"));
+    assertEquals(GadgetsHandler.FAILURE_TOKEN, gadget.getString("error"));
+  }
+
+  @Test
+  public void testMetadataMultipleGadgets() throws Exception {
+    registerGadgetsHandler(null);
+    JSONObject request = makeMetadataRequest("en", "US", GADGET1_URL, 
GADGET2_URL);
+    RpcHandler operation = registry.getRpcHandler(request);
+    Object responseObj = operation.execute(emptyFormItems, token, 
converter).get();
+    JSONObject response = new 
JSONObject(converter.convertToString(responseObj));
 
-    // First gadget..
-    gadget = response.getJSONObject(FakeProcessor.SPEC_URL.toString());
-    assertNotNull("got gadget1", gadget);
-    assertEquals(FakeProcessor.SPEC_TITLE, 
gadget.getJSONObject("modulePrefs").getString("title"));
+    JSONObject modulePrefs1 = 
response.getJSONObject(GADGET1_URL).getJSONObject("modulePrefs");
+    assertEquals(FakeProcessor.SPEC_TITLE, modulePrefs1.getString("title"));
 
-    gadget = response.getJSONObject(FakeProcessor.SPEC_URL2.toString());
-    assertNotNull("got gadget2", gadget);
-    assertEquals(FakeProcessor.SPEC_TITLE2, 
gadget.getJSONObject("modulePrefs").getString("title"));
+    JSONObject modulePrefs2 = 
response.getJSONObject(GADGET2_URL).getJSONObject("modulePrefs");
+    assertEquals(FakeProcessor.SPEC_TITLE2, modulePrefs2.getString("title"));
   }
 
   @Test
-  public void testMultipleGadgetsWithAnError() throws Exception {
-    JSONObject metadataRequest = makeMetadataRequest("en", "US",
-        ImmutableList.of(FakeProcessor.SPEC_URL.toString(),
-                         FakeProcessor.SPEC_URL2.toString()));
+  public void testTokenMultipleGadgetsWithSuccessAndFailure() throws Exception 
{
+    SecurityTokenDecoder decoder = 
EasyMock.createMock(SecurityTokenDecoder.class);
+    EasyMock.expect(decoder.encodeToken(token)).andReturn(TOKEN);
+    EasyMock.expect(decoder.encodeToken(token)).andThrow(new 
SecurityTokenException("blah"));
+    replay(decoder);
 
-    processor.exceptions.put(FakeProcessor.SPEC_URL2,
-        new ProcessingException("broken", HttpServletResponse.SC_BAD_REQUEST));
+    registerGadgetsHandler(decoder);
+    JSONObject request = makeTokenRequest(GADGET1_URL, GADGET2_URL);
 
-    RpcHandler operation = registry.getRpcHandler(metadataRequest);
+    RpcHandler operation = registry.getRpcHandler(request);
     Object responseObj = operation.execute(emptyFormItems, token, 
converter).get();
     JSONObject response = new 
JSONObject(converter.convertToString(responseObj));
 
-    JSONObject gadget;
+    JSONObject gadget1 = response.getJSONObject(GADGET1_URL);
+    assertEquals(TOKEN, gadget1.getString("token"));
+    assertFalse(gadget1.has("error"));
+
+    JSONObject gadget2 = response.getJSONObject(GADGET2_URL);
+    assertFalse(gadget2.has("token"));
+    assertEquals(GadgetsHandler.FAILURE_TOKEN, gadget2.getString("error"));
+  }
 
-    // First gadget..
-    gadget = response.getJSONObject(FakeProcessor.SPEC_URL.toString());
-    assertNotNull("got gadget1", gadget);
-    assertEquals(FakeProcessor.SPEC_TITLE, 
gadget.getJSONObject("modulePrefs").getString("title"));
+  @Test
+  public void testMetadataMultipleGadgetsWithFailure() throws Exception {
+    registerGadgetsHandler(null);
+    JSONObject request = makeMetadataRequest("en", "US", GADGET1_URL, 
GADGET2_URL);
+    processor.exceptions.put(FakeProcessor.SPEC_URL2, new 
ProcessingException("broken",
+        HttpServletResponse.SC_BAD_REQUEST));
+    RpcHandler operation = registry.getRpcHandler(request);
+    Object responseObj = operation.execute(emptyFormItems, token, 
converter).get();
+    JSONObject response = new 
JSONObject(converter.convertToString(responseObj));
+
+    JSONObject modulePrefs1 = 
response.getJSONObject(GADGET1_URL).getJSONObject("modulePrefs");
+    assertEquals(FakeProcessor.SPEC_TITLE, modulePrefs1.getString("title"));
 
-    gadget = response.getJSONObject(FakeProcessor.SPEC_URL2.toString());
-    assertNotNull("got gadget2", gadget);
-    assertEquals("broken", gadget.getString("error"));
+    JSONObject gadget2 = response.getJSONObject(GADGET2_URL);
+    assertNotNull("got gadget2", gadget2);
+    assertEquals(GadgetsHandler.FAILURE_METADATA, gadget2.getString("error"));
   }
 }


Reply via email to