/** * ` * Copyright 2016 Confluent Inc. * * 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. **/ package io.confluent.kafka.schemaregistry.maven; import io.confluent.kafka.schemaregistry.client.SchemaMetadata; import io.confluent.kafka.schemaregistry.client.rest.exceptions.RestClientException; import org.apache.avro.Schema; import org.apache.avro.SchemaParseException; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @Mojo(name = "download") public class DownloadSchemaRegistryMojo extends SchemaRegistryMojo { @Parameter(required = false, defaultValue = ".avsc") String schemaExtension; @Parameter(required = true) List<String> subjectPatterns = new ArrayList<>(); @Parameter(required = true) File outputDirectory; @Parameter(required = false, defaultValue = "true") boolean prettyPrintSchemas; Map<String, Schema> downloadSchemas(Collection<String> subjects) throws MojoExecutionException { Map<String, Schema> results = new LinkedHashMap<>(); for (String subject : subjects) { Schema.Parser parser = new Schema.Parser(); SchemaMetadata schemaMetadata; try { getLog().info(String.format("Downloading latest metadata for %s.", subject)); schemaMetadata = this.client().getLatestSchemaMetadata(subject); Schema schema = parser.parse(schemaMetadata.getSchema()); results.put(subject, schema); } catch (RestClientException | IOException ex) { throw new MojoExecutionException( String.format("Exception thrown while downloading metadata for %s.", subject), ex ); } catch (SchemaParseException ex) { throw new MojoExecutionException( String.format("Exception thrown while parsing avro schema for %s.", subject), ex ); } } return results; } @Override public void execute() throws MojoExecutionException, MojoFailureException { try { getLog().debug( String.format("Checking if '%s' exists and is not a directory.", this.outputDirectory)); if (outputDirectory.exists() && !outputDirectory.isDirectory()) { throw new IllegalStateException("outputDirectory must be a directory"); } getLog() .debug(String.format("Checking if outputDirectory('%s') exists.", this.outputDirectory)); if (!outputDirectory.isDirectory()) { getLog().debug(String.format("Creating outputDirectory('%s').", this.outputDirectory)); if (!outputDirectory.mkdirs()) { throw new IllegalStateException( "Could not create output directory " + this.outputDirectory); } } } catch (Exception ex) { throw new MojoExecutionException("Exception thrown while creating outputDirectory", ex); } List<Pattern> patterns = new ArrayList<>(); for (String subject : subjectPatterns) { try { getLog().debug(String.format("Creating pattern for '%s'", subject)); Pattern pattern = Pattern.compile(subject); patterns.add(pattern); } catch (Exception ex) { throw new IllegalStateException( String.format("Exception thrown while creating pattern '%s'", subject), ex ); } } Collection<String> allSubjects; try { getLog().info("Getting all subjects on schema registry..."); allSubjects = this.client().getAllSubjects(); } catch (Exception ex) { throw new MojoExecutionException("Exception thrown", ex); } getLog().info(String.format("Schema Registry has %s subject(s).", allSubjects.size())); Set<String> subjectsToDownload = new LinkedHashSet<>(); for (String subject : allSubjects) { for (Pattern pattern : patterns) { getLog() .debug(String.format("Checking '%s' against pattern '%s'", subject, pattern.pattern())); Matcher matcher = pattern.matcher(subject); if (matcher.matches()) { getLog().debug(String.format("'%s' matches pattern '%s' so downloading.", subject, pattern.pattern())); subjectsToDownload.add(subject); break; } } } Map<String, Schema> subjectToSchema = downloadSchemas(subjectsToDownload); for (Map.Entry<String, Schema> kvp : subjectToSchema.entrySet()) { String fileName = String.format("%s%s", kvp.getKey(), this.schemaExtension); File outputFile = new File(this.outputDirectory, fileName); getLog().info( String.format("Writing schema for Subject(%s) to %s.", kvp.getKey(), outputFile) ); try (FileWriter writer = new FileWriter(outputFile)) { writer.write(kvp.getValue().toString(this.prettyPrintSchemas)); } catch (IOException ex) { throw new MojoExecutionException( String.format("Exception thrown while writing subject('%s') schema to %s", kvp.getKey(), outputFile), ex ); } } } }