]> source.dussan.org Git - vaadin-framework.git/commitdiff
Make push path configurable (#14432).
authorTapio Aali <tapio@vaadin.com>
Mon, 9 Feb 2015 13:37:41 +0000 (15:37 +0200)
committerVaadin Code Review <review@vaadin.com>
Wed, 18 Feb 2015 14:44:27 +0000 (14:44 +0000)
In order to use websockets with Weblogic 12.1.2 or later, push path 'ws'
needs to be used instead of 'PUSH'.

Change-Id: Ia90d11c20a375cef9cf4a53986a70d616a83db06

17 files changed:
WebContent/WEB-INF/web.xml
client/src/com/vaadin/client/communication/AtmospherePushConnection.java
push/build.xml
push/ivy.xml
server/src/com/vaadin/server/Constants.java
server/src/com/vaadin/server/DefaultDeploymentConfiguration.java
server/src/com/vaadin/server/DeploymentConfiguration.java
server/src/com/vaadin/server/ServletPortletHelper.java
server/src/com/vaadin/server/communication/UIInitHandler.java
server/src/com/vaadin/ui/PushConfiguration.java
server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java
server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java
shared/src/com/vaadin/shared/ApplicationConstants.java
shared/src/com/vaadin/shared/ui/ui/UIState.java
uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java
uitest/src/com/vaadin/tests/push/PushPath.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/push/PushPathTest.java [new file with mode: 0644]

index ef6036420203e644a12ac2e64aa1ef90a6fd33cc..c1102f46827510997c54db4358bb8724289471c9 100644 (file)
@@ -87,9 +87,9 @@
     </servlet>
 
     <servlet>
-        <!-- This servlet is a separate instance for the sole purpose of 
-            testing #12446 (com.vaadin.tests.components.ui.TimeoutRedirectResetsOnActivity) 
-            because it modifies the VaadinService timeout parameters -->
+        <!-- This servlet is a separate instance for the sole purpose of testing 
+            #12446 (com.vaadin.tests.components.ui.TimeoutRedirectResetsOnActivity) because 
+            it modifies the VaadinService timeout parameters -->
         <servlet-name>VaadinApplicationRunnerWithTimeoutRedirect</servlet-name>
         <servlet-class>com.vaadin.launcher.ApplicationRunnerServlet</servlet-class>
     </servlet>
         <async-supported>true</async-supported>
     </servlet>
 
+    <!-- For testing custom push path with, for example, Weblogic 12.1.2 -->
+    <servlet>
+        <servlet-name>VaadinApplicationRunnerWithPushPathTest</servlet-name>
+        <servlet-class>com.vaadin.launcher.ApplicationRunnerServlet</servlet-class>
+        <init-param>
+            <param-name>pushPath</param-name>
+            <param-value>ws</param-value>
+        </init-param>
+        <async-supported>true</async-supported>
+    </servlet>
+
     <servlet-mapping>
         <servlet-name>Embed App 1</servlet-name>
         <url-pattern>/embed1/*</url-pattern>
         <url-pattern>/run-push/*</url-pattern>
     </servlet-mapping>
 
+    <servlet-mapping>
+        <servlet-name>VaadinApplicationRunnerWithPushPathTest</servlet-name>
+        <url-pattern>/run-pushpath/*</url-pattern>
+    </servlet-mapping>
+
     <servlet-mapping>
         <servlet-name>IntegrationTest</servlet-name>
         <url-pattern>/integration/*</url-pattern>
index da08928f36ba1ef87467cf49bf79ff50e13e2279..a3a8caa1b42f29beb29337ea2da73f75c4eecde3 100644 (file)
@@ -41,7 +41,7 @@ import elemental.json.JsonObject;
 /**
  * The default {@link PushConnection} implementation that uses Atmosphere for
  * handling the communication channel.
- *
+ * 
  * @author Vaadin Ltd
  * @since 7.1
  */
@@ -133,6 +133,8 @@ public class AtmospherePushConnection implements PushConnection {
      */
     private Command pendingDisconnectCommand;
 
+    private String pushPath;
+
     public AtmospherePushConnection() {
     }
 
@@ -160,6 +162,9 @@ public class AtmospherePushConnection implements PushConnection {
                     pushConfiguration.parameters.get(param));
         }
 
+        pushPath = pushConfiguration.pushPath;
+        assert pushPath != null;
+
         runWhenAtmosphereLoaded(new Command() {
             @Override
             public void execute() {
@@ -176,7 +181,7 @@ public class AtmospherePushConnection implements PushConnection {
     private void connect() {
         String baseUrl = connection
                 .translateVaadinUri(ApplicationConstants.APP_PROTOCOL_PREFIX
-                        + ApplicationConstants.PUSH_PATH + '/');
+                        + pushPath + '/');
         String extraParams = UIConstants.UI_ID_PARAMETER + "="
                 + connection.getConfiguration().getUIId();
 
@@ -251,9 +256,9 @@ public class AtmospherePushConnection implements PushConnection {
     /**
      * Called whenever a server push connection is established (or
      * re-established).
-     *
+     * 
      * @param response
-     *
+     * 
      * @since 7.2
      */
     protected void onConnect(AtmosphereResponse response) {
@@ -342,7 +347,7 @@ public class AtmospherePushConnection implements PushConnection {
     /**
      * Called if the push connection fails. Atmosphere will automatically retry
      * the connection until successful.
-     *
+     * 
      */
     protected void onError(AtmosphereResponse response) {
         state = State.DISCONNECTED;
index 9afe76620caeaf31900144f1b1f76aa2cf698c75..4e180fa03d039cb0a8b26ed769799545a3c078af 100644 (file)
@@ -18,7 +18,7 @@
         location="${result.dir}/js/VAADIN/vaadinPush.debug.js" />
 
     <!-- Keep the version number in sync with ivy.xml, server/src/com/vaadin/server/Constants.java -->
-    <property name="atmosphere.runtime.version" value="2.2.4.vaadin2" />
+    <property name="atmosphere.runtime.version" value="2.2.4.vaadin3" />
     <property name="jquery.js" location="lib/jquery/jquery-1.11.0.js" />
 
     <path id="classpath.compile.custom" />
index b899b34af7dbcad46216370fbb648b095b09813b..b8d943f176a21c17169e374c2e978827caf7dd11 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE ivy-module [
 <!-- Keep the version number in sync with build.xml -->
-    <!ENTITY atmosphere.runtime.version "2.2.4.vaadin2">
+    <!ENTITY atmosphere.runtime.version "2.2.4.vaadin3">
 
     <!ENTITY atmosphere.js.version "2.2.6.vaadin3">
 ]>
index 8036490333a300949dfac3279bad5d483c0b84b4..b20b8004a5a577c6075c29da68b96a57df832867 100644 (file)
@@ -67,7 +67,7 @@ public interface Constants {
 
     // Keep the version number in sync with push/build.xml and other locations
     // listed in that file
-    static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.2.4.vaadin2";
+    static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.2.4.vaadin3";
 
     static final String INVALID_ATMOSPHERE_VERSION_WARNING = "\n"
             + "=================================================================\n"
@@ -132,11 +132,12 @@ public interface Constants {
     static final String SERVLET_PARAMETER_RESOURCE_CACHE_TIME = "resourceCacheTime";
     static final String SERVLET_PARAMETER_HEARTBEAT_INTERVAL = "heartbeatInterval";
     static final String SERVLET_PARAMETER_CLOSE_IDLE_SESSIONS = "closeIdleSessions";
-    static final String SERVLET_PARAMETER_PUSH_MODE = "pushMode";
     static final String SERVLET_PARAMETER_UI_PROVIDER = "UIProvider";
     static final String SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING = "legacyPropertyToString";
     static final String SERVLET_PARAMETER_SYNC_ID_CHECK = "syncIdCheck";
     static final String SERVLET_PARAMETER_SENDURLSASPARAMETERS = "sendUrlsAsParameters";
+    static final String SERVLET_PARAMETER_PUSH_MODE = "pushMode";
+    static final String SERVLET_PARAMETER_PUSH_PATH = "pushPath";
 
     // Configurable parameter names
     static final String PARAMETER_VAADIN_RESOURCES = "Resources";
index b26e0484314570013f806c90169aeccc5cc25f06..5402979be886296977be8c52e56a2be2bbabf447 100644 (file)
@@ -61,6 +61,13 @@ public class DefaultDeploymentConfiguration extends
 
     public static final boolean DEFAULT_SEND_URLS_AS_PARAMETERS = true;
 
+    /**
+     * Default value for {@link #getPushPath()} = {@value} .
+     * 
+     * @since 7.4.1
+     */
+    public static final String DEFAULT_PUSH_PATH = "PUSH";
+
     private final Properties initParameters;
     private boolean productionMode;
     private boolean xsrfProtectionEnabled;
@@ -284,6 +291,18 @@ public class DefaultDeploymentConfiguration extends
         return initParameters;
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The default path {@link DEFAULT_PUSH_PATH} can be changed by using init
+     * parameter {@link Constants.SERVLET_PARAMETER_PUSH_PATH}.
+     */
+    @Override
+    public String getPushPath() {
+        return getApplicationOrSystemProperty(
+                Constants.SERVLET_PARAMETER_PUSH_PATH, DEFAULT_PUSH_PATH);
+    }
+
     /**
      * Log a warning if Vaadin is not running in production mode.
      */
index 968ec7c0c3471436fa28b0e646ea03d548cdbd67..06556e28a78f83ab7ecd8422fb9c24dc50f9488d 100644 (file)
@@ -195,7 +195,7 @@ public interface DeploymentConfiguration extends Serializable {
      * 
      * @since 7.4
      * 
-     * @return UI class name
+     * @return the name of the widgetset
      */
     public String getWidgetset(String defaultValue);
 
@@ -213,6 +213,14 @@ public interface DeploymentConfiguration extends Serializable {
      */
     public String getClassLoaderName();
 
+    /**
+     * Returns the push path configuration option value. Should never be null.
+     * 
+     * @since 7.4.1
+     * @return the path used with server push
+     */
+    public String getPushPath();
+
     /**
      * Returns to legacy Property.toString() mode used. See
      * {@link AbstractProperty#isLegacyToStringEnabled()} for more information.
index 197d9fe4161d8b0d21ea1d5f5b41abdcc5cc79c4..1f0c7f02b93e7ef5712f23e0c62b1a203aa3471e 100644 (file)
@@ -124,7 +124,8 @@ public class ServletPortletHelper implements Serializable {
     }
 
     public static boolean isPushRequest(VaadinRequest request) {
-        return hasPathPrefix(request, ApplicationConstants.PUSH_PATH + '/');
+        return hasPathPrefix(request, request.getService()
+                .getDeploymentConfiguration().getPushPath() + '/');
     }
 
     public static void initDefaultUIProvider(VaadinSession session,
index 3a6dc1e55fcf6edd88a2c5acf1b31955292eb2b6..02b4e64159676cd0154dec12e75f13134a2e4d3c 100644 (file)
@@ -198,10 +198,11 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
 
         PushMode pushMode = provider.getPushMode(event);
         if (pushMode == null) {
-            pushMode = session.getService().getDeploymentConfiguration()
-                    .getPushMode();
+            pushMode = session.getConfiguration().getPushMode();
         }
         ui.getPushConfiguration().setPushMode(pushMode);
+        ui.getPushConfiguration().setPushPath(
+                session.getConfiguration().getPushPath());
 
         Transport transport = provider.getPushTransport(event);
         if (transport != null) {
index 90ad28542c201784030200411af109d7aee5ed6f..d5e89b4b14ebb1baa0ff90a39329b318e5b8079e 100644 (file)
@@ -104,6 +104,26 @@ public interface PushConfiguration extends Serializable {
      */
     public void setFallbackTransport(Transport fallbackTransport);
 
+    /**
+     * Sets the path that is used with push.
+     * 
+     * @since 7.4.1
+     * @param pushPath
+     *            The path to be used with push
+     * 
+     * @throws IllegalArgumentException
+     *             if the argument is null or empty.
+     */
+    public void setPushPath(String pushPath);
+
+    /**
+     * Returns the path used with push.
+     * 
+     * @since 7.4.1
+     * @return The path that is used with push
+     */
+    public String getPushPath();
+
     /**
      * Returns the given parameter, if set.
      * <p>
@@ -255,6 +275,32 @@ class PushConfigurationImpl implements PushConfiguration {
                 fallbackTransport.getIdentifier());
     }
 
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.vaadin.ui.PushConfiguration#setPushPath(java.lang.String)
+     */
+    @Override
+    public void setPushPath(String pushPath) {
+        if (pushPath != null && !pushPath.isEmpty()) {
+            getState().pushPath = pushPath;
+        } else {
+            throw new IllegalArgumentException(
+                    "Push path can't be empty or null");
+        }
+
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.vaadin.ui.PushConfiguration#getPushPath()
+     */
+    @Override
+    public String getPushPath() {
+        return getState(false).pushPath;
+    }
+
     /*
      * (non-Javadoc)
      * 
@@ -290,5 +336,4 @@ class PushConfigurationImpl implements PushConfiguration {
         return Collections.unmodifiableCollection(getState(false).parameters
                 .keySet());
     }
-
 }
index 0518bea6501267a7a1c87681edb19f45d1e53c9f..ccdbfea150675222de5d282ff74c503b33cf2ff7 100644 (file)
@@ -158,5 +158,9 @@ public class AbstractDeploymentConfigurationTest {
             return DefaultDeploymentConfiguration.DEFAULT_SEND_URLS_AS_PARAMETERS;
         }
 
+        @Override
+        public String getPushPath() {
+            return null;
+        }
     }
 }
index ddee23a9ecf4eea3666342a4bd8036ce9d7a4baa..175dcb2b9423a972b91e5119a54d66db06793171 100644 (file)
@@ -22,6 +22,7 @@ public class MockDeploymentConfiguration extends
     private LegacyProperyToStringMode legacyPropertyToStringMode = LegacyProperyToStringMode.DISABLED;
     private boolean syncIdCheckEnabled = true;
     private boolean sendUrlsAsParameters = true;
+    private String pushPath = "PUSH";
 
     @Override
     public boolean isProductionMode() {
@@ -125,4 +126,9 @@ public class MockDeploymentConfiguration extends
         return sendUrlsAsParameters;
     }
 
+    @Override
+    public String getPushPath() {
+        return pushPath;
+    }
+
 }
index d7aaee6267a6e89b22cf387986ceff5d1cabc016..990564a6b83b4a77621fc1dad97a80d5d9ad6217 100644 (file)
@@ -28,8 +28,6 @@ public class ApplicationConstants implements Serializable {
 
     public static final String HEARTBEAT_PATH = "HEARTBEAT";
 
-    public static final String PUSH_PATH = "PUSH";
-
     public static final String PUBLISHED_FILE_PATH = APP_PATH + '/'
             + "PUBLISHED";
 
@@ -76,7 +74,7 @@ public class ApplicationConstants implements Serializable {
     /**
      * The name of the javascript containing the bootstrap code. The file is
      * located in the VAADIN directory.
-     *
+     * 
      * @since 7.3
      */
     public static final String VAADIN_BOOTSTRAP_JS = "vaadinBootstrap.js";
@@ -90,7 +88,7 @@ public class ApplicationConstants implements Serializable {
     /**
      * The name of the debug version of the javascript containing push support.
      * The file is located in the VAADIN directory.
-     *
+     * 
      * @since 7.1.6
      */
     public static final String VAADIN_PUSH_DEBUG_JS = "vaadinPush.debug.js";
@@ -102,14 +100,14 @@ public class ApplicationConstants implements Serializable {
 
     /**
      * The name of the parameter used to transmit RPC invocations
-     *
+     * 
      * @since 7.2
      */
     public static final String RPC_INVOCATIONS = "rpc";
 
     /**
      * The name of the parameter used to transmit the CSRF token
-     *
+     * 
      * @since 7.2
      */
     public static final String CSRF_TOKEN = "csrfToken";
@@ -118,7 +116,7 @@ public class ApplicationConstants implements Serializable {
      * The name of the parameter used to transmit the sync id. The value can be
      * set to -1 e.g. when testing with pre-recorded requests to make the
      * framework ignore the sync id.
-     *
+     * 
      * @see com.vaadin.ui.ConnectorTracker#getCurrentSyncId()
      * @since 7.2
      */
index 2f51fef6ee660bcb14abbf059c88e4d094df0b8e..04e182c5d4adda2dad6520e56cbdbc57bb1d2872 100644 (file)
@@ -110,6 +110,7 @@ public class UIState extends TabIndexState {
         public static final String FALLBACK_TRANSPORT_PARAM = "fallbackTransport";
 
         public PushMode mode = PushMode.DISABLED;
+        public String pushPath;
         public Map<String, String> parameters = new HashMap<String, String>();
         {
             parameters
index e2b93ab7d235465ed1b1658fb52cd37fc465faf5..5c2e58d3a2263e55de0c0e7f569cff5b8116a610 100644 (file)
@@ -402,9 +402,12 @@ public class ApplicationRunnerServlet extends LegacyVaadinServlet {
                         try {
                             VaadinServletService service = (VaadinServletService) VaadinService
                                     .getCurrent();
-                            session = service
-                                    .findVaadinSession(new VaadinServletRequest(
-                                            currentRequest, service));
+                            if (service != null) {
+                                session = service
+                                        .findVaadinSession(new VaadinServletRequest(
+                                                currentRequest, service));
+                            }
+
                         } finally {
                             /*
                              * Clear some state set by findVaadinSession to
diff --git a/uitest/src/com/vaadin/tests/push/PushPath.java b/uitest/src/com/vaadin/tests/push/PushPath.java
new file mode 100644 (file)
index 0000000..20771bd
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ * 
+ * Licensed 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 com.vaadin.tests.push;
+
+import com.vaadin.annotations.Push;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.ui.Transport;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Label;
+
+@Push(transport = Transport.WEBSOCKET)
+public class PushPath extends AbstractTestUI {
+
+    public static final String PUSH_PATH_LABEL_ID = "push-path-label-id";
+    public static final String PUSH_PATH_LABEL_TEXT = "Label by push";
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        // use only websockets
+        getPushConfiguration().setFallbackTransport(Transport.WEBSOCKET);
+
+        String pushPath = request.getService().getDeploymentConfiguration()
+                .getPushPath();
+        String transport = getPushConfiguration().getTransport().name();
+        Label pushPathLabel = new Label(String.format(
+                "Waiting for push from path '%s' using %s in 3 seconds.",
+                pushPath, transport));
+        addComponent(pushPathLabel);
+
+        new PushThread().start();
+    }
+
+    public class PushThread extends Thread {
+
+        @Override
+        public void run() {
+            try {
+                Thread.sleep(3000);
+            } catch (InterruptedException e) {
+            }
+            access(new Runnable() {
+
+                @Override
+                public void run() {
+                    Label pushLabel = new Label(PUSH_PATH_LABEL_TEXT);
+                    pushLabel.setId(PUSH_PATH_LABEL_ID);
+                    addComponent(pushLabel);
+                }
+            });
+
+        }
+    }
+
+    @Override
+    public Integer getTicketNumber() {
+        return 14432;
+    }
+
+    @Override
+    public String getDescription() {
+        return "Push path should be configurable since some servers can't serve both websockets and long polling from same URL.";
+    }
+
+}
diff --git a/uitest/src/com/vaadin/tests/push/PushPathTest.java b/uitest/src/com/vaadin/tests/push/PushPathTest.java
new file mode 100644 (file)
index 0000000..6357c28
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ * 
+ * Licensed 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 com.vaadin.tests.push;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.tests.tb3.WebsocketTest;
+
+public class PushPathTest extends WebsocketTest {
+
+    private static final int TEN_SECONDS_IN_MS = 10 * 1000;
+
+    @Test
+    public void testCustomPushPath() throws InterruptedException {
+        openTestURL();
+        sleep(TEN_SECONDS_IN_MS);
+        Assert.assertEquals(vaadinElementById(PushPath.PUSH_PATH_LABEL_ID)
+                .getText(), PushPath.PUSH_PATH_LABEL_TEXT);
+    }
+
+    @Override
+    public String getDeploymentPath() {
+        Class<?> uiClass = getUIClass();
+        return "/run-pushpath/" + uiClass.getCanonicalName();
+    }
+
+}