Author: etnu
Date: Sat Sep  6 20:15:47 2008
New Revision: 692769

URL: http://svn.apache.org/viewvc?rev=692769&view=rev
Log:
Added HttpPreloader. This will replace the Preload logic in GadgetServer when 
the rendering pipeline cutover is complete.


Added:
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/HttpPreloader.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/preload/HttpPreloaderTest.java

Added: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/HttpPreloader.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/HttpPreloader.java?rev=692769&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/HttpPreloader.java
 (added)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/HttpPreloader.java
 Sat Sep  6 20:15:47 2008
@@ -0,0 +1,112 @@
+/*
+ * 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.gadgets.preload;
+
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.http.ContentFetcherFactory;
+import org.apache.shindig.gadgets.http.HttpRequest;
+import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.oauth.OAuthArguments;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+import org.apache.shindig.gadgets.spec.Preload;
+
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+/**
+ * Handles HTTP Preloading (/ModulePrefs/Preload elements).
+ *
+ * @see org.apache.shindig.gadgets.spec.Preload
+ */
+public class HttpPreloader implements Preloader {
+  // TODO: This needs to be fixed.
+  private final ContentFetcherFactory fetcher;
+
+  @Inject
+  public HttpPreloader(ContentFetcherFactory fetcherFactory) {
+    this.fetcher = fetcherFactory;
+  }
+
+  public Map<String, Callable<PreloadedData>> createPreloadTasks(GadgetContext 
context,
+      GadgetSpec gadget) {
+    Map<String, Callable<PreloadedData>> preloads = Maps.newHashMap();
+
+    for (Preload preload : gadget.getModulePrefs().getPreloads()) {
+      preloads.put(preload.getHref().toString(), new PreloadTask(context, 
preload));
+    }
+
+    return preloads;
+  }
+
+  private class PreloadTask implements Callable<PreloadedData> {
+    private final GadgetContext context;
+    private final Preload preload;
+
+    public PreloadTask(GadgetContext context, Preload preload) {
+      this.context = context;
+      this.preload = preload;
+    }
+
+    public PreloadedData call() throws Exception {
+      // TODO: This should be extracted into a common helper that takes any
+      // org.apache.shindig.gadgets.spec.RequestAuthenticationInfo.
+      HttpRequest request = new HttpRequest(Uri.fromJavaUri(preload.getHref()))
+            .setSignOwner(preload.isSignOwner())
+            .setSignViewer(preload.isSignViewer())
+            .setContainer(context.getContainer())
+            .setSecurityToken(context.getToken())
+            .setGadget(Uri.fromJavaUri(context.getUrl()));
+      HttpResponse response = null;
+      switch (preload.getAuthType()) {
+        case NONE:
+          response = fetcher.get().fetch(request);
+          break;
+        case SIGNED:
+          response = 
fetcher.getSigningFetcher(context.getToken()).fetch(request);
+          break;
+        case OAUTH:
+          response = fetcher.getOAuthFetcher(context.getToken(), new 
OAuthArguments(preload))
+              .fetch(request);
+          break;
+      }
+      return new HttpPreloadData(response);
+    }
+  }
+
+  /**
+   * Implements PreloadData by returning a Map that matches the output format 
used by makeRequest.
+   */
+  private static class HttpPreloadData implements PreloadedData {
+    private final Map<String, String> data;
+
+    public HttpPreloadData(HttpResponse response) {
+      data = Maps.newHashMap(response.getMetadata());
+      data.put("body", response.getResponseAsString());
+      data.put("rc", Integer.toString(response.getHttpStatusCode()));
+    }
+
+    public Object toJson() {
+      return data;
+    }
+  }
+}

Added: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/preload/HttpPreloaderTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/preload/HttpPreloaderTest.java?rev=692769&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/preload/HttpPreloaderTest.java
 (added)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/preload/HttpPreloaderTest.java
 Sat Sep  6 20:15:47 2008
@@ -0,0 +1,201 @@
+/*
+ * 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.gadgets.preload;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.common.testing.FakeGadgetToken;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.http.ContentFetcherFactory;
+import org.apache.shindig.gadgets.http.HttpFetcher;
+import org.apache.shindig.gadgets.http.HttpRequest;
+import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.http.HttpResponseBuilder;
+import org.apache.shindig.gadgets.oauth.OAuthArguments;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import org.easymock.IMocksControl;
+import org.easymock.classextension.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+/**
+ * Tests for HttpPreloader.
+ */
+public class HttpPreloaderTest {
+  private static final String PRELOAD_HREF = "http://www.example.org/file";;
+  private static final String PRELOAD_HREF2 = "http://www.example.org/file";;
+  private static final String PRELOAD_CONTENT = "Preloaded data";
+  private static final String CONTAINER = "some-container";
+  private static final URI GADGET_URL = 
URI.create("http://example.org/gadget.xml";);
+  private static final Map<String, String> PRELOAD_METADATA = 
Maps.immutableMap("foo", "bar");
+
+  private final IMocksControl control = EasyMock.createNiceControl();
+  private final ContentFetcherFactory fetchers = 
control.createMock(ContentFetcherFactory.class);
+  private final RecordingHttpFetcher plainFetcher = new RecordingHttpFetcher();
+  private final RecordingHttpFetcher signedFetcher = new 
RecordingHttpFetcher();
+  private final RecordingHttpFetcher oauthFetcher = new RecordingHttpFetcher();
+
+  private final GadgetContext context = new GadgetContext() {
+    @Override
+    public SecurityToken getToken() {
+      return new FakeGadgetToken();
+    }
+
+    @Override
+    public String getContainer() {
+      return CONTAINER;
+    }
+
+    @Override
+    public URI getUrl() {
+      return GADGET_URL;
+    }
+  };
+
+  @Before
+  public void setUp() throws Exception {
+    expect(fetchers.get())
+        .andReturn(plainFetcher).anyTimes();
+    expect(fetchers.getSigningFetcher(isA(SecurityToken.class)))
+        .andReturn(signedFetcher).anyTimes();
+    expect(fetchers.getOAuthFetcher(isA(SecurityToken.class), 
isA(OAuthArguments.class)))
+        .andReturn(oauthFetcher).anyTimes();
+    control.replay();
+  }
+
+  private void checkRequest(HttpRequest request) {
+    assertEquals(context.getContainer(), request.getContainer());
+    assertEquals(GADGET_URL.toString(), request.getGadget().toString());
+    assertEquals(context.getToken().getAppId(), 
request.getSecurityToken().getAppId());
+  }
+
+  private static void checkResults(Map<String, String> results) {
+    assertEquals(PRELOAD_CONTENT, results.get("body"));
+    assertEquals(HttpResponse.SC_OK, Integer.parseInt(results.get("rc")));
+    assertTrue("Metadata values not copied to output.",
+        results.entrySet().containsAll(PRELOAD_METADATA.entrySet()));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void normalPreloads() throws Exception {
+    String xml =
+        "<Module><ModulePrefs title=''>" +
+        " <Preload href='" + PRELOAD_HREF + "'/>" +
+        "</ModulePrefs><Content/></Module>";
+    GadgetSpec gadget = new GadgetSpec(GADGET_URL, xml);
+    Preloader preloader = new HttpPreloader(fetchers);
+
+    Map<String, Callable<PreloadedData>> preloaded = 
preloader.createPreloadTasks(context, gadget);
+
+    PreloadedData data = preloaded.get(PRELOAD_HREF).call();
+
+    checkRequest(plainFetcher.requests.get(0));
+    checkResults((Map<String, String>)data.toJson());
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void signedPreloads() throws Exception {
+    String xml =
+        "<Module><ModulePrefs title=''>" +
+        " <Preload href='" + PRELOAD_HREF + "' authz='signed' 
sign_viewer='false'/>" +
+        "</ModulePrefs><Content/></Module>";
+    GadgetSpec gadget = new GadgetSpec(GADGET_URL, xml);
+    Preloader preloader = new HttpPreloader(fetchers);
+
+    Map<String, Callable<PreloadedData>> preloaded = 
preloader.createPreloadTasks(context, gadget);
+
+    PreloadedData data = preloaded.get(PRELOAD_HREF).call();
+
+    HttpRequest request = signedFetcher.requests.get(0);
+    checkRequest(request);
+    assertTrue(request.getSignOwner());
+    assertFalse(request.getSignViewer());
+    checkResults((Map<String, String>)data.toJson());
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void oauthPreloads() throws Exception {
+    String xml =
+        "<Module><ModulePrefs title=''>" +
+        // This is kind of a bogus test since oauth params aren't set.
+        " <Preload href='" + PRELOAD_HREF + "' authz='oauth'/>" +
+        "</ModulePrefs><Content/></Module>";
+    GadgetSpec gadget = new GadgetSpec(GADGET_URL, xml);
+    Preloader preloader = new HttpPreloader(fetchers);
+
+    Map<String, Callable<PreloadedData>> preloaded = 
preloader.createPreloadTasks(context, gadget);
+
+    PreloadedData data = preloaded.get(PRELOAD_HREF).call();
+
+    HttpRequest request = oauthFetcher.requests.get(0);
+    checkRequest(request);
+    checkResults((Map<String, String>)data.toJson());
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void multiplePreloads() throws Exception {
+    String xml =
+        "<Module><ModulePrefs title=''>" +
+        " <Preload href='" + PRELOAD_HREF + "'/>" +
+        " <Preload href='" + PRELOAD_HREF2 + "'/>" +
+        "</ModulePrefs><Content/></Module>";
+    GadgetSpec gadget = new GadgetSpec(GADGET_URL, xml);
+    Preloader preloader = new HttpPreloader(fetchers);
+
+    Map<String, Callable<PreloadedData>> preloaded = 
preloader.createPreloadTasks(context, gadget);
+
+    PreloadedData data = preloaded.get(PRELOAD_HREF).call();
+    checkRequest(plainFetcher.requests.get(0));
+    checkResults((Map<String, String>)data.toJson());
+
+    data = preloaded.get(PRELOAD_HREF2).call();
+    checkRequest(plainFetcher.requests.get(1));
+    checkResults((Map<String, String>)data.toJson());
+  }
+
+  private static class RecordingHttpFetcher implements HttpFetcher {
+    private List<HttpRequest> requests = Lists.newArrayList();
+
+    public HttpResponse fetch(HttpRequest request) {
+      requests.add(request);
+      return new HttpResponseBuilder()
+          .setMetadata(PRELOAD_METADATA)
+          .setResponseString(PRELOAD_CONTENT)
+          .create();
+    }
+  }
+}


Reply via email to