You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by lr...@apache.org on 2009/02/11 22:29:49 UTC
svn commit: r743517 - in /incubator/shindig/trunk/java:
common/src/main/java/org/apache/shindig/protocol/
common/src/test/java/org/apache/shindig/protocol/
social-api/src/test/java/org/apache/shindig/social/opensocial/service/
Author: lryan
Date: Wed Feb 11 21:29:49 2009
New Revision: 743517
URL: http://svn.apache.org/viewvc?rev=743517&view=rev
Log:
Add support for a cross-cutting handler execution listener. Useful for containers to do logging, request extensions
Added:
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/HandlerExecutionListener.java
Modified:
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DataServiceServlet.java
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DefaultHandlerRegistry.java
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DataServiceServletTest.java
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DefaultHandlerRegistryTest.java
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/ActivityHandlerTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/AppDataHandlerTest.java
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/PersonHandlerTest.java
Modified: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DataServiceServlet.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DataServiceServlet.java?rev=743517&r1=743516&r2=743517&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DataServiceServlet.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DataServiceServlet.java Wed Feb 11 21:29:49 2009
@@ -99,17 +99,8 @@
HttpServletResponse servletResponse, SecurityToken token,
BeanConverter converter) throws IOException {
- // TODO Rework to allow sub-services
- String path = servletRequest.getPathInfo();
-
- // TODO - This shouldnt be on BaseRequestItem
- String method = servletRequest.getParameter(X_HTTP_METHOD_OVERRIDE);
- if (method == null) {
- method = servletRequest.getMethod();
- }
-
// Always returns a non-null handler.
- RestHandler handler = dispatcher.getRestHandler(path, method.toUpperCase());
+ RestHandler handler = getRestHandler(servletRequest);
Reader bodyReader = null;
if (!servletRequest.getMethod().equals("GET") && !servletRequest.getMethod().equals("HEAD")) {
@@ -139,6 +130,19 @@
}
}
+ protected RestHandler getRestHandler(HttpServletRequest servletRequest) {
+ // TODO Rework to allow sub-services
+ String path = servletRequest.getPathInfo();
+
+ // TODO - This shouldnt be on BaseRequestItem
+ String method = servletRequest.getParameter(X_HTTP_METHOD_OVERRIDE);
+ if (method == null) {
+ method = servletRequest.getMethod();
+ }
+
+ // Always returns a non-null handler.
+ return dispatcher.getRestHandler(path, method.toUpperCase());
+ }
BeanConverter getConverterForRequest(HttpServletRequest servletRequest) {
String formatString = null;
Modified: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DefaultHandlerRegistry.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DefaultHandlerRegistry.java?rev=743517&r1=743516&r2=743517&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DefaultHandlerRegistry.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DefaultHandlerRegistry.java Wed Feb 11 21:29:49 2009
@@ -62,6 +62,7 @@
private final Injector injector;
private final BeanJsonConverter beanJsonConverter;
+ private final HandlerExecutionListener executionListener;
/**
* Creates a dispatcher with the specified handler classes
@@ -72,9 +73,11 @@
@Inject
public DefaultHandlerRegistry(Injector injector,
@Named("org.apache.shindig.handlers")Set handlers,
- BeanJsonConverter beanJsonConverter) {
+ BeanJsonConverter beanJsonConverter,
+ HandlerExecutionListener executionListener) {
this.injector = injector;
this.beanJsonConverter = beanJsonConverter;
+ this.executionListener = executionListener;
addHandlers(handlers.toArray());
}
@@ -175,8 +178,13 @@
Constructor reqItemConstructor =
requestItemType.getConstructor(Map.class, SecurityToken.class, BeanConverter.class,
BeanJsonConverter.class);
+ String opName = m.getName();
+ if (!StringUtils.isEmpty(op.name())) {
+ opName = op.name();
+ }
RestInvocationHandler restHandler = new RestInvocationHandler(service, op, m, handler,
- beanJsonConverter, reqItemConstructor);
+ beanJsonConverter, reqItemConstructor,
+ new ExecutionListenerWrapper(service.name(), opName, executionListener));
String serviceName = service.name();
Map<String, SortedSet<RestPath>> methods = serviceMethodPathMap.get(serviceName);
@@ -221,14 +229,15 @@
requestItemType.getConstructor(JSONObject.class, SecurityToken.class,
BeanConverter.class,
BeanJsonConverter.class);
- RpcInvocationHandler rpcHandler =
- new RpcInvocationHandler(m, handler, beanJsonConverter, reqItemConstructor);
- String defaultName = service.name() + "." + m.getName();
+ String opName = m.getName();
// Use the override if its defined
if (op.name().length() > 0) {
- defaultName = service.name() + "." + op.name();
+ opName = op.name();
}
- rpcOperations.put(defaultName, rpcHandler);
+ RpcInvocationHandler rpcHandler =
+ new RpcInvocationHandler(m, handler, beanJsonConverter, reqItemConstructor,
+ new ExecutionListenerWrapper(service.name(), opName, executionListener));
+ rpcOperations.put(service.name() + "." + opName, rpcHandler);
}
} catch (NoSuchMethodException nme) {
logger.log(Level.INFO, "No RPC binding for " + service.name() + "." + m.getName());
@@ -236,6 +245,26 @@
}
/**
+ * Utility wrapper for the HandlerExecutionListener
+ */
+ private static class ExecutionListenerWrapper {
+ final String service;
+ final String operation;
+ final HandlerExecutionListener listener;
+
+ ExecutionListenerWrapper(String service, String operation,
+ HandlerExecutionListener listener) {
+ this.service = service;
+ this.operation = operation;
+ this.listener = listener;
+ }
+
+ private void executing(RequestItem req) {
+ listener.executing(service, operation, req);
+ }
+ }
+
+ /**
* Proxy binding for an RPC operation. We allow binding to methods that
* return non-Future types by wrapping them in ImmediateFuture.
*/
@@ -244,14 +273,17 @@
Object handlerInstance;
BeanJsonConverter beanJsonConverter;
Constructor requestItemConstructor;
+ ExecutionListenerWrapper listener;
private RpcInvocationHandler(Method receiver, Object handlerInstance,
BeanJsonConverter beanJsonConverter,
- Constructor reqItemConstructor) {
+ Constructor reqItemConstructor,
+ ExecutionListenerWrapper listener) {
this.receiver = receiver;
this.handlerInstance = handlerInstance;
this.beanJsonConverter = beanJsonConverter;
this.requestItemConstructor = reqItemConstructor;
+ this.listener = listener;
}
public Future execute(JSONObject rpc, SecurityToken token, BeanConverter converter) {
@@ -264,6 +296,7 @@
item = (RequestItem) requestItemConstructor.newInstance(new JSONObject(), token,
converter, beanJsonConverter);
}
+ listener.executing(item);
Object result = receiver.invoke(handlerInstance, item);
if (result instanceof Future) {
return (Future) result;
@@ -308,11 +341,13 @@
final String[] expectedUrl;
BeanJsonConverter beanJsonConverter;
Constructor requestItemConstructor;
+ ExecutionListenerWrapper listener;
private RestInvocationHandler(Service service, Operation operation,
Method receiver, Object handlerInstance,
BeanJsonConverter beanJsonConverter,
- Constructor requestItemConstructor) {
+ Constructor requestItemConstructor,
+ ExecutionListenerWrapper listener) {
this.service = service;
this.operation = operation;
this.receiver = receiver;
@@ -320,6 +355,7 @@
expectedUrl = service.path().split("/");
this.beanJsonConverter = beanJsonConverter;
this.requestItemConstructor = requestItemConstructor;
+ this.listener = listener;
}
public Future<?> execute(Map<String, String[]> parameters, Reader body,
@@ -331,6 +367,7 @@
}
RequestItem item = (RequestItem) requestItemConstructor.newInstance(parameters, token,
converter, beanJsonConverter);
+ listener.executing(item);
Object result = receiver.invoke(handlerInstance, item);
if (result instanceof Future) {
return (Future) result;
@@ -489,6 +526,7 @@
return new RestInvocationWrapper(parsedParams, handler);
}
+
/**
* Rank based on the number of consant parts they accept, where the constant parts occur
* and lexical ordering.
Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/HandlerExecutionListener.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/HandlerExecutionListener.java?rev=743517&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/HandlerExecutionListener.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/HandlerExecutionListener.java Wed Feb 11 21:29:49 2009
@@ -0,0 +1,48 @@
+/*
+ * 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.protocol;
+
+import com.google.inject.ImplementedBy;
+
+/**
+ * Called by the handler dispatcher prior to executing a handler. Used to allow
+ * containers to implement cross-cutting features such as request logging.
+ */
+@ImplementedBy(HandlerExecutionListener.NoOpHandlerExecutionListener.class)
+public interface HandlerExecutionListener {
+
+ /**
+ * Called prior to executing a REST or RPC handler
+ * @param service Name of the service being called
+ * @param operation Name of operation being called
+ * @param request being executed
+ */
+ void executing(String service, String operation, RequestItem request);
+
+ /**
+ * Default no-op implementation
+ */
+ public static class NoOpHandlerExecutionListener implements HandlerExecutionListener {
+
+ public void executing(String service, String operation, RequestItem request) {
+ // No-op
+ }
+ }
+}
+
Modified: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java?rev=743517&r1=743516&r2=743517&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java Wed Feb 11 21:29:49 2009
@@ -100,7 +100,7 @@
// into single requests.
for (int i = 0; i < batch.length(); i++) {
JSONObject batchObj = batch.getJSONObject(i);
- responses.add(dispatcher.getRpcHandler(batchObj).execute(token, jsonConverter));
+ responses.add(getHandler(batchObj, servletRequest).execute(token, jsonConverter));
}
// Resolve each Future into a response.
@@ -125,7 +125,7 @@
}
// getRpcHandler never returns null
- Future future = dispatcher.getRpcHandler(request).execute(token, jsonConverter);
+ Future future = getHandler(request, servletRequest).execute(token, jsonConverter);
// Resolve each Future into a response.
// TODO: should use shared deadline across each request
@@ -134,6 +134,14 @@
servletResponse.getWriter().write(result.toString());
}
+ /**
+ * Wrap call to dispatcher to allow for implementation specific overrides
+ * and servlet-request contextual handling
+ */
+ protected RpcHandler getHandler(JSONObject rpc, HttpServletRequest request) {
+ return dispatcher.getRpcHandler(rpc);
+ }
+
private JSONObject getJSONResponse(String key, ResponseItem responseItem) throws JSONException {
JSONObject result = new JSONObject();
if (key != null) {
Modified: incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DataServiceServletTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DataServiceServletTest.java?rev=743517&r1=743516&r2=743517&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DataServiceServletTest.java (original)
+++ incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DataServiceServletTest.java Wed Feb 11 21:29:49 2009
@@ -73,7 +73,8 @@
EasyMock.expect(atomConverter.getContentType()).andReturn("application/atom+xml").anyTimes();
HandlerRegistry registry = new DefaultHandlerRegistry(null,
- Sets.newHashSet(new TestHandler()), jsonConverter);
+ Sets.newHashSet(new TestHandler()), jsonConverter,
+ new HandlerExecutionListener.NoOpHandlerExecutionListener());
servlet.setHandlerRegistry(registry);
Modified: incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DefaultHandlerRegistryTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DefaultHandlerRegistryTest.java?rev=743517&r1=743516&r2=743517&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DefaultHandlerRegistryTest.java (original)
+++ incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DefaultHandlerRegistryTest.java Wed Feb 11 21:29:49 2009
@@ -45,7 +45,8 @@
protected void setUp() throws Exception {
super.setUp();
registry = new DefaultHandlerRegistry(null,
- Sets.newHashSet(new TestHandler()), null);
+ Sets.newHashSet(new TestHandler()), null,
+ new HandlerExecutionListener.NoOpHandlerExecutionListener());
}
public void testGetHandlerRPC() throws Exception {
Modified: incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java?rev=743517&r1=743516&r2=743517&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java (original)
+++ incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java Wed Feb 11 21:29:49 2009
@@ -68,7 +68,8 @@
atomConverter = mockControl.createMock(BeanConverter.class);
HandlerRegistry registry = new DefaultHandlerRegistry(null,
- Sets.newHashSet(new TestHandler()), jsonConverter);
+ Sets.newHashSet(new TestHandler()), jsonConverter,
+ new HandlerExecutionListener.NoOpHandlerExecutionListener());
servlet.setHandlerRegistry(registry);
servlet.setBeanConverters(jsonConverter, xmlConverter, atomConverter);
Modified: incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/ActivityHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/ActivityHandlerTest.java?rev=743517&r1=743516&r2=743517&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/ActivityHandlerTest.java (original)
+++ incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/ActivityHandlerTest.java Wed Feb 11 21:29:49 2009
@@ -24,6 +24,7 @@
import org.apache.shindig.config.JsonContainerConfig;
import org.apache.shindig.expressions.Expressions;
import org.apache.shindig.protocol.DefaultHandlerRegistry;
+import org.apache.shindig.protocol.HandlerExecutionListener;
import org.apache.shindig.protocol.HandlerRegistry;
import org.apache.shindig.protocol.RestHandler;
import org.apache.shindig.protocol.RestfulCollection;
@@ -81,7 +82,8 @@
containerConfig = new JsonContainerConfig(config, new Expressions());
handler = new ActivityHandler(activityService, containerConfig);
- registry = new DefaultHandlerRegistry(null, Sets.newHashSet(handler), converter);
+ registry = new DefaultHandlerRegistry(null, Sets.newHashSet(handler), converter,
+ new HandlerExecutionListener.NoOpHandlerExecutionListener());
}
private void assertHandleGetForGroup(GroupId.Type group) throws Exception {
Modified: incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/AppDataHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/AppDataHandlerTest.java?rev=743517&r1=743516&r2=743517&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/AppDataHandlerTest.java (original)
+++ incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/AppDataHandlerTest.java Wed Feb 11 21:29:49 2009
@@ -22,6 +22,7 @@
import org.apache.shindig.common.util.ImmediateFuture;
import org.apache.shindig.protocol.DataCollection;
import org.apache.shindig.protocol.DefaultHandlerRegistry;
+import org.apache.shindig.protocol.HandlerExecutionListener;
import org.apache.shindig.protocol.HandlerRegistry;
import org.apache.shindig.protocol.ResponseError;
import org.apache.shindig.protocol.RestHandler;
@@ -67,7 +68,8 @@
converter = mock(BeanJsonConverter.class);
appDataService = mock(AppDataService.class);
AppDataHandler handler = new AppDataHandler(appDataService);
- registry = new DefaultHandlerRegistry(null, Sets.newHashSet(handler), converter);
+ registry = new DefaultHandlerRegistry(null, Sets.newHashSet(handler), converter,
+ new HandlerExecutionListener.NoOpHandlerExecutionListener());
}
private void assertHandleGetForGroup(GroupId.Type group) throws Exception {
Modified: incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/PersonHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/PersonHandlerTest.java?rev=743517&r1=743516&r2=743517&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/PersonHandlerTest.java (original)
+++ incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/service/PersonHandlerTest.java Wed Feb 11 21:29:49 2009
@@ -24,6 +24,7 @@
import org.apache.shindig.config.JsonContainerConfig;
import org.apache.shindig.expressions.Expressions;
import org.apache.shindig.protocol.DefaultHandlerRegistry;
+import org.apache.shindig.protocol.HandlerExecutionListener;
import org.apache.shindig.protocol.HandlerRegistry;
import org.apache.shindig.protocol.RestHandler;
import org.apache.shindig.protocol.RestfulCollection;
@@ -89,7 +90,8 @@
containerConfig = new JsonContainerConfig(config, new Expressions());
handler = new PersonHandler(personService, containerConfig);
- registry = new DefaultHandlerRegistry(null, Sets.newHashSet(handler), converter);
+ registry = new DefaultHandlerRegistry(null, Sets.newHashSet(handler), converter,
+ new HandlerExecutionListener.NoOpHandlerExecutionListener());
}
public void testHandleGetAllNoParams() throws Exception {