You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2014/07/02 13:38:42 UTC

git commit: WICKET-5627 broadcastMessage(): hook to set more thread-local context before rendering components

Repository: wicket
Updated Branches:
  refs/heads/wicket-6.x 35f2003a4 -> e877ae211


WICKET-5627 broadcastMessage(): hook to set more thread-local context before rendering components


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/e877ae21
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/e877ae21
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/e877ae21

Branch: refs/heads/wicket-6.x
Commit: e877ae211673aaa093dac94cf20baf12a93a4150
Parents: 35f2003
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
Authored: Wed Jul 2 14:38:16 2014 +0300
Committer: Martin Tzvetanov Grigorov <mg...@apache.org>
Committed: Wed Jul 2 14:38:16 2014 +0300

----------------------------------------------------------------------
 .../wicket/protocol/ws/WebSocketSettings.java   |  39 ++++++-
 .../ws/api/AbstractWebSocketProcessor.java      |  51 +++++---
 .../util/tester/SendPayloadWithContextTest.java | 115 +++++++++++++++++++
 .../util/tester/WebSocketBehaviorTestPage.java  |   5 +-
 4 files changed, 191 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/e877ae21/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/WebSocketSettings.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/WebSocketSettings.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/WebSocketSettings.java
index 1b5ea56..4df75a6 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/WebSocketSettings.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/WebSocketSettings.java
@@ -34,6 +34,12 @@ public class WebSocketSettings implements IWebSocketSettings
 	private Executor webSocketPushMessageExecutor = new SameThreadExecutor();
 
 	/**
+	 * The executor that handles broadcast of the {@link org.apache.wicket.protocol.ws.api.event.WebSocketPayload}
+	 * via Wicket's event bus.
+	 */
+	private Executor sendPayloadExecutor = new SameThreadExecutor();
+
+	/**
 	 * Tracks all currently connected WebSocket clients
 	 */
 	private IWebSocketConnectionRegistry connectionRegistry = new SimpleWebSocketConnectionRegistry();
@@ -67,9 +73,40 @@ public class WebSocketSettings implements IWebSocketSettings
 	}
 
 	/**
+	 * The executor that broadcasts the {@link org.apache.wicket.protocol.ws.api.event.WebSocketPayload}
+	 * via Wicket's event bus.
+	 * Default executor does all the processing in the caller thread.
+	 *
+	 * @param sendPayloadExecutor
+	 *            The executor used for broadcasting the events with web socket payloads to
+	 *            {@link org.apache.wicket.protocol.ws.api.WebSocketBehavior}s and
+	 *            {@link org.apache.wicket.protocol.ws.api.WebSocketResource}s.
+	 */
+	public WebSocketSettings setSendPayloadExecutor(Executor sendPayloadExecutor)
+	{
+		Args.notNull(sendPayloadExecutor, "sendPayloadExecutor");
+		this.sendPayloadExecutor = sendPayloadExecutor;
+		return this;
+	}
+
+	/**
+	 * The executor that broadcasts the {@link org.apache.wicket.protocol.ws.api.event.WebSocketPayload}
+	 * via Wicket's event bus.
+	 *
+	 * @return
+	 *            The executor used for broadcasting the events with web socket payloads to
+	 *            {@link org.apache.wicket.protocol.ws.api.WebSocketBehavior}s and
+	 *            {@link org.apache.wicket.protocol.ws.api.WebSocketResource}s.
+	 */
+	public Executor getSendPayloadExecutor()
+	{
+		return sendPayloadExecutor;
+	}
+
+	/**
 	 * Simple executor that runs the tasks in the caller thread.
 	 */
-	static final class SameThreadExecutor implements Executor
+	public static class SameThreadExecutor implements Executor
 	{
 		@Override
 		public void run(Runnable command)

http://git-wip-us.apache.org/repos/asf/wicket/blob/e877ae21/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
index 6a98ccd..34cc816 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
@@ -32,6 +32,7 @@ import org.apache.wicket.page.IPageManager;
 import org.apache.wicket.protocol.http.WebApplication;
 import org.apache.wicket.protocol.http.WicketFilter;
 import org.apache.wicket.protocol.ws.IWebSocketSettings;
+import org.apache.wicket.protocol.ws.WebSocketSettings;
 import org.apache.wicket.protocol.ws.api.event.WebSocketBinaryPayload;
 import org.apache.wicket.protocol.ws.api.event.WebSocketClosedPayload;
 import org.apache.wicket.protocol.ws.api.event.WebSocketConnectedPayload;
@@ -302,28 +303,44 @@ public abstract class AbstractWebSocketProcessor implements IWebSocketProcessor
 	 * @param page
 	 *          The page that owns the WebSocketBehavior, in case of behavior usage
 	 */
-	private void sendPayload(WebSocketPayload payload, Page page)
+	private void sendPayload(final WebSocketPayload payload, final Page page)
 	{
-		if (pageId != NO_PAGE_ID)
+		final Runnable action = new Runnable()
 		{
-			page.send(application, Broadcast.BREADTH, payload);
+			@Override
+			public void run()
+			{
+				if (pageId != NO_PAGE_ID)
+				{
+					page.send(application, Broadcast.BREADTH, payload);
+				} else
+				{
+					ResourceReference reference = new SharedResourceReference(resourceName);
+					IResource resource = reference.getResource();
+					if (resource instanceof WebSocketResource)
+					{
+						WebSocketResource wsResource = (WebSocketResource) resource;
+						wsResource.onPayload(payload);
+					} else
+					{
+						throw new IllegalStateException(
+								String.format("Shared resource with name '%s' is not a %s but %s",
+										resourceName, WebSocketResource.class.getSimpleName(),
+										Classes.name(resource.getClass())));
+					}
+				}
+			}
+		};
+
+		IWebSocketSettings webSocketSettings = IWebSocketSettings.Holder.get(application);
+		if (webSocketSettings instanceof WebSocketSettings)
+		{
+			WebSocketSettings wss = (WebSocketSettings) webSocketSettings;
+			wss.getSendPayloadExecutor().run(action);
 		}
 		else
 		{
-			ResourceReference reference = new SharedResourceReference(resourceName);
-			IResource resource = reference.getResource();
-			if (resource instanceof WebSocketResource)
-			{
-				WebSocketResource wsResource = (WebSocketResource) resource;
-				wsResource.onPayload(payload);
-			}
-			else
-			{
-				throw new IllegalStateException(
-						String.format("Shared resource with name '%s' is not a %s but %s",
-								resourceName, WebSocketResource.class.getSimpleName(),
-								Classes.name(resource.getClass())));
-			}
+			action.run();
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/e877ae21/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/SendPayloadWithContextTest.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/SendPayloadWithContextTest.java b/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/SendPayloadWithContextTest.java
new file mode 100644
index 0000000..1a6b6a5
--- /dev/null
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/SendPayloadWithContextTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.wicket.protocol.ws.util.tester;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.IMarkupResourceStreamProvider;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.protocol.ws.IWebSocketSettings;
+import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.protocol.ws.api.WebSocketBehavior;
+import org.apache.wicket.protocol.ws.api.WebSocketRequestHandler;
+import org.apache.wicket.protocol.ws.api.message.TextMessage;
+import org.apache.wicket.util.resource.IResourceStream;
+import org.apache.wicket.util.resource.StringResourceStream;
+import org.apache.wicket.util.tester.WicketTester;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test for https://issues.apache.org/jira/browse/WICKET-5627.
+ * Uses WebSocketBehavior.
+ *
+ * @since 6.17.0
+ */
+public class SendPayloadWithContextTest extends Assert
+{
+	final AtomicBoolean context = new AtomicBoolean(false);
+
+	WicketTester tester;
+
+	@Before
+	public void before()
+	{
+		tester = new WicketTester();
+		WebSocketSettings webSocketSettings = (WebSocketSettings) IWebSocketSettings.Holder.get(tester.getApplication());
+		webSocketSettings.setSendPayloadExecutor(new WebSocketSettings.SameThreadExecutor() {
+			@Override
+			public void run(Runnable command)
+			{
+				context.set(true);
+				super.run(command);
+				context.set(false);
+			}
+		});
+	}
+
+	@After
+	public void after()
+	{
+		tester.destroy();
+	}
+
+	@Test
+	public void sendPayloadWithContext()
+	{
+		SendPayloadWithContextTestPage page = new SendPayloadWithContextTestPage();
+		tester.startPage(page);
+
+		WebSocketTester webSocketTester = new WebSocketTester(tester, page) {
+			@Override
+			protected void onOutMessage(String message)
+			{
+				assertThat(Boolean.parseBoolean(message), is(equalTo(Boolean.TRUE)));
+			}
+		};
+		assertThat(context.get(), is(false));
+		webSocketTester.sendMessage("trigger web socket communication");
+		assertThat(context.get(), is(false));
+		webSocketTester.destroy();
+	}
+
+	class SendPayloadWithContextTestPage extends WebPage implements IMarkupResourceStreamProvider
+	{
+		SendPayloadWithContextTestPage()
+		{
+			add(new WebSocketBehavior()
+			{
+				@Override
+				protected void onMessage(WebSocketRequestHandler handler, TextMessage ignored)
+				{
+					// send an outbound message with the current context encoded as String
+					handler.push(String.valueOf(context.get()));
+				}
+			});
+		}
+
+		@Override
+		public IResourceStream getMarkupResourceStream(MarkupContainer container, Class<?> containerClass)
+		{
+			return new StringResourceStream("<html/>");
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/e877ae21/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketBehaviorTestPage.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketBehaviorTestPage.java b/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketBehaviorTestPage.java
index 504a0c5..ca6e39f 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketBehaviorTestPage.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketBehaviorTestPage.java
@@ -16,6 +16,9 @@
  */
 package org.apache.wicket.protocol.ws.util.tester;
 
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.protocol.ws.api.WebSocketRequestHandler;
 import org.apache.wicket.markup.IMarkupResourceStreamProvider;
@@ -50,7 +53,7 @@ class WebSocketBehaviorTestPage extends WebPage implements IMarkupResourceStream
 			protected void onMessage(WebSocketRequestHandler handler, TextMessage message)
 			{
 				// assert the inbould message
-				Assert.assertEquals(expectedMessage, message.getText());
+				Assert.assertThat(message.getText(), is(equalTo(expectedMessage)));
 
 				// now send an outbound message
 				handler.push(Strings.capitalize(expectedMessage));