Search in sources :

Example 1 with ClusterTransferFileEndInfo

use of com.sun.messaging.jmq.jmsserver.multibroker.raptor.ClusterTransferFileEndInfo in project openmq by eclipse-ee4j.

the class ClusterImpl method transferFiles.

@Override
public void transferFiles(String[] fileNames, BrokerAddress targetBroker, Long syncTimeout, String uuid, String myBrokerID, String module, FileTransferCallback callback) throws BrokerException {
    String to = targetBroker.toString();
    Socket socket = null;
    MessageDigest digest = null;
    try {
        if (fileTransferShutdownOut) {
            String emsg = br.getKString(br.W_CLUSTER_SERVICE_SHUTDOWN);
            logger.log(logger.WARNING, emsg);
            throw new BrokerException(emsg);
        }
        try {
            digest = MessageDigest.getInstance("SHA1");
        } catch (Exception e) {
            String emsg = "";
            if (e instanceof NoSuchAlgorithmException) {
                emsg = "Unable to create MessageDigest for file transfer";
                logger.log(logger.ERROR, emsg + ": " + e);
            } else {
                emsg = "Unexpectd exception in creating MessageDigest for file transfer";
                logger.logStack(logger.ERROR, emsg, e);
            }
            throw new BrokerException(emsg, e);
        }
        logger.log(logger.INFO, br.getKString(br.I_CONNECT_REMOTE_FOR_FILE_TX, targetBroker));
        socket = BrokerLink.makeSocket((BrokerAddressImpl) targetBroker, this, false, null);
        to += "[" + socket.getInetAddress() + "]";
        try {
            socket.setTcpNoDelay(false);
        } catch (Exception e) {
            logger.log(logger.WARNING, "Failed to set socket TCP_NODELAY for file transfer: " + e);
        }
        try {
            socket.setSoTimeout((int) Math.min(FILE_TRANSFER_SOTIMEOUT_OUT, syncTimeout.longValue()));
        } catch (Exception e) {
            logger.log(logger.WARNING, "Failed to set socket timeout for file transfer: " + e);
        }
        OutputStream os = socket.getOutputStream();
        logger.log(logger.INFO, br.getKString(br.I_CLUSTER_SEND_TX_FILE_LINK_REQUEST, to));
        Packet pkt = getLinkInitPkt(Integer.valueOf(LinkInfo.SERVICE_FILE_TRANSFER));
        pkt.writePacket(os);
        os.flush();
        int numFiles = fileNames.length;
        ClusterTransferFileListInfo tfl = ClusterTransferFileListInfo.newInstance(uuid, myBrokerID, Integer.valueOf(numFiles), FileTransferCallback.STORE);
        Object[] tmpargs = { String.valueOf(numFiles), tfl.toString(), to };
        logger.log(logger.INFO, br.getKString(br.I_CLUSTER_TX_FILES, tmpargs));
        GPacket gp = tfl.getGPacket();
        gp.write(os);
        os.flush();
        String filename = null;
        long filesize = 0L;
        long lastmodtime = 0L;
        for (int cnt = 0; cnt < numFiles; cnt++) {
            filename = fileNames[cnt];
            logger.log(logger.INFO, br.getKString(br.I_CLUSTER_TX_FILE, filename + " [" + Arrays.toString(tmpargs) + "]", to));
            if (fileTransferShutdownOut) {
                String emsg = br.getKString(br.W_CLUSTER_SERVICE_SHUTDOWN);
                logger.log(logger.WARNING, emsg);
                throw new BrokerException(emsg);
            }
            Map props = new HashMap();
            InputStream is = callback.getFileInputStream(filename, targetBroker, props);
            try {
                filesize = ((Long) props.get("filesize")).longValue();
                lastmodtime = ((Long) props.get("lastmodtime")).longValue();
                ClusterTransferFileStartInfo tfs = ClusterTransferFileStartInfo.newInstance(uuid, module, myBrokerID, filename, filesize, lastmodtime);
                gp = tfs.getGPacket();
                gp.write(os);
                os.flush();
                digest.reset();
                byte[] buf = new byte[FILE_TRANSFER_CHUNK_SIZE];
                int totalread = 0;
                int count;
                while (totalread < filesize) {
                    if (fileTransferShutdownOut) {
                        String emsg = br.getKString(br.W_CLUSTER_SERVICE_SHUTDOWN);
                        logger.log(logger.WARNING, emsg);
                        throw new BrokerException(emsg);
                    }
                    count = 0;
                    try {
                        count = is.read(buf, 0, (int) Math.min(FILE_TRANSFER_CHUNK_SIZE, (filesize - totalread)));
                    } catch (IOException e) {
                        String emsg = br.getKString(br.E_FILE_READ, filename);
                        throw new BrokerException(emsg);
                    }
                    if (count < 0) {
                        String[] args = { String.valueOf(totalread), String.valueOf(filesize - totalread), filename };
                        String emsg = br.getKString(br.E_FILE_READ_EOF, args);
                        throw new BrokerException(emsg);
                    }
                    totalread += count;
                    os.write(buf, 0, count);
                    os.flush();
                    digest.update(buf, 0, count);
                }
                byte[] dg = digest.digest();
                ClusterTransferFileEndInfo tfe = ClusterTransferFileEndInfo.newInstance(uuid, module, myBrokerID, filename, dg, ((cnt + 1) < numFiles));
                gp = tfe.getGPacket();
                gp.write(os);
                os.flush();
            } finally {
                try {
                    is.close();
                } catch (Exception e) {
                }
            }
        }
        if (numFiles > 0) {
            InputStream sis = socket.getInputStream();
            gp = GPacket.getInstance();
            gp.read(sis);
            if (gp.getType() != ProtocolGlobals.G_TRANSFER_FILE_END_ACK) {
                String[] args = { ProtocolGlobals.getPacketTypeDisplayString(gp.getType()), to, ProtocolGlobals.getPacketTypeDisplayString(ProtocolGlobals.G_TRANSFER_FILE_END_ACK) };
                String emsg = br.getKString(br.E_CLUSTER_UNEXPECTED_PACKET_FROM_1, args);
                logger.log(logger.ERROR, emsg);
                throw new BrokerException(emsg);
            }
            int status = ClusterTransferFileEndInfo.getReplyStatus(gp);
            if (status != Status.OK) {
                throw new BrokerException(ClusterTransferFileEndInfo.getReplyStatusReason(gp));
            }
            try {
                gp = ClusterTransferFileEndInfo.getReplyAckGPacket(Status.OK, null);
                gp.write(os);
                os.flush();
            } catch (Throwable t) {
                if (DEBUG) {
                    logger.log(logger.INFO, "Exception in sending " + ProtocolGlobals.getPacketTypeDisplayString(ProtocolGlobals.G_TRANSFER_FILE_END_ACK_ACK) + " to " + to);
                }
            }
            try {
                sis.close();
            } catch (Exception e) {
            }
        }
        try {
            socket.close();
        } catch (Exception e) {
        }
    } catch (Throwable t) {
        if (socket != null) {
            try {
                socket.close();
            } catch (Exception e) {
            }
        }
        StringBuilder buf = new StringBuilder();
        if (fileNames != null) {
            int len = fileNames.length;
            for (int i = 0; i < len; i++) {
                if (i > 0) {
                    buf.append(", ");
                }
                buf.append(fileNames[i]);
            }
        }
        String emsg = br.getKString(br.X_CLUSTER_FILE_TX_FAIL, "[" + buf.toString() + "[" + uuid + "]]: " + ((t instanceof java.io.EOFException) ? "peer socket closed" : t.getMessage()), to);
        logger.log(logger.ERROR, emsg);
        if (t instanceof BrokerException) {
            throw (BrokerException) t;
        }
        throw new BrokerException(emsg, t);
    }
}
Also used : BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) ClusterTransferFileStartInfo(com.sun.messaging.jmq.jmsserver.multibroker.raptor.ClusterTransferFileStartInfo) ClusterTransferFileEndInfo(com.sun.messaging.jmq.jmsserver.multibroker.raptor.ClusterTransferFileEndInfo) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) GPacket(com.sun.messaging.jmq.io.GPacket) MessageDigest(java.security.MessageDigest) GPacket(com.sun.messaging.jmq.io.GPacket) FilteringObjectInputStream(com.sun.messaging.jmq.util.io.FilteringObjectInputStream) LoopbackAddressException(com.sun.messaging.jmq.jmsserver.util.LoopbackAddressException) LoadException(com.sun.messaging.jmq.jmsserver.persist.api.LoadException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) ClusterTransferFileListInfo(com.sun.messaging.jmq.jmsserver.multibroker.raptor.ClusterTransferFileListInfo)

Example 2 with ClusterTransferFileEndInfo

use of com.sun.messaging.jmq.jmsserver.multibroker.raptor.ClusterTransferFileEndInfo in project openmq by eclipse-ee4j.

the class FileTransferRunnable method run.

@Override
public void run() {
    String from = remote + "[" + socket.getInetAddress() + "]";
    try {
        socket.setTcpNoDelay(true);
    } catch (Exception e) {
        logger.log(logger.WARNING, "Failed to set socket TCP_NODELAY in processing file transfer request: " + e);
    }
    try {
        socket.setSoTimeout(timeout);
    } catch (Exception e) {
        logger.log(logger.WARNING, "Failed to set socket timeout in processing file transfer request: " + e);
    }
    try {
        InputStream is = socket.getInputStream();
        GPacket gp = GPacket.getInstance();
        gp.read(is);
        if (gp.getType() != ProtocolGlobals.G_TRANSFER_FILE_LIST) {
            String[] emsg = { ProtocolGlobals.getPacketTypeDisplayString(gp.getType()), from, ProtocolGlobals.getPacketTypeDisplayString(ProtocolGlobals.G_TRANSFER_FILE_LIST) };
            logger.log(logger.ERROR, br.getKString(br.E_CLUSTER_UNEXPECTED_PACKET_FROM_1, emsg));
            try {
                socket.close();
            } catch (Exception e) {
            /* ignore */
            }
            return;
        }
        ClusterTransferFileListInfo tfl = ClusterTransferFileListInfo.newInstance(gp);
        String uuid = tfl.getUUID();
        String pendingUUID = parent.pendingFileTransfers.get(remote);
        if (pendingUUID == null || !pendingUUID.startsWith(tfl.getUUID())) {
            logger.log(logger.ERROR, br.getKString(br.E_CLUSTER_RECEIVED_UNKNOW_FILE_TX_LIST, ProtocolGlobals.getPacketTypeDisplayString(gp.getType()) + tfl, remote));
            try {
                socket.close();
            } catch (Exception e) {
            }
            return;
        }
        if (!tfl.getModule().equals(FileTransferCallback.STORE)) {
            logger.log(logger.ERROR, br.getKString(br.E_CLUSTER_UNEXPECTED_PACKET_FROM, ProtocolGlobals.getPacketTypeDisplayString(gp.getType()) + tfl.toString(true), from));
            try {
                socket.close();
            } catch (Exception e) {
            }
            return;
        }
        FileTransferCallback callback = (FileTransferCallback) Globals.getStore();
        int numFiles = tfl.getNumFiles();
        for (int cnt = 0; cnt < numFiles; cnt++) {
            if (parent.fileTransferShutdownIn) {
                String emsg = br.getKString(br.W_CLUSTER_SERVICE_SHUTDOWN);
                logger.log(logger.WARNING, emsg);
                throw new BrokerException(emsg);
            }
            gp.read(is);
            if (gp.getType() != ProtocolGlobals.G_TRANSFER_FILE_START) {
                String[] emsg = { ProtocolGlobals.getPacketTypeDisplayString(gp.getType()), from, ProtocolGlobals.getPacketTypeDisplayString(ProtocolGlobals.G_TRANSFER_FILE_START) };
                logger.log(logger.ERROR, br.getKString(br.E_CLUSTER_UNEXPECTED_PACKET_FROM_1, emsg));
                try {
                    socket.close();
                } catch (Exception e) {
                }
                return;
            }
            ClusterTransferFileStartInfo tfs = ClusterTransferFileStartInfo.newInstance(gp);
            if (!tfs.getModule().equals(FileTransferCallback.STORE)) {
                logger.log(logger.ERROR, br.getKString(br.E_CLUSTER_UNEXPECTED_PACKET_FROM, ProtocolGlobals.getPacketTypeDisplayString(gp.getType()) + tfs.toString(true), from));
                try {
                    socket.close();
                } catch (Exception e) {
                }
                return;
            }
            if (!tfs.getBrokerID().equals(tfl.getBrokerID())) {
                logger.log(logger.ERROR, br.getKString(br.E_CLUSTER_UNEXPECTED_PACKET_FROM, ProtocolGlobals.getPacketTypeDisplayString(gp.getType()) + tfs.toString(true), from));
                try {
                    socket.close();
                } catch (Exception e) {
                }
                return;
            }
            String tmpfile = tfs.getFileName() + ".tmp";
            ClusterTransferFileEndInfo fte = null;
            boolean success = false;
            OutputStream os = callback.getFileOutputStream(tmpfile, tfs.getBrokerID(), uuid, cnt == 0, remote);
            try {
                digest.reset();
                long size = tfs.getFileSize();
                byte[] buf = new byte[parent.FILE_TRANSFER_CHUNK_SIZE];
                int totalread = 0;
                int count;
                while (totalread < size) {
                    if (parent.fileTransferShutdownIn) {
                        String emsg = br.getKString(br.W_CLUSTER_SERVICE_SHUTDOWN);
                        logger.log(logger.WARNING, emsg);
                        throw new BrokerException(emsg);
                    }
                    count = 0;
                    try {
                        count = is.read(buf, 0, (int) Math.min(parent.FILE_TRANSFER_CHUNK_SIZE, (size - totalread)));
                    } catch (IOException e) {
                        logger.log(logger.ERROR, br.getKString(br.E_CLUSTER_FILE_TX_READ, from + ": " + e));
                        try {
                            socket.close();
                        } catch (Exception e1) {
                        }
                        return;
                    }
                    if (count < 0) {
                        String[] args = { String.valueOf(totalread), String.valueOf(size - totalread), from };
                        logger.log(logger.ERROR, br.getKString(br.E_CLUSTER_FILE_TX_EOF, args));
                        try {
                            socket.close();
                        } catch (Exception e) {
                        }
                        return;
                    }
                    totalread += count;
                    os.write(buf, 0, count);
                    digest.update(buf, 0, count);
                }
                String[] args = { String.valueOf(size), tfs.getFileName(), from };
                logger.log(logger.INFO, br.getKString(br.I_FILE_TX_COMPLETE, args));
                gp = GPacket.getInstance();
                gp.read(is);
                if (gp.getType() != ProtocolGlobals.G_TRANSFER_FILE_END) {
                    String[] emsg = { ProtocolGlobals.getPacketTypeDisplayString(gp.getType()), from, ProtocolGlobals.getPacketTypeDisplayString(ProtocolGlobals.G_TRANSFER_FILE_END) };
                    logger.log(logger.ERROR, br.getKString(br.E_CLUSTER_UNEXPECTED_PACKET_FROM_1, emsg));
                    try {
                        socket.close();
                    } catch (Exception e) {
                    }
                    return;
                }
                fte = ClusterTransferFileEndInfo.newInstance(gp);
                if (!Arrays.equals(digest.digest(), fte.getDigest())) {
                    logger.log(logger.ERROR, br.getKString(br.E_CLUSTER_FILE_TX_DIGEST_MISMATCH, tfs.getFileName(), from));
                    try {
                        socket.close();
                    } catch (Exception e) {
                    }
                    return;
                }
                os.close();
                logger.log(logger.INFO, br.getKString(br.I_FILE_TX_SUCCESS, tfs.getFileName(), from));
                callback.doneTransfer(tmpfile, tfs.getFileName(), tfs.getBrokerID(), tfs.getLastModifiedTime(), true, remote);
                success = true;
            } finally {
                if (!success) {
                    // cleanup
                    try {
                        os.close();
                    } catch (Exception e) {
                    }
                    callback.doneTransfer(tmpfile, tfs.getFileName(), tfs.getBrokerID(), tfs.getLastModifiedTime(), false, remote);
                }
            }
            if (fte.hasMoreFiles() != ((cnt + 1) < numFiles)) {
                String[] args = { String.valueOf(numFiles), from, String.valueOf(cnt + 1), String.valueOf(fte.hasMoreFiles()) };
                String emsg = br.getKString(br.E_CLUSTER_FILE_TX_NUMFILES, args);
                logger.log(logger.ERROR, emsg);
                throw new BrokerException(emsg);
            }
        }
        if (numFiles > 0) {
            callback.allDoneTransfer(tfl.getBrokerID(), tfl.getUUID(), remote);
            OutputStream sos = socket.getOutputStream();
            gp = ClusterTransferFileEndInfo.getReplyGPacket(Status.OK, (String) null);
            gp.write(sos);
            sos.flush();
            try {
                gp = GPacket.getInstance();
                gp.read(is);
                if (gp.getType() != ProtocolGlobals.G_TRANSFER_FILE_END_ACK_ACK) {
                    String[] args = { ProtocolGlobals.getPacketTypeDisplayString(gp.getType()), from, ProtocolGlobals.getPacketTypeDisplayString(ProtocolGlobals.G_TRANSFER_FILE_END_ACK_ACK) };
                    String emsg = br.getKString(br.E_CLUSTER_UNEXPECTED_PACKET_FROM_1, args);
                    logger.log(logger.ERROR, emsg);
                    throw new BrokerException(emsg);
                }
            } catch (Throwable t) {
                if (parent.DEBUG) {
                    logger.log(logger.INFO, "Exception in receiving " + ProtocolGlobals.getPacketTypeDisplayString(ProtocolGlobals.G_TRANSFER_FILE_END_ACK_ACK) + " from " + from + " for tranfer files of broker " + tfl.getBrokerID() + ": " + t.getMessage());
                }
            }
            try {
                is.close();
            } catch (Exception e) {
            }
            try {
                sos.close();
            } catch (Exception e) {
            }
            try {
                socket.close();
            } catch (Exception e) {
            }
        }
    } catch (Throwable t) {
        try {
            socket.close();
        } catch (Exception e) {
        }
        logger.logStack(logger.ERROR, br.getKString(br.E_CLUSTER_PROCESS_FILE_TX_REQUEST, from), t);
    } finally {
        es.shutdownNow();
    }
}
Also used : BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) ClusterTransferFileStartInfo(com.sun.messaging.jmq.jmsserver.multibroker.raptor.ClusterTransferFileStartInfo) ClusterTransferFileEndInfo(com.sun.messaging.jmq.jmsserver.multibroker.raptor.ClusterTransferFileEndInfo) GPacket(com.sun.messaging.jmq.io.GPacket) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) ClusterTransferFileListInfo(com.sun.messaging.jmq.jmsserver.multibroker.raptor.ClusterTransferFileListInfo)

Aggregations

GPacket (com.sun.messaging.jmq.io.GPacket)2 ClusterTransferFileEndInfo (com.sun.messaging.jmq.jmsserver.multibroker.raptor.ClusterTransferFileEndInfo)2 ClusterTransferFileListInfo (com.sun.messaging.jmq.jmsserver.multibroker.raptor.ClusterTransferFileListInfo)2 ClusterTransferFileStartInfo (com.sun.messaging.jmq.jmsserver.multibroker.raptor.ClusterTransferFileStartInfo)2 BrokerException (com.sun.messaging.jmq.jmsserver.util.BrokerException)2 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)2 LoadException (com.sun.messaging.jmq.jmsserver.persist.api.LoadException)1 LoopbackAddressException (com.sun.messaging.jmq.jmsserver.util.LoopbackAddressException)1 FilteringObjectInputStream (com.sun.messaging.jmq.util.io.FilteringObjectInputStream)1 MessageDigest (java.security.MessageDigest)1