Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 88260 invoked from network); 18 Aug 2007 02:43:26 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 18 Aug 2007 02:43:26 -0000 Received: (qmail 10525 invoked by uid 500); 18 Aug 2007 02:43:23 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 10489 invoked by uid 500); 18 Aug 2007 02:43:23 -0000 Mailing-List: contact scm-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list scm@geronimo.apache.org Received: (qmail 10478 invoked by uid 99); 18 Aug 2007 02:43:23 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 17 Aug 2007 19:43:23 -0700 X-ASF-Spam-Status: No, hits=-98.8 required=10.0 tests=ALL_TRUSTED,DNS_FROM_DOB,RCVD_IN_DOB X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 18 Aug 2007 02:43:47 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 9DC531A981A; Fri, 17 Aug 2007 19:43:00 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r567215 - in /geronimo/server/branches/2.0: applications/geronimo-remote-deploy/src/main/java/org/apache/geronimo/deployment/remote/ modules/geronimo-deploy-jsr88/src/main/java/org/apache/geronimo/deployment/plugin/remote/ Date: Sat, 18 Aug 2007 02:43:00 -0000 To: scm@geronimo.apache.org From: dwoods@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070818024300.9DC531A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: dwoods Date: Fri Aug 17 19:42:59 2007 New Revision: 567215 URL: http://svn.apache.org/viewvc?view=rev&rev=567215 Log: GERONIMO-3420 Remote deploy of an EAR without an application.xml plan fails Modified: geronimo/server/branches/2.0/applications/geronimo-remote-deploy/src/main/java/org/apache/geronimo/deployment/remote/FileUploadServlet.java geronimo/server/branches/2.0/modules/geronimo-deploy-jsr88/src/main/java/org/apache/geronimo/deployment/plugin/remote/RemoteDeployUtil.java Modified: geronimo/server/branches/2.0/applications/geronimo-remote-deploy/src/main/java/org/apache/geronimo/deployment/remote/FileUploadServlet.java URL: http://svn.apache.org/viewvc/geronimo/server/branches/2.0/applications/geronimo-remote-deploy/src/main/java/org/apache/geronimo/deployment/remote/FileUploadServlet.java?view=diff&rev=567215&r1=567214&r2=567215 ============================================================================== --- geronimo/server/branches/2.0/applications/geronimo-remote-deploy/src/main/java/org/apache/geronimo/deployment/remote/FileUploadServlet.java (original) +++ geronimo/server/branches/2.0/applications/geronimo-remote-deploy/src/main/java/org/apache/geronimo/deployment/remote/FileUploadServlet.java Fri Aug 17 19:42:59 2007 @@ -29,64 +29,164 @@ /** * A servlet that accepts file uploads. It takes only POST requests, which should - * contain a Java "DataOutput" formatted stream containing: + * contain a Java "DataOutput" formatted stream from RemoteDeployUtil containing: * - * 1) an int, the number of files being uploaded - * 2) for each file: - * 1) an int, the length of the file in bytes - * 2) a number of raw bytes equal to the above for the file + * RemoteDeployer data stream format: + * 0) an int, the version of this datastream format - REMOTE_DEPLOY_REQUEST_VER + * 1) an int, the number of files being uploaded + * 2) for each file: + * 2.0) a UTF String, the filename of the file being uploaded + * 2.1) a long, the length of the file in bytes + * 2.2) byte[], byte count equal to the number above for the file * - * It returns a serialized stream containing: + * RemoteDeployer response stream format: + * It returns a serialized stream containing: + * 0) an int, the version of this datastream format - REMOTE_DEPLOY_RESPONSE_VER + * 1) a UTF string, the status (should be "OK") + * 2) an int, the number of files received + * 3) for each file: + * 3.1) a UTF String, the path to the file as saved to the server's filesystem * - * 1) a UTF string, the status (should be "OK") - * 2) an int, the number of files received - * 3) for each file: - * 1) a UTF String, the path to the file as saved to the server's filesystem - * - * The file positions in the response will be the same as in the request. - * The is, a name for upload file #2 will be in response position #2. + * The file positions in the response will be the same as in the request. + * That is, a name for upload file #2 will be in response position #2. * * @version $Rev$ $Date$ */ public class FileUploadServlet extends HttpServlet { + + /** Note: The below versions should be kept in sync with those in RemoteDeployUtil.java **/ + // Starting RemoteDeploy datastream versions + public static final int REMOTE_DEPLOY_REQUEST_VER_0 = 0; + public static final int REMOTE_DEPLOY_RESPONSE_VER_0 = 0; + // Current RemoteDeploy datastream versions + public static final int REMOTE_DEPLOY_REQUEST_VER = 0; + public static final int REMOTE_DEPLOY_RESPONSE_VER = 0; + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - int fileCount; - String names[]; + int fileCount = 0, filesCreated = 0; + String names[] = null; + String status = "OK"; + + /* -------------------- + * RemoteDeploy Request + * -------------------- + * + * Note: The below code has to match RemoteDeployUtil.java + * + * RemoteDeployer data stream format: + * 0) an int, the version of this datastream format - REMOTE_DEPLOY_REQUEST_VER + * 1) an int, the number of files being uploaded + * 2) for each file: + * 2.0) a UTF String, the filename of the file being uploaded + * 2.1) a long, the length of the file in bytes + * 2.2) byte[], byte count equal to the number above for the file + */ + DataInputStream in = null; try { - DataInputStream in = new DataInputStream(request.getInputStream()); - fileCount = in.readInt(); - names = new String[fileCount]; - for(int i=0; i= REMOTE_DEPLOY_REQUEST_VER_0) + // but until then, be more restrictive so we can handle old deployers + // that don't send a version as the first thing, but a file count instead... + if ((reqVer >= REMOTE_DEPLOY_REQUEST_VER_0) && (reqVer <= REMOTE_DEPLOY_REQUEST_VER)) { + // 1) an int, the number of files being uploaded + fileCount = in.readInt(); + names = new String[fileCount]; + // 2) for each file: + for(int i=0; i -1) { + while((read = in.read(buf, 0, (int)Math.min(buf.length, length - total))) > -1) { out.write(buf, 0, read); total += read; if(total == length) { @@ -96,9 +196,10 @@ } finally { try {out.flush();} catch (IOException e) {} out.close(); + out = null; } if(total != length) { - throw new IOException("Unable to read entire upload file ("+total+"b expecting "+length+"b)"); + throw new IOException("Unable to read entire upload file ("+total+"B expecting "+length+"B)"); } } } Modified: geronimo/server/branches/2.0/modules/geronimo-deploy-jsr88/src/main/java/org/apache/geronimo/deployment/plugin/remote/RemoteDeployUtil.java URL: http://svn.apache.org/viewvc/geronimo/server/branches/2.0/modules/geronimo-deploy-jsr88/src/main/java/org/apache/geronimo/deployment/plugin/remote/RemoteDeployUtil.java?view=diff&rev=567215&r1=567214&r2=567215 ============================================================================== --- geronimo/server/branches/2.0/modules/geronimo-deploy-jsr88/src/main/java/org/apache/geronimo/deployment/plugin/remote/RemoteDeployUtil.java (original) +++ geronimo/server/branches/2.0/modules/geronimo-deploy-jsr88/src/main/java/org/apache/geronimo/deployment/plugin/remote/RemoteDeployUtil.java Fri Aug 17 19:42:59 2007 @@ -16,6 +16,8 @@ */ package org.apache.geronimo.deployment.plugin.remote; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.geronimo.deployment.plugin.local.AbstractDeployCommand; import org.apache.geronimo.util.encoders.Base64; @@ -38,6 +40,18 @@ * @version $Rev$ $Date$ */ public class RemoteDeployUtil { + + private static final Log log = LogFactory.getLog(RemoteDeployUtil.class); + + /** Note: The below versions should be kept in sync with those in FileUploadServlet.java **/ + // Starting RemoteDeploy datastream versions + public static final int REMOTE_DEPLOY_REQUEST_VER_0 = 0; + public static final int REMOTE_DEPLOY_RESPONSE_VER_0 = 0; + // Current RemoteDeploy datastream versions + public static final int REMOTE_DEPLOY_REQUEST_VER = 0; + public static final int REMOTE_DEPLOY_RESPONSE_VER = 0; + + public static void uploadFilesToServer(File[] files, AbstractDeployCommand progress) { if(files == null) { return; @@ -55,26 +69,55 @@ } if(valid.size() > 0) { progress.updateStatus("Uploading "+valid.size()+" file(s) to server"); + if (log.isDebugEnabled()) { + log.debug("Uploading "+valid.size()+" file(s) to server"); + } try { + /* -------------------- + * RemoteDeploy Request + * -------------------- + * + * Note: The below code has to match FileUploadServlet.java + * + * RemoteDeployer data stream format: + * 0) an int, the version of this datastream format - REMOTE_DEPLOY_REQUEST_VER + * 1) an int, the number of files being uploaded + * 2) for each file: + * 2.0) a UTF String, the filename of the file being uploaded + * 2.1) a long, the length of the file in bytes + * 2.2) byte[], byte count equal to the number above for the file + */ URL url = progress.getRemoteDeployUploadURL(); URLConnection con = connectToServer(url, progress.getCommandContext().getUsername(), progress.getCommandContext().getPassword()); DataOutputStream out = new DataOutputStream(new BufferedOutputStream(con.getOutputStream())); + // 0) an int, the version of this datastream format - REMOTE_DEPLOY_REQUEST_VER + out.writeInt(REMOTE_DEPLOY_REQUEST_VER); + // 1) an int, the number of files being uploaded out.writeInt(valid.size()); byte[] buf = new byte[1024]; - int size, total, length, threshold, next; + int size; + long total, length, threshold, next; + // 2) for each file: for (Iterator it = valid.iterator(); it.hasNext();) { Integer index = (Integer) it.next(); File file = files[index.intValue()]; - out.writeInt(length = (int)file.length()); - threshold = Math.max(length / 100, 10240); + // 2.0) a UTF String, the filename of the file being uploaded + out.writeUTF(file.getName().trim()); + // 2.1) a long, the length of the file in bytes + out.writeLong(length = file.length()); + threshold = Math.max(length / 100, (long)10240); next = threshold; BufferedInputStream in = new BufferedInputStream(new FileInputStream(file)); + if (log.isDebugEnabled()) { + log.debug("Uploading "+file.getName()); + } total = 0; + // 2.2) raw bytes, equal to the number above for the file while((size = in.read(buf)) > -1) { out.write(buf, 0, size); total += size; if(total > next) { - progress.updateStatus("Uploading "+file.getName()+": "+(total/1024)+" kB"); + progress.updateStatus("Uploading "+file.getName()+": "+(total/1024)+" KB"); while(total > next) next += threshold; } } @@ -82,24 +125,83 @@ } out.flush(); out.close(); + + /* --------------------- + * RemoteDeploy Response + * --------------------- + * + * Note: The below code has to match FileUploadServlet.java + * + * RemoteDeployer response stream format: + * It returns a serialized stream containing: + * 0) an int, the version of this datastream format - REMOTE_DEPLOY_RESPONSE_VER + * 1) a UTF string, the status (should be "OK") + * 2) an int, the number of files received + * 3) for each file: + * 3.1) a UTF String, the path to the file as saved to the server's filesystem + * x) new data would be added here + * + * The file positions in the response will be the same as in the request. + * That is, a name for upload file #2 will be in response position #2. + */ + DataInputStream in = new DataInputStream(new BufferedInputStream(con.getInputStream())); - String status = in.readUTF(); - if(!status.equals("OK")) { - progress.fail("Unable to upload files to server: "+status); - return; - } - progress.updateStatus("File upload complete (Server: "+status+")"); - int count = in.readInt(); - if(count != valid.size()) { - progress.fail("Server did not receive all "+valid.size()+" files ("+count+")"); - } - for (Iterator it = valid.iterator(); it.hasNext();) { - Integer index = (Integer) it.next(); - String serverFileName = in.readUTF(); - files[index.intValue()] = new File(serverFileName); + // 0) an int, the version of this datastream format - REMOTE_DEPLOY_RESPONSE_VER + int rspVer = in.readInt(); + // whenever we update the stream version, the next line needs to + // be changed to just - (rspVer >= REMOTE_DEPLOY_RESPONSE_VER_0) + // but until then, be more restrictive so we can handle old servers + // that don't send a version as the first thing, but UTF instead... + if ((rspVer >= REMOTE_DEPLOY_RESPONSE_VER_0) && (rspVer <= REMOTE_DEPLOY_RESPONSE_VER)) { + // 1) a UTF string, the status (should be "OK") + String status = in.readUTF(); + if(!status.equals("OK")) { + progress.fail("Unable to upload files to server. Server returned status="+status); + log.error("Unable to upload files to server. Server returned status="+status); + return; + } + progress.updateStatus("File upload complete (Server status="+status+")"); + if (log.isDebugEnabled()) { + log.debug("File upload complete (Server status="+status+")"); + } + // 2) an int, the number of files received + int count = in.readInt(); + if(count != valid.size()) { + progress.fail("Server only received "+count+" of "+valid.size()+" files"); + log.warn("Server only received "+count+" of "+valid.size()+" files"); + } + // 3) for each file: + for (Iterator it = valid.iterator(); it.hasNext();) { + Integer index = (Integer) it.next(); + // 3.1) a UTF String, the path to the file as saved to the server's filesystem + String serverFileName = in.readUTF(); + if (serverFileName != null) { + files[index.intValue()] = new File(serverFileName); + } else { + log.error("Received an invalid filename from the server"); + files[index.intValue()] = null; + } + if (log.isDebugEnabled()) { + log.debug("Server created file="+serverFileName); + } + } + // x) new data would be added here + if (rspVer > REMOTE_DEPLOY_RESPONSE_VER_0) { + // additions in later datastream versions would be handled here + + if (rspVer > REMOTE_DEPLOY_RESPONSE_VER) { + // if the server is sending a newer version than we know about + // just ignore it and warn the user about the mismatch + log.warn("Received a newer server response ("+rspVer+") than expected ("+REMOTE_DEPLOY_RESPONSE_VER+"). Ignoring any additional server response data."); + } + } + } else { + // should never happen, but handle it anyway + progress.fail("Received unknown server response version="+rspVer); + log.warn("Received unknown server response version="+rspVer); } in.close(); - progress.updateStatus(count+" file(s) transferred to server. Resuming deployment operation."); + progress.updateStatus("File(s) transferred to server. Resuming deployment operation."); } catch (Exception e) { progress.doFail(e); }