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 2012/10/01 14:42:09 UTC
git commit: WICKET-4793 Support Jetty 9.x websocket implementation
Updated Branches:
refs/heads/master 8fe07e5de -> 77ac60071
WICKET-4793 Support Jetty 9.x websocket implementation
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/77ac6007
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/77ac6007
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/77ac6007
Branch: refs/heads/master
Commit: 77ac60071dee246ab634ec49eb67b8544b173838
Parents: 8fe07e5
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
Authored: Mon Oct 1 15:41:22 2012 +0300
Committer: Martin Tzvetanov Grigorov <mg...@apache.org>
Committed: Mon Oct 1 15:41:22 2012 +0300
----------------------------------------------------------------------
pom.xml | 1 +
.../wicket-native-websocket/pom.xml | 1 +
.../wicket-native-websocket-jetty9/pom.xml | 82 ++++++++++
.../protocol/http/Jetty9WebSocketFilter.java | 119 +++++++++++++++
.../ws/jetty/Jetty9WebSocketConnection.java | 110 +++++++++++++
.../ws/jetty/Jetty9WebSocketProcessor.java | 102 ++++++++++++
.../ws/util/license/ApacheLicenceHeaderTest.java | 34 ++++
7 files changed, 449 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/77ac6007/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index eb7eb5b..ce18916 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,6 +31,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jetty.version>7.6.3.v20120416</jetty.version>
+ <jetty9.version>9.0.0.M0</jetty9.version>
<spring.version>3.0.7.RELEASE</spring.version>
<maven.javadoc.version>2.8.1</maven.javadoc.version>
<maven.surefire.version>2.12.2</maven.surefire.version>
http://git-wip-us.apache.org/repos/asf/wicket/blob/77ac6007/wicket-experimental/wicket-native-websocket/pom.xml
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-native-websocket/pom.xml b/wicket-experimental/wicket-native-websocket/pom.xml
index 9593ab6..e080d83 100644
--- a/wicket-experimental/wicket-native-websocket/pom.xml
+++ b/wicket-experimental/wicket-native-websocket/pom.xml
@@ -31,6 +31,7 @@
<modules>
<module>wicket-native-websocket-core</module>
<module>wicket-native-websocket-jetty</module>
+ <module>wicket-native-websocket-jetty9</module>
<module>wicket-native-websocket-tomcat</module>
</modules>
<dependencyManagement>
http://git-wip-us.apache.org/repos/asf/wicket/blob/77ac6007/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/pom.xml
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/pom.xml b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/pom.xml
new file mode 100644
index 0000000..1f58eef
--- /dev/null
+++ b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/pom.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.wicket</groupId>
+ <artifactId>wicket-native-websocket</artifactId>
+ <version>0.4-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>wicket-native-websocket-jetty9</artifactId>
+ <packaging>jar</packaging>
+ <version>0.4-SNAPSHOT</version>
+ <name>Wicket Native WebSocket Jetty 9</name>
+ <description>Provides the code specific to integrate with Jetty 9 web container</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.wicket</groupId>
+ <artifactId>wicket-native-websocket-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty.websocket</groupId>
+ <artifactId>websocket-server</artifactId>
+ <version>${jetty9.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>
+ org.apache.felix
+ </groupId>
+ <artifactId>
+ maven-bundle-plugin
+ </artifactId>
+ <versionRange>
+ [2.3.7,)
+ </versionRange>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <ignore />
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/wicket/blob/77ac6007/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/main/java/org/apache/wicket/protocol/http/Jetty9WebSocketFilter.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/main/java/org/apache/wicket/protocol/http/Jetty9WebSocketFilter.java b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/main/java/org/apache/wicket/protocol/http/Jetty9WebSocketFilter.java
new file mode 100644
index 0000000..2ecfb7a
--- /dev/null
+++ b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/main/java/org/apache/wicket/protocol/http/Jetty9WebSocketFilter.java
@@ -0,0 +1,119 @@
+/*
+ * 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.http;
+
+import java.io.IOException;
+
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.protocol.ws.jetty.Jetty9WebSocketProcessor;
+import org.eclipse.jetty.websocket.core.api.UpgradeRequest;
+import org.eclipse.jetty.websocket.core.api.UpgradeResponse;
+import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
+import org.eclipse.jetty.websocket.server.WebSocketCreator;
+import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An upgrade filter that uses Jetty9's WebSocketServerFactory to decide whether to upgrade or not.
+ */
+public class Jetty9WebSocketFilter extends AbstractUpgradeFilter
+{
+ private static final Logger LOG = LoggerFactory.getLogger(Jetty9WebSocketFilter.class);
+
+ private WebSocketServerFactory _webSocketFactory;
+
+ @Override
+ public void init(final boolean isServlet, final FilterConfig filterConfig)
+ throws ServletException
+ {
+ super.init(isServlet, filterConfig);
+
+ try
+ {
+ WebSocketPolicy serverPolicy = WebSocketPolicy.newServerPolicy();
+ String bs = filterConfig.getInitParameter("bufferSize");
+ if (bs != null)
+ serverPolicy.setBufferSize(Integer.parseInt(bs));
+ String max = filterConfig.getInitParameter("maxIdleTime");
+ if (max != null)
+ serverPolicy.setIdleTimeout(Integer.parseInt(max));
+
+ max = filterConfig.getInitParameter("maxTextMessageSize");
+ if (max != null)
+ serverPolicy.setMaxTextMessageSize(Integer.parseInt(max));
+
+ max = filterConfig.getInitParameter("maxBinaryMessageSize");
+ if (max != null)
+ serverPolicy.setMaxBinaryMessageSize(Integer.parseInt(max));
+ _webSocketFactory = new WebSocketServerFactory(serverPolicy);
+
+ _webSocketFactory.setCreator(new WebSocketCreator()
+ {
+ @Override
+ public Object createWebSocket(UpgradeRequest upgradeRequest,
+ UpgradeResponse upgradeResponse)
+ {
+ return new Jetty9WebSocketProcessor(upgradeRequest, upgradeResponse,
+ getApplication());
+ }
+ });
+
+ _webSocketFactory.start();
+ }
+ catch (ServletException x)
+ {
+ throw x;
+ }
+ catch (Exception x)
+ {
+ throw new ServletException(x);
+ }
+ }
+
+ @Override
+ protected boolean acceptWebSocket(HttpServletRequest req, HttpServletResponse resp,
+ Application application) throws ServletException, IOException
+ {
+ return super.acceptWebSocket(req, resp, application) &&
+ _webSocketFactory.acceptWebSocket(req, resp);
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public void destroy()
+ {
+ try
+ {
+ if (_webSocketFactory != null)
+ {
+ _webSocketFactory.stop();
+ }
+ }
+ catch (Exception x)
+ {
+ LOG.warn("A problem occurred while stopping the web socket factory", x);
+ }
+
+ super.destroy();
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/77ac6007/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/main/java/org/apache/wicket/protocol/ws/jetty/Jetty9WebSocketConnection.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/main/java/org/apache/wicket/protocol/ws/jetty/Jetty9WebSocketConnection.java b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/main/java/org/apache/wicket/protocol/ws/jetty/Jetty9WebSocketConnection.java
new file mode 100644
index 0000000..bfc5d01
--- /dev/null
+++ b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/main/java/org/apache/wicket/protocol/ws/jetty/Jetty9WebSocketConnection.java
@@ -0,0 +1,110 @@
+/*
+ * 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.jetty;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.concurrent.ExecutionException;
+
+import org.apache.wicket.protocol.ws.api.IWebSocketConnection;
+import org.apache.wicket.util.lang.Args;
+import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.FutureCallback;
+import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
+
+/**
+ * A wrapper around Jetty9's native WebSocket.Connection
+ *
+ * @since 6.2
+ */
+public class Jetty9WebSocketConnection implements IWebSocketConnection
+{
+ private final WebSocketConnection connection;
+
+ /**
+ * Constructor.
+ *
+ * @param connection
+ * the jetty websocket connection
+ */
+ public Jetty9WebSocketConnection(WebSocketConnection connection)
+ {
+ this.connection = Args.notNull(connection, "connection");
+ }
+
+ @Override
+ public boolean isOpen()
+ {
+ return connection.isOpen();
+ }
+
+ @Override
+ public void close(int code, String reason)
+ {
+ if (isOpen())
+ {
+ connection.close(code, reason);
+ }
+ }
+
+ @Override
+ public IWebSocketConnection sendMessage(String message) throws IOException
+ {
+ checkClosed();
+
+ FutureCallback<Void> waiter = new FutureCallback<Void>();
+ connection.write(null, waiter, message);
+ waitForMessageSent(waiter);
+ return this;
+ }
+
+ @Override
+ public IWebSocketConnection sendMessage(byte[] message, int offset, int length)
+ throws IOException
+ {
+ checkClosed();
+
+ FutureCallback<Void> waiter = new FutureCallback<Void>();
+ connection.write(null, new Callback.Empty<Void>(), message, offset, length);
+ waitForMessageSent(waiter);
+ return this;
+ }
+
+ private void waitForMessageSent(FutureCallback<?> waiter) throws IOException
+ {
+ try
+ {
+ waiter.get();
+ }
+ catch (InterruptedException e)
+ {
+ throw new InterruptedIOException();
+ }
+ catch (ExecutionException e)
+ {
+ FutureCallback.rethrow(e);
+ }
+ }
+
+ private void checkClosed()
+ {
+ if (!isOpen())
+ {
+ throw new IllegalStateException("The connection is closed.");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/77ac6007/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/main/java/org/apache/wicket/protocol/ws/jetty/Jetty9WebSocketProcessor.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/main/java/org/apache/wicket/protocol/ws/jetty/Jetty9WebSocketProcessor.java b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/main/java/org/apache/wicket/protocol/ws/jetty/Jetty9WebSocketProcessor.java
new file mode 100644
index 0000000..7a5b1d4
--- /dev/null
+++ b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/main/java/org/apache/wicket/protocol/ws/jetty/Jetty9WebSocketProcessor.java
@@ -0,0 +1,102 @@
+/*
+ * 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.jetty;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.protocol.ws.api.AbstractWebSocketProcessor;
+import org.eclipse.jetty.websocket.core.annotations.WebSocket;
+import org.eclipse.jetty.websocket.core.api.UpgradeRequest;
+import org.eclipse.jetty.websocket.core.api.UpgradeResponse;
+import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
+import org.eclipse.jetty.websocket.core.api.WebSocketException;
+import org.eclipse.jetty.websocket.core.api.WebSocketListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An {@link org.apache.wicket.protocol.ws.api.IWebSocketProcessor processor} that integrates with
+ * Jetty 9.x {@link WebSocket web socket} implementation.
+ *
+ * @since 6.2
+ */
+public class Jetty9WebSocketProcessor extends AbstractWebSocketProcessor
+ implements
+ WebSocketListener
+{
+ private static final Logger LOG = LoggerFactory.getLogger(Jetty9WebSocketProcessor.class);
+
+ /**
+ * Constructor.
+ *
+ * @param upgradeRequest
+ * the jetty upgrade request
+ * @param upgradeResponse
+ * the jetty upgrade response
+ * @param application
+ * the current Wicket Application
+ */
+ public Jetty9WebSocketProcessor(final UpgradeRequest upgradeRequest,
+ final UpgradeResponse upgradeResponse, final Application application)
+ {
+ super((HttpServletRequest)((HttpServletRequestWrapper)upgradeRequest).getRequest(),
+ application);
+ }
+
+ @Override
+ public void onWebSocketConnect(WebSocketConnection connection)
+ {
+ onConnect(new Jetty9WebSocketConnection(connection));
+ }
+
+ @Override
+ public void onWebSocketText(String message)
+ {
+ onMessage(message);
+ }
+
+ @Override
+ public void onWebSocketBinary(byte[] payload, int offset, int len)
+ {
+ onMessage(payload, offset, len);
+ }
+
+ @Override
+ public void onWebSocketClose(int statusCode, String reason)
+ {
+ onClose(statusCode, reason);
+ }
+
+ @Override
+ public void onWebSocketException(WebSocketException error)
+ {
+ LOG.error("An error occurred when using WebSocket.", error);
+ }
+
+ @Override
+ public void onOpen(Object connection)
+ {
+ if (!(connection instanceof WebSocketConnection))
+ {
+ throw new IllegalArgumentException(WebSocketConnection.class.getName() +
+ " can work only with " + WebSocketConnection.class.getName());
+ }
+ onWebSocketConnect((WebSocketConnection)connection);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/77ac6007/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/test/java/org/apache/wicket/protocol/ws/util/license/ApacheLicenceHeaderTest.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/test/java/org/apache/wicket/protocol/ws/util/license/ApacheLicenceHeaderTest.java b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/test/java/org/apache/wicket/protocol/ws/util/license/ApacheLicenceHeaderTest.java
new file mode 100644
index 0000000..9e3759d
--- /dev/null
+++ b/wicket-experimental/wicket-native-websocket/wicket-native-websocket-jetty9/src/test/java/org/apache/wicket/protocol/ws/util/license/ApacheLicenceHeaderTest.java
@@ -0,0 +1,34 @@
+/*
+ * 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.license;
+
+import org.apache.wicket.util.license.ApacheLicenseHeaderTestCase;
+
+/**
+ * Test that the license headers are in place in this project. The tests are run from
+ * {@link org.apache.wicket.util.license.ApacheLicenseHeaderTestCase}, but you can add project specific tests here if needed.
+ */
+public class ApacheLicenceHeaderTest extends ApacheLicenseHeaderTestCase
+{
+ /**
+ * Construct.
+ */
+ public ApacheLicenceHeaderTest()
+ {
+ // addHeaders = true;
+ }
+}