From 8245079252865d19a929c86bfd67cbe139259f18 Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Mon, 16 Dec 2013 13:08:02 +0200 Subject: Decrease the websocket buffer size due to a Jetty 9.1 issue (#13087) Jetty 9.1 throws if InputBufferSize is set to greater than or equal to MaxTextMessageBufferSize. We cannot simply increase the value of the latter because Atmosphere sets the former first. Thus, its value must be set to less than 32768 (the default for MaxTextMessageBufferSize). This should not cause problems with regard to performance; the original figure of 65536 was more or less an arbitrary choice. Change-Id: If9596fc2bffdd14e8c1f31ff4b9b10d6685e01ed --- shared/src/com/vaadin/shared/communication/PushConstants.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'shared') diff --git a/shared/src/com/vaadin/shared/communication/PushConstants.java b/shared/src/com/vaadin/shared/communication/PushConstants.java index f16cbb7390..4b4f247e5f 100644 --- a/shared/src/com/vaadin/shared/communication/PushConstants.java +++ b/shared/src/com/vaadin/shared/communication/PushConstants.java @@ -27,8 +27,11 @@ public class PushConstants implements Serializable { /** * The size, in bytes, of the receiving buffer used by some servers. + *

+ * Should not be set to a value equal to or greater than 32768 due to a + * Jetty 9.1 issue (see #13087) */ - public static final int WEBSOCKET_BUFFER_SIZE = 65536; + public static final int WEBSOCKET_BUFFER_SIZE = 16384; /** * The maximum size, in characters, of a websocket message fragment. -- cgit v1.2.3 From 0579fba63048ffa8daa22db5243a149e67f73594 Mon Sep 17 00:00:00 2001 From: Tomi Virtanen Date: Mon, 9 Dec 2013 13:44:27 +0200 Subject: Upload control with empty selection (#9602) Event is now sent on submit even if no file is selected. Removed forceSubmit UIDL attribute and replaced it with a UploadClientRpc call. Added TestBench3 test. Change-Id: Id32b82532ec34e61a9c0718413fd1755015d2c30 --- client/src/com/vaadin/client/ui/VUpload.java | 7 +- .../vaadin/client/ui/upload/UploadConnector.java | 14 ++-- server/src/com/vaadin/ui/Upload.java | 14 +--- .../vaadin/shared/ui/upload/UploadClientRpc.java | 26 +++++++ .../tests/components/upload/UploadNoSelection.java | 83 ++++++++++++++++++++++ .../components/upload/UploadNoSelectionTest.java | 56 +++++++++++++++ 6 files changed, 182 insertions(+), 18 deletions(-) create mode 100644 shared/src/com/vaadin/shared/ui/upload/UploadClientRpc.java create mode 100644 uitest/src/com/vaadin/tests/components/upload/UploadNoSelection.java create mode 100644 uitest/src/com/vaadin/tests/components/upload/UploadNoSelectionTest.java (limited to 'shared') diff --git a/client/src/com/vaadin/client/ui/VUpload.java b/client/src/com/vaadin/client/ui/VUpload.java index c08d75e9b7..8e55387d39 100644 --- a/client/src/com/vaadin/client/ui/VUpload.java +++ b/client/src/com/vaadin/client/ui/VUpload.java @@ -295,10 +295,13 @@ public class VUpload extends SimplePanel { /** For internal use only. May be removed or replaced in the future. */ public void submit() { - if (fu.getFilename().length() == 0 || submitted || !enabled) { - VConsole.log("Submit cancelled (disabled, no file or already submitted)"); + if (submitted || !enabled) { + VConsole.log("Submit cancelled (disabled or already submitted)"); return; } + if (fu.getFilename().length() == 0) { + VConsole.log("Submitting empty selection (no file)"); + } // flush possibly pending variable changes, so they will be handled // before upload client.sendPendingVariableChanges(); diff --git a/client/src/com/vaadin/client/ui/upload/UploadConnector.java b/client/src/com/vaadin/client/ui/upload/UploadConnector.java index 937ff438ac..989a913adc 100644 --- a/client/src/com/vaadin/client/ui/upload/UploadConnector.java +++ b/client/src/com/vaadin/client/ui/upload/UploadConnector.java @@ -22,12 +22,22 @@ import com.vaadin.client.UIDL; import com.vaadin.client.ui.AbstractComponentConnector; import com.vaadin.client.ui.VUpload; import com.vaadin.shared.ui.Connect; +import com.vaadin.shared.ui.upload.UploadClientRpc; import com.vaadin.ui.Upload; @Connect(Upload.class) public class UploadConnector extends AbstractComponentConnector implements Paintable { + public UploadConnector() { + registerRpc(UploadClientRpc.class, new UploadClientRpc() { + @Override + public void submitUpload() { + getWidget().submit(); + } + }); + } + @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { if (!isRealUpdate(uidl)) { @@ -37,10 +47,6 @@ public class UploadConnector extends AbstractComponentConnector implements getWidget().t.schedule(400); return; } - if (uidl.hasAttribute("forceSubmit")) { - getWidget().submit(); - return; - } getWidget().setImmediate(getState().immediate); getWidget().client = client; getWidget().paintableId = uidl.getId(); diff --git a/server/src/com/vaadin/ui/Upload.java b/server/src/com/vaadin/ui/Upload.java index 08cabf979a..98f5d2ded9 100644 --- a/server/src/com/vaadin/ui/Upload.java +++ b/server/src/com/vaadin/ui/Upload.java @@ -28,6 +28,7 @@ import com.vaadin.server.NoOutputStreamException; import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.server.StreamVariable.StreamingProgressEvent; +import com.vaadin.shared.ui.upload.UploadClientRpc; /** * Component for uploading files from client to server. @@ -106,11 +107,6 @@ public class Upload extends AbstractComponent implements Component.Focusable, private int nextid; - /** - * Flag to indicate that submitting file has been requested. - */ - private boolean forceSubmit; - /** * Creates a new instance of Upload. * @@ -157,11 +153,6 @@ public class Upload extends AbstractComponent implements Component.Focusable, notStarted = false; return; } - if (forceSubmit) { - target.addAttribute("forceSubmit", true); - forceSubmit = true; - return; - } // The field should be focused if (focus) { target.addAttribute("focus", true); @@ -1011,12 +1002,11 @@ public class Upload extends AbstractComponent implements Component.Focusable, */ public void submitUpload() { markAsDirty(); - forceSubmit = true; + getRpcProxy(UploadClientRpc.class).submitUpload(); } @Override public void markAsDirty() { - forceSubmit = false; super.markAsDirty(); } diff --git a/shared/src/com/vaadin/shared/ui/upload/UploadClientRpc.java b/shared/src/com/vaadin/shared/ui/upload/UploadClientRpc.java new file mode 100644 index 0000000000..1757ddb001 --- /dev/null +++ b/shared/src/com/vaadin/shared/ui/upload/UploadClientRpc.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2013 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.shared.ui.upload; + +import com.vaadin.shared.communication.ClientRpc; + +public interface UploadClientRpc extends ClientRpc { + + /** + * Forces the upload the send selected file to the server. + */ + void submitUpload(); +} diff --git a/uitest/src/com/vaadin/tests/components/upload/UploadNoSelection.java b/uitest/src/com/vaadin/tests/components/upload/UploadNoSelection.java new file mode 100644 index 0000000000..c304293170 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/upload/UploadNoSelection.java @@ -0,0 +1,83 @@ +/* + * Copyright 2000-2013 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.components.upload; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Upload; +import com.vaadin.ui.Upload.FailedEvent; +import com.vaadin.ui.Upload.FinishedEvent; +import com.vaadin.ui.Upload.Receiver; + +public class UploadNoSelection extends AbstractTestUIWithLog implements + Receiver { + + static final String LOG_ID_PREFIX = "Log_row_"; + static final String UPLOAD_ID = "u"; + + static final String UPLOAD_FINISHED = "Upload Finished"; + static final String RECEIVING_UPLOAD = "Receiving upload"; + + static final String FILE_LENGTH_PREFIX = "File length:"; + static final String FILE_NAME_PREFIX = "File name:"; + + @Override + protected Integer getTicketNumber() { + return 9602; + } + + @Override + protected String getTestDescription() { + return "Uploading an empty selection (no file) will trigger FinishedEvent with 0-length file size and empty filename."; + } + + @Override + protected void setup(VaadinRequest request) { + Upload u = new Upload("Upload", this); + u.setId(UPLOAD_ID); + u.setSizeUndefined(); + + addComponent(u); + + u.addFinishedListener(new Upload.FinishedListener() { + @Override + public void uploadFinished(FinishedEvent event) { + log(UPLOAD_FINISHED); + log(FILE_LENGTH_PREFIX + " " + event.getLength()); + log(FILE_NAME_PREFIX + " " + event.getFilename()); + } + }); + u.addFailedListener(new Upload.FailedListener() { + + @Override + public void uploadFailed(FailedEvent event) { + log("Upload Failed"); + log(FILE_LENGTH_PREFIX + " " + event.getLength()); + log(FILE_NAME_PREFIX + " " + event.getFilename()); + } + }); + } + + @Override + public OutputStream receiveUpload(String filename, String MIMEType) { + log(RECEIVING_UPLOAD); + return new ByteArrayOutputStream(); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/upload/UploadNoSelectionTest.java b/uitest/src/com/vaadin/tests/components/upload/UploadNoSelectionTest.java new file mode 100644 index 0000000000..1b30c4080a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/upload/UploadNoSelectionTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2013 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.components.upload; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class UploadNoSelectionTest extends MultiBrowserTest { + + @Test + public void testUploadNoSelection() throws Exception { + openTestURL(); + + // empty content is populated by com.vaadin.tests.util.Log + Assert.assertEquals(" ", getLogRow(0)); + + getSubmitButton().click(); + + // expecting empty file name + assertLogRow(0, 4, UploadNoSelection.FILE_NAME_PREFIX); + // expecting 0-length file + assertLogRow(1, 3, UploadNoSelection.FILE_LENGTH_PREFIX + " " + 0); + assertLogRow(2, 2, UploadNoSelection.UPLOAD_FINISHED); + assertLogRow(3, 1, UploadNoSelection.RECEIVING_UPLOAD); + } + + private WebElement getSubmitButton() { + WebElement element = getDriver().findElement( + By.id(UploadNoSelection.UPLOAD_ID)); + WebElement submitButton = element.findElement(By.className("v-button")); + return submitButton; + } + + private void assertLogRow(int index, int expentedRowNo, + String expectedValueWithoutRowNo) { + Assert.assertEquals(expentedRowNo + ". " + expectedValueWithoutRowNo, + getLogRow(index)); + } +} -- cgit v1.2.3 From efd8f211612fa55a2b35d1c72a9913f2011bfe7a Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Wed, 22 Jan 2014 17:48:19 +0200 Subject: Implement long polling support for push (#13011) * The Transport enum has a new LONG_POLLING constant * AbstractTestUI supports the ?transport=long-polling GET parameter Change-Id: Ic2f5abfbd4aa3c875f5c83932ce5ee6f31c366ad --- shared/src/com/vaadin/shared/ui/ui/Transport.java | 6 ++- .../vaadin/tests/components/AbstractTestUI.java | 30 +++++------ .../vaadin/tests/push/BasicPushLongPolling.java | 34 ++++++++++++ .../tests/push/BasicPushLongPollingTest.java | 19 +++++++ .../tests/push/LongPollingReconnectTest.java | 25 +++++++++ .../tests/push/PushLargeDataLongPolling.java | 32 ++++++++++++ .../tests/push/PushLargeDataLongPollingTest.java | 61 ++++++++++++++++++++++ 7 files changed, 191 insertions(+), 16 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/push/BasicPushLongPolling.java create mode 100644 uitest/src/com/vaadin/tests/push/BasicPushLongPollingTest.java create mode 100644 uitest/src/com/vaadin/tests/push/LongPollingReconnectTest.java create mode 100644 uitest/src/com/vaadin/tests/push/PushLargeDataLongPolling.java create mode 100644 uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java (limited to 'shared') diff --git a/shared/src/com/vaadin/shared/ui/ui/Transport.java b/shared/src/com/vaadin/shared/ui/ui/Transport.java index ea641c0a3c..ebc0ba3aea 100644 --- a/shared/src/com/vaadin/shared/ui/ui/Transport.java +++ b/shared/src/com/vaadin/shared/ui/ui/Transport.java @@ -30,7 +30,11 @@ public enum Transport { /** * HTTP streaming */ - STREAMING("streaming"); + STREAMING("streaming"), + /** + * HTTP long polling + */ + LONG_POLLING("long-polling"); private String identifier; diff --git a/uitest/src/com/vaadin/tests/components/AbstractTestUI.java b/uitest/src/com/vaadin/tests/components/AbstractTestUI.java index 8f92ff3118..cbca4bcf7f 100644 --- a/uitest/src/com/vaadin/tests/components/AbstractTestUI.java +++ b/uitest/src/com/vaadin/tests/components/AbstractTestUI.java @@ -113,27 +113,27 @@ public abstract class AbstractTestUI extends UI { protected void setTransport(VaadinRequest request) { String transport = request.getParameter("transport"); PushConfiguration config = getPushConfiguration(); - PushMode mode = config.getPushMode(); if ("xhr".equals(transport)) { config.setPushMode(PushMode.DISABLED); } else if ("websocket".equals(transport)) { - if (!mode.isEnabled()) { - config.setPushMode(PushMode.AUTOMATIC); - } - config.setTransport(Transport.WEBSOCKET); - // Ensure no fallback is used - getPushConfiguration().setParameter( - PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); + enablePush(Transport.WEBSOCKET); } else if ("streaming".equals(transport)) { - if (!mode.isEnabled()) { - config.setPushMode(PushMode.AUTOMATIC); - } - config.setTransport(Transport.STREAMING); - // Ensure no fallback is used - getPushConfiguration().setParameter( - PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); + enablePush(Transport.STREAMING); + } else if ("long-polling".equals(transport)) { + enablePush(Transport.LONG_POLLING); + } + } + + protected void enablePush(Transport transport) { + PushConfiguration config = getPushConfiguration(); + if (!config.getPushMode().isEnabled()) { + config.setPushMode(PushMode.AUTOMATIC); } + config.setTransport(transport); + // Ensure no fallback is used + getPushConfiguration().setParameter( + PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); } private VerticalLayout layout; diff --git a/uitest/src/com/vaadin/tests/push/BasicPushLongPolling.java b/uitest/src/com/vaadin/tests/push/BasicPushLongPolling.java new file mode 100644 index 0000000000..bbb7895f20 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/BasicPushLongPolling.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2013 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.shared.ui.ui.UIState.PushConfigurationState; + +@Push(transport = Transport.LONG_POLLING) +public class BasicPushLongPolling extends BasicPush { + + @Override + public void init(VaadinRequest request) { + super.init(request); + // Don't use fallback so we can easier detect if long polling fails + getPushConfiguration().setParameter( + PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); + } + +} diff --git a/uitest/src/com/vaadin/tests/push/BasicPushLongPollingTest.java b/uitest/src/com/vaadin/tests/push/BasicPushLongPollingTest.java new file mode 100644 index 0000000000..b526a11d38 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/BasicPushLongPollingTest.java @@ -0,0 +1,19 @@ +/* + * Copyright 2000-2013 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; + +public class BasicPushLongPollingTest extends BasicPushTest { +} \ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/push/LongPollingReconnectTest.java b/uitest/src/com/vaadin/tests/push/LongPollingReconnectTest.java new file mode 100644 index 0000000000..81c974e1e5 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/LongPollingReconnectTest.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2013 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; + +public class LongPollingReconnectTest extends PushReconnectTest { + + @Override + protected Class getUIClass() { + return BasicPushLongPolling.class; + } + +} diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataLongPolling.java b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPolling.java new file mode 100644 index 0000000000..52a647115a --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPolling.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2013 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.shared.ui.ui.UIState.PushConfigurationState; + +@Push(transport = Transport.LONG_POLLING) +public class PushLargeDataLongPolling extends PushLargeData { + + @Override + protected void setup(VaadinRequest request) { + super.setup(request); + getPushConfiguration().setParameter( + PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); + } +} diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java new file mode 100644 index 0000000000..624310f1b5 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2013 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.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.support.ui.ExpectedConditions; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class PushLargeDataLongPollingTest extends MultiBrowserTest { + + @Test + public void testLongPollingLargeData() { + openTestURL(); + + // Without this there is a large chance that we will wait for all pushes + // to complete before moving on + testBench(driver).disableWaitForVaadin(); + + push(); + // Push complete. Browser will reconnect now as > 10MB has been sent + // Push again to ensure push still works + push(); + + } + + private void push() { + // Wait for startButton to be present + waitForElementToBePresent(vaadinLocatorById("startButton")); + + String logRow0Id = "Log_row_0"; + By logRow0 = vaadinLocatorById(logRow0Id); + + vaadinElementById("startButton").click(); + // Wait for push to start + waitUntil(ExpectedConditions.textToBePresentInElement(logRow0, + "Package ")); + + // Wait for until push should be done + sleep(PushLargeData.DEFAULT_DURATION_MS); + + // Wait until push is actually done + waitUntil(ExpectedConditions.textToBePresentInElement(logRow0, + "Push complete")); + } + +} -- cgit v1.2.3