package com.linkedin.databus2.core.schema.tools; /* * * Copyright 2013 LinkedIn Corp. All rights reserved * * Licensed 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. * */ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.avro.Schema; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.SimpleLayout; import com.linkedin.databus2.core.schema.tools.AvroConverter.AvroFormat; public class AvroConvertMain { public static final String MODULE = AvroConvertMain.class.getName(); public static final Logger LOG = Logger.getLogger(MODULE); /** * @param args */ public static void main(String[] args) throws Exception { ConsoleAppender app = new ConsoleAppender(new SimpleLayout()); Logger.getRootLogger().removeAllAppenders(); Logger.getRootLogger().addAppender(app); AvroConvertCli cli = new AvroConvertCli(); try { cli.parseCommandLine(args); } catch (ParseException pe) { System.err.println(pe.getMessage()); cli.printUsage(); System.exit(1); } if (!cli.hasOptions() || cli.hasHelpOption()) { cli.printUsage(); System.exit(0); } int verbosity = cli.getVerbosity(); switch (verbosity) { case 0: Logger.getRootLogger().setLevel(Level.ERROR); break; case 1: Logger.getRootLogger().setLevel(Level.INFO); break; case 2: Logger.getRootLogger().setLevel(Level.DEBUG); break; default: Logger.getRootLogger().setLevel(Level.ALL); break; } AvroFormat inputFormat = cli.getInputFormat(AvroFormat.JSON); LOG.info("Using input format: " + inputFormat); AvroFormat outputFormat = cli.getOutputFormat(AvroFormat.JSON); LOG.info("Using output format: " + outputFormat); String inputSchemaName = cli.getInputSchema(null); if (null == inputSchemaName) { System.err.println("Input schema expected"); cli.printUsage(); System.exit(4); } Schema inputSchema = null; try { inputSchema = openSchema(inputSchemaName); } catch (IOException ioe) { System.err.println("Unable to open input schema: " + ioe); System.exit(2); } LOG.info("Using input schema:" + inputSchemaName); String outputSchemaName = cli.getOutputSchema(inputSchemaName); Schema outputSchema = null; try { outputSchema = outputSchemaName.equals(inputSchemaName) ? inputSchema : openSchema(outputSchemaName); } catch (IOException ioe) { System.err.println("Unable to open output schema: " + ioe); System.exit(3); } LOG.info("Using output schema:" + outputSchemaName); String inputFileName = cli.getInputFileName("-"); InputStream input = inputFileName.equals("-") ? System.in : new FileInputStream(inputFileName); LOG.info("Using input: " + inputFileName); String outputFileName = cli.getOutputFileName("-"); OutputStream output = outputFileName.equals("-") ? System.out : new FileOutputStream(outputFileName); LOG.info("Using output: " + outputFileName); AvroConverter avroConverter = new AvroConverter(inputFormat, outputFormat, inputSchema, outputSchema); avroConverter.convert(input, output); if (! inputFileName.equals("-")) input.close(); if (! outputFileName.equals("-")) output.close(); } private static Schema openSchema(String schemaName) throws IOException { return Schema.parse(new File(schemaName)); } } class AvroConvertCli { public static final String HELP_OPT_NAME = " help"; public static final char HELP_OPT_CHAR = 'h'; public static final String INPUT_SCHEMA_OPT_NAME = "input_schema"; public static final char INPUT_SCHEMA_OPT_CHAR = 'I'; public static final String INPUT_FORMAT_OPT_NAME = "input_format"; public static final char INPUT_FORMAT_OPT_CHAR = 'i'; public static final String OUTPUT_SCHEMA_OPT_NAME = "output_schema"; public static final char OUTPUT_SCHEMA_OPT_CHAR = 'O'; public static final String OUTPUT_FORMAT_OPT_NAME = "output_format"; public static final char OUTPUT_FORMAT_OPT_CHAR = 'o'; public static final String INPUT_FILE_OPT_NAME = "input_file"; public static final char INPUT_FILE_OPT_CHAR = 'f'; public static final String OUTPUT_FILE_OPT_NAME = "output_file"; public static final char OUTPUT_FILE_OPT_CHAR = 'F'; public static final char VERBOSE_OPT_CHAR = 'v'; private final Options _options = new Options(); private CommandLine _cmdLine; @SuppressWarnings("static-access") public AvroConvertCli() { Option helpOption = OptionBuilder.withLongOpt(HELP_OPT_NAME) .withDescription("this help screen") .create(HELP_OPT_CHAR); Option inpFormatOption = OptionBuilder.withLongOpt(INPUT_FORMAT_OPT_NAME) .withDescription("Input format: JSON, JSON_LINES, BINARY") .hasArg() .withArgName("format") .create(INPUT_FORMAT_OPT_CHAR); Option outFormatOption = OptionBuilder.withLongOpt(OUTPUT_FORMAT_OPT_NAME) .withDescription("Output format: JSON, JSON_LINES, BINARY") .hasArg() .withArgName("format") .create(OUTPUT_FORMAT_OPT_CHAR); Option inpSchemaOption = OptionBuilder.withLongOpt(INPUT_SCHEMA_OPT_NAME) .withDescription("Input schema file") .hasArg() .withArgName("file") .create(INPUT_SCHEMA_OPT_CHAR); Option outSchemaOption = OptionBuilder.withLongOpt(OUTPUT_SCHEMA_OPT_NAME) .withDescription("Output schema file") .hasArg() .withArgName("file") .create(OUTPUT_SCHEMA_OPT_CHAR); Option inpFileOption = OptionBuilder.withLongOpt(INPUT_FILE_OPT_NAME) .withDescription("input file name or - for STDIN") .hasArg() .withArgName("file | - ") .create(INPUT_FILE_OPT_CHAR); Option outFileOption = OptionBuilder.withLongOpt(OUTPUT_FILE_OPT_NAME) .withDescription("output file name or - for STDOUT") .hasArg() .withArgName("file | - ") .create(OUTPUT_FILE_OPT_CHAR); Option verboseOption = OptionBuilder.withDescription("verbose; more occurrences increase verbosity") .create(VERBOSE_OPT_CHAR); _options.addOption(helpOption); _options.addOption(inpFormatOption); _options.addOption(outFormatOption); _options.addOption(inpSchemaOption); _options.addOption(outSchemaOption); _options.addOption(inpFileOption); _options.addOption(outFileOption); _options.addOption(verboseOption); } public void parseCommandLine(String[] args) throws ParseException { GnuParser cmdLineParser = new GnuParser(); _cmdLine = cmdLineParser.parse(_options, args); } public void printUsage() { HelpFormatter help = new HelpFormatter(); help.setWidth(100); help.printHelp("java " + AvroConvertMain.class.getName() + " [options]", _options); } public boolean hasOptions() { return _cmdLine.getOptions().length > 0; } public boolean hasHelpOption() { return _cmdLine.hasOption(HELP_OPT_CHAR); } public AvroConverter.AvroFormat getInputFormat(AvroConverter.AvroFormat defaultFormat) { String inpFormatString = _cmdLine.getOptionValue(INPUT_FORMAT_OPT_CHAR, defaultFormat.toString()); return AvroConverter.AvroFormat.valueOf(inpFormatString.toUpperCase()); } public AvroConverter.AvroFormat getOutputFormat(AvroConverter.AvroFormat defaultFormat) { String outFormatString = _cmdLine.getOptionValue(OUTPUT_FORMAT_OPT_CHAR, defaultFormat.toString()); return AvroConverter.AvroFormat.valueOf(outFormatString.toUpperCase()); } public String getInputSchema(String defaultValue) { return _cmdLine.getOptionValue(INPUT_SCHEMA_OPT_CHAR, defaultValue); } public String getOutputSchema(String defaultValue) { return _cmdLine.getOptionValue(OUTPUT_SCHEMA_OPT_CHAR, defaultValue); } public String getInputFileName(String defaultValue) { return _cmdLine.getOptionValue(INPUT_FILE_OPT_CHAR, defaultValue); } public String getOutputFileName(String defaultValue) { return _cmdLine.getOptionValue(OUTPUT_FILE_OPT_CHAR, defaultValue); } public int getVerbosity() { int cnt = 0; for (Option o: _cmdLine.getOptions()) if (o.getOpt().equals("v")) ++cnt; return cnt; } }