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"));
}
}