diff --git a/build.gradle b/build.gradle index 73761436..6f303b71 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ buildscript { classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' classpath 'com.netflix.nebula:nebula-publishing-plugin:14.1.1' classpath 'com.palantir.gradle.consistentversions:gradle-consistent-versions:1.13.1' - classpath 'com.palantir.baseline:gradle-baseline-java:2.39.0' + classpath 'com.palantir.baseline:gradle-baseline-java:2.40.2' classpath 'com.palantir.gradle.conjure:gradle-conjure:4.14.0' classpath 'com.palantir.gradle.gitversion:gradle-git-version:0.12.2' classpath 'gradle.plugin.org.inferred:gradle-processors:3.1.0' diff --git a/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/CompileMetricSchemaTask.java b/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/CompileMetricSchemaTask.java index 3d079da0..c34d7ad6 100644 --- a/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/CompileMetricSchemaTask.java +++ b/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/CompileMetricSchemaTask.java @@ -51,9 +51,11 @@ public final void action() throws IOException { File output = getOutputFile().getAsFile().get(); getProject().mkdir(output.getParent()); - writer.writeValue(output, getSource().getFiles().stream() - .map(CompileMetricSchemaTask::readFile) - .collect(ImmutableSet.toImmutableSet())); + writer.writeValue( + output, + getSource().getFiles().stream() + .map(CompileMetricSchemaTask::readFile) + .collect(ImmutableSet.toImmutableSet())); } private static MetricSchema readFile(File file) { diff --git a/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/CreateMetricsManifestTask.java b/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/CreateMetricsManifestTask.java index 80bd538c..a613ef14 100644 --- a/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/CreateMetricsManifestTask.java +++ b/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/CreateMetricsManifestTask.java @@ -119,8 +119,9 @@ public final void createManifest() throws IOException { private Map> getLocalMetrics() throws IOException { if (getMetricsFile().getAsFile().isPresent()) { - return ImmutableMap.of(getProjectCoordinates(getProject()), mapper.readValue( - getMetricsFile().getAsFile().get(), new TypeReference>() {})); + return ImmutableMap.of( + getProjectCoordinates(getProject()), + mapper.readValue(getMetricsFile().getAsFile().get(), new TypeReference>() {})); } return Collections.emptyMap(); } diff --git a/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/GenerateMetricMarkdownTask.java b/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/GenerateMetricMarkdownTask.java index f1ca780f..ddb7914f 100644 --- a/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/GenerateMetricMarkdownTask.java +++ b/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/GenerateMetricMarkdownTask.java @@ -75,9 +75,11 @@ public final void generate() throws IOException { GFileUtils.writeFile(upToDateContents, markdown); } else { if (!markdown.exists()) { - throw new GradleException(String.format( - "%s does not exist, please run `./gradlew %s --write-locks` and commit the resultant file", - markdown.getName(), getName())); + throw new GradleException( + String.format( + "%s does not exist, please run `./gradlew %s --write-locks` and commit the resultant" + + " file", + markdown.getName(), getName())); } else { String fromDisk = GFileUtils.readFile(markdown); Preconditions.checkState( diff --git a/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/GenerateMetricSchemaTask.java b/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/GenerateMetricSchemaTask.java index 56b3c2a8..b0ea0fc4 100644 --- a/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/GenerateMetricSchemaTask.java +++ b/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/GenerateMetricSchemaTask.java @@ -42,11 +42,15 @@ public final void generate() { GFileUtils.deleteDirectory(output); getProject().mkdir(output); - JavaGenerator.generate(JavaGeneratorArgs.builder() - .inputs(getSource().getFiles().stream().map(File::toPath).collect(ImmutableSet.toImmutableSet())) - .output(output.toPath()) - // TODO(forozco): probably want something better - .defaultPackageName(getProject().getGroup().toString()) - .build()); + JavaGenerator.generate( + JavaGeneratorArgs.builder() + .inputs( + getSource().getFiles().stream() + .map(File::toPath) + .collect(ImmutableSet.toImmutableSet())) + .output(output.toPath()) + // TODO(forozco): probably want something better + .defaultPackageName(getProject().getGroup().toString()) + .build()); } } diff --git a/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/MetricSchemaPlugin.java b/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/MetricSchemaPlugin.java index 8dcb5387..b603374a 100644 --- a/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/MetricSchemaPlugin.java +++ b/gradle-metric-schema/src/main/java/com/palantir/metric/schema/gradle/MetricSchemaPlugin.java @@ -134,14 +134,16 @@ private static void configureIdea( project.getTasks().getByName("ideaModule", task -> task.dependsOn(generateMetrics)); project.getExtensions().configure(IdeaModel.class, idea -> { IdeaModule module = idea.getModule(); - module.setSourceDirs(ImmutableSet.builder() - .addAll(module.getSourceDirs()) - .add(outputDir.get().getAsFile()) - .build()); - module.setGeneratedSourceDirs(ImmutableSet.builder() - .addAll(module.getGeneratedSourceDirs()) - .add(outputDir.get().getAsFile()) - .build()); + module.setSourceDirs( + ImmutableSet.builder() + .addAll(module.getSourceDirs()) + .add(outputDir.get().getAsFile()) + .build()); + module.setGeneratedSourceDirs( + ImmutableSet.builder() + .addAll(module.getGeneratedSourceDirs()) + .add(outputDir.get().getAsFile()) + .build()); }); }); } diff --git a/metric-schema-java/src/main/java/com/palantir/metric/schema/JavaGenerator.java b/metric-schema-java/src/main/java/com/palantir/metric/schema/JavaGenerator.java index 1e1f6778..63c3f4f2 100644 --- a/metric-schema-java/src/main/java/com/palantir/metric/schema/JavaGenerator.java +++ b/metric-schema-java/src/main/java/com/palantir/metric/schema/JavaGenerator.java @@ -34,8 +34,8 @@ public final class JavaGenerator { public static List generate(JavaGeneratorArgs args) { return args.inputs().stream() .map(SchemaParser.get()::parseFile) - .flatMap(schema -> - schema.getNamespaces().entrySet().stream().map(entry -> UtilityGenerator.generateUtilityClass( + .flatMap(schema -> schema.getNamespaces().entrySet().stream().map(entry -> + UtilityGenerator.generateUtilityClass( entry.getKey(), entry.getValue(), getPackage(args, schema), getVisibility(schema)))) .map(javaFile -> Goethe.formatAndEmit(javaFile, args.output())) .collect(ImmutableList.toImmutableList()); diff --git a/metric-schema-java/src/main/java/com/palantir/metric/schema/UtilityGenerator.java b/metric-schema-java/src/main/java/com/palantir/metric/schema/UtilityGenerator.java index 127cafec..27d17c4f 100644 --- a/metric-schema-java/src/main/java/com/palantir/metric/schema/UtilityGenerator.java +++ b/metric-schema-java/src/main/java/com/palantir/metric/schema/UtilityGenerator.java @@ -43,21 +43,23 @@ static JavaFile generateUtilityClass( TypeSpec.Builder builder = TypeSpec.classBuilder(className.simpleName()) .addModifiers(visibility.apply(Modifier.FINAL)) .addJavadoc(Javadoc.render(metrics.getDocs())) - .addMethod(MethodSpec.methodBuilder(ReservedNames.FACTORY_METHOD) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .addParameter(TaggedMetricRegistry.class, ReservedNames.REGISTRY_NAME) - .addStatement( - "return new $T($T.checkNotNull(registry, \"TaggedMetricRegistry\"))", - className, - Preconditions.class) - .returns(className) - .build()) + .addMethod( + MethodSpec.methodBuilder(ReservedNames.FACTORY_METHOD) + .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .addParameter(TaggedMetricRegistry.class, ReservedNames.REGISTRY_NAME) + .addStatement( + "return new $T($T.checkNotNull(registry, \"TaggedMetricRegistry\"))", + className, + Preconditions.class) + .returns(className) + .build()) .addField(TaggedMetricRegistry.class, ReservedNames.REGISTRY_NAME, Modifier.PRIVATE, Modifier.FINAL) - .addMethod(MethodSpec.constructorBuilder() - .addModifiers(Modifier.PRIVATE) - .addParameter(TaggedMetricRegistry.class, ReservedNames.REGISTRY_NAME) - .addStatement("this.$1L = $1L", ReservedNames.REGISTRY_NAME) - .build()); + .addMethod( + MethodSpec.constructorBuilder() + .addModifiers(Modifier.PRIVATE) + .addParameter(TaggedMetricRegistry.class, ReservedNames.REGISTRY_NAME) + .addStatement("this.$1L = $1L", ReservedNames.REGISTRY_NAME) + .build()); // metrics for (Map.Entry entry : metrics.getMetrics().entrySet()) { @@ -115,9 +117,10 @@ private static MethodSpec generateSimpleMetricFactory( MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(Custodian.sanitizeName(metricName)) .addModifiers(visibility.apply()) .returns(MetricTypes.get(definition.getType())) - .addParameters(definition.getTags().stream() - .map(tag -> ParameterSpec.builder(String.class, Custodian.sanitizeName(tag)).build()) - .collect(ImmutableList.toImmutableList())) + .addParameters( + definition.getTags().stream() + .map(tag -> ParameterSpec.builder(String.class, Custodian.sanitizeName(tag)).build()) + .collect(ImmutableList.toImmutableList())) .addJavadoc(Javadoc.render(definition.getDocs())); CodeBlock metricNameBlock = metricName(namespace, metricName, definition.getTags()); String metricRegistryMethod = definition.getType().toString().toLowerCase(Locale.ENGLISH); @@ -155,23 +158,29 @@ private static void generateMetricFactoryBuilder( ParameterizedTypeName.get(ClassName.get(Gauge.class), WildcardTypeName.subtypeOf(Object.class)), ReservedNames.GAUGE_NAME); } - outerBuilder.addType(TypeSpec.interfaceBuilder(buildStage(metricName)) - .addModifiers(visibility.apply()) - .addMethod(abstractBuildMethodBuilder.build()) - .build()); + outerBuilder.addType( + TypeSpec.interfaceBuilder(buildStage(metricName)) + .addModifiers(visibility.apply()) + .addMethod(abstractBuildMethodBuilder.build()) + .build()); ImmutableList tagList = ImmutableList.copyOf(definition.getTags()); for (int i = 0; i < tagList.size(); i++) { boolean lastTag = i == tagList.size() - 1; String tag = tagList.get(i); - outerBuilder.addType(TypeSpec.interfaceBuilder(stageName(metricName, tag)) - .addModifiers(visibility.apply()) - .addMethod(MethodSpec.methodBuilder(Custodian.sanitizeName(tag)) - .addParameter(String.class, Custodian.sanitizeName(tag)) - .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) - .returns(ClassName.bestGuess( - lastTag ? buildStage(metricName) : stageName(metricName, tagList.get(i + 1)))) - .build()) - .build()); + outerBuilder.addType( + TypeSpec.interfaceBuilder(stageName(metricName, tag)) + .addModifiers(visibility.apply()) + .addMethod( + MethodSpec.methodBuilder(Custodian.sanitizeName(tag)) + .addParameter(String.class, Custodian.sanitizeName(tag)) + .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) + .returns( + ClassName.bestGuess( + lastTag + ? buildStage(metricName) + : stageName(metricName, tagList.get(i + 1)))) + .build()) + .build()); } CodeBlock metricNameBlock = metricName(namespaceName, metricName, definition.getTags()); String metricRegistryMethod = definition.getType().toString().toLowerCase(Locale.ENGLISH); @@ -199,32 +208,43 @@ private static void generateMetricFactoryBuilder( "return $L.$L($L)", ReservedNames.REGISTRY_NAME, metricRegistryMethod, metricNameBlock); } - outerBuilder.addType(TypeSpec.classBuilder(Custodian.anyToUpperCamel(metricName) + "Builder") - .addModifiers(Modifier.PRIVATE, Modifier.FINAL) - .addSuperinterfaces(tagList.stream() - .map(tag -> ClassName.bestGuess(stageName(metricName, tag))) - .collect(ImmutableList.toImmutableList())) - .addSuperinterface(ClassName.bestGuess(buildStage(metricName))) - .addFields(tagList.stream() - .map(tag -> FieldSpec.builder(String.class, Custodian.sanitizeName(tag), Modifier.PRIVATE) - .build()) - .collect(ImmutableList.toImmutableList())) - .addMethod(buildMethodBuilder.build()) - .addMethods(tagList.stream() - .map(tag -> MethodSpec.methodBuilder(Custodian.sanitizeName(tag)) - .addModifiers(Modifier.PUBLIC) - .addAnnotation(Override.class) - .returns(ClassName.bestGuess(Custodian.anyToUpperCamel(metricName) + "Builder")) - .addParameter(String.class, Custodian.sanitizeName(tag)) - .addStatement( - "this.$1L = $2T.checkNotNull($1L, $3S)", - Custodian.sanitizeName(tag), - Preconditions.class, - tag + " is required") - .addStatement("return this") - .build()) - .collect(ImmutableList.toImmutableList())) - .build()); + outerBuilder.addType( + TypeSpec.classBuilder(Custodian.anyToUpperCamel(metricName) + "Builder") + .addModifiers(Modifier.PRIVATE, Modifier.FINAL) + .addSuperinterfaces( + tagList.stream() + .map(tag -> ClassName.bestGuess(stageName(metricName, tag))) + .collect(ImmutableList.toImmutableList())) + .addSuperinterface(ClassName.bestGuess(buildStage(metricName))) + .addFields( + tagList.stream() + .map(tag -> + FieldSpec.builder( + String.class, + Custodian.sanitizeName(tag), + Modifier.PRIVATE) + .build()) + .collect(ImmutableList.toImmutableList())) + .addMethod(buildMethodBuilder.build()) + .addMethods( + tagList.stream() + .map(tag -> + MethodSpec.methodBuilder(Custodian.sanitizeName(tag)) + .addModifiers(Modifier.PUBLIC) + .addAnnotation(Override.class) + .returns(ClassName.bestGuess(Custodian.anyToUpperCamel( + metricName) + + "Builder")) + .addParameter(String.class, Custodian.sanitizeName(tag)) + .addStatement( + "this.$1L = $2T.checkNotNull($1L, $3S)", + Custodian.sanitizeName(tag), + Preconditions.class, + tag + " is required") + .addStatement("return this") + .build()) + .collect(ImmutableList.toImmutableList())) + .build()); MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(Custodian.sanitizeName(metricName)) .addModifiers(visibility.apply()) diff --git a/metric-schema-java/src/main/java/com/palantir/metric/schema/Validator.java b/metric-schema-java/src/main/java/com/palantir/metric/schema/Validator.java index 91c15e91..b5d14b35 100644 --- a/metric-schema-java/src/main/java/com/palantir/metric/schema/Validator.java +++ b/metric-schema-java/src/main/java/com/palantir/metric/schema/Validator.java @@ -41,16 +41,18 @@ private static void validateNamespace(String namespace, MetricNamespace namespac // Provide enough data to figure out which schema is missing a namespace SafeArg.of("namespaceValue", namespaceValue)); Preconditions.checkArgument( - NAME_PREDICATE.matcher(namespace).matches(), "Namespace must match pattern", SafeArg.of( - "pattern", NAME_PATTERN)); + NAME_PREDICATE.matcher(namespace).matches(), + "Namespace must match pattern", + SafeArg.of("pattern", NAME_PATTERN)); validateShortName(namespaceValue); validateDocumentation(namespaceValue.getDocs()); namespaceValue.getMetrics().forEach((name, definition) -> { Preconditions.checkArgument( !name.isEmpty(), "MetricDefinition names must not be empty", SafeArg.of("namespace", namespace)); Preconditions.checkArgument( - NAME_PREDICATE.matcher(name).matches(), "MetricDefinition names must match pattern", SafeArg.of( - "pattern", NAME_PATTERN)); + NAME_PREDICATE.matcher(name).matches(), + "MetricDefinition names must match pattern", + SafeArg.of("pattern", NAME_PATTERN)); Preconditions.checkArgument( MetricType.Value.UNKNOWN != definition.getType().get(), "Unknown metric type", @@ -64,16 +66,19 @@ private static void validateNamespace(String namespace, MetricNamespace namespac SafeArg.of("namespace", namespace), SafeArg.of("definition", definition)); Preconditions.checkArgument( - NAME_PREDICATE.matcher(tag).matches(), "MetricDefinition tags must match pattern", SafeArg.of( - "pattern", NAME_PATTERN)); + NAME_PREDICATE.matcher(tag).matches(), + "MetricDefinition tags must match pattern", + SafeArg.of("pattern", NAME_PATTERN)); }); }); } private static void validateShortName(MetricNamespace namespace) { - namespace.getShortName().ifPresent(shortName -> Preconditions.checkArgument( - SHORT_NAME_PREDICATE.matcher(shortName).matches(), "ShortName must match pattern", SafeArg.of( - "pattern", SHORT_NAME_PATTERN))); + namespace.getShortName().ifPresent(shortName -> + Preconditions.checkArgument( + SHORT_NAME_PREDICATE.matcher(shortName).matches(), + "ShortName must match pattern", + SafeArg.of("pattern", SHORT_NAME_PATTERN))); } private static void validateDocumentation(Documentation documentation) { diff --git a/metric-schema-java/src/test/java/com/palantir/metric/schema/GoetheTest.java b/metric-schema-java/src/test/java/com/palantir/metric/schema/GoetheTest.java index c18750cf..38b0acab 100644 --- a/metric-schema-java/src/test/java/com/palantir/metric/schema/GoetheTest.java +++ b/metric-schema-java/src/test/java/com/palantir/metric/schema/GoetheTest.java @@ -27,9 +27,11 @@ public class GoetheTest { @Test public void testFormatAndEmit() { - JavaFile javaFile = JavaFile.builder("com.palantir.foo", TypeSpec.classBuilder("Foo") - .addStaticBlock(CodeBlock.builder().addStatement("type oops name = bar").build()) - .build()) + JavaFile javaFile = JavaFile.builder( + "com.palantir.foo", + TypeSpec.classBuilder("Foo") + .addStaticBlock(CodeBlock.builder().addStatement("type oops name = bar").build()) + .build()) .build(); assertThatThrownBy(() -> Goethe.format(javaFile)) .hasMessageContaining("Failed to format 'com.palantir.foo.Foo'") diff --git a/metric-schema-java/src/test/java/com/palantir/metric/schema/JavaGeneratorTest.java b/metric-schema-java/src/test/java/com/palantir/metric/schema/JavaGeneratorTest.java index aa92403e..96e724e8 100644 --- a/metric-schema-java/src/test/java/com/palantir/metric/schema/JavaGeneratorTest.java +++ b/metric-schema-java/src/test/java/com/palantir/metric/schema/JavaGeneratorTest.java @@ -38,11 +38,12 @@ public class JavaGeneratorTest { @Test void generates_code() { - JavaGenerator.generate(JavaGeneratorArgs.builder() - .output(tempDir) - .inputs(listFiles(Paths.get("src/test/resources"))) - .defaultPackageName("com.palantir.test") - .build()) + JavaGenerator.generate( + JavaGeneratorArgs.builder() + .output(tempDir) + .inputs(listFiles(Paths.get("src/test/resources"))) + .defaultPackageName("com.palantir.test") + .build()) .stream() .map(tempDir::relativize) .map(Path::toString) diff --git a/metric-schema-java/src/test/java/com/palantir/metric/schema/ValidatorTest.java b/metric-schema-java/src/test/java/com/palantir/metric/schema/ValidatorTest.java index 63d27951..175dc9d7 100644 --- a/metric-schema-java/src/test/java/com/palantir/metric/schema/ValidatorTest.java +++ b/metric-schema-java/src/test/java/com/palantir/metric/schema/ValidatorTest.java @@ -27,102 +27,145 @@ class ValidatorTest { @Test void testValidateNamespace_empty() { - assertThatThrownBy(() -> Validator.validate( - MetricSchema.builder().namespaces("", MetricNamespace.builder().docs(DOCS).build()).build())) + assertThatThrownBy(() -> + Validator.validate( + MetricSchema.builder() + .namespaces("", MetricNamespace.builder().docs(DOCS).build()) + .build())) .isInstanceOf(SafeIllegalArgumentException.class) .hasMessageContaining("Namespace must not be empty"); } @Test void testValidateNamespace_doublePeriod() { - assertThatThrownBy(() -> Validator.validate(MetricSchema.builder() - .namespaces("a..b", MetricNamespace.builder().docs(DOCS).build()) - .build())) + assertThatThrownBy(() -> + Validator.validate( + MetricSchema.builder() + .namespaces("a..b", MetricNamespace.builder().docs(DOCS).build()) + .build())) .isInstanceOf(SafeIllegalArgumentException.class) .hasMessageContaining("Namespace must match pattern"); } @Test void testValidateNamespace_whitespace() { - assertThatThrownBy(() -> Validator.validate( - MetricSchema.builder().namespaces("a b", MetricNamespace.builder().docs(DOCS).build()).build())) + assertThatThrownBy(() -> + Validator.validate( + MetricSchema.builder() + .namespaces("a b", MetricNamespace.builder().docs(DOCS).build()) + .build())) .isInstanceOf(SafeIllegalArgumentException.class) .hasMessageContaining("Namespace must match pattern"); } @Test void testValidateNamespace_newline() { - assertThatThrownBy(() -> Validator.validate(MetricSchema.builder() - .namespaces("a\nb", MetricNamespace.builder().docs(DOCS).build()) - .build())) + assertThatThrownBy(() -> + Validator.validate( + MetricSchema.builder() + .namespaces("a\nb", MetricNamespace.builder().docs(DOCS).build()) + .build())) .isInstanceOf(SafeIllegalArgumentException.class) .hasMessageContaining("Namespace must match pattern"); } @Test void testEmptyMetricName() { - assertThatThrownBy(() -> Validator.validate(MetricSchema.builder() - .namespaces("test", MetricNamespace.builder() - .docs(DOCS) - .metrics("", MetricDefinition.builder().docs(DOCS).type(MetricType.COUNTER).build()) - .build()) - .build())) + assertThatThrownBy(() -> + Validator.validate( + MetricSchema.builder() + .namespaces( + "test", + MetricNamespace.builder() + .docs(DOCS) + .metrics( + "", + MetricDefinition.builder() + .docs(DOCS) + .type(MetricType.COUNTER) + .build()) + .build()) + .build())) .isInstanceOf(SafeIllegalArgumentException.class) .hasMessageContaining("MetricDefinition names must not be empty"); } @Test void testUnknownType() { - assertThatThrownBy(() -> Validator.validate(MetricSchema.builder() - .namespaces("test", MetricNamespace.builder() - .docs(DOCS) - .metrics("name", MetricDefinition.builder() - .docs(DOCS) - .type(MetricType.valueOf("other")) - .tags("") - .build()) - .build()) - .build())) + assertThatThrownBy(() -> + Validator.validate( + MetricSchema.builder() + .namespaces( + "test", + MetricNamespace.builder() + .docs(DOCS) + .metrics( + "name", + MetricDefinition.builder() + .docs(DOCS) + .type(MetricType.valueOf("other")) + .tags("") + .build()) + .build()) + .build())) .isInstanceOf(SafeIllegalArgumentException.class) .hasMessageContaining("Unknown metric type"); } @Test void testEmptyTag() { - assertThatThrownBy(() -> Validator.validate(MetricSchema.builder() - .namespaces("test", MetricNamespace.builder() - .docs(DOCS) - .metrics("name", MetricDefinition.builder() - .docs(DOCS) - .type(MetricType.COUNTER) - .tags("") - .build()) - .build()) - .build())) + assertThatThrownBy(() -> + Validator.validate( + MetricSchema.builder() + .namespaces( + "test", + MetricNamespace.builder() + .docs(DOCS) + .metrics( + "name", + MetricDefinition.builder() + .docs(DOCS) + .type(MetricType.COUNTER) + .tags("") + .build()) + .build()) + .build())) .isInstanceOf(SafeIllegalArgumentException.class) .hasMessageContaining("MetricDefinition tags must not be empty"); } @Test void testBlankTopLevelDocs() { - assertThatThrownBy(() -> Validator.validate(MetricSchema.builder() - .namespaces("test", MetricNamespace.builder().docs(Documentation.of("\t \n")).build()) - .build())) + assertThatThrownBy(() -> + Validator.validate( + MetricSchema.builder() + .namespaces( + "test", + MetricNamespace.builder() + .docs(Documentation.of("\t \n")) + .build()) + .build())) .isInstanceOf(SafeIllegalArgumentException.class) .hasMessageContaining("Documentation must not be blank"); } @Test void testBlankMetricDocs() { - assertThatThrownBy(() -> Validator.validate(MetricSchema.builder() - .namespaces("test", MetricNamespace.builder() - .docs(DOCS) - .metrics("test", MetricDefinition.builder() - .type(MetricType.METER) - .docs(Documentation.of("\t \n")) - .build()) - .build()) - .build())) + assertThatThrownBy(() -> + Validator.validate( + MetricSchema.builder() + .namespaces( + "test", + MetricNamespace.builder() + .docs(DOCS) + .metrics( + "test", + MetricDefinition.builder() + .type(MetricType.METER) + .docs(Documentation.of("\t \n")) + .build()) + .build()) + .build())) .isInstanceOf(SafeIllegalArgumentException.class) .hasMessageContaining("Documentation must not be blank"); } @@ -141,9 +184,16 @@ void testValidNamespace_multipleGroups() { @Test void testLowerCamelShortName() { - assertThatThrownBy(() -> Validator.validate(MetricSchema.builder() - .namespaces("test0.test1", MetricNamespace.builder().docs(DOCS).shortName("abcdEfg").build()) - .build())) + assertThatThrownBy(() -> + Validator.validate( + MetricSchema.builder() + .namespaces( + "test0.test1", + MetricNamespace.builder() + .docs(DOCS) + .shortName("abcdEfg") + .build()) + .build())) .isInstanceOf(SafeIllegalArgumentException.class) .hasMessageContaining("ShortName must match pattern"); } diff --git a/metric-schema-markdown/src/main/java/com/palantir/metric/schema/markdown/MarkdownRenderer.java b/metric-schema-markdown/src/main/java/com/palantir/metric/schema/markdown/MarkdownRenderer.java index a28881c5..b0865093 100644 --- a/metric-schema-markdown/src/main/java/com/palantir/metric/schema/markdown/MarkdownRenderer.java +++ b/metric-schema-markdown/src/main/java/com/palantir/metric/schema/markdown/MarkdownRenderer.java @@ -86,25 +86,40 @@ private static void renderLine(String namespace, String metricName, MetricDefini private static ImmutableList
namespaces(String localCoordinate, Map> schemas) { return schemas.entrySet().stream() .sorted(Map.Entry.comparingByKey(new CoordinateComparator(localCoordinate))) - .map(entry -> Section.builder() - .sourceCoordinates(entry.getKey()) - .namespaces(entry.getValue().stream() - .flatMap(schema -> schema.getNamespaces().entrySet().stream()) - // Break ties on the namespace name using the documentation, number of metrics, then - // MetricNamespace hashCode. - .sorted(Map.Entry.comparingByKey() - .thenComparing(Map.Entry.comparingByValue( - Comparator.comparing(namespace -> namespace.getDocs().get()))) - .thenComparing(Map.Entry.comparingByValue( - Comparator.comparing(namespace -> namespace.getMetrics().size()))) - .thenComparing(Map.Entry.comparingByValue( - Comparator.comparing(MetricNamespace::hashCode)))) - .map(schemaEntry -> Namespace.builder() - .name(schemaEntry.getKey()) - .definition(schemaEntry.getValue()) - .build()) - .collect(ImmutableList.toImmutableList())) - .build()) + .map(entry -> + Section.builder() + .sourceCoordinates(entry.getKey()) + .namespaces( + entry.getValue().stream() + .flatMap(schema -> schema.getNamespaces().entrySet().stream()) + // Break ties on the namespace name using the documentation, number of + // metrics, then + // MetricNamespace hashCode. + .sorted( + Map.Entry.comparingByKey() + .thenComparing( + Map.Entry.comparingByValue( + Comparator.comparing(namespace -> + namespace + .getDocs() + .get()))) + .thenComparing( + Map.Entry.comparingByValue( + Comparator.comparing(namespace -> + namespace + .getMetrics() + .size()))) + .thenComparing( + Map.Entry.comparingByValue( + Comparator.comparing( + MetricNamespace::hashCode)))) + .map(schemaEntry -> + Namespace.builder() + .name(schemaEntry.getKey()) + .definition(schemaEntry.getValue()) + .build()) + .collect(ImmutableList.toImmutableList())) + .build()) .collect(ImmutableList.toImmutableList()); } diff --git a/metric-schema-markdown/src/test/java/com/palantir/metric/schema/markdown/MarkdownRendererTest.java b/metric-schema-markdown/src/test/java/com/palantir/metric/schema/markdown/MarkdownRendererTest.java index a357ebcd..b244802c 100644 --- a/metric-schema-markdown/src/test/java/com/palantir/metric/schema/markdown/MarkdownRendererTest.java +++ b/metric-schema-markdown/src/test/java/com/palantir/metric/schema/markdown/MarkdownRendererTest.java @@ -32,36 +32,51 @@ class MarkdownRendererTest { @Test void testSimple() { MetricSchema firstSchema = MetricSchema.builder() - .namespaces("namespace", MetricNamespace.builder() - .docs(Documentation.of("namespace docs")) - .metrics("metric", MetricDefinition.builder() - .type(MetricType.METER) - .docs(Documentation.of("metric docs")) + .namespaces( + "namespace", + MetricNamespace.builder() + .docs(Documentation.of("namespace docs")) + .metrics( + "metric", + MetricDefinition.builder() + .type(MetricType.METER) + .docs(Documentation.of("metric docs")) + .build()) .build()) - .build()) - .namespaces("anamespace", MetricNamespace.builder() - .docs(Documentation.of("namespace docs")) - .metrics("metric", MetricDefinition.builder() - .type(MetricType.METER) - .docs(Documentation.of("metric docs")) + .namespaces( + "anamespace", + MetricNamespace.builder() + .docs(Documentation.of("namespace docs")) + .metrics( + "metric", + MetricDefinition.builder() + .type(MetricType.METER) + .docs(Documentation.of("metric docs")) + .build()) .build()) - .build()) .build(); MetricSchema secondSchema = MetricSchema.builder() - .namespaces("secondSchema", MetricNamespace.builder() - .docs(Documentation.of("namespace docs")) - .metrics("metric", MetricDefinition.builder() - .type(MetricType.METER) - .docs(Documentation.of("metric docs")) + .namespaces( + "secondSchema", + MetricNamespace.builder() + .docs(Documentation.of("namespace docs")) + .metrics( + "metric", + MetricDefinition.builder() + .type(MetricType.METER) + .docs(Documentation.of("metric docs")) + .build()) .build()) - .build()) .build(); - String firstMarkdown = MarkdownRenderer.render("com.palantir:test", ImmutableMap.of( - "com.palantir:test:1.0.0", ImmutableList.of(firstSchema, secondSchema))); - String secondMarkdown = MarkdownRenderer.render("com.palantir:test", ImmutableMap.of( - "com.palantir:test:1.0.0", - // reverse order should produce the same results - ImmutableList.of(secondSchema, firstSchema))); + String firstMarkdown = MarkdownRenderer.render( + "com.palantir:test", + ImmutableMap.of("com.palantir:test:1.0.0", ImmutableList.of(firstSchema, secondSchema))); + String secondMarkdown = MarkdownRenderer.render( + "com.palantir:test", + ImmutableMap.of( + "com.palantir:test:1.0.0", + // reverse order should produce the same results + ImmutableList.of(secondSchema, firstSchema))); assertThat(firstMarkdown) .isEqualTo("# Metrics\n" + "\n" @@ -86,29 +101,40 @@ void testSimple() { @Test void testMultipleNamespacesWithSameName() { MetricSchema firstSchema = MetricSchema.builder() - .namespaces("namespace", MetricNamespace.builder() - .docs(Documentation.of("namespace docs")) - .metrics("metric1", MetricDefinition.builder() - .type(MetricType.METER) - .docs(Documentation.of("metric docs 1")) + .namespaces( + "namespace", + MetricNamespace.builder() + .docs(Documentation.of("namespace docs")) + .metrics( + "metric1", + MetricDefinition.builder() + .type(MetricType.METER) + .docs(Documentation.of("metric docs 1")) + .build()) .build()) - .build()) .build(); MetricSchema secondSchema = MetricSchema.builder() - .namespaces("namespace", MetricNamespace.builder() - .docs(Documentation.of("namespace docs")) - .metrics("metric2", MetricDefinition.builder() - .type(MetricType.METER) - .docs(Documentation.of("metric docs 2")) + .namespaces( + "namespace", + MetricNamespace.builder() + .docs(Documentation.of("namespace docs")) + .metrics( + "metric2", + MetricDefinition.builder() + .type(MetricType.METER) + .docs(Documentation.of("metric docs 2")) + .build()) .build()) - .build()) .build(); - String firstMarkdown = MarkdownRenderer.render("com.palantir:test", ImmutableMap.of( - "com.palantir:test:1.0.0", ImmutableList.of(firstSchema, secondSchema))); - String secondMarkdown = MarkdownRenderer.render("com.palantir:test", ImmutableMap.of( - "com.palantir:test:1.0.0", - // reverse order should produce the same results - ImmutableList.of(secondSchema, firstSchema))); + String firstMarkdown = MarkdownRenderer.render( + "com.palantir:test", + ImmutableMap.of("com.palantir:test:1.0.0", ImmutableList.of(firstSchema, secondSchema))); + String secondMarkdown = MarkdownRenderer.render( + "com.palantir:test", + ImmutableMap.of( + "com.palantir:test:1.0.0", + // reverse order should produce the same results + ImmutableList.of(secondSchema, firstSchema))); assertThat(firstMarkdown) .isEqualTo("# Metrics\n" + "\n" @@ -129,17 +155,25 @@ void testMultipleNamespacesWithSameName() { @Test void testTagged() { String markdown = MarkdownRenderer.render( - "com.palantir:test", ImmutableMap.of("com.palantir:test:1.0.0", ImmutableList.of(MetricSchema.builder() - .namespaces("namespace", MetricNamespace.builder() - .docs(Documentation.of("namespace docs")) - .metrics("metric", MetricDefinition.builder() - .type(MetricType.METER) - .tags("service") - .tags("endpoint") - .docs(Documentation.of("metric docs")) - .build()) - .build()) - .build()))); + "com.palantir:test", + ImmutableMap.of( + "com.palantir:test:1.0.0", + ImmutableList.of( + MetricSchema.builder() + .namespaces( + "namespace", + MetricNamespace.builder() + .docs(Documentation.of("namespace docs")) + .metrics( + "metric", + MetricDefinition.builder() + .type(MetricType.METER) + .tags("service") + .tags("endpoint") + .docs(Documentation.of("metric docs")) + .build()) + .build()) + .build()))); assertThat(markdown).isEqualTo("# Metrics\n" + "\n" + "## Test\n" @@ -154,18 +188,28 @@ void testTagged() { @Test void testEmptyNamespacesExcluded() { String markdown = MarkdownRenderer.render( - "com.palantir:test", ImmutableMap.of("com.palantir:test", ImmutableList.of(MetricSchema.builder() - .namespaces("com.foo.namespace", MetricNamespace.builder() - .docs(Documentation.of("Foo namespace docs")) - .metrics("metric", MetricDefinition.builder() - .type(MetricType.METER) - .docs(Documentation.of("metric docs")) - .build()) - .build()) - .namespaces("empty", MetricNamespace.builder() - .docs(Documentation.of("empty namespace docs")) - .build()) - .build()))); + "com.palantir:test", + ImmutableMap.of( + "com.palantir:test", + ImmutableList.of( + MetricSchema.builder() + .namespaces( + "com.foo.namespace", + MetricNamespace.builder() + .docs(Documentation.of("Foo namespace docs")) + .metrics( + "metric", + MetricDefinition.builder() + .type(MetricType.METER) + .docs(Documentation.of("metric docs")) + .build()) + .build()) + .namespaces( + "empty", + MetricNamespace.builder() + .docs(Documentation.of("empty namespace docs")) + .build()) + .build()))); assertThat(markdown).isEqualTo("# Metrics\n" + "\n" + "## Test\n"