-
Notifications
You must be signed in to change notification settings - Fork 83
Generate config props docs #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # Spring gRPC Docs | ||
|
|
||
| ## Configuration Properties | ||
| The Spring gRPC configuration properties are automatically documented as follows: | ||
|
|
||
| 1. This module contains a Java class (`org.springframework.grpc.internal.ConfigurationPropertiesAsciidocGenerator`) that is compiled when the module is built. | ||
| 1. This class is then used during the Maven `package` phase to generate an asciidoc page containing each of the configuration properties. | ||
| 1. The asciidoc is then included in the Antora reference documentation. | ||
|
|
||
| ## Antora Site | ||
|
|
||
| To build the Antora site locally run the following command from the project root directory: | ||
| ``` | ||
| ./mvnw -pl spring-grpc-docs antora | ||
| ``` | ||
| You can then view the output by opening `spring-grpc-docs/target/antora/site/index.html`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,5 @@ | ||
| * xref:index.adoc[Overview] | ||
| * xref:concepts.adoc[GRPC Concepts] | ||
| * xref:getting-started.adoc[Getting Started] | ||
|
|
||
| * xref:contribution-guidelines.adoc[Contribution Guidelines] | ||
|
|
||
| * xref:appendix.adoc[] |
11 changes: 11 additions & 0 deletions
11
spring-grpc-docs/src/main/antora/modules/ROOT/pages/appendix.adoc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| :numbered!: | ||
|
|
||
| [appendix] | ||
| [[common-application-properties]] | ||
| = Common application properties | ||
| :page-section-summary-toc: 1 | ||
|
|
||
| Various properties can be specified inside your `application.properties` file, inside your `application.yml` file, or as command line switches. | ||
| This appendix provides a list of common `Spring gRPC` properties. | ||
|
|
||
| include::partial$_configprops.adoc[] |
18 changes: 18 additions & 0 deletions
18
spring-grpc-docs/src/main/antora/modules/ROOT/partials/_configprops.adoc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| |=== | ||
| |Name | Default | Description | ||
|
|
||
| |spring.grpc.client.channels | | | ||
| |spring.grpc.server.address | `+++*+++` | Server address to bind to. The default is any IP address ('*'). | ||
| |spring.grpc.server.keep-alive.max-age | | Maximum time a connection may exist before being gracefully terminated (default infinite). | ||
| |spring.grpc.server.keep-alive.max-age-grace | | Maximum time for graceful connection termination (default infinite). | ||
| |spring.grpc.server.keep-alive.max-idle | | Maximum time a connection can remain idle before being gracefully terminated (default infinite). | ||
| |spring.grpc.server.keep-alive.permit-time | `+++5m+++` | Maximum keep-alive time clients are permitted to configure (default 5m). | ||
| |spring.grpc.server.keep-alive.permit-without-calls | `+++false+++` | Whether clients are permitted to send keep alive pings when there are no outstanding RPCs on the connection (default false). | ||
| |spring.grpc.server.keep-alive.time | `+++2h+++` | Duration without read activity before sending a keep alive ping (default 2h). | ||
| |spring.grpc.server.keep-alive.timeout | `+++20s+++` | Maximum time to wait for read activity after sending a keep alive ping. If sender does not receive an acknowledgment within this time, it will close the connection (default 20s). | ||
| |spring.grpc.server.max-inbound-message-size | `+++4194304B+++` | Maximum message size allowed to be received by the server (default 4MiB). | ||
| |spring.grpc.server.max-inbound-metadata-size | `+++8192B+++` | Maximum metadata size allowed to be received by the server (default 8KiB). | ||
| |spring.grpc.server.port | `+++9090+++` | Server port to listen on. When the value is 0, a random available port is selected. The default is 9090. | ||
| |spring.grpc.server.shutdown-grace-period | `+++30s+++` | Maximum time to wait for the server to gracefully shutdown. When the value is negative, the server waits forever. When the value is 0, the server will force shutdown immediately. The default is 30 seconds. | ||
|
|
||
| |=== | ||
157 changes: 157 additions & 0 deletions
157
...main/java/org/springframework/grpc/internal/ConfigurationPropertiesAsciidocGenerator.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| /* | ||
| * Copyright 2012-2024 the original author or authors. | ||
| * | ||
| * 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 | ||
| * | ||
| * https://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.springframework.grpc.internal; | ||
|
|
||
| import java.io.File; | ||
| import java.io.IOException; | ||
| import java.nio.file.Files; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.TreeSet; | ||
| import java.util.concurrent.atomic.AtomicInteger; | ||
| import java.util.regex.Pattern; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
|
||
| import org.springframework.core.io.Resource; | ||
| import org.springframework.core.io.support.PathMatchingResourcePatternResolver; | ||
| import org.springframework.util.StreamUtils; | ||
| import org.springframework.util.StringUtils; | ||
|
|
||
| /** | ||
| * Generate Asciidoc for configuration properties. | ||
| * <p> | ||
| * Copied from 'spring-cloud-build' to avoid direct dependency on Spring Cloud. | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did not want to put a direct dependency on I will take a pass through this code in a subsequent PR as it can be simplified greatly and get a little 2024 makeover. |
||
| * | ||
| * @author Marcin Grzejszczak | ||
| * @author Chris Bono | ||
| */ | ||
| public class ConfigurationPropertiesAsciidocGenerator { | ||
|
|
||
| public static void main(String... args) { | ||
| String outputFile = args[0]; | ||
| String inclusionPattern = args.length > 1 ? args[1] : ".*"; | ||
| File parent = new File(outputFile).getParentFile(); | ||
| if (!parent.exists()) { | ||
| System.out.println("No parent directory [" + parent.toString() | ||
| + "] found. Will not generate the configuration properties file"); | ||
| return; | ||
| } | ||
| new Generator().generate(outputFile, inclusionPattern); | ||
| } | ||
|
|
||
| static class Generator { | ||
|
|
||
| void generate(String outputFile, String inclusionPattern) { | ||
| try { | ||
| System.out.println("Parsing all configuration metadata"); | ||
| Resource[] resources = getResources(); | ||
| System.out.println("Found [" + resources.length + "] configuration metadata jsons"); | ||
| TreeSet<String> names = new TreeSet<>(); | ||
| Map<String, ConfigValue> descriptions = new HashMap<>(); | ||
| final AtomicInteger count = new AtomicInteger(); | ||
| final AtomicInteger matchingPropertyCount = new AtomicInteger(); | ||
| final AtomicInteger propertyCount = new AtomicInteger(); | ||
| Pattern pattern = Pattern.compile(inclusionPattern); | ||
| for (Resource resource : resources) { | ||
| if (resourceNameContainsPattern(resource)) { | ||
| count.incrementAndGet(); | ||
| byte[] bytes = StreamUtils.copyToByteArray(resource.getInputStream()); | ||
| Map<String, Object> response = new ObjectMapper().readValue(bytes, HashMap.class); | ||
| List<Map<String, Object>> properties = (List<Map<String, Object>>) response.get("properties"); | ||
| properties.forEach(val -> { | ||
| propertyCount.incrementAndGet(); | ||
| String name = String.valueOf(val.get("name")); | ||
| if (!pattern.matcher(name).matches()) { | ||
| return; | ||
| } | ||
| Object description = val.get("description"); | ||
| Object defaultValue = val.get("defaultValue"); | ||
| matchingPropertyCount.incrementAndGet(); | ||
| names.add(name); | ||
| descriptions.put(name, new ConfigValue(name, description, defaultValue)); | ||
| }); | ||
| } | ||
| } | ||
| System.out.println( | ||
| "Found [" + count + "] Spring projects configuration metadata jsons. [" + matchingPropertyCount | ||
| + "/" + propertyCount + "] were matching the pattern [" + inclusionPattern + "]"); | ||
| System.out.println("Successfully built the description table"); | ||
| if (names.isEmpty()) { | ||
| System.out.println("Will not update the table, since no configuration properties were found!"); | ||
| return; | ||
| } | ||
| Files.write(new File(outputFile).toPath(), ("|===\n" + "|Name | Default | Description\n\n" | ||
| + names.stream().map(it -> descriptions.get(it).toString()).collect(Collectors.joining("\n")) | ||
| + "\n\n" + "|===") | ||
| .getBytes()); | ||
| System.out.println("Successfully stored the output file"); | ||
| } | ||
| catch (IOException e) { | ||
| throw new IllegalStateException(e); | ||
| } | ||
| } | ||
|
|
||
| protected boolean resourceNameContainsPattern(Resource resource) { | ||
| try { | ||
| return resource.getURL().toString().contains("spring"); | ||
| } | ||
| catch (Exception e) { | ||
| System.out.println("Exception [" + e + "] for resource [" + resource | ||
| + "] occurred while trying to retrieve its URL"); | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| protected Resource[] getResources() throws IOException { | ||
| return new PathMatchingResourcePatternResolver() | ||
| .getResources("classpath*:/META-INF/spring-configuration-metadata.json"); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| static class ConfigValue { | ||
|
|
||
| public String name; | ||
|
|
||
| public String description; | ||
|
|
||
| public String defaultValue; | ||
|
|
||
| ConfigValue() { | ||
| } | ||
|
|
||
| ConfigValue(String name, Object description, Object defaultValue) { | ||
| this.name = name; | ||
| this.description = escapedValue(description); | ||
| this.defaultValue = escapedValue(defaultValue); | ||
| } | ||
|
|
||
| private String escapedValue(Object value) { | ||
| return value != null ? value.toString().replaceAll("\\|", "\\\\|") : ""; | ||
| } | ||
|
|
||
| public String toString() { | ||
| return "|" + name + " | " + (StringUtils.hasText(defaultValue) ? ("`+++" + defaultValue + "+++`") : "") | ||
| + " | " + description; | ||
| } | ||
|
|
||
| } | ||
|
|
||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is automatically generated. Should we even check it in? I notice other spring-cloud repos are checking it in. I believe having it checked in avoids annoying red warnings coming from the consuming adocs that are referencing it.