diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 3d558acc..1b48f80e 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -17,6 +17,8 @@ dependencies { implementation "io.github.gradle-nexus:publish-plugin:1.1.0" implementation "io.spring.javaformat:spring-javaformat-gradle-plugin:0.0.31" implementation "io.spring.nohttp:nohttp-gradle:0.0.10" + implementation "org.asciidoctor:asciidoctor-gradle-jvm:3.3.2" + implementation "org.asciidoctor:asciidoctor-gradle-jvm-pdf:3.3.2" implementation "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10" implementation "org.hidetake:gradle-ssh-plugin:2.10.1" implementation "org.jfrog.buildinfo:build-info-extractor-gradle:4.26.1" diff --git a/buildSrc/src/main/java/io/spring/gradle/convention/SpringDocsPlugin.java b/buildSrc/src/main/java/io/spring/gradle/convention/SpringDocsPlugin.java index 9c6ed0b4..e567d608 100644 --- a/buildSrc/src/main/java/io/spring/gradle/convention/SpringDocsPlugin.java +++ b/buildSrc/src/main/java/io/spring/gradle/convention/SpringDocsPlugin.java @@ -16,17 +16,24 @@ package io.spring.gradle.convention; +import java.io.File; + +import org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.file.DuplicatesStrategy; import org.gradle.api.plugins.BasePlugin; +import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.PluginManager; import org.gradle.api.tasks.TaskContainer; import org.gradle.api.tasks.bundling.Zip; +import org.springframework.gradle.docs.SpringAsciidoctorPlugin; import org.springframework.gradle.docs.SpringJavadocApiPlugin; import org.springframework.gradle.docs.SpringJavadocOptionsPlugin; +import org.springframework.gradle.management.SpringManagementConfigurationPlugin; +import org.springframework.gradle.maven.SpringRepositoryPlugin; /** * Aggregates asciidoc, javadoc, and deploying of the docs into a single plugin. @@ -39,31 +46,43 @@ public class SpringDocsPlugin implements Plugin { // Apply default plugins PluginManager pluginManager = project.getPluginManager(); pluginManager.apply(BasePlugin.class); + pluginManager.apply(JavaPlugin.class); + pluginManager.apply(SpringManagementConfigurationPlugin.class); + pluginManager.apply(SpringRepositoryPlugin.class); + pluginManager.apply(SpringAsciidoctorPlugin.class); // Note: Applying plugin via id since it requires groovy compilation pluginManager.apply("org.springframework.gradle.deploy-docs"); pluginManager.apply(SpringJavadocApiPlugin.class); pluginManager.apply(SpringJavadocOptionsPlugin.class); - // Add task to create documentation archive TaskContainer tasks = project.getTasks(); + project.configure(tasks.withType(AbstractAsciidoctorTask.class), (task) -> { + File destination = new File(project.getBuildDir(), "docs"); + task.setOutputDir(destination); + task.sources((patternSet) -> { + patternSet.include("**/*.adoc"); + patternSet.exclude("_*/**"); + }); + }); + + // Add task to create documentation archive Zip docsZip = tasks.create("docsZip", Zip.class, (zip) -> { - zip.dependsOn(tasks.getByName("api")); + zip.dependsOn(tasks.getByName("api"), tasks.getByName("asciidoctor")/*, tasks.getByName("asciidoctorPdf")*/); zip.setGroup("Distribution"); zip.getArchiveBaseName().set(project.getRootProject().getName()); zip.getArchiveClassifier().set("docs"); zip.setDescription("Builds -docs archive containing all " + "Docs for deployment at docs.spring.io"); - - zip.from(tasks.getByName("api").getOutputs(), (copy) -> copy.into("api")); zip.into("docs"); zip.setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE); }); // Add task to aggregate documentation - Task docs = tasks.create("docs"); - docs.dependsOn(docsZip); - docs.setGroup("Documentation"); - docs.setDescription("An aggregator task to generate all the documentation"); + Task docs = tasks.create("docs", (task) -> { + task.dependsOn(docsZip); + task.setGroup("Documentation"); + task.setDescription("An aggregator task to generate all the documentation"); + }); // Wire docs task into the build tasks.getByName("assemble").dependsOn(docs); diff --git a/buildSrc/src/main/java/org/springframework/gradle/docs/SpringAsciidoctorPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/docs/SpringAsciidoctorPlugin.java new file mode 100644 index 00000000..bbf55aab --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/docs/SpringAsciidoctorPlugin.java @@ -0,0 +1,143 @@ +/* + * Copyright 2019-2020 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.gradle.docs; + +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask; +import org.asciidoctor.gradle.jvm.AsciidoctorJExtension; +import org.asciidoctor.gradle.jvm.AsciidoctorJPlugin; +import org.asciidoctor.gradle.jvm.AsciidoctorTask; +import org.asciidoctor.gradle.jvm.pdf.AsciidoctorJPdfPlugin; +import org.gradle.api.Plugin; +import org.gradle.api.Project; + +/** + * Conventions that are applied in the presence of the {@link AsciidoctorJPlugin}. When + * the plugin is applied: + * + * + * + * @author Andy Wilkinson + * @author Rob Winch + * @author Steve Riesenberg + */ +public class SpringAsciidoctorPlugin implements Plugin { + private static final String ASCIIDOCTORJ_VERSION = "2.4.3"; + private static final String EXTENSIONS_CONFIGURATION_NAME = "asciidoctorExtensions"; + + @Override + public void apply(Project project) { + // Apply asciidoctor plugin + project.getPluginManager().apply(AsciidoctorJPlugin.class); + project.getPluginManager().apply(AsciidoctorJPdfPlugin.class); + + // Configure asciidoctor + project.getPlugins().withType(AsciidoctorJPlugin.class, (asciidoctorPlugin) -> { + configureDocumentationDependenciesRepository(project); + makeAllWarningsFatal(project); + upgradeAsciidoctorJVersion(project); + createAsciidoctorExtensionsConfiguration(project); + project.getTasks().withType(AbstractAsciidoctorTask.class, this::configureAsciidoctorExtension); + }); + } + + private void configureDocumentationDependenciesRepository(Project project) { + project.getRepositories().maven((mavenRepo) -> { + mavenRepo.setUrl(URI.create("https://repo.spring.io/release")); + mavenRepo.mavenContent((mavenContent) -> { + mavenContent.includeGroup("io.spring.asciidoctor"); + mavenContent.includeGroup("io.spring.asciidoctor.backends"); + mavenContent.includeGroup("io.spring.docresources"); + }); + }); + } + + private void makeAllWarningsFatal(Project project) { + project.getExtensions().getByType(AsciidoctorJExtension.class).fatalWarnings(".*"); + } + + private void upgradeAsciidoctorJVersion(Project project) { + project.getExtensions().getByType(AsciidoctorJExtension.class).setVersion(ASCIIDOCTORJ_VERSION); + } + + private void createAsciidoctorExtensionsConfiguration(Project project) { + project.getConfigurations().create(EXTENSIONS_CONFIGURATION_NAME, (configuration) -> { + project.getConfigurations().matching((candidate) -> "management".equals(candidate.getName())) + .all(configuration::extendsFrom); + configuration.getDependencies().add(project.getDependencies() + .create("io.spring.asciidoctor.backends:spring-asciidoctor-backends:0.0.3")); + configuration.getDependencies() + .add(project.getDependencies().create("org.asciidoctor:asciidoctorj-pdf:1.5.3")); + }); + } + + private void configureAsciidoctorExtension(AbstractAsciidoctorTask asciidoctorTask) { + asciidoctorTask.configurations(EXTENSIONS_CONFIGURATION_NAME); + configureCommonAttributes(asciidoctorTask); + configureOptions(asciidoctorTask); + asciidoctorTask.baseDirFollowsSourceDir(); + asciidoctorTask.resources((resourcesSpec) -> { + resourcesSpec.from(asciidoctorTask.getSourceDir(), (resourcesSrcDirSpec) -> { + // Not using intermediateWorkDir. + // See https://github.com/asciidoctor/asciidoctor-gradle-plugin/issues/523 + resourcesSrcDirSpec.include("images/*.png", "css/**", "js/**"); + }); + }); + if (asciidoctorTask instanceof AsciidoctorTask) { + boolean pdf = asciidoctorTask.getName().toLowerCase().contains("pdf"); + String backend = (!pdf) ? "spring-html" : "spring-pdf"; + ((AsciidoctorTask) asciidoctorTask).outputOptions((outputOptions) -> + outputOptions.backends(backend)); + } + } + + private void configureCommonAttributes(AbstractAsciidoctorTask asciidoctorTask) { + Map attributes = new HashMap<>(); + attributes.put("attribute-missing", "warn"); + attributes.put("revnumber", null); + asciidoctorTask.attributes(attributes); + } + + private void configureOptions(AbstractAsciidoctorTask asciidoctorTask) { + asciidoctorTask.options(Collections.singletonMap("doctype", "book")); + } +} diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 074ab526..00000000 --- a/docs/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -package-lock.json -node_modules \ No newline at end of file diff --git a/docs/antora.yml b/docs/antora.yml deleted file mode 100644 index 759aac96..00000000 --- a/docs/antora.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: reference -version: 0.2.2 -prerelease: '-SNAPSHOT' - -title: Spring Authorization Server -display_version: latest -start_page: ROOT:index.adoc -nav: - - modules/ROOT/nav.adoc - - modules/guides/nav.adoc - - modules/appendix/nav.adoc diff --git a/docs/local-antora-playbook.yml b/docs/local-antora-playbook.yml deleted file mode 100644 index b1e5cac2..00000000 --- a/docs/local-antora-playbook.yml +++ /dev/null @@ -1,16 +0,0 @@ -site: - title: Spring Authorization Server - url: https://docs.spring.io/spring-authorization-server - start_page: reference::index.adoc -asciidoc: - attributes: - page-pagination: true -content: - sources: - - url: ../ - branches: [main] - start_path: docs -ui: - bundle: - url: https://github.com/spring-io/antora-ui-spring/releases/download/latest/ui-bundle.zip - snapshot: true diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc deleted file mode 100644 index 8f0baea1..00000000 --- a/docs/modules/ROOT/nav.adoc +++ /dev/null @@ -1,7 +0,0 @@ -.xref:index.adoc[Reference Manual] -* xref:overview.adoc[Overview] -* xref:getting-help.adoc[Getting Help] -* xref:getting-started.adoc[Getting Started] -* xref:configuration-model.adoc[Configuration Model] -* xref:core-components.adoc[Core Components] -* xref:protocol-endpoints.adoc[Protocol Endpoints] diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc deleted file mode 100644 index 9799ee01..00000000 --- a/docs/modules/ROOT/pages/index.adoc +++ /dev/null @@ -1,3 +0,0 @@ -= Reference Manual - -This page is under construction. diff --git a/docs/modules/appendix/nav.adoc b/docs/modules/appendix/nav.adoc deleted file mode 100644 index d54f6847..00000000 --- a/docs/modules/appendix/nav.adoc +++ /dev/null @@ -1 +0,0 @@ -* xref:index.adoc[Appendices] \ No newline at end of file diff --git a/docs/modules/guides/examples/gradle/wrapper/gradle-wrapper.jar b/docs/modules/guides/examples/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 7454180f..00000000 Binary files a/docs/modules/guides/examples/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/docs/modules/guides/examples/gradle/wrapper/gradle-wrapper.properties b/docs/modules/guides/examples/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 69a97150..00000000 --- a/docs/modules/guides/examples/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/docs/modules/guides/examples/gradlew b/docs/modules/guides/examples/gradlew deleted file mode 100755 index 744e882e..00000000 --- a/docs/modules/guides/examples/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 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. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MSYS* | MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/docs/modules/guides/examples/gradlew.bat b/docs/modules/guides/examples/gradlew.bat deleted file mode 100644 index 107acd32..00000000 --- a/docs/modules/guides/examples/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/docs/modules/guides/nav.adoc b/docs/modules/guides/nav.adoc deleted file mode 100644 index 81845c93..00000000 --- a/docs/modules/guides/nav.adoc +++ /dev/null @@ -1,2 +0,0 @@ -.xref:index.adoc["How-to" Guides] -* xref:how-to-jpa.adoc[Implement core services with JPA] diff --git a/docs/modules/guides/pages/how-to-jpa.adoc b/docs/modules/guides/pages/how-to-jpa.adoc deleted file mode 100644 index b6243586..00000000 --- a/docs/modules/guides/pages/how-to-jpa.adoc +++ /dev/null @@ -1,144 +0,0 @@ -= How-to: Implement core services with JPA - -[[getting-started]] -== Getting Started - -In this guide, we will demonstrate how to implement the xref:ROOT:core-components.adoc[core services] of xref:ROOT:index.adoc[Spring Authorization Server] with JPA. The purpose of this guide is to provide a starting point for implementing these services yourself, with the intention that you will make modifications as necessary to suit your needs. - -[[define-data-model]] -== Define the data model - -This guide seeks to provide a starting point for the data model and uses the simplest possible structure and data types. To come up with the initial schema, we begin by reviewing the xref:ROOT:core-components.adoc[domain objects] used by the core services. Please note: - -NOTE: Except for token, state, metadata, settings and claims values, we will use the JPA default column length of 255 for all columns. In reality, the length and even type of columns you use may need to be customized. Your mileage may vary and you are encouraged to experiment and test before deploying to production. - -The xref:ROOT:core-components.adoc#registered-client-repository[`RegisteredClient`] domain object contains a few multi-valued fields and some settings fields that require storing arbitrary key/value data. The following is an example that we will use to create a JPA entity. - -[[client-schema]] -.Client Schema -[source,sql] ----- -include::example$src/main/resources/oauth2-registered-client-schema.sql[] ----- - -The xref:ROOT:core-components.adoc#oauth2-authorization-service[`OAuth2Authorization`] domain object is more complex, and contains several multi-valued fields as well as numerous arbitrarily long token values, metadata, settings and claims values. The built-in JDBC implementation utilizes a flattened structure that prefers performance over normalization, which we adopt here as well. - -CAUTION: It has been difficult to find a flattened database schema that works well in all cases and with all database vendors. You may need to normalize or heavily alter the following schema for your needs. - -The following is an example that we will use to create a JPA entity. - -[[authorization-schema]] -.Authorization Schema -[source,sql] ----- -include::example$src/main/resources/oauth2-authorization-schema.sql[] ----- - -The xref:ROOT:core-components.adoc#oauth2-authorization-consent-service[`OAuth2AuthorizationConsent`] domain object is the simplest to model, and only contains a single multi-valued field in addition to a composite key. The following is an example that we will use to create a JPA entity. - -[[authorization-consent-schema]] -.Authorization Consent Schema -[source,sql] ----- -include::example$src/main/resources/oauth2-authorization-consent-schema.sql[] ----- - -[[create-jpa-entities]] -== Create JPA entities - -The preceding schema examples provide a reference for the structure of the entities we need to create. - -NOTE: The following entities are minimally annotated and are just examples. They allow the schema to be created dynamically and therefore do not require the above sql scripts to be executed manually. - -The following is an example of the `Client` entity which is used to persist information mapped from the xref:ROOT:core-components.adoc#registered-client-repository[`RegisteredClient`] domain object. - -[[client-entity]] -.Client Entity -[source,java] ----- -include::example$src/main/java/sample/jpa/Client.java[tag=class] ----- - -The following is an example of the `Authorization` entity which is used to persist information mapped from the xref:ROOT:core-components.adoc#oauth2-authorization-service[`OAuth2Authorization`] domain object. - -[[authorization-entity]] -.Authorization Entity -[source,java] ----- -include::example$src/main/java/sample/jpa/Authorization.java[tag=class] ----- - -The following is an example of the `AuthorizationConsent` entity which is used to persist information mapped from the xref:ROOT:core-components.adoc#oauth2-authorization-consent-service[`OAuth2AuthorizationConsent`] domain object. - -[[authorization-consent-entity]] -.Authorization Consent Entity -[source,java] ----- -include::example$src/main/java/sample/jpa/AuthorizationConsent.java[tag=class] ----- - -[[create-spring-data-repositories]] -== Create Spring Data repositories - -By closely examining the interfaces of each core service and reviewing the `Jdbc` implementations, we can derive a minimal set of queries needed for supporting a JPA version of each interface. - -The following is an example of the `ClientRepository` capable of finding a <> by the `id` and `clientId` fields. - -[[client-repository]] -.Client Repository -[source,java] ----- -include::example$src/main/java/sample/jpa/ClientRepository.java[tag=class] ----- - -The following is an example of the `AuthorizationRepository` capable of finding an <> by the `id` field as well as the `state`, `authorizationCodeValue`, `accessTokenValue` and `refreshTokenValue` token fields. It also allows querying a combination of token fields. - -[[authorization-repository]] -.Authorization Repository -[source,java] ----- -include::example$src/main/java/sample/jpa/AuthorizationRepository.java[tag=class] ----- - -The following is an example of the `AuthorizationConsentRepository` capable of finding and deleting an <> by the `registeredClientId` and `principalName` fields, which form a composite primary key. - -[[authorization-consent-repository]] -.Authorization Consent Repository -[source,java] ----- -include::example$src/main/java/sample/jpa/AuthorizationConsentRepository.java[tag=class] ----- - -[[implement-core-services]] -== Implement core services - -With the above <> and <>, we can begin implementing the core services. By reviewing the `Jdbc` implementations, we can derive a minimal set of internal utilities for converting to/from string values for enumerations and reading/writing JSON data for attributes, settings, metadata and claims fields. - -CAUTION: Keep in mind that writing JSON data to text columns with a fixed length has proven problematic with the `Jdbc` implementations. While these examples continue to do so, you may need to split these fields out into a separate table or data store that supports arbitrarily long data values. - -The following is an example of the `JpaRegisteredClientRepository` which uses a <> for persisting a <>, and maps to/from the xref:ROOT:core-components.adoc#registered-client-repository[`RegisteredClient`] domain object. - -[[jpa-registered-client-repository]] -.`RegisteredClientRepository` Implementation -[source,java] ----- -include::example$src/main/java/sample/jpa/JpaRegisteredClientRepository.java[tag=class] ----- - -The following is an example of the `JpaOAuth2AuthorizationService` which uses an <> for persisting an <>, and maps to/from the xref:ROOT:core-components.adoc#oauth2-authorization-service[`OAuth2Authorization`] domain object. - -[[jpa-oauth2-authorization-service]] -.`OAuth2AuthorizationService` Implementation -[source,java] ----- -include::example$src/main/java/sample/jpa/JpaOAuth2AuthorizationService.java[tag=class] ----- - -The following is an example of the `JpaOAuth2AuthorizationConsentService` which uses an <> for persisting an <>, and maps to/from the xref:ROOT:core-components.adoc#oauth2-authorization-consent-service[`OAuth2AuthorizationConsent`] domain object. - -[[jpa-oauth2-authorization-consent-service]] -.`OAuth2AuthorizationConsentService` Implementation -[source,java] ----- -include::example$src/main/java/sample/jpa/JpaOAuth2AuthorizationConsentService.java[tag=class] ----- \ No newline at end of file diff --git a/docs/package.json b/docs/package.json deleted file mode 100644 index 58af6109..00000000 --- a/docs/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dependencies": { - "@antora/cli": "^3.0.0-alpha.8", - "@antora/site-generator-default": "^3.0.0-alpha.8" - } -} diff --git a/docs/spring-authorization-server-docs.gradle b/docs/spring-authorization-server-docs.gradle index 53c680f0..9570b710 100644 --- a/docs/spring-authorization-server-docs.gradle +++ b/docs/spring-authorization-server-docs.gradle @@ -1,3 +1,23 @@ plugins { id "io.spring.convention.docs" } + +asciidoctor { + attributes([ + "spring-authorization-server-version": project.version, + "examples-dir": "examples", + "docs-java": "$sourceDir/examples/src/main/java", + "chomp": "default headers packages", + "toc": "left", + "toclevels": "4" + ]) +} + +docsZip { + from (api) { + into "api" + } + from(asciidoctor) { + into "reference/html" + } +} diff --git a/docs/modules/appendix/pages/index.adoc b/docs/src/docs/asciidoc/appendix.adoc similarity index 54% rename from docs/modules/appendix/pages/index.adoc rename to docs/src/docs/asciidoc/appendix.adoc index 4e0fc5c5..d51f57fe 100644 --- a/docs/modules/appendix/pages/index.adoc +++ b/docs/src/docs/asciidoc/appendix.adoc @@ -1,3 +1,6 @@ +[[appendices]] = Appendices +:toc: left +:toclevels: 1 This page is under construction. diff --git a/docs/modules/ROOT/pages/configuration-model.adoc b/docs/src/docs/asciidoc/configuration-model.adoc similarity index 89% rename from docs/modules/ROOT/pages/configuration-model.adoc rename to docs/src/docs/asciidoc/configuration-model.adoc index 54e1f001..2882954e 100644 --- a/docs/modules/ROOT/pages/configuration-model.adoc +++ b/docs/src/docs/asciidoc/configuration-model.adoc @@ -1,4 +1,7 @@ +[[configuration-model]] = Configuration Model +:toc: left +:toclevels: 1 This page is under construction. diff --git a/docs/modules/ROOT/pages/core-components.adoc b/docs/src/docs/asciidoc/core-components.adoc similarity index 93% rename from docs/modules/ROOT/pages/core-components.adoc rename to docs/src/docs/asciidoc/core-components.adoc index e47ad285..055cfc28 100644 --- a/docs/modules/ROOT/pages/core-components.adoc +++ b/docs/src/docs/asciidoc/core-components.adoc @@ -1,4 +1,7 @@ +[[core-components]] = Core Components +:toc: left +:toclevels: 1 This page is under construction. diff --git a/docs/modules/guides/examples/docs-modules-guides-examples.gradle b/docs/src/docs/asciidoc/examples/spring-authorization-server-docs-examples.gradle similarity index 100% rename from docs/modules/guides/examples/docs-modules-guides-examples.gradle rename to docs/src/docs/asciidoc/examples/spring-authorization-server-docs-examples.gradle diff --git a/docs/modules/guides/examples/src/main/java/sample/jpa/Authorization.java b/docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/Authorization.java similarity index 100% rename from docs/modules/guides/examples/src/main/java/sample/jpa/Authorization.java rename to docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/Authorization.java diff --git a/docs/modules/guides/examples/src/main/java/sample/jpa/AuthorizationConsent.java b/docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/AuthorizationConsent.java similarity index 100% rename from docs/modules/guides/examples/src/main/java/sample/jpa/AuthorizationConsent.java rename to docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/AuthorizationConsent.java diff --git a/docs/modules/guides/examples/src/main/java/sample/jpa/AuthorizationConsentRepository.java b/docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/AuthorizationConsentRepository.java similarity index 100% rename from docs/modules/guides/examples/src/main/java/sample/jpa/AuthorizationConsentRepository.java rename to docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/AuthorizationConsentRepository.java diff --git a/docs/modules/guides/examples/src/main/java/sample/jpa/AuthorizationRepository.java b/docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/AuthorizationRepository.java similarity index 100% rename from docs/modules/guides/examples/src/main/java/sample/jpa/AuthorizationRepository.java rename to docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/AuthorizationRepository.java diff --git a/docs/modules/guides/examples/src/main/java/sample/jpa/Client.java b/docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/Client.java similarity index 100% rename from docs/modules/guides/examples/src/main/java/sample/jpa/Client.java rename to docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/Client.java diff --git a/docs/modules/guides/examples/src/main/java/sample/jpa/ClientRepository.java b/docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/ClientRepository.java similarity index 100% rename from docs/modules/guides/examples/src/main/java/sample/jpa/ClientRepository.java rename to docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/ClientRepository.java diff --git a/docs/modules/guides/examples/src/main/java/sample/jpa/JpaOAuth2AuthorizationConsentService.java b/docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/JpaOAuth2AuthorizationConsentService.java similarity index 100% rename from docs/modules/guides/examples/src/main/java/sample/jpa/JpaOAuth2AuthorizationConsentService.java rename to docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/JpaOAuth2AuthorizationConsentService.java diff --git a/docs/modules/guides/examples/src/main/java/sample/jpa/JpaOAuth2AuthorizationService.java b/docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/JpaOAuth2AuthorizationService.java similarity index 100% rename from docs/modules/guides/examples/src/main/java/sample/jpa/JpaOAuth2AuthorizationService.java rename to docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/JpaOAuth2AuthorizationService.java diff --git a/docs/modules/guides/examples/src/main/java/sample/jpa/JpaRegisteredClientRepository.java b/docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/JpaRegisteredClientRepository.java similarity index 100% rename from docs/modules/guides/examples/src/main/java/sample/jpa/JpaRegisteredClientRepository.java rename to docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/JpaRegisteredClientRepository.java diff --git a/docs/modules/guides/examples/src/main/resources/application.yml b/docs/src/docs/asciidoc/examples/src/main/resources/application.yml similarity index 100% rename from docs/modules/guides/examples/src/main/resources/application.yml rename to docs/src/docs/asciidoc/examples/src/main/resources/application.yml diff --git a/docs/modules/guides/examples/src/main/resources/oauth2-authorization-consent-schema.sql b/docs/src/docs/asciidoc/examples/src/main/resources/oauth2-authorization-consent-schema.sql similarity index 100% rename from docs/modules/guides/examples/src/main/resources/oauth2-authorization-consent-schema.sql rename to docs/src/docs/asciidoc/examples/src/main/resources/oauth2-authorization-consent-schema.sql diff --git a/docs/modules/guides/examples/src/main/resources/oauth2-authorization-schema.sql b/docs/src/docs/asciidoc/examples/src/main/resources/oauth2-authorization-schema.sql similarity index 100% rename from docs/modules/guides/examples/src/main/resources/oauth2-authorization-schema.sql rename to docs/src/docs/asciidoc/examples/src/main/resources/oauth2-authorization-schema.sql diff --git a/docs/modules/guides/examples/src/main/resources/oauth2-registered-client-schema.sql b/docs/src/docs/asciidoc/examples/src/main/resources/oauth2-registered-client-schema.sql similarity index 100% rename from docs/modules/guides/examples/src/main/resources/oauth2-registered-client-schema.sql rename to docs/src/docs/asciidoc/examples/src/main/resources/oauth2-registered-client-schema.sql diff --git a/docs/modules/guides/examples/src/test/java/sample/jose/TestJwks.java b/docs/src/docs/asciidoc/examples/src/test/java/sample/jose/TestJwks.java similarity index 100% rename from docs/modules/guides/examples/src/test/java/sample/jose/TestJwks.java rename to docs/src/docs/asciidoc/examples/src/test/java/sample/jose/TestJwks.java diff --git a/docs/modules/guides/examples/src/test/java/sample/jose/TestKeys.java b/docs/src/docs/asciidoc/examples/src/test/java/sample/jose/TestKeys.java similarity index 100% rename from docs/modules/guides/examples/src/test/java/sample/jose/TestKeys.java rename to docs/src/docs/asciidoc/examples/src/test/java/sample/jose/TestKeys.java diff --git a/docs/modules/guides/examples/src/test/java/sample/jpa/JpaTests.java b/docs/src/docs/asciidoc/examples/src/test/java/sample/jpa/JpaTests.java similarity index 100% rename from docs/modules/guides/examples/src/test/java/sample/jpa/JpaTests.java rename to docs/src/docs/asciidoc/examples/src/test/java/sample/jpa/JpaTests.java diff --git a/docs/modules/guides/examples/src/test/java/sample/test/SpringTestContext.java b/docs/src/docs/asciidoc/examples/src/test/java/sample/test/SpringTestContext.java similarity index 100% rename from docs/modules/guides/examples/src/test/java/sample/test/SpringTestContext.java rename to docs/src/docs/asciidoc/examples/src/test/java/sample/test/SpringTestContext.java diff --git a/docs/modules/guides/examples/src/test/java/sample/test/SpringTestContextExtension.java b/docs/src/docs/asciidoc/examples/src/test/java/sample/test/SpringTestContextExtension.java similarity index 100% rename from docs/modules/guides/examples/src/test/java/sample/test/SpringTestContextExtension.java rename to docs/src/docs/asciidoc/examples/src/test/java/sample/test/SpringTestContextExtension.java diff --git a/docs/modules/guides/examples/src/test/java/sample/util/RegisteredClients.java b/docs/src/docs/asciidoc/examples/src/test/java/sample/util/RegisteredClients.java similarity index 100% rename from docs/modules/guides/examples/src/test/java/sample/util/RegisteredClients.java rename to docs/src/docs/asciidoc/examples/src/test/java/sample/util/RegisteredClients.java diff --git a/docs/modules/ROOT/pages/getting-help.adoc b/docs/src/docs/asciidoc/getting-help.adoc similarity index 53% rename from docs/modules/ROOT/pages/getting-help.adoc rename to docs/src/docs/asciidoc/getting-help.adoc index 441c87c9..92fc7d1b 100644 --- a/docs/modules/ROOT/pages/getting-help.adoc +++ b/docs/src/docs/asciidoc/getting-help.adoc @@ -1,3 +1,6 @@ +[[getting-help]] = Getting Help +:toc: left +:toclevels: 1 This page is under construction. diff --git a/docs/modules/ROOT/pages/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc similarity index 89% rename from docs/modules/ROOT/pages/getting-started.adoc rename to docs/src/docs/asciidoc/getting-started.adoc index 8b8e990d..93cecfb9 100644 --- a/docs/modules/ROOT/pages/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -1,4 +1,7 @@ +[[getting-started]] = Getting Started +:toc: left +:toclevels: 1 This page is under construction. diff --git a/docs/src/docs/asciidoc/guides/how-to-jpa.adoc b/docs/src/docs/asciidoc/guides/how-to-jpa.adoc new file mode 100644 index 00000000..986dbc04 --- /dev/null +++ b/docs/src/docs/asciidoc/guides/how-to-jpa.adoc @@ -0,0 +1,174 @@ +[[how-to-jpa]] += How-to: Implement core services with JPA +:toc: left +:toclevels: 3 +:index-link: ../how-to.html +:docs-dir: .. +:examples-dir: ../examples + +[[jpa-getting-started]] +== Getting Started + +In this guide, we will demonstrate how to implement the xref:{docs-dir}/core-components.adoc#core-components[core services] of xref:{docs-dir}/index.adoc#top[Spring Authorization Server] with JPA. The purpose of this guide is to provide a starting point for implementing these services yourself, with the intention that you will make modifications as necessary to suit your needs. + +[[jpa-define-data-model]] +== Define the data model + +This guide seeks to provide a starting point for the data model and uses the simplest possible structure and data types. To come up with the initial schema, we begin by reviewing the xref:{docs-dir}/core-components.adoc#core-components[domain objects] used by the core services. Please note: + +NOTE: Except for token, state, metadata, settings and claims values, we will use the JPA default column length of 255 for all columns. In reality, the length and even type of columns you use may need to be customized. Your mileage may vary and you are encouraged to experiment and test before deploying to production. + +[[jpa-client-schema]] +=== Client Schema + +The xref:{docs-dir}/core-components.adoc#registered-client-repository[`RegisteredClient`] domain object contains a few multi-valued fields and some settings fields that require storing arbitrary key/value data. The following is an example that we will use to create a JPA entity. + +.Client Schema +[source,sql] +---- +include::{examples-dir}/src/main/resources/oauth2-registered-client-schema.sql[] +---- + +[[jpa-authorization-schema]] +=== Authorization Schema + +The xref:{docs-dir}/core-components.adoc#oauth2-authorization-service[`OAuth2Authorization`] domain object is more complex, and contains several multi-valued fields as well as numerous arbitrarily long token values, metadata, settings and claims values. The built-in JDBC implementation utilizes a flattened structure that prefers performance over normalization, which we adopt here as well. + +CAUTION: It has been difficult to find a flattened database schema that works well in all cases and with all database vendors. You may need to normalize or heavily alter the following schema for your needs. + +The following is an example that we will use to create a JPA entity. + +.Authorization Schema +[source,sql] +---- +include::{examples-dir}/src/main/resources/oauth2-authorization-schema.sql[] +---- + +[[jpa-authorization-consent-schema]] +=== Authorization Consent Schema + +The xref:{docs-dir}/core-components.adoc#oauth2-authorization-consent-service[`OAuth2AuthorizationConsent`] domain object is the simplest to model, and only contains a single multi-valued field in addition to a composite key. The following is an example that we will use to create a JPA entity. + +.Authorization Consent Schema +[source,sql] +---- +include::{examples-dir}/src/main/resources/oauth2-authorization-consent-schema.sql[] +---- + +[[jpa-create-jpa-entities]] +== Create JPA entities + +The preceding schema examples provide a reference for the structure of the entities we need to create. + +NOTE: The following entities are minimally annotated and are just examples. They allow the schema to be created dynamically and therefore do not require the above sql scripts to be executed manually. + +[[jpa-client-entity]] +=== Client Entity + +The following is an example of the `Client` entity which is used to persist information mapped from the xref:{docs-dir}/core-components.adoc#registered-client-repository[`RegisteredClient`] domain object. + +.Client Entity +[source,java] +---- +include::{examples-dir}/src/main/java/sample/jpa/Client.java[tag=class] +---- + +[[jpa-authorization-entity]] +=== Authorization Entity + +The following is an example of the `Authorization` entity which is used to persist information mapped from the xref:{docs-dir}/core-components.adoc#oauth2-authorization-service[`OAuth2Authorization`] domain object. + +.Authorization Entity +[source,java] +---- +include::{examples-dir}/src/main/java/sample/jpa/Authorization.java[tag=class] +---- + +[[jpa-authorization-consent-entity]] +=== Authorization Consent Entity + +The following is an example of the `AuthorizationConsent` entity which is used to persist information mapped from the xref:{docs-dir}/core-components.adoc#oauth2-authorization-consent-service[`OAuth2AuthorizationConsent`] domain object. + +.Authorization Consent Entity +[source,java] +---- +include::{examples-dir}/src/main/java/sample/jpa/AuthorizationConsent.java[tag=class] +---- + +[[jpa-create-spring-data-repositories]] +== Create Spring Data repositories + +By closely examining the interfaces of each core service and reviewing the `Jdbc` implementations, we can derive a minimal set of queries needed for supporting a JPA version of each interface. + +[[jpa-client-repository]] +=== Client Repository + +The following is an example of the `ClientRepository` capable of finding a <> by the `id` and `clientId` fields. + +.Client Repository +[source,java] +---- +include::{examples-dir}/src/main/java/sample/jpa/ClientRepository.java[tag=class] +---- + +[[jpa-authorization-repository]] +=== Authorization Repository + +The following is an example of the `AuthorizationRepository` capable of finding an <> by the `id` field as well as the `state`, `authorizationCodeValue`, `accessTokenValue` and `refreshTokenValue` token fields. It also allows querying a combination of token fields. + +.Authorization Repository +[source,java] +---- +include::{examples-dir}/src/main/java/sample/jpa/AuthorizationRepository.java[tag=class] +---- + +[[jpa-authorization-consent-repository]] +=== Authorization Consent Repository + +The following is an example of the `AuthorizationConsentRepository` capable of finding and deleting an <> by the `registeredClientId` and `principalName` fields, which form a composite primary key. + +.Authorization Consent Repository +[source,java] +---- +include::{examples-dir}/src/main/java/sample/jpa/AuthorizationConsentRepository.java[tag=class] +---- + +[[jpa-implement-core-services]] +== Implement core services + +With the above <> and <>, we can begin implementing the core services. By reviewing the `Jdbc` implementations, we can derive a minimal set of internal utilities for converting to/from string values for enumerations and reading/writing JSON data for attributes, settings, metadata and claims fields. + +CAUTION: Keep in mind that writing JSON data to text columns with a fixed length has proven problematic with the `Jdbc` implementations. While these examples continue to do so, you may need to split these fields out into a separate table or data store that supports arbitrarily long data values. + +[[jpa-registered-client-repository]] +=== Registered Client Repository + +The following is an example of the `JpaRegisteredClientRepository` which uses a <> for persisting a <>, and maps to/from the xref:{docs-dir}/core-components.adoc#registered-client-repository[`RegisteredClient`] domain object. + +.`RegisteredClientRepository` Implementation +[source,java] +---- +include::{examples-dir}/src/main/java/sample/jpa/JpaRegisteredClientRepository.java[tag=class] +---- + +[[jpa-authorization-service]] +=== Authorization Service + +The following is an example of the `JpaOAuth2AuthorizationService` which uses an <> for persisting an <>, and maps to/from the xref:{docs-dir}/core-components.adoc#oauth2-authorization-service[`OAuth2Authorization`] domain object. + +.`OAuth2AuthorizationService` Implementation +[source,java] +---- +include::{examples-dir}/src/main/java/sample/jpa/JpaOAuth2AuthorizationService.java[tag=class] +---- + +[[jpa-authorization-consent-service]] +=== Authorization Consent Service + +The following is an example of the `JpaOAuth2AuthorizationConsentService` which uses an <> for persisting an <>, and maps to/from the xref:{docs-dir}/core-components.adoc#oauth2-authorization-consent-service[`OAuth2AuthorizationConsent`] domain object. + +.`OAuth2AuthorizationConsentService` Implementation +[source,java] +---- +include::{examples-dir}/src/main/java/sample/jpa/JpaOAuth2AuthorizationConsentService.java[tag=class] +---- \ No newline at end of file diff --git a/docs/modules/guides/pages/index.adoc b/docs/src/docs/asciidoc/how-to.adoc similarity index 84% rename from docs/modules/guides/pages/index.adoc rename to docs/src/docs/asciidoc/how-to.adoc index 4b826592..2c596875 100644 --- a/docs/modules/guides/pages/index.adoc +++ b/docs/src/docs/asciidoc/how-to.adoc @@ -1,8 +1,12 @@ +[[how-to]] = "How-to" Guides +:toc: left +:toclevels: 3 This page is under construction. -== Table of contents +[[how-to-overview]] +== Overview ** Obtain an access token using a specific grant_type: *** `authorization_code` @@ -22,7 +26,4 @@ This page is under construction. ** Deny access for a revoked JWT access token *** Introspect / revoke an access token ** Provide a JWK source backed by a key rotation strategy -** Implement the core services with JPA: -*** `RegisteredClientRepository` -*** `OAuth2AuthorizationService` -*** `OAuth2AuthorizationConsentService` +** xref:guides/how-to-jpa.adoc[Implement core services with JPA] diff --git a/docs/src/docs/asciidoc/index-docinfo.xml b/docs/src/docs/asciidoc/index-docinfo.xml new file mode 100644 index 00000000..172acb7e --- /dev/null +++ b/docs/src/docs/asciidoc/index-docinfo.xml @@ -0,0 +1,13 @@ +Spring Authorization Server +{spring-authorization-server-version} + +2020-2022 + + + + Copies of this document may be made for your own use and for distribution to + others, provided that you do not charge any fee for such copies and further provided + that each copy contains this Copyright Notice, whether distributed in print or + electronically. + + diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc new file mode 100644 index 00000000..24b4b317 --- /dev/null +++ b/docs/src/docs/asciidoc/index.adoc @@ -0,0 +1,14 @@ +[[top]] += Spring Authorization Server Reference +Joe Grandja, Steve Riesenberg +v{spring-authorization-server-version} + +[horizontal] +xref:overview.adoc[Overview] :: Introduction and list of supported features +xref:getting-help.adoc[Getting Help] :: Links to samples, questions and issues +xref:getting-started.adoc[Getting Started] :: System requirements, dependencies and developing your first application +xref:configuration-model.adoc[Configuration Model] :: Configuration and provider settings +xref:core-components.adoc[Core Components] :: Domain objects and service interfaces +xref:protocol-endpoints.adoc[Protocol Endpoints] :: Specifications and endpoints +xref:how-to.adoc["How-to" Guides] :: Guides to get the most from Spring Authorization Server +xref:appendix.adoc[Appendices] :: Additional information diff --git a/docs/modules/ROOT/pages/overview.adoc b/docs/src/docs/asciidoc/overview.adoc similarity index 86% rename from docs/modules/ROOT/pages/overview.adoc rename to docs/src/docs/asciidoc/overview.adoc index 493b1501..bb140030 100644 --- a/docs/modules/ROOT/pages/overview.adoc +++ b/docs/src/docs/asciidoc/overview.adoc @@ -1,4 +1,7 @@ +[[overview]] = Overview +:toc: left +:toclevels: 1 This page is under construction. diff --git a/docs/modules/ROOT/pages/protocol-endpoints.adoc b/docs/src/docs/asciidoc/protocol-endpoints.adoc similarity index 95% rename from docs/modules/ROOT/pages/protocol-endpoints.adoc rename to docs/src/docs/asciidoc/protocol-endpoints.adoc index 56ef25de..a1d4452e 100644 --- a/docs/modules/ROOT/pages/protocol-endpoints.adoc +++ b/docs/src/docs/asciidoc/protocol-endpoints.adoc @@ -1,4 +1,7 @@ +[[protocol-endpoints]] = Protocol Endpoints +:toc: left +:toclevels: 1 This page is under construction.