.classpath
| 2
modules/core/util/src/main/java/org/rhq/core/util/StringUtil.java
| 15
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASUploadConnection.java
| 226 +++++-----
3 files changed, 133 insertions(+), 110 deletions(-)
New commits:
commit 456999641d532be8d438ecdb60b2b442c0929874
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Thu Dec 20 15:23:15 2012 +0100
Share first modifications
diff --git a/.classpath b/.classpath
index d8e11f6..ab18820 100644
--- a/.classpath
+++ b/.classpath
@@ -190,7 +190,7 @@
<classpathentry exported="true" kind="var"
path="M2_REPO/com/sun/xml/bind/jaxb-impl/2.2.4/jaxb-impl-2.2.4.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/i18nlog/i18nlog/1.0.10/i18nlog-1.0.10.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/gnu-getopt/getopt/1.0.13/getopt-1.0.13.jar"/>
- <classpathentry exported="true" kind="var"
path="M2_REPO/commons-httpclient/commons-httpclient/3.0.1/commons-httpclient-3.0.1.jar"/>
+ <classpathentry exported="true" kind="var"
path="M2_REPO/commons-httpclient/commons-httpclient/3.0.1/commons-httpclient-3.0.1.jar"
sourcepath="/M2_REPO/commons-httpclient/commons-httpclient/3.0.1/commons-httpclient-3.0.1-sources.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/jboss/jboss-remoting/2.2.2.SP8/jboss-remoting-2.2.2.SP8.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/oswego-concurrent/concurrent/1.3.4/concurrent-1.3.4.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/rss4j/rss4j/0.92-on.2/rss4j-0.92-on.2.jar"/>
diff --git a/modules/core/util/src/main/java/org/rhq/core/util/StringUtil.java
b/modules/core/util/src/main/java/org/rhq/core/util/StringUtil.java
index bf020ca..59a09f2 100644
--- a/modules/core/util/src/main/java/org/rhq/core/util/StringUtil.java
+++ b/modules/core/util/src/main/java/org/rhq/core/util/StringUtil.java
@@ -284,7 +284,7 @@ public class StringUtil {
for (int i = 0; i < (size - 1); i++) {
buf.append(objs.get(i).toString());
- buf.append( delim);
+ buf.append(delim);
}
if (size != 0) {
@@ -553,4 +553,17 @@ public class StringUtil {
public static boolean isEmpty(String s) {
return s == null || s.length() == 0;
}
+
+ public static boolean isNotEmpty(String s) {
+ return !isEmpty(s);
+ }
+
+ public static boolean isBlank(String s) {
+ return s == null || s.trim().length() == 0;
+ }
+
+ public static boolean isNotBlank(String s) {
+ return !isBlank(s);
+ }
+
}
\ No newline at end of file
diff --git
a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASUploadConnection.java
b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASUploadConnection.java
index a7fe82d..3a3b651 100644
---
a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASUploadConnection.java
+++
b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASUploadConnection.java
@@ -21,99 +21,161 @@ package org.rhq.modules.plugins.jbossas7;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.Closeable;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.Authenticator;
-import java.net.HttpURLConnection;
-import java.net.URL;
+import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
+import org.rhq.core.util.StringUtil;
+
/**
+ * TODO review comments of the class. Add message to say that's it's callers
resonsability to call finishUpload or cancelUpload in order to free resources
+ *
* Connection for uploading of content.
* Partially taken from
https://github.com/jbossas/jboss-as/blob/master/testsuite/smoke/src/test/...
*
* @author Jonathan Pearlin (of the original code)
* @author Heiko W. Rupp
+ *
*/
public class ASUploadConnection {
- private static final String BOUNDARY_PARAM = "NeAG1QNIHHOyB5joAS7Rox!!";
-
- private static final String BOUNDARY = "--" + BOUNDARY_PARAM;
+ private static final String HTTP_SCHEME = "http";
- private static final String CRLF = "\r\n";
+ private static final String UPLOAD_URL_PATH = ASConnection.MANAGEMENT +
"/add-content";
- private static final String POST_REQUEST_METHOD = "POST";
+ private static final int SOCKET_READ_TIMEOUT = 60 * 1000; // 30sec
- private static final String UPLOAD_URL_PATH = ASConnection.MANAGEMENT +
"/add-content";
+ private static final int SOCKET_CONNECTION_TIMEOUT = 30 * 1000; // 60sec
private static final Log log = LogFactory.getLog(ASUploadConnection.class);
- Authenticator passwordAuthenticator ;
- BufferedOutputStream os = null;
- InputStream is = null;
- private HttpURLConnection connection;
+ private String scheme = HTTP_SCHEME;
+
private String host;
+
private int port;
- private int timeout;
- private static final int DEFAULT_TIMEOUT = 60; // 60sec
- public ASUploadConnection(String dcHost, int port, String user, String password) {
+ private Credentials credentials;
+
+ private String fileName;
+
+ private File cacheFile;
+
+ private BufferedOutputStream cacheOutputStream;
+
+ private boolean credentialsProvided() {
+ // If null user or password is given to the constructor
+ // no credentials instance is created
+ return credentials != null;
+ }
+
+ public ASUploadConnection(String dcHost, int port, String user, String password,
String fileName) {
if (dcHost == null) {
throw new IllegalArgumentException("Management host cannot be
null.");
}
if (port <= 0 || port > 65535) {
throw new IllegalArgumentException("Invalid port: " + port);
}
+ if (StringUtil.isBlank(fileName)) {
+ throw new IllegalArgumentException("Filename cannot be blank");
+ }
this.host = dcHost;
this.port = port;
- if (user != null) {
- passwordAuthenticator = new AS7Authenticator(user,password);
- Authenticator.setDefault(passwordAuthenticator);
+ if (user != null && password != null) {
+ credentials = new UsernamePasswordCredentials(user, password);
}
- timeout = DEFAULT_TIMEOUT;
+ this.fileName = fileName;
}
- public ASUploadConnection(ASConnection asConnection) {
- this.host=asConnection.getHost();
- this.port=asConnection.getPort();
- this.timeout = DEFAULT_TIMEOUT;
+ /**
+ * TODO : more
+ * Gives an outpustream where callers should write the content that will be uploaded
to AS7 when {@link #finishUpload()} will be called.
+ *
+ * @return an outputstream or null if it could not be created.
+ */
+ public OutputStream getOutputStream() {
+ try {
+ cacheFile = File.createTempFile("as7upload-" + fileName,
"cache");
+ cacheOutputStream = new BufferedOutputStream(new
FileOutputStream(cacheFile));
+ return cacheOutputStream;
+ } catch (IOException e) {
+ log.error("Could not create outputstream for " + fileName, e);
+ }
+ return null;
+
+ // String url = "http://" + host + ":" + port +
UPLOAD_URL_PATH;
+ // try {
+ // // Create the HTTP connection to the upload URL
+ // connection = (HttpURLConnection) new URL(url).openConnection();
+ // connection.setConnectTimeout(30 * 1000); // 30s
+ // connection.setReadTimeout(timeout * 1000); // default 60s
+ // connection.setDoInput(true);
+ // connection.setDoOutput(true);
+ // connection.setRequestMethod(POST_REQUEST_METHOD);
+ // connection.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + BOUNDARY_PARAM);
+ //
+ // // Grab the test WAR file and get a stream to its contents to be
included in the POST.
+ // os = new BufferedOutputStream(connection.getOutputStream());
+ // os.write(buildPostRequestHeader(fileName));
+ //
+ // return os;
+ // }
+ // catch (Exception e) {
+ // log.error("Failed to open output stream to URL [" + url +
"]: " + e, e);
+ // }
+ //
+ // return null;
}
+ /**
+ * TODO
+ */
+ public void cancelUpload() {
+ closeQuietly(cacheOutputStream);
+ cacheFile.delete();
+ }
- public OutputStream getOutputStream(String fileName) {
- String url = "http://" + host + ":" + port +
UPLOAD_URL_PATH;
- try {
- // Create the HTTP connection to the upload URL
- connection = (HttpURLConnection) new URL(url).openConnection();
- connection.setConnectTimeout(30 * 1000); // 30s
- connection.setReadTimeout(timeout * 1000); // default 60s
- connection.setDoInput(true);
- connection.setDoOutput(true);
- connection.setRequestMethod(POST_REQUEST_METHOD);
- connection.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + BOUNDARY_PARAM);
-
- // Grab the test WAR file and get a stream to its contents to be included in
the POST.
- os = new BufferedOutputStream(connection.getOutputStream());
- os.write(buildPostRequestHeader(fileName));
-
- return os;
- }
- catch (Exception e) {
- log.error("Failed to open output stream to URL [" + url + "]:
" + e, e);
- }
+ /**
+ * TODO
+ * @return
+ */
+ public JsonNode finishUpload() {
- return null;
- }
+ closeQuietly(cacheOutputStream);
+
+ String targetURL = scheme + "://" + host + ":" + port +
UPLOAD_URL_PATH;
+
+ // TODO : we use the same url for the hack but there maybe is a management
endpoint with very little response
+ // We will issue a simple get request in order to trigger authentication
challenge.
+ // This allows to send the potentially big file only once to the server
+ // The typical resulting http exchange would be:
+ // GET without auth <- 401 (start auth challenge : the server will name the
realm and the scheme)
+ // GET with auth <- 200
+ // POST big file
+ GetMethod triggerAuthGET = new GetMethod(targetURL);
+
+ PostMethod filePOST = new PostMethod(targetURL);
+
+ HttpClient client = new HttpClient();
+ if (credentialsProvided()) {
+ client.getState().setCredentials(new AuthScope(host, port,
AuthScope.ANY_REALM), credentials);
+ }
+
client.getHttpConnectionManager().getParams().setConnectionTimeout(SOCKET_CONNECTION_TIMEOUT);
+ client.getHttpConnectionManager().getParams().setSoTimeout(SOCKET_READ_TIMEOUT);
- public JsonNode finishUpload() {
JsonNode tree = null;
try {
os.write(buildPostRequestFooter());
@@ -139,18 +201,16 @@ public class ASUploadConnection {
ObjectMapper mapper = new ObjectMapper();
String s = builder.toString();
- if (s!=null)
+ if (s != null)
tree = mapper.readTree(s);
else
log.warn("- no result received from InputStream -");
- }
- else
+ } else
log.warn("- no InputStream available -");
} catch (IOException e) {
log.error(e);
- }
- finally {
+ } finally {
closeQuietly(is);
closeQuietly(os);
}
@@ -158,43 +218,8 @@ public class ASUploadConnection {
return tree;
}
-
- private byte[] buildPostRequestHeader(String fileName) throws
UnsupportedEncodingException {
- final StringBuilder builder = new StringBuilder();
- builder.append(buildPostRequestHeaderSection("form-data;
name=\"file\"; filename=\""+fileName+"\"",
"application/octet-stream", ""));
- return builder.toString().getBytes("US-ASCII");
- }
-
- private StringBuilder buildPostRequestHeaderSection(final String contentDisposition,
final String contentType, final String content) {
- final StringBuilder builder = new StringBuilder();
- builder.append(BOUNDARY);
- builder.append(CRLF);
- if(contentDisposition != null && contentDisposition.length() > 0) {
- builder.append(String.format("Content-Disposition: %s",
contentDisposition));
- }
- builder.append(CRLF);
- if(contentType != null && contentType.length() > 0) {
- builder.append(String.format("Content-Type: %s", contentType));
- }
- builder.append(CRLF);
- if(content != null && content.length() > 0) {
- builder.append(content);
- }
- builder.append(CRLF);
- return builder;
- }
-
- private byte[] buildPostRequestFooter() throws UnsupportedEncodingException{
- final StringBuilder builder = new StringBuilder();
- builder.append(CRLF);
- builder.append(BOUNDARY);
- builder.append("--");
- builder.append(CRLF);
- return builder.toString().getBytes("US-ASCII");
- }
-
public static String getFailureDescription(JsonNode jsonNode) {
- if (jsonNode==null)
+ if (jsonNode == null)
return "getFailureDescription: -input was null-";
JsonNode node = jsonNode.findValue("failure-description");
return node.getValueAsText();
@@ -212,7 +237,7 @@ public class ASUploadConnection {
if (outcome.equals("failed")) {
JsonNode reasonNode = in.findValue("failure-description");
- String reason = reasonNode.getTextValue();
+ reasonNode.getTextValue();
return true;
}
} catch (Exception e) {
@@ -224,7 +249,7 @@ public class ASUploadConnection {
}
private void closeQuietly(final Closeable closeable) {
- if(closeable != null) {
+ if (closeable != null) {
try {
closeable.close();
} catch (final IOException ignore) {
@@ -232,19 +257,4 @@ public class ASUploadConnection {
}
}
- /**
- * Get the currently active upload timeout
- * @return timeout in seconds
- */
- public int getTimeout() {
- return timeout;
- }
-
- /**
- * Set upload timeout in seconds.
- * @param timeout upload timeout in seconds
- */
- public void setTimeout(int timeout) {
- this.timeout = timeout;
- }
}