Package org.apache.geronimo.deployment.plugin.remote

Source Code of org.apache.geronimo.deployment.plugin.remote.RemoteDeployUtil

/**
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You 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 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;

import java.io.File;
import java.io.IOException;
import java.io.DataOutputStream;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.LinkedList;
import java.util.List;
import java.util.Iterator;

/**
* Knows how to upload files to a server
*
* @version $Rev: 567215 $ $Date: 2007-08-17 22:42:59 -0400 (Fri, 17 Aug 2007) $
*/
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;
        }
        List valid = new LinkedList();
        for(int i=0; i<files.length; i++) {
            if(files[i] == null) {
                continue;
            }
            File file = files[i];
            if(!file.exists() || !file.canRead()) {
                continue;
            }
            valid.add(new Integer(i));
        }
        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;
                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()];
                    // 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");
                            while(total > next) next += threshold;
                        }
                    }
                    in.close();
                }
                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()));
                // 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("File(s) transferred to server.  Resuming deployment operation.");
            } catch (Exception e) {
                progress.doFail(e);
            }
        }
    }

    private static URLConnection connectToServer(URL url, String username, String password) throws IOException {
        URLConnection con = url.openConnection();
        String auth = username + ":" + password;
        byte[] data = auth.getBytes();
        String s = new String(Base64.encode(data));
        while(s.length() % 4 != 0) s += "=";
        con.setRequestProperty("Authorization", "Basic "+s);
        con.setDoInput(true);
        con.setDoOutput(true);
        con.connect();
        return con;
    }
}
TOP

Related Classes of org.apache.geronimo.deployment.plugin.remote.RemoteDeployUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.