Пример #1
0
  /** Part of the ChecksumMover interface. */
  private ChecksumFactory getChecksumFactory(GFtpProtocolInfo protocol) {
    String type = protocol.getChecksumType();
    if (type == null || type.equals("Unknown")) {
      return null;
    }

    try {
      return ChecksumFactory.getFactory(ChecksumType.getChecksumType(type));
    } catch (NoSuchAlgorithmException e) {
      esay("CRC Algorithm is not supported: " + type);
    }

    return null;
  }
Пример #2
0
  /** Part of the MoverProtocol interface. */
  @Override
  public void runIO(
      FileAttributes fileAttributes,
      RepositoryChannel fileChannel,
      ProtocolInfo protocol,
      Allocator allocator,
      IoMode access)
      throws Exception {
    if (!(protocol instanceof GFtpProtocolInfo)) {
      throw new CacheException(44, "Protocol info not of type GFtpProtocolInfo");
    }
    GFtpProtocolInfo gftpProtocolInfo = (GFtpProtocolInfo) protocol;

    Role role = access == IoMode.WRITE ? Role.Receiver : Role.Sender;
    int version = gftpProtocolInfo.getMajorVersion();
    String host = gftpProtocolInfo.getSocketAddress().getAddress().getHostAddress();
    int port = gftpProtocolInfo.getSocketAddress().getPort();
    int bufferSize = gftpProtocolInfo.getBufferSize();
    int parallelism = gftpProtocolInfo.getParallelStart();
    long offset = gftpProtocolInfo.getOffset();
    long size = gftpProtocolInfo.getSize();
    boolean passive = gftpProtocolInfo.getPassive() && _allowPassivePool;

    say(
        MessageFormat.format(
            "version={0}, role={1}, mode={2}, host={3}:{4,number,#}, buffer={5}, passive={6}, parallelism={7}",
            version,
            role,
            gftpProtocolInfo.getMode(),
            host,
            port,
            bufferSize,
            passive,
            parallelism));

    /* Sanity check the parameters.
     */
    if (gftpProtocolInfo.getPassive() && version == 1) {
      /* In passive mode we need to be able to send the port we
       * listen on to the client. With GFtp/1, we cannot send
       * this information back to the door.
       */
      throw new CacheException(
          44, "Internal error: Cannot do passive transfer with mover protocol version 1.");
    }

    /* If on transfer checksum calculation is enabled, check if
     * we have a protocol specific preferred algorithm.
     */
    if (_checksumFactory != null) {
      ChecksumFactory factory = getChecksumFactory(gftpProtocolInfo);
      if (factory != null) {
        _checksumFactory = factory;
      }
      _digest = _checksumFactory.create();
    }

    /* We initialise these things early, as the job timeout
     * manager will not kill the job otherwise.
     */
    _transferStarted = System.currentTimeMillis();
    _lastTransferred = _transferStarted;

    Mode mode = createMode(gftpProtocolInfo.getMode(), role, fileChannel);
    mode.setBufferSize(bufferSize);

    /* For GFtp/2, the FTP door expects a
     * GFtpTransferStartedMessage when the mover is ready to
     * transfer the data.
     */
    if (version == 2) {
      GFtpTransferStartedMessage message;

      if (passive) {
        /* When in passive mode, the door passes us the host
         * from which the control channel was created. It
         * seems like a safe assumption that the data channel
         * will be established from the same network.
         */
        InetAddress clientAddress = InetAddress.getByName(gftpProtocolInfo.getClientAddress());
        InetAddress localAddress = NetworkUtils.getLocalAddress(clientAddress);

        /* When using true passive mode, we open a server
         * socket and send a message containing the port
         * number back to the door.
         */
        ServerSocketChannel channel = ServerSocketChannel.open();
        if (bufferSize > 0) {
          channel.socket().setReceiveBufferSize(bufferSize);
        }
        _portRange.bind(channel.socket(), localAddress, 128);

        message =
            new GFtpTransferStartedMessage(
                fileAttributes.getPnfsId().getId(),
                channel.socket().getInetAddress().getHostAddress(),
                channel.socket().getLocalPort());
        mode.setPassive(channel);
      } else {
        /* If passive mode is disabled, then fall back to
         * active mode.  When notified about this, the door
         * will fall back to proxy mode.
         */
        message = new GFtpTransferStartedMessage(fileAttributes.getPnfsId().getId());
      }
      CellPath path =
          new CellPath(
              gftpProtocolInfo.getDoorCellName(), gftpProtocolInfo.getDoorCellDomainName());
      _cell.sendMessage(new CellMessage(path, message));
    }

    if (!passive) {
      /* We use PROXY or ACTIVE mode. In proxy mode, host and
       * port identify the SocketAdapter running at the door. In
       * Active mode, host and port identify the client. Either
       * way, we do not really care.
       */

      try {
        mode.setActive(new InetSocketAddress(host, port));
      } catch (UnresolvedAddressException e) {
        throw new CacheException("Failed to resolve " + host);
      }
    }

    /* - Parallel transfers in stream mode are not defined.
     *
     * - Receiption in E mode must be passive (incomming). If the
     *   connection is outgoing, it means we use a proxy at the door.
     *   This proxy is limitted to one connection from the mover.
     *
     * In either case, set the parallelism to one.
     */
    switch (Character.toUpperCase(gftpProtocolInfo.getMode().charAt(0))) {
      case 'E':
        if (role == Role.Receiver && !passive) {
          parallelism = 1;
        }
        break;
      case 'S':
        parallelism = 1;
        break;
    }
    mode.setParallelism(parallelism);

    /* Setup partial retrieve parameters. These settings have
     * already been checked by the door, but better safe than
     * sorry...
     */
    if (role == Role.Sender) {
      long fileSize = fileChannel.size();
      if (offset < 0) {
        String err = "prm_offset is " + offset;
        esay(err);
        throw new IllegalArgumentException(err);
      }
      if (size < 0) {
        String err = "prm_offset is " + size;
        esay(err);
        throw new IllegalArgumentException(err);
      }
      if (offset + size > fileSize) {
        String err =
            "invalid prm_offset="
                + offset
                + " and prm_size "
                + size
                + " for file of size "
                + fileSize;
        esay(err);
        throw new IllegalArgumentException(err);
      }
      mode.setPartialRetrieveParameters(offset, size);
    }

    try {
      transfer(fileChannel, role, mode, allocator);
    } finally {
      /* Log some useful information about the transfer. This
       * will be send back to the door by the pool cell.
       */
      gftpProtocolInfo.setBytesTransferred(getBytesTransferred());
      gftpProtocolInfo.setTransferTime(getTransferTime());
    }
  }