Author: etnu
Date: Wed Aug 27 16:06:19 2008
New Revision: 689653
URL: http://svn.apache.org/viewvc?rev=689653&view=rev
Log:
Added new Preloader interface. The new rendering pipeline will use this for all
preloading rather than the ad-hoc preloading currently being done in
GadgetServer.
This is a part of SHINDIG-523.
The preloader is not currently used by anything other than tests. This is
because properly using it is going to require other changes first.
Added:
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/TestExecutorService.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preload.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preloader.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloaderService.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/PreloaderServiceTest.java
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicGadgetSpecFactoryTest.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
Added:
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/TestExecutorService.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/TestExecutorService.java?rev=689653&view=auto
==============================================================================
---
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/TestExecutorService.java
(added)
+++
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/TestExecutorService.java
Wed Aug 27 16:06:19 2008
@@ -0,0 +1,55 @@
+/**
+ * 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.common.testing;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * ExecutorService used for testing. Executes all tasks immediately.
+ */
+public class TestExecutorService extends AbstractExecutorService {
+ private boolean shutdown;
+
+ public void execute(Runnable command) {
+ command.run();
+ }
+
+ public boolean isTerminated() {
+ return shutdown;
+ }
+
+ public boolean isShutdown() {
+ return shutdown;
+ }
+
+ public boolean awaitTermination(long timeout, TimeUnit unit) {
+ return true;
+ }
+
+ public void shutdown() {
+ shutdown = true;
+ }
+
+ public List<Runnable> shutdownNow() {
+ shutdown();
+ return Collections.emptyList();
+ }
+}
\ No newline at end of file
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java?rev=689653&r1=689652&r2=689653&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
Wed Aug 27 16:06:19 2008
@@ -165,46 +165,46 @@
}
return libraries;
}
-}
-/**
- * Provides a task for preloading data into the gadget content
- * TODO: Remove when new preloading is committed.
- */
-class PreloadTask implements Callable<HttpResponse> {
- private final Preload preload;
- private final ContentFetcherFactory preloadFetcherFactory;
- private final GadgetContext context;
+ /**
+ * Provides a task for preloading data into the gadget content
+ * TODO: Remove when new preloading is committed.
+ */
+ private static class PreloadTask implements Callable<HttpResponse> {
+ private final Preload preload;
+ private final ContentFetcherFactory preloadFetcherFactory;
+ private final GadgetContext context;
- public HttpResponse call() {
- try {
- 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()));
- switch (preload.getAuth()) {
- case NONE:
- return preloadFetcherFactory.get().fetch(request);
- case SIGNED:
- return preloadFetcherFactory.getSigningFetcher(context.getToken())
- .fetch(request);
- case OAUTH:
- return preloadFetcherFactory.getOAuthFetcher(context.getToken(),
- new OAuthArguments(preload)).fetch(request);
- default:
- return HttpResponse.error();
+ public HttpResponse call() {
+ try {
+ 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()));
+ switch (preload.getAuth()) {
+ case NONE:
+ return preloadFetcherFactory.get().fetch(request);
+ case SIGNED:
+ return preloadFetcherFactory.getSigningFetcher(context.getToken())
+ .fetch(request);
+ case OAUTH:
+ return preloadFetcherFactory.getOAuthFetcher(context.getToken(),
+ new OAuthArguments(preload)).fetch(request);
+ default:
+ return HttpResponse.error();
+ }
+ } catch (GadgetException e) {
+ return HttpResponse.error();
}
- } catch (GadgetException e) {
- return HttpResponse.error();
}
- }
- public PreloadTask(GadgetContext context, Preload preload,
- ContentFetcherFactory preloadFetcherFactory) {
- this.preload = preload;
- this.preloadFetcherFactory = preloadFetcherFactory;
- this.context = context;
+ public PreloadTask(GadgetContext context, Preload preload,
+ ContentFetcherFactory preloadFetcherFactory) {
+ this.preload = preload;
+ this.preloadFetcherFactory = preloadFetcherFactory;
+ this.context = context;
+ }
}
-}
\ No newline at end of file
+}
Added:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preload.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preload.java?rev=689653&view=auto
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preload.java
(added)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preload.java
Wed Aug 27 16:06:19 2008
@@ -0,0 +1,31 @@
+/**
+ * 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;
+
+/**
+ * Contains preloaded data and methods for manipulating it.
+ */
+public interface Preload {
+
+ /**
+ * Serialize the preloaded data into json.
+ *
+ * @return A JSON object suitable for passing to
org.json.JSONObject.put(String, Object).
+ */
+ Object toJson();
+}
Added:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preloader.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preloader.java?rev=689653&view=auto
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preloader.java
(added)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preloader.java
Wed Aug 27 16:06:19 2008
@@ -0,0 +1,36 @@
+/**
+ * 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;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+/**
+ * Performs an individual preloading operation.
+ */
+public interface Preloader {
+ /**
+ * Create new preload tasks for the provided gadget.
+ *
+ * @param gadget The gadget that the operations will be performed for.
+ * @return Preloading tasks that will be executed in parallel with other
preloading tasks by
+ * [EMAIL PROTECTED] PreloaderService#preload(Gadget)}. Callables will be
converted to Futures for lazy
+ * evaluation.
+ */
+ Map<String, Callable<Preload>> createPreloadTasks(Gadget gadget);
+}
Added:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloaderService.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloaderService.java?rev=689653&view=auto
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloaderService.java
(added)
+++
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloaderService.java
Wed Aug 27 16:06:19 2008
@@ -0,0 +1,62 @@
+/**
+ * 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;
+
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+/**
+ * Handles preloading operations, such as HTTP fetches, social data retrieval,
or anything else that
+ * would benefit from preloading on the server instead of incurring a network
request for users.
+ *
+ * Preloads will be fetched concurrently using the injected ExecutorService,
and they can be read
+ * lazily using the returned map of futures.
+ */
+public class PreloaderService {
+ private final ExecutorService executor;
+ private final List<? extends Preloader> preloaders;
+
+ @Inject
+ public PreloaderService(ExecutorService executor, List<? extends Preloader>
preloaders) {
+ this.executor = executor;
+ this.preloaders = preloaders;
+ }
+
+ /**
+ * Begin all preload operations.
+ *
+ * @param gadget The gadget to perform preloading for.
+ * @return A map of all preloaded data. Callers can retrieve preloads by
unique key.
+ */
+ public Map<String, Future<Preload>> preload(Gadget gadget) {
+ Map<String, Future<Preload>> preloads = Maps.newHashMap();
+ for (Preloader preloader : preloaders) {
+ Map<String, Callable<Preload>> tasks =
preloader.createPreloadTasks(gadget);
+ for (Map.Entry<String, Callable<Preload>> entry : tasks.entrySet()) {
+ preloads.put(entry.getKey(), executor.submit(entry.getValue()));
+ }
+ }
+ return preloads;
+ }
+}
Modified:
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicGadgetSpecFactoryTest.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicGadgetSpecFactoryTest.java?rev=689653&r1=689652&r2=689653&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicGadgetSpecFactoryTest.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicGadgetSpecFactoryTest.java
Wed Aug 27 16:06:19 2008
@@ -21,6 +21,7 @@
import org.apache.shindig.common.cache.CacheProvider;
import org.apache.shindig.common.cache.DefaultCacheProvider;
import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.common.testing.TestExecutorService;
import org.apache.shindig.gadgets.http.HttpFetcher;
import org.apache.shindig.gadgets.http.HttpRequest;
import org.apache.shindig.gadgets.http.HttpResponse;
@@ -39,11 +40,7 @@
import org.junit.Test;
import java.net.URI;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
/**
* Tests for BasicGadgetSpecFactory
@@ -85,34 +82,7 @@
return SPEC_URL.toJavaUri();
}
};
- private final static ExecutorService FAKE_EXECUTOR = new
AbstractExecutorService() {
- private boolean shutdown;
-
- public void execute(Runnable command) {
- command.run();
- }
-
- public boolean isTerminated() {
- return shutdown;
- }
-
- public boolean isShutdown() {
- return shutdown;
- }
-
- public boolean awaitTermination(long timeout, TimeUnit unit) {
- return true;
- }
-
- public void shutdown() {
- shutdown = true;
- }
-
- public List<Runnable> shutdownNow() {
- shutdown();
- return Collections.emptyList();
- }
- };
+ private final static ExecutorService FAKE_EXECUTOR = new
TestExecutorService();
private final HttpFetcher fetcher =
EasyMock.createNiceMock(HttpFetcher.class);
private final CaptureRewriter rewriter = new CaptureRewriter();
Modified:
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java?rev=689653&r1=689652&r2=689653&view=diff
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
(original)
+++
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
Wed Aug 27 16:06:19 2008
@@ -21,6 +21,7 @@
import org.apache.shindig.common.ContainerConfig;
import org.apache.shindig.common.SecurityTokenDecoder;
+import org.apache.shindig.common.testing.TestExecutorService;
import org.apache.shindig.common.cache.CacheProvider;
import org.apache.shindig.common.cache.DefaultCacheProvider;
import org.apache.shindig.common.util.FakeTimeSource;
@@ -36,11 +37,7 @@
import org.apache.shindig.gadgets.servlet.JsonRpcHandler;
import org.apache.shindig.gadgets.servlet.UrlGenerator;
-import java.util.List;
-import java.util.Collections;
-import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -71,34 +68,7 @@
public final LockedDomainService lockedDomainService =
mock(LockedDomainService.class);
public final ContentRewriter rewriter = new NoOpContentRewriter();
public final FakeTimeSource timeSource = new FakeTimeSource();
- public final ExecutorService executor = new AbstractExecutorService() {
- private boolean shutdown;
-
- public void execute(Runnable command) {
- command.run();
- }
-
- public boolean isTerminated() {
- return shutdown;
- }
-
- public boolean isShutdown() {
- return shutdown;
- }
-
- public boolean awaitTermination(long timeout, TimeUnit unit) {
- return true;
- }
-
- public void shutdown() {
- shutdown = true;
- }
-
- public List<Runnable> shutdownNow() {
- shutdown();
- return Collections.emptyList();
- }
- };
+ public final ExecutorService executor = new TestExecutorService();
public final GadgetSpecFactory specFactory = new BasicGadgetSpecFactory(
fetcher, cacheProvider, new BasicContentRewriterRegistry(null),
executor, 0, 0L, 0L);
Added:
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/PreloaderServiceTest.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/PreloaderServiceTest.java?rev=689653&view=auto
==============================================================================
---
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/PreloaderServiceTest.java
(added)
+++
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/PreloaderServiceTest.java
Wed Aug 27 16:06:19 2008
@@ -0,0 +1,127 @@
+/**
+ * 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;
+
+import org.apache.shindig.common.testing.TestExecutorService;
+
+import com.google.common.collect.Maps;
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+
+/**
+ * Tests for PreloaderService.
+ */
+public class PreloaderServiceTest {
+ private static final String PRELOAD_STRING_KEY = "key a";
+ private static final String PRELOAD_NUMERIC_KEY = "key b";
+ private static final String PRELOAD_MAP_KEY = "key c";
+ private static final String PRELOAD_BEAN_KEY = "key d";
+ private static final String PRELOAD_STRING_VALUE = "Some random string";
+ private static final Integer PRELOAD_NUMERIC_VALUE = 5;
+ private static final Map<String, String> PRELOAD_MAP_VALUE
+ = Maps.immutableMap("foo", "bar", "baz", "blah");
+ private static final Object PRELOAD_BEAN_VALUE = new Object() {
+ public String getFoo() {
+ return "foo";
+ }
+
+ public String getBar() {
+ return "bar";
+ }
+ };
+
+ private final TestPreloader preloader = new TestPreloader();
+ private final TestPreloader preloader2 = new TestPreloader();
+
+ @Test
+ public void preloadSingleService() throws Exception {
+ preloader.tasks.put(PRELOAD_STRING_KEY,
+ new TestPreloadCallable(new DataPreload(PRELOAD_STRING_VALUE)));
+
+ PreloaderService service
+ = new PreloaderService(new TestExecutorService(),
Arrays.asList(preloader));
+
+ assertEquals(PRELOAD_STRING_VALUE,
+
(String)service.preload(null).get(PRELOAD_STRING_KEY).get().toJson());
+ }
+
+ @Test
+ public void preloadMultipleServices() throws Exception {
+ preloader.tasks.put(PRELOAD_STRING_KEY,
+ new TestPreloadCallable(new DataPreload(PRELOAD_STRING_VALUE)));
+
+ preloader.tasks.put(PRELOAD_NUMERIC_KEY,
+ new TestPreloadCallable(new DataPreload(PRELOAD_NUMERIC_VALUE)));
+
+ preloader2.tasks.put(PRELOAD_MAP_KEY,
+ new TestPreloadCallable(new DataPreload(PRELOAD_MAP_VALUE)));
+
+ preloader2.tasks.put(PRELOAD_BEAN_KEY,
+ new TestPreloadCallable(new DataPreload(PRELOAD_BEAN_VALUE)));
+
+ PreloaderService service
+ = new PreloaderService(new TestExecutorService(),
Arrays.asList(preloader, preloader2));
+
+ Map<String, Future<Preload>> preloads = service.preload(null);
+
+ assertEquals(PRELOAD_STRING_VALUE,
+ (String) preloads.get(PRELOAD_STRING_KEY).get().toJson());
+ assertEquals(PRELOAD_NUMERIC_VALUE,
+ (Integer) preloads.get(PRELOAD_NUMERIC_KEY).get().toJson());
+ assertEquals(PRELOAD_MAP_VALUE,
+ (Map) preloads.get(PRELOAD_MAP_KEY).get().toJson());
+ assertEquals(PRELOAD_BEAN_VALUE,
preloads.get(PRELOAD_BEAN_KEY).get().toJson());
+ }
+
+ private static class TestPreloader implements Preloader {
+ private final Map<String, Callable<Preload>> tasks = Maps.newHashMap();
+
+ public Map<String, Callable<Preload>> createPreloadTasks(Gadget gadget) {
+ return tasks;
+ }
+ }
+
+ private static class TestPreloadCallable implements Callable<Preload> {
+ private final Preload preload;
+
+ public TestPreloadCallable(Preload preload) {
+ this.preload = preload;
+ }
+
+ public Preload call() {
+ return preload;
+ }
+ }
+
+ private static class DataPreload implements Preload {
+ private final Object data;
+
+ public DataPreload(Object data) {
+ this.data = data;
+ }
+
+ public Object toJson() {
+ return data;
+ }
+ }
+}