From 98e1d886ab4aa32227d73cf1d16196ed999a54b5 Mon Sep 17 00:00:00 2001 From: Konstantin Krivopustov Date: Thu, 29 Nov 2012 12:40:41 +0000 Subject: [PATCH] Refs #1697 Desktop: Unable to updload file if app cluster is used --- .../haulmont/cuba/client/ClientConfig.java | 4 +- .../components/DesktopFileUploadField.java | 2 +- .../desktop/src/cuba-desktop-app.properties | 2 +- .../cuba/gui/export/FileDataProvider.java | 92 ++++++++++++------- .../cuba/gui/export/RestApiDataProvider.java | 76 ++++++++++----- .../gui/export/SimpleFileDataProvider.java | 86 +++++++++++------ modules/portal/src/cuba-portal-app.properties | 2 +- modules/web/src/cuba-web-app.properties | 2 +- 8 files changed, 177 insertions(+), 89 deletions(-) diff --git a/modules/client/src/com/haulmont/cuba/client/ClientConfig.java b/modules/client/src/com/haulmont/cuba/client/ClientConfig.java index f00f81fff5..63283e912d 100644 --- a/modules/client/src/com/haulmont/cuba/client/ClientConfig.java +++ b/modules/client/src/com/haulmont/cuba/client/ClientConfig.java @@ -31,10 +31,10 @@ public interface ClientConfig extends Config { String getConnectionUrl(); /** - * @return Context of the middleware file download controller.
- * Usually /remoting/download + * @return Context of the middleware file download controller. */ @Property("cuba.fileDownloadContext") + @DefaultString("/download") String getFileDownloadContext(); /** diff --git a/modules/desktop/src/com/haulmont/cuba/desktop/gui/components/DesktopFileUploadField.java b/modules/desktop/src/com/haulmont/cuba/desktop/gui/components/DesktopFileUploadField.java index 6cfdafac0e..579eca225f 100644 --- a/modules/desktop/src/com/haulmont/cuba/desktop/gui/components/DesktopFileUploadField.java +++ b/modules/desktop/src/com/haulmont/cuba/desktop/gui/components/DesktopFileUploadField.java @@ -55,7 +55,7 @@ public class DesktopFileUploadField extends DesktopAbstractComponent im fileUploading = AppBeans.get(FileUploadingAPI.NAME); final JFileChooser fileChooser = new JFileChooser(); - String caption = MessageProvider.getMessage(getClass(), "selectFile"); + String caption = MessageProvider.getMessage(getClass(), "export.selectFile"); impl = new JButton(); impl.setAction(new AbstractAction(caption) { @Override diff --git a/modules/desktop/src/cuba-desktop-app.properties b/modules/desktop/src/cuba-desktop-app.properties index 7833e48005..227b4e075a 100644 --- a/modules/desktop/src/cuba-desktop-app.properties +++ b/modules/desktop/src/cuba-desktop-app.properties @@ -10,7 +10,7 @@ # Middleware connection cuba.connectionUrl=http://localhost:8080/cuba-core -cuba.fileDownloadContext=/remoting/download + # System directories cuba.confDir=${cuba.desktop.home}/conf cuba.logDir=${cuba.desktop.home}/logs diff --git a/modules/gui/src/com/haulmont/cuba/gui/export/FileDataProvider.java b/modules/gui/src/com/haulmont/cuba/gui/export/FileDataProvider.java index bc43ac9661..f46999fbd5 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/export/FileDataProvider.java +++ b/modules/gui/src/com/haulmont/cuba/gui/export/FileDataProvider.java @@ -8,11 +8,13 @@ package com.haulmont.cuba.gui.export; import com.haulmont.cuba.client.ClientConfig; import com.haulmont.cuba.core.entity.FileDescriptor; -import com.haulmont.cuba.core.global.ConfigProvider; -import com.haulmont.cuba.core.global.FileStorageException; -import com.haulmont.cuba.core.global.UserSessionProvider; +import com.haulmont.cuba.core.global.*; +import com.haulmont.cuba.core.sys.remoting.ClusterInvocationSupport; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.ClientConnectionManager; @@ -20,6 +22,7 @@ import org.apache.http.impl.client.DefaultHttpClient; import java.io.IOException; import java.io.InputStream; +import java.util.Iterator; /** * Data provider for FileDescriptor @@ -29,16 +32,25 @@ import java.io.InputStream; */ public class FileDataProvider implements ExportDataProvider { - private static final int HTTP_OK = 200; + protected Log log = LogFactory.getLog(getClass()); - private FileDescriptor fileDescriptor; - private InputStream inputStream; - private boolean closed = false; + protected FileDescriptor fileDescriptor; + protected InputStream inputStream; + protected boolean closed = false; protected ClientConnectionManager connectionManager; + protected ClusterInvocationSupport clusterInvocationSupport = AppBeans.get(ClusterInvocationSupport.NAME); + + protected UserSessionSource userSessionSource = AppBeans.get(UserSessionSource.class); + + protected Configuration configuration = AppBeans.get(Configuration.class); + + protected String fileDownloadContext; + public FileDataProvider(FileDescriptor fileDescriptor) { this.fileDescriptor = fileDescriptor; + fileDownloadContext = configuration.getConfig(ClientConfig.class).getFileDownloadContext(); } public InputStream provide() { @@ -48,36 +60,54 @@ public class FileDataProvider implements ExportDataProvider { if (fileDescriptor == null) throw new IllegalArgumentException("Null file descriptor"); - String fileDownloadContext = ConfigProvider.getConfig(ClientConfig.class).getFileDownloadContext(); - String connectionUrl = ConfigProvider.getConfig(ClientConfig.class).getConnectionUrl(); + for (Iterator iterator = clusterInvocationSupport.getUrlList().iterator(); iterator.hasNext(); ) { + String url = iterator.next() + fileDownloadContext + + "?s=" + userSessionSource.getUserSession().getId() + + "&f=" + fileDescriptor.getId().toString(); - String url = connectionUrl + fileDownloadContext + - "?s=" + UserSessionProvider.getUserSession().getId() + - "&f=" + fileDescriptor.getId().toString(); + HttpClient httpClient = new DefaultHttpClient(); + HttpGet httpGet = new HttpGet(url); - HttpClient httpClient = new DefaultHttpClient(); - HttpGet httpGet = new HttpGet(url); - - try { - HttpResponse httpResponse = httpClient.execute(httpGet); - int httpStatus = httpResponse.getStatusLine().getStatusCode(); - switch (httpStatus) { - case HTTP_OK: + try { + HttpResponse httpResponse = httpClient.execute(httpGet); + int httpStatus = httpResponse.getStatusLine().getStatusCode(); + if (httpStatus == HttpStatus.SC_OK) { HttpEntity httpEntity = httpResponse.getEntity(); - if (httpEntity != null) + if (httpEntity != null) { inputStream = httpEntity.getContent(); + break; + } else { + log.debug("Unable to download file from " + url + "\nHttpEntity is null"); + if (iterator.hasNext()) + log.debug("Trying next URL"); + else + throw new RuntimeException( + new FileStorageException(FileStorageException.Type.IO_EXCEPTION, + fileDescriptor.getName()) + ); + } + } else { + log.debug("Unable to download file from " + url + "\n" + httpResponse.getStatusLine()); + if (iterator.hasNext()) + log.debug("Trying next URL"); else - throw new FileStorageException(FileStorageException.Type.IO_EXCEPTION, - fileDescriptor.getName()); - break; - default: - throw new FileStorageException(FileStorageException.Type.fromHttpStatus(httpStatus), - fileDescriptor.getName()); + throw new RuntimeException( + new FileStorageException(FileStorageException.Type.fromHttpStatus(httpStatus), + fileDescriptor.getName()) + ); + } + } catch (IOException ex) { + log.debug("Unable to download file from " + url + "\n" + ex); + if (iterator.hasNext()) + log.debug("Trying next URL"); + else + throw new RuntimeException( + new FileStorageException(FileStorageException.Type.IO_EXCEPTION, + fileDescriptor.getName(), ex) + ); + } finally { + connectionManager = httpClient.getConnectionManager(); } - } catch (Exception ex) { - throw new RuntimeException(ex); - } finally { - connectionManager = httpClient.getConnectionManager(); } return inputStream; diff --git a/modules/gui/src/com/haulmont/cuba/gui/export/RestApiDataProvider.java b/modules/gui/src/com/haulmont/cuba/gui/export/RestApiDataProvider.java index 9f756bdc02..0b540278f1 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/export/RestApiDataProvider.java +++ b/modules/gui/src/com/haulmont/cuba/gui/export/RestApiDataProvider.java @@ -7,9 +7,15 @@ package com.haulmont.cuba.gui.export; import com.haulmont.cuba.client.ClientConfig; +import com.haulmont.cuba.core.global.AppBeans; import com.haulmont.cuba.core.global.ConfigProvider; +import com.haulmont.cuba.core.global.FileStorageException; +import com.haulmont.cuba.core.sys.remoting.ClusterInvocationSupport; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.ClientConnectionManager; @@ -17,6 +23,7 @@ import org.apache.http.impl.client.DefaultHttpClient; import java.io.IOException; import java.io.InputStream; +import java.util.Iterator; /** * Class providing data using Rest API by the query given @@ -28,12 +35,14 @@ public class RestApiDataProvider implements ExportDataProvider { public static final String API_URL = "/api/"; - private static final int HTTP_OK = 200; + private Log log = LogFactory.getLog(getClass()); - private ClientConnectionManager connectionManager; - private String query; - private InputStream inputStream; - private boolean closed = false; + protected ClientConnectionManager connectionManager; + protected String query; + protected InputStream inputStream; + protected boolean closed = false; + + protected ClusterInvocationSupport clusterInvocationSupport = AppBeans.get(ClusterInvocationSupport.NAME); public RestApiDataProvider(String query) { this.query = query; @@ -44,29 +53,48 @@ public class RestApiDataProvider implements ExportDataProvider { if (closed) throw new IllegalStateException("DataProvider is closed"); - String connectionUrl = ConfigProvider.getConfig(ClientConfig.class).getConnectionUrl(); - String url = connectionUrl + API_URL + query; + int remotingServletPathLen = clusterInvocationSupport.getServletPath().length() + 1; - HttpClient httpClient = new DefaultHttpClient(); - HttpGet httpGet = new HttpGet(url); + for (Iterator iterator = clusterInvocationSupport.getUrlList().iterator(); iterator.hasNext(); ) { + String remotingUrl = iterator.next(); + String url = remotingUrl.substring(0, remotingUrl.length() - remotingServletPathLen) + API_URL + query; - try { - HttpResponse response = httpClient.execute(httpGet); - int status = response.getStatusLine().getStatusCode(); - if (status == HTTP_OK) { - HttpEntity httpEntity = response.getEntity(); - if (httpEntity != null) - inputStream = httpEntity.getContent(); + HttpClient httpClient = new DefaultHttpClient(); + HttpGet httpGet = new HttpGet(url); + + try { + HttpResponse response = httpClient.execute(httpGet); + int status = response.getStatusLine().getStatusCode(); + if (status == HttpStatus.SC_OK) { + HttpEntity httpEntity = response.getEntity(); + if (httpEntity != null) { + inputStream = httpEntity.getContent(); + break; + } else { + log.debug("Unable to retrieve data using REST API from " + url + "\nHttpEntity is null"); + if (iterator.hasNext()) + log.debug("Trying next URL"); + else + throw new RuntimeException("Unable to retrieve data using REST API from " + url + + "\nHttpEntity is null"); + } + } else { + log.debug("Unable to retrieve data using REST API from " + url + "\n" + response.getStatusLine()); + if (iterator.hasNext()) + log.debug("Trying next URL"); + else + throw new RuntimeException("Unable to retrieve data using REST API from " + url + "\n" + + response.getStatusLine()); + } + } catch (IOException e) { + log.debug("Unable to retrieve data using REST API from " + url + "\n" + e); + if (iterator.hasNext()) + log.debug("Trying next URL"); else - throw new RuntimeException("Cannot retrieve data using Rest API and the query given: " + query); - } else { - throw new RuntimeException("Cannot retrieve data using Rest API and the query given: " + query - + ". Http status: " + status); + throw new RuntimeException(e); + } finally { + connectionManager = httpClient.getConnectionManager(); } - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - connectionManager = httpClient.getConnectionManager(); } return inputStream; diff --git a/modules/gui/src/com/haulmont/cuba/gui/export/SimpleFileDataProvider.java b/modules/gui/src/com/haulmont/cuba/gui/export/SimpleFileDataProvider.java index 31bb01a9b3..139cf18fc1 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/export/SimpleFileDataProvider.java +++ b/modules/gui/src/com/haulmont/cuba/gui/export/SimpleFileDataProvider.java @@ -7,11 +7,13 @@ package com.haulmont.cuba.gui.export; import com.haulmont.cuba.client.ClientConfig; -import com.haulmont.cuba.core.global.ConfigProvider; -import com.haulmont.cuba.core.global.FileStorageException; -import com.haulmont.cuba.core.global.UserSessionProvider; +import com.haulmont.cuba.core.global.*; +import com.haulmont.cuba.core.sys.remoting.ClusterInvocationSupport; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.ClientConnectionManager; @@ -20,6 +22,7 @@ import org.apache.http.impl.client.DefaultHttpClient; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; +import java.util.Iterator; /** *

$Id$

@@ -29,16 +32,25 @@ import java.net.URLEncoder; */ public class SimpleFileDataProvider implements ExportDataProvider { - private static final int HTTP_OK = 200; + protected Log log = LogFactory.getLog(getClass()); - private String filePath; - private InputStream inputStream; - private boolean closed = false; + protected String filePath; + protected InputStream inputStream; + protected boolean closed = false; protected ClientConnectionManager connectionManager; + protected ClusterInvocationSupport clusterInvocationSupport = AppBeans.get(ClusterInvocationSupport.NAME); + + protected UserSessionSource userSessionSource = AppBeans.get(UserSessionSource.class); + + protected Configuration configuration = AppBeans.get(Configuration.class); + + protected String fileDownloadContext; + public SimpleFileDataProvider(String filePath) { this.filePath = filePath; + fileDownloadContext = configuration.getConfig(ClientConfig.class).getFileDownloadContext(); } public InputStream provide() { @@ -48,33 +60,51 @@ public class SimpleFileDataProvider implements ExportDataProvider { if (filePath == null) throw new IllegalArgumentException("Null file path"); - String fileDownloadContext = ConfigProvider.getConfig(ClientConfig.class).getFileDownloadContext(); - String connectionUrl = ConfigProvider.getConfig(ClientConfig.class).getConnectionUrl(); - String url = connectionUrl + fileDownloadContext + - "?s=" + UserSessionProvider.getUserSession().getId() + - "&p=" + encodeUTF8(filePath); + for (Iterator iterator = clusterInvocationSupport.getUrlList().iterator(); iterator.hasNext(); ) { + String url = iterator.next() + fileDownloadContext + + "?s=" + userSessionSource.getUserSession().getId() + + "&p=" + encodeUTF8(filePath); - HttpClient httpClient = new DefaultHttpClient(); - HttpGet httpGet = new HttpGet(url); + HttpClient httpClient = new DefaultHttpClient(); + HttpGet httpGet = new HttpGet(url); - try { - HttpResponse httpResponse = httpClient.execute(httpGet); - int httpStatus = httpResponse.getStatusLine().getStatusCode(); - switch (httpStatus) { - case HTTP_OK: + try { + HttpResponse httpResponse = httpClient.execute(httpGet); + int httpStatus = httpResponse.getStatusLine().getStatusCode(); + if (httpStatus == HttpStatus.SC_OK) { HttpEntity httpEntity = httpResponse.getEntity(); - if (httpEntity != null) + if (httpEntity != null) { inputStream = httpEntity.getContent(); + break; + } else { + log.debug("Unable to download file from " + url + "\nHttpEntity is null"); + if (iterator.hasNext()) + log.debug("Trying next URL"); + else + throw new RuntimeException( + new FileStorageException(FileStorageException.Type.IO_EXCEPTION, filePath) + ); + } + } else { + log.debug("Unable to download file from " + url + "\n" + httpResponse.getStatusLine()); + if (iterator.hasNext()) + log.debug("Trying next URL"); else - throw new FileStorageException(FileStorageException.Type.IO_EXCEPTION, filePath); - break; - default: - throw new FileStorageException(FileStorageException.Type.fromHttpStatus(httpStatus), filePath); + throw new RuntimeException( + new FileStorageException(FileStorageException.Type.fromHttpStatus(httpStatus), filePath) + ); + } + } catch (IOException ex) { + log.debug("Unable to download file from " + url + "\n" + ex); + if (iterator.hasNext()) + log.debug("Trying next URL"); + else + throw new RuntimeException( + new FileStorageException(FileStorageException.Type.IO_EXCEPTION, filePath, ex) + ); + } finally { + connectionManager = httpClient.getConnectionManager(); } - } catch (Exception ex) { - throw new RuntimeException(ex); - } finally { - connectionManager = httpClient.getConnectionManager(); } return inputStream; diff --git a/modules/portal/src/cuba-portal-app.properties b/modules/portal/src/cuba-portal-app.properties index 508910a532..525c63f717 100644 --- a/modules/portal/src/cuba-portal-app.properties +++ b/modules/portal/src/cuba-portal-app.properties @@ -10,7 +10,7 @@ # Middleware connection # cuba.connectionUrl=http://localhost:8080/cuba-core -cuba.fileDownloadContext=/remoting/download + # Set to false if the middleware works on different JVM cuba.useLocalServiceInvocation=true diff --git a/modules/web/src/cuba-web-app.properties b/modules/web/src/cuba-web-app.properties index 36b25594c0..6c4df03c52 100644 --- a/modules/web/src/cuba-web-app.properties +++ b/modules/web/src/cuba-web-app.properties @@ -4,7 +4,7 @@ # Middleware connection cuba.connectionUrl=http://localhost:8080/cuba-core -cuba.fileDownloadContext=/remoting/download + # Set to false if the middleware works on different JVM cuba.useLocalServiceInvocation=true