예제 #1
0
  /** The main driver loop that enforces the protocol message sequence and implements it. */
  @Override
  public void run() {
    /* The initial protocol */
    Protocol protocol =
        new Protocol(feederManager.nameIdPair, Protocol.VERSION, feederManager.getEnvImpl());
    try {
      configureChannel();
      protocol = checkProtocol(protocol);
      checkFeeder(protocol);
      sendFileList(protocol);
      sendRequestedFiles(protocol);

      /* Done, cleanup */
      dbBackup.endBackup();
      dbBackup = null;
    } catch (ClosedByInterruptException e) {
      LoggerUtils.fine(
          logger,
          feederManager.getEnvImpl(),
          "Ignoring ClosedByInterruptException normal shutdown");
    } catch (IOException e) {
      LoggerUtils.warning(logger, feederManager.getEnvImpl(), " IO Exception: " + e.getMessage());
    } catch (ProtocolException e) {
      LoggerUtils.severe(
          logger, feederManager.getEnvImpl(), " Protocol Exception: " + e.getMessage());
    } catch (Exception e) {
      throw new EnvironmentFailureException(
          feederManager.getEnvImpl(), EnvironmentFailureReason.UNCAUGHT_EXCEPTION, e);
    } finally {
      try {
        namedChannel.getChannel().close();
      } catch (IOException e) {
        LoggerUtils.warning(
            logger,
            feederManager.getEnvImpl(),
            "Log File feeder io exception on " + "channel close: " + e.getMessage());
      }
      shutdown();

      if (dbBackup != null) {
        if (feederManager.shutdown.get()) {
          dbBackup.endBackup();
        } else {

          /*
           * Establish lease so client can resume within the lease
           * period.
           */
          feederManager.new Lease(clientId, feederManager.leaseDuration, dbBackup);
          LoggerUtils.info(
              logger, feederManager.getEnvImpl(), "Lease created for node: " + clientId);
        }
      }
      LoggerUtils.info(
          logger,
          feederManager.getEnvImpl(),
          "Log file feeder for client: " + clientId + " exited");
    }
  }
예제 #2
0
  /**
   * Send files in response to request messages. The request sequence looks like the following:
   *
   * <p>[FileReq | StatReq]+ Done
   *
   * <p>The response sequence to a FileReq looks like:
   *
   * <p>FileStart <file byte stream> FileEnd
   *
   * <p>and that for a StatReq, is simply a StatResp
   */
  private void sendRequestedFiles(Protocol protocol)
      throws IOException, ProtocolException, DatabaseException {

    try {
      while (true) {
        FileReq fileReq = protocol.read(namedChannel.getChannel(), FileReq.class);
        final String fileName = fileReq.getFileName();

        /*
         * Calculate the full path for a specified log file name,
         * especially when this Feeder is configured to run with sub
         * directories.
         */
        FileManager fMgr = feederManager.getEnvImpl().getFileManager();
        File file = new File(fMgr.getFullFileName(fileName));

        if (!file.exists()) {
          throw EnvironmentFailureException.unexpectedState("Log file not found: " + fileName);
        }
        /* Freeze the length and last modified date. */
        final long length = file.length();
        final long lastModified = file.lastModified();
        byte digest[] = null;
        FileInfoResp resp = null;
        Protocol.FileInfoResp cachedResp = feederManager.statResponses.get(fileName);
        byte cachedDigest[] =
            ((cachedResp != null)
                    && (cachedResp.getFileLength() == length)
                    && (cachedResp.getLastModifiedTime() == lastModified))
                ? cachedResp.getDigestSHA1()
                : null;

        if (fileReq instanceof FileInfoReq) {
          if (cachedDigest != null) {
            digest = cachedDigest;
          } else if (((FileInfoReq) fileReq).getNeedSHA1()) {
            digest = getSHA1Digest(file, length).digest();
          } else {
            // Digest not requested
            digest = new byte[0];
          }
          resp = protocol.new FileInfoResp(fileName, length, lastModified, digest);
        } else {
          protocol.write(protocol.new FileStart(fileName, length, lastModified), namedChannel);
          digest = sendFileContents(file, length);
          if ((cachedDigest != null) && !Arrays.equals(cachedDigest, digest)) {
            throw EnvironmentFailureException.unexpectedState(
                "Inconsistent cached and computed digests");
          }
          resp = protocol.new FileEnd(fileName, length, lastModified, digest);
        }
        /* Cache for subsequent requests, if it was computed. */
        if (digest.length > 0) {
          feederManager.statResponses.put(fileName, resp);
        }
        protocol.write(resp, namedChannel);
      }
    } catch (ProtocolException pe) {
      if (pe.getUnexpectedMessage() instanceof Protocol.Done) {
        return;
      }
      throw pe;
    }
  }