content: /*
   * 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.hadoop.chukwa.extraction.demux;
  
  
  import java.io.IOException;
  import org.apache.hadoop.chukwa.conf.ChukwaConfiguration;
  import org.apache.hadoop.fs.FileStatus;
  import org.apache.hadoop.fs.FileSystem;
  import org.apache.hadoop.fs.FileUtil;
  import org.apache.hadoop.fs.Path;
  import org.apache.hadoop.util.Tool;
  import org.apache.hadoop.util.ToolRunner;
  import org.apache.log4j.Logger;
  import org.apache.hadoop.chukwa.util.ExceptionUtil;
  
  public class RecordMerger extends Thread {
    static Logger log = Logger.getLogger(RecordMerger.class);
    ChukwaConfiguration conf = null;
    FileSystem fs = null;
    String[] mergeArgs = null;
    Tool tool = null;
    boolean deleteRawData = false;
  
    public RecordMerger(ChukwaConfiguration conf, FileSystem fs, Tool tool,
                        String[] mergeArgs, boolean deleteRawData) {
      this.conf = conf;
      this.fs = fs;
      this.tool = tool;
      this.mergeArgs = mergeArgs.clone();
      this.deleteRawData = deleteRawData;
    }
  
    @Override
    public void run() {
      mergeRecords();
    }
  
    void mergeRecords() {
      System.out.println("\t Running Merge! : output [" + mergeArgs[1] + "]");
      int res;
      try {
        res = ToolRunner.run(conf, tool, mergeArgs);
        System.out.println("MR exit status: " + res);
        if (res == 0) {
          writeRecordFile(mergeArgs[1] + "/part-00000", mergeArgs[2],
              mergeArgs[3]);
  
          // delete input
          if (deleteRawData) {
            FileUtil.fullyDelete(fs, new Path(mergeArgs[0]));
  
            Path hours = new Path(mergeArgs[2]);
            FileStatus[] hoursOrMinutesFS = fs.listStatus(hours);
            for (FileStatus hourOrMinuteFS : hoursOrMinutesFS) {
              String dirName = hourOrMinuteFS.getPath().getName();
  
              try {
                Integer.parseInt(dirName);
                FileUtil.fullyDelete(fs, new Path(mergeArgs[2] + "/" + dirName));
                if (log.isDebugEnabled()) {
                  log.debug("Deleting Hour directory: " + mergeArgs[2] + "/"
                      + dirName);
                }
              } catch (NumberFormatException e) { /*
                                                   * Not an Hour or Minutes
                                                   * directory- Do nothing
                                                   */
                log.debug(ExceptionUtil.getStackTrace(e));
              }
            }
          }
  
          // delete rolling tag
          FileUtil.fullyDelete(fs, new Path(mergeArgs[3]));
          // delete M/R temp directory
          FileUtil.fullyDelete(fs, new Path(mergeArgs[1]));
        } else {
          throw new RuntimeException("Error in M/R merge operation!");
        }
  
      } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException("Error in M/R merge operation!", e);
      }
    }
  
    void writeRecordFile(String input, String outputDir, String fileName)
        throws IOException {
      boolean done = false;
      int count = 1;
      Path recordFile = new Path(input);
      do {
        Path destDirPath = new Path(outputDir);
        Path destFilePath = new Path(outputDir + "/" + fileName + "." + count
            + ".evt");
  
        if (!fs.exists(destDirPath)) {
          fs.mkdirs(destDirPath);
          log.info(">>>>>>>>>>>> create Dir" + destDirPath);
        }
  
        if (!fs.exists(destFilePath)) {
          boolean res = fs.rename(recordFile, destFilePath);
  
          if (res == false) {
            log.info(">>>>>>>>>>>> Use standard copy rename failded");
            FileUtil.copy(fs, recordFile, fs, destFilePath, false, false, conf);
          }
          done = true;
        } else {
          log.info("Start MoveToRepository main()");
        }
        count++;
        // Just put a limit here
        // TODO read from config
        if (count > 1000) {
          throw new IOException("too many files in this directory: "
              + destDirPath);
        }
      } while (!done);
    }
  }
  