Skip to content

Commit

Permalink
Merge branch 'allegro:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
tuliren authored Jan 23, 2022
2 parents 8bb7343 + 55c3b43 commit 51079af
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package tech.allegro.schema.json2avro.validator;

import tech.allegro.schema.json2avro.validator.schema.ValidationOutput;
import tech.allegro.schema.json2avro.validator.schema.ValidatorException;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

class FileValidationOutput implements ValidationOutput {

private final Path outputPath;

FileValidationOutput(Path outputPath) {
this.outputPath = outputPath;
}

@Override
public void write(byte[] output) {
try {
Files.write(outputPath, output);
} catch (IOException e) {
throw new ValidatorException("Error occurred when writing the output", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,41 @@

import com.beust.jcommander.Parameter;

import java.nio.file.Path;

public class ValidatorOptions {

@Parameter(names = {"-s", "--schema"}, description = "Path to the schema file", required = true)
private String schemaPath;
private Path schemaPath;

@Parameter(names = {"-i", "--input"}, description = "Path to the validated file", required = true)
private String inputPath;
private Path inputPath;

@Parameter(names = {"-d", "--debug"}, description = "Enables logging in debug mode")
private boolean debug = true;

@Parameter(names = {"-m", "--mode"}, description = "Validation mode. Supported: json2avro, avro2json, json2avro2json")
private String mode = "json2avro";

@Parameter(names = {"-o", "--output"}, description = "Path to the generated file (it will be created or it will be truncated if exists)")
private Path outputPath;

@Parameter(names = "--help", help = true, description = "Displays this help message")
private boolean help;

public String getSchemaPath() {
public Path getSchemaPath() {
return schemaPath;
}

public void setSchemaPath(String schemaPath) {
public void setSchemaPath(Path schemaPath) {
this.schemaPath = schemaPath;
}

public String getInputPath() {
public Path getInputPath() {
return inputPath;
}

public void setInputPath(String inputPath) {
public void setInputPath(Path inputPath) {
this.inputPath = inputPath;
}

Expand All @@ -43,6 +48,14 @@ public void setDebug(boolean debug) {
this.debug = debug;
}

public Path getOutputPath() {
return outputPath;
}

public void setOutputPath(Path outputPath) {
this.outputPath = outputPath;
}

public boolean isHelp() {
return help;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tech.allegro.schema.json2avro.validator.schema.ValidationMode;
import tech.allegro.schema.json2avro.validator.schema.ValidationOutput;
import tech.allegro.schema.json2avro.validator.schema.ValidatorException;
import tech.allegro.schema.json2avro.validator.schema.Validators;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path;

public class ValidatorRunner {

Expand All @@ -23,6 +24,7 @@ public static void run(ValidatorOptions options) {
.withMode(getMode(options))
.withInput(readFile(options.getInputPath()))
.withSchema(readFile(options.getSchemaPath()))
.withOutput(getOutput(options.getOutputPath()))
.build()
.validate();
} catch (IOException e) {
Expand All @@ -46,8 +48,12 @@ private static ValidationMode getMode(ValidatorOptions options) {
return ValidationMode.from(options.getMode());
}

private static byte[] readFile(String path) throws IOException {
return Files.readAllBytes(Paths.get(path));
private static byte[] readFile(Path path) throws IOException {
return Files.readAllBytes(path);
}

private static ValidationOutput getOutput(Path outputPath) {
return outputPath != null ? new FileValidationOutput(outputPath) : ValidationOutput.NO_OUTPUT;
}

private static void configureLogging(ValidatorOptions options) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package tech.allegro.schema.json2avro.validator.schema;

public interface ValidationOutput {

ValidationOutput NO_OUTPUT = output -> {};

void write(byte[] output);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.slf4j.LoggerFactory;
import tech.allegro.schema.json2avro.converter.JsonAvroConverter;
import tech.allegro.schema.json2avro.validator.schema.ValidationMode;
import tech.allegro.schema.json2avro.validator.schema.ValidationOutput;
import tech.allegro.schema.json2avro.validator.schema.ValidationResult;
import tech.allegro.schema.json2avro.validator.schema.Validator;
import tech.allegro.schema.json2avro.validator.schema.ValidatorException;
Expand All @@ -22,14 +23,17 @@ public class AvroValidator implements Validator {

private final ValidationMode mode;

private final ValidationOutput output;

private final JsonAvroConverter converter;

public AvroValidator(byte[] schema, byte[] content, ValidationMode mode) {
public AvroValidator(byte[] schema, byte[] content, ValidationMode mode, ValidationOutput output) {
converter = new JsonAvroConverter();
try {
this.schema = new Schema.Parser().parse(new ByteArrayInputStream(schema));
this.content = content;
this.mode = mode;
this.output = output;
} catch (IOException e) {
throw new ValidatorException("An unexpected error occurred when parsing the schema", e);
}
Expand All @@ -56,8 +60,9 @@ public ValidationResult validate() {
private byte [] convertAvroToJson(byte [] avro) {
try {
logger.debug("Converting AVRO to JSON");
byte [] json = converter.convertToJson(avro, schema);;
byte [] json = converter.convertToJson(avro, schema);
logger.debug("Validation result: success. JSON: \n{}", new String(json));
output.write(json);
return json;
} catch (RuntimeException e) {
throw new ValidatorException("Error occurred when validating the document", e);
Expand All @@ -69,6 +74,7 @@ public ValidationResult validate() {
logger.debug("Converting JSON to AVRO");
byte [] avro = converter.convertToAvro(json, schema);
logger.debug("Validation result: success. AVRO: \n{}", new String(avro));
output.write(avro);
return avro;
} catch (RuntimeException e) {
throw new ValidatorException("Error occurred when validating the document", e);
Expand All @@ -87,6 +93,8 @@ public static class Builder {

private ValidationMode mode = ValidationMode.JSON_TO_AVRO;

private ValidationOutput output = ValidationOutput.NO_OUTPUT;

public Builder withSchema(byte[] schema) {
this.schema = schema;
return this;
Expand All @@ -102,8 +110,13 @@ public Builder withMode(ValidationMode mode) {
return this;
}

public Builder withOutput(ValidationOutput output) {
this.output = output;
return this;
}

public AvroValidator build() {
return new AvroValidator(schema, input, mode);
return new AvroValidator(schema, input, mode, output);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import groovy.json.JsonSlurper
import org.apache.avro.Schema
import org.apache.avro.generic.GenericData
import org.apache.avro.generic.GenericRecord
import tech.allegro.schema.json2avro.validator.schema.ValidationMode
import tech.allegro.schema.json2avro.validator.schema.ValidatorException
import spock.lang.Specification
import spock.lang.Subject
import tech.allegro.schema.json2avro.validator.FileValidationOutput
import tech.allegro.schema.json2avro.validator.schema.ValidationMode
import tech.allegro.schema.json2avro.validator.schema.ValidationResult
import tech.allegro.schema.json2avro.validator.schema.ValidatorException
import tech.allegro.schema.json2avro.validator.schema.Validators
import tech.allegro.schema.json2avro.validator.test.AvroUtils

import java.nio.file.Files

import static tech.allegro.schema.json2avro.validator.test.ResourceUtils.readResource

class AvroValidatorSpec extends Specification {
Expand Down Expand Up @@ -100,4 +103,59 @@ class AvroValidatorSpec extends Specification {
expect:
json.name == "Bob"
}

def "should save conversion from JSON to AVRO in file"() {

setup:
def tempDirectory = Files.createTempDirectory(getClass().simpleName)
def savedUserPath = tempDirectory.resolve("saved_user.avro")

and:
validator = Validators.avro()
.withInput(readResource("user.json"))
.withSchema(avroSchema)
.withOutput(new FileValidationOutput(savedUserPath))
.build()

when:
validator.validate()

then:
def actualOutput = Files.readAllBytes(savedUserPath)
Arrays.equals(actualOutput, readResource("user.avro"))

cleanup:
Files.delete(savedUserPath)
Files.delete(tempDirectory)
}

def "should save conversion from AVRO to JSON in file"() {

setup:
def tempDirectory = Files.createTempDirectory(getClass().simpleName)
def savedUserPath = tempDirectory.resolve("saved_user.json")

and:
validator = Validators.avro()
.withInput(readResource("user.avro"))
.withSchema(avroSchema)
.withMode(ValidationMode.AVRO_TO_JSON)
.withOutput(new FileValidationOutput(savedUserPath))
.build()

when:
validator.validate()

then:
def actualUser = new JsonSlurper().parseText(Files.readString(savedUserPath))

expect:
actualUser.name == "Bob"
actualUser.age == 50
actualUser.favoriteColor == "blue"

cleanup:
Files.delete(savedUserPath)
Files.delete(tempDirectory)
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package tech.allegro.schema.json2avro.validator.test

import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths

class ResourceUtils {

static String resource(String path) {
static Path resource(String path) {

new File(ResourceUtils.classLoader.getResource(path).toURI()).getAbsolutePath()
Paths.get(ResourceUtils.classLoader.getResource(path).toURI())
}

static byte[] readResource(String path) {

String filePath = resource(path)
return Files.readAllBytes(Paths.get(filePath))
Path filePath = resource(path)
return Files.readAllBytes(filePath)
}
}

0 comments on commit 51079af

Please sign in to comment.