浏览代码

Polish "How-to: Implement core services with JPA"

Issue gh-545
Steve Riesenberg 3 年之前
父节点
当前提交
7edbe2a30d
共有 14 个文件被更改,包括 108 次插入162 次删除
  1. 3 9
      docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/entity/authorization/Authorization.java
  2. 5 15
      docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/entity/authorizationConsent/AuthorizationConsent.java
  3. 3 9
      docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/entity/client/Client.java
  4. 3 6
      docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/repository/authorization/AuthorizationRepository.java
  5. 3 6
      docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/repository/authorizationConsent/AuthorizationConsentRepository.java
  6. 3 6
      docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/repository/client/ClientRepository.java
  7. 3 6
      docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/service/authorization/JpaOAuth2AuthorizationService.java
  8. 4 6
      docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/service/authorizationConsent/JpaOAuth2AuthorizationConsentService.java
  9. 3 6
      docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/service/client/JpaRegisteredClientRepository.java
  10. 0 6
      docs/src/docs/asciidoc/examples/src/main/resources/oauth2-authorization-consent-schema.sql
  11. 0 28
      docs/src/docs/asciidoc/examples/src/main/resources/oauth2-authorization-schema.sql
  12. 0 15
      docs/src/docs/asciidoc/examples/src/main/resources/oauth2-registered-client-schema.sql
  13. 3 0
      docs/src/docs/asciidoc/examples/src/test/java/sample/jpa/JpaTests.java
  14. 75 44
      docs/src/docs/asciidoc/guides/how-to-jpa.adoc

+ 3 - 9
docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/Authorization.java → docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/entity/authorization/Authorization.java

@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package sample.jpa;
+package sample.jpa.entity.authorization;
 
 
 import java.time.Instant;
 import java.time.Instant;
 
 
@@ -21,10 +21,6 @@ import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.Id;
 
 
-/**
- * @author Steve Riesenberg
- */
-// tag::class[]
 @Entity
 @Entity
 public class Authorization {
 public class Authorization {
 	@Id
 	@Id
@@ -69,8 +65,7 @@ public class Authorization {
 	@Column(length = 2000)
 	@Column(length = 2000)
 	private String oidcIdTokenClaims;
 	private String oidcIdTokenClaims;
 
 
-	// getters and setters
-// end::class[]
+	// @fold:on
 	public String getId() {
 	public String getId() {
 		return id;
 		return id;
 	}
 	}
@@ -270,6 +265,5 @@ public class Authorization {
 	public void setOidcIdTokenClaims(String idTokenClaims) {
 	public void setOidcIdTokenClaims(String idTokenClaims) {
 		this.oidcIdTokenClaims = idTokenClaims;
 		this.oidcIdTokenClaims = idTokenClaims;
 	}
 	}
-// tag::class[]
+	// @fold:off
 }
 }
-// end::class[]

+ 5 - 15
docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/AuthorizationConsent.java → docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/entity/authorizationConsent/AuthorizationConsent.java

@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package sample.jpa;
+package sample.jpa.entity.authorizationConsent;
 
 
 import java.io.Serializable;
 import java.io.Serializable;
 import java.util.Objects;
 import java.util.Objects;
@@ -23,10 +23,6 @@ import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.Id;
 import javax.persistence.IdClass;
 import javax.persistence.IdClass;
 
 
-/**
- * @author Steve Riesenberg
- */
-// tag::class[]
 @Entity
 @Entity
 @IdClass(AuthorizationConsent.AuthorizationConsentId.class)
 @IdClass(AuthorizationConsent.AuthorizationConsentId.class)
 public class AuthorizationConsent {
 public class AuthorizationConsent {
@@ -37,8 +33,7 @@ public class AuthorizationConsent {
 	@Column(length = 1000)
 	@Column(length = 1000)
 	private String authorities;
 	private String authorities;
 
 
-	// getters and setters
-// end::class[]
+	// @fold:on
 	public String getRegisteredClientId() {
 	public String getRegisteredClientId() {
 		return registeredClientId;
 		return registeredClientId;
 	}
 	}
@@ -62,14 +57,13 @@ public class AuthorizationConsent {
 	public void setAuthorities(String authorities) {
 	public void setAuthorities(String authorities) {
 		this.authorities = authorities;
 		this.authorities = authorities;
 	}
 	}
-// tag::class[]
+	// @fold:off
 
 
 	public static class AuthorizationConsentId implements Serializable {
 	public static class AuthorizationConsentId implements Serializable {
 		private String registeredClientId;
 		private String registeredClientId;
 		private String principalName;
 		private String principalName;
 
 
-		// getters and setters
-// end::class[]
+		// @fold:on
 		public String getRegisteredClientId() {
 		public String getRegisteredClientId() {
 			return registeredClientId;
 			return registeredClientId;
 		}
 		}
@@ -85,10 +79,8 @@ public class AuthorizationConsent {
 		public void setPrincipalName(String principalName) {
 		public void setPrincipalName(String principalName) {
 			this.principalName = principalName;
 			this.principalName = principalName;
 		}
 		}
-// tag::class[]
+		// @fold:off
 
 
-		// equals and hashCode
-// end::class[]
 		@Override
 		@Override
 		public boolean equals(Object o) {
 		public boolean equals(Object o) {
 			if (this == o) return true;
 			if (this == o) return true;
@@ -101,7 +93,5 @@ public class AuthorizationConsent {
 		public int hashCode() {
 		public int hashCode() {
 			return Objects.hash(registeredClientId, principalName);
 			return Objects.hash(registeredClientId, principalName);
 		}
 		}
-// tag::class[]
 	}
 	}
 }
 }
-// end::class[]

+ 3 - 9
docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/Client.java → docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/entity/client/Client.java

@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package sample.jpa;
+package sample.jpa.entity.client;
 
 
 import java.time.Instant;
 import java.time.Instant;
 
 
@@ -21,10 +21,6 @@ import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.Id;
 
 
-/**
- * @author Steve Riesenberg
- */
-// tag::class[]
 @Entity
 @Entity
 public class Client {
 public class Client {
 	@Id
 	@Id
@@ -47,8 +43,7 @@ public class Client {
 	@Column(length = 2000)
 	@Column(length = 2000)
 	private String tokenSettings;
 	private String tokenSettings;
 
 
-	// getters and setters
-// end::class[]
+	// @fold:on
 	public String getId() {
 	public String getId() {
 		return id;
 		return id;
 	}
 	}
@@ -144,6 +139,5 @@ public class Client {
 	public void setTokenSettings(String tokenSettings) {
 	public void setTokenSettings(String tokenSettings) {
 		this.tokenSettings = tokenSettings;
 		this.tokenSettings = tokenSettings;
 	}
 	}
-// tag::class[]
+	// @fold:off
 }
 }
-// end::class[]

+ 3 - 6
docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/AuthorizationRepository.java → docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/repository/authorization/AuthorizationRepository.java

@@ -13,19 +13,17 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package sample.jpa;
+package sample.jpa.repository.authorization;
 
 
 import java.util.Optional;
 import java.util.Optional;
 
 
+import sample.jpa.entity.authorization.Authorization;
+
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.query.Param;
 import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 import org.springframework.stereotype.Repository;
 
 
-/**
- * @author Steve Riesenberg
- */
-// tag::class[]
 @Repository
 @Repository
 public interface AuthorizationRepository extends JpaRepository<Authorization, String> {
 public interface AuthorizationRepository extends JpaRepository<Authorization, String> {
 	Optional<Authorization> findByState(String state);
 	Optional<Authorization> findByState(String state);
@@ -39,4 +37,3 @@ public interface AuthorizationRepository extends JpaRepository<Authorization, St
 	)
 	)
 	Optional<Authorization> findByStateOrAuthorizationCodeValueOrAccessTokenValueOrRefreshTokenValue(@Param("token") String token);
 	Optional<Authorization> findByStateOrAuthorizationCodeValueOrAccessTokenValueOrRefreshTokenValue(@Param("token") String token);
 }
 }
-// end::class[]

+ 3 - 6
docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/AuthorizationConsentRepository.java → docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/repository/authorizationConsent/AuthorizationConsentRepository.java

@@ -13,20 +13,17 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package sample.jpa;
+package sample.jpa.repository.authorizationConsent;
 
 
 import java.util.Optional;
 import java.util.Optional;
 
 
+import sample.jpa.entity.authorizationConsent.AuthorizationConsent;
+
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 import org.springframework.stereotype.Repository;
 
 
-/**
- * @author Steve Riesenberg
- */
-// tag::class[]
 @Repository
 @Repository
 public interface AuthorizationConsentRepository extends JpaRepository<AuthorizationConsent, AuthorizationConsent.AuthorizationConsentId> {
 public interface AuthorizationConsentRepository extends JpaRepository<AuthorizationConsent, AuthorizationConsent.AuthorizationConsentId> {
 	Optional<AuthorizationConsent> findByRegisteredClientIdAndPrincipalName(String registeredClientId, String principalName);
 	Optional<AuthorizationConsent> findByRegisteredClientIdAndPrincipalName(String registeredClientId, String principalName);
 	void deleteByRegisteredClientIdAndPrincipalName(String registeredClientId, String principalName);
 	void deleteByRegisteredClientIdAndPrincipalName(String registeredClientId, String principalName);
 }
 }
-// end::class[]

+ 3 - 6
docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/ClientRepository.java → docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/repository/client/ClientRepository.java

@@ -13,19 +13,16 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package sample.jpa;
+package sample.jpa.repository.client;
 
 
 import java.util.Optional;
 import java.util.Optional;
 
 
+import sample.jpa.entity.client.Client;
+
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 import org.springframework.stereotype.Repository;
 
 
-/**
- * @author Steve Riesenberg
- */
-// tag::class[]
 @Repository
 @Repository
 public interface ClientRepository extends JpaRepository<Client, String> {
 public interface ClientRepository extends JpaRepository<Client, String> {
 	Optional<Client> findByClientId(String clientId);
 	Optional<Client> findByClientId(String clientId);
 }
 }
-// end::class[]

+ 3 - 6
docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/JpaOAuth2AuthorizationService.java → docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/service/authorization/JpaOAuth2AuthorizationService.java

@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package sample.jpa;
+package sample.jpa.service.authorization;
 
 
 import java.time.Instant;
 import java.time.Instant;
 import java.util.List;
 import java.util.List;
@@ -24,6 +24,8 @@ import java.util.function.Consumer;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.Module;
 import com.fasterxml.jackson.databind.Module;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import sample.jpa.entity.authorization.Authorization;
+import sample.jpa.repository.authorization.AuthorizationRepository;
 
 
 import org.springframework.dao.DataRetrievalFailureException;
 import org.springframework.dao.DataRetrievalFailureException;
 import org.springframework.security.jackson2.SecurityJackson2Modules;
 import org.springframework.security.jackson2.SecurityJackson2Modules;
@@ -44,10 +46,6 @@ import org.springframework.stereotype.Component;
 import org.springframework.util.Assert;
 import org.springframework.util.Assert;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
 
 
-/**
- * @author Steve Riesenberg
- */
-// tag::class[]
 @Component
 @Component
 public class JpaOAuth2AuthorizationService implements OAuth2AuthorizationService {
 public class JpaOAuth2AuthorizationService implements OAuth2AuthorizationService {
 	private final AuthorizationRepository authorizationRepository;
 	private final AuthorizationRepository authorizationRepository;
@@ -261,4 +259,3 @@ public class JpaOAuth2AuthorizationService implements OAuth2AuthorizationService
 		return new AuthorizationGrantType(authorizationGrantType);              // Custom authorization grant type
 		return new AuthorizationGrantType(authorizationGrantType);              // Custom authorization grant type
 	}
 	}
 }
 }
-// end::class[]

+ 4 - 6
docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/JpaOAuth2AuthorizationConsentService.java → docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/service/authorizationConsent/JpaOAuth2AuthorizationConsentService.java

@@ -13,11 +13,14 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package sample.jpa;
+package sample.jpa.service.authorizationConsent;
 
 
 import java.util.HashSet;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.Set;
 
 
+import sample.jpa.entity.authorizationConsent.AuthorizationConsent;
+import sample.jpa.repository.authorizationConsent.AuthorizationConsentRepository;
+
 import org.springframework.dao.DataRetrievalFailureException;
 import org.springframework.dao.DataRetrievalFailureException;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -29,10 +32,6 @@ import org.springframework.stereotype.Component;
 import org.springframework.util.Assert;
 import org.springframework.util.Assert;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
 
 
-/**
- * @author Steve Riesenberg
- */
-// tag::class[]
 @Component
 @Component
 public class JpaOAuth2AuthorizationConsentService implements OAuth2AuthorizationConsentService {
 public class JpaOAuth2AuthorizationConsentService implements OAuth2AuthorizationConsentService {
 	private final AuthorizationConsentRepository authorizationConsentRepository;
 	private final AuthorizationConsentRepository authorizationConsentRepository;
@@ -99,4 +98,3 @@ public class JpaOAuth2AuthorizationConsentService implements OAuth2Authorization
 		return entity;
 		return entity;
 	}
 	}
 }
 }
-// end::class[]

+ 3 - 6
docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/JpaRegisteredClientRepository.java → docs/src/docs/asciidoc/examples/src/main/java/sample/jpa/service/client/JpaRegisteredClientRepository.java

@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package sample.jpa;
+package sample.jpa.service.client;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
@@ -23,6 +23,8 @@ import java.util.Set;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.Module;
 import com.fasterxml.jackson.databind.Module;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import sample.jpa.entity.client.Client;
+import sample.jpa.repository.client.ClientRepository;
 
 
 import org.springframework.security.jackson2.SecurityJackson2Modules;
 import org.springframework.security.jackson2.SecurityJackson2Modules;
 import org.springframework.security.oauth2.core.AuthorizationGrantType;
 import org.springframework.security.oauth2.core.AuthorizationGrantType;
@@ -36,10 +38,6 @@ import org.springframework.stereotype.Component;
 import org.springframework.util.Assert;
 import org.springframework.util.Assert;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
 
 
-/**
- * @author Steve Riesenberg
- */
-// tag::class[]
 @Component
 @Component
 public class JpaRegisteredClientRepository implements RegisteredClientRepository {
 public class JpaRegisteredClientRepository implements RegisteredClientRepository {
 	private final ClientRepository clientRepository;
 	private final ClientRepository clientRepository;
@@ -172,4 +170,3 @@ public class JpaRegisteredClientRepository implements RegisteredClientRepository
 		return new ClientAuthenticationMethod(clientAuthenticationMethod);      // Custom client authentication method
 		return new ClientAuthenticationMethod(clientAuthenticationMethod);      // Custom client authentication method
 	}
 	}
 }
 }
-// end::class[]

+ 0 - 6
docs/src/docs/asciidoc/examples/src/main/resources/oauth2-authorization-consent-schema.sql

@@ -1,6 +0,0 @@
-CREATE TABLE authorizationConsent (
-    registeredClientId varchar(255) NOT NULL,
-    principalName varchar(255) NOT NULL,
-    authorities varchar(1000) NOT NULL,
-    PRIMARY KEY (registeredClientId, principalName)
-);

+ 0 - 28
docs/src/docs/asciidoc/examples/src/main/resources/oauth2-authorization-schema.sql

@@ -1,28 +0,0 @@
-CREATE TABLE authorization (
-    id varchar(255) NOT NULL,
-    registeredClientId varchar(255) NOT NULL,
-    principalName varchar(255) NOT NULL,
-    authorizationGrantType varchar(255) NOT NULL,
-    attributes varchar(4000) DEFAULT NULL,
-    state varchar(500) DEFAULT NULL,
-    authorizationCodeValue varchar(4000) DEFAULT NULL,
-    authorizationCodeIssuedAt timestamp DEFAULT NULL,
-    authorizationCodeExpiresAt timestamp DEFAULT NULL,
-    authorizationCodeMetadata varchar(2000) DEFAULT NULL,
-    accessTokenValue varchar(4000) DEFAULT NULL,
-    accessTokenIssuedAt timestamp DEFAULT NULL,
-    accessTokenExpiresAt timestamp DEFAULT NULL,
-    accessTokenMetadata varchar(2000) DEFAULT NULL,
-    accessTokenType varchar(255) DEFAULT NULL,
-    accessTokenScopes varchar(1000) DEFAULT NULL,
-    refreshTokenValue varchar(4000) DEFAULT NULL,
-    refreshTokenIssuedAt timestamp DEFAULT NULL,
-    refreshTokenExpiresAt timestamp DEFAULT NULL,
-    refreshTokenMetadata varchar(2000) DEFAULT NULL,
-    oidcIdTokenValue varchar(4000) DEFAULT NULL,
-    oidcIdTokenIssuedAt timestamp DEFAULT NULL,
-    oidcIdTokenExpiresAt timestamp DEFAULT NULL,
-    oidcIdTokenMetadata varchar(2000) DEFAULT NULL,
-    oidcIdTokenClaims varchar(2000) DEFAULT NULL,
-    PRIMARY KEY (id)
-);

+ 0 - 15
docs/src/docs/asciidoc/examples/src/main/resources/oauth2-registered-client-schema.sql

@@ -1,15 +0,0 @@
-CREATE TABLE client (
-    id varchar(255) NOT NULL,
-    clientId varchar(255) NOT NULL,
-    clientIdIssuedAt timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
-    clientSecret varchar(255) DEFAULT NULL,
-    clientSecretExpiresAt timestamp DEFAULT NULL,
-    clientName varchar(255) NOT NULL,
-    clientAuthenticationMethods varchar(1000) NOT NULL,
-    authorizationGrantTypes varchar(1000) NOT NULL,
-    redirectUris varchar(1000) DEFAULT NULL,
-    scopes varchar(1000) NOT NULL,
-    clientSettings varchar(2000) NOT NULL,
-    tokenSettings varchar(2000) NOT NULL,
-    PRIMARY KEY (id)
-);

+ 3 - 0
docs/src/docs/asciidoc/examples/src/test/java/sample/jpa/JpaTests.java

@@ -26,6 +26,9 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.extension.ExtendWith;
 import sample.AuthorizationCodeGrantFlow;
 import sample.AuthorizationCodeGrantFlow;
 import sample.jose.TestJwks;
 import sample.jose.TestJwks;
+import sample.jpa.service.authorization.JpaOAuth2AuthorizationService;
+import sample.jpa.service.authorizationConsent.JpaOAuth2AuthorizationConsentService;
+import sample.jpa.service.client.JpaRegisteredClientRepository;
 import sample.test.SpringTestContext;
 import sample.test.SpringTestContext;
 import sample.test.SpringTestContextExtension;
 import sample.test.SpringTestContextExtension;
 
 

+ 75 - 44
docs/src/docs/asciidoc/guides/how-to-jpa.adoc

@@ -2,7 +2,6 @@
 = How-to: Implement core services with JPA
 = How-to: Implement core services with JPA
 :index-link: ../how-to.html
 :index-link: ../how-to.html
 :docs-dir: ..
 :docs-dir: ..
-:examples-dir: ../examples
 
 
 This guide shows how to implement the xref:{docs-dir}/core-model-components.adoc#core-model-components[core services] of xref:{docs-dir}/index.adoc#top[Spring Authorization Server] with JPA.
 This guide shows how to implement the xref:{docs-dir}/core-model-components.adoc#core-model-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 can make modifications to suit your needs.
 The purpose of this guide is to provide a starting point for implementing these services yourself, with the intention that you can make modifications to suit your needs.
@@ -18,7 +17,8 @@ The purpose of this guide is to provide a starting point for implementing these
 This guide provides a starting point for the data model and uses the simplest possible structure and data types.
 This guide provides 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-model-components.adoc#core-model-components[domain objects] used by the core services.
 To come up with the initial schema, we begin by reviewing the xref:{docs-dir}/core-model-components.adoc#core-model-components[domain objects] used by the core services.
 
 
-NOTE: Except for token, state, metadata, settings, and claims values, we use the JPA default column length of 255 for all columns.
+[NOTE]
+Except for token, state, metadata, settings, and claims values, we 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.
 In reality, the length and even type of columns you use may need to be customized.
 You are encouraged to experiment and test before deploying to production.
 You are encouraged to experiment and test before deploying to production.
 
 
@@ -35,7 +35,21 @@ The following listing shows the `client` schema.
 .Client Schema
 .Client Schema
 [source,sql]
 [source,sql]
 ----
 ----
-include::{examples-dir}/src/main/resources/oauth2-registered-client-schema.sql[]
+CREATE TABLE client (
+    id varchar(255) NOT NULL,
+    clientId varchar(255) NOT NULL,
+    clientIdIssuedAt timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
+    clientSecret varchar(255) DEFAULT NULL,
+    clientSecretExpiresAt timestamp DEFAULT NULL,
+    clientName varchar(255) NOT NULL,
+    clientAuthenticationMethods varchar(1000) NOT NULL,
+    authorizationGrantTypes varchar(1000) NOT NULL,
+    redirectUris varchar(1000) DEFAULT NULL,
+    scopes varchar(1000) NOT NULL,
+    clientSettings varchar(2000) NOT NULL,
+    tokenSettings varchar(2000) NOT NULL,
+    PRIMARY KEY (id)
+);
 ----
 ----
 
 
 [[authorization-schema]]
 [[authorization-schema]]
@@ -44,7 +58,8 @@ include::{examples-dir}/src/main/resources/oauth2-registered-client-schema.sql[]
 The xref:{docs-dir}/core-model-components.adoc#oauth2-authorization[`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 xref:{docs-dir}/core-model-components.adoc#oauth2-authorization[`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.
 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.
+[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.
 You may need to normalize or heavily alter the following schema for your needs.
 
 
 The following listing shows the `authorization` schema.
 The following listing shows the `authorization` schema.
@@ -52,7 +67,34 @@ The following listing shows the `authorization` schema.
 .Authorization Schema
 .Authorization Schema
 [source,sql]
 [source,sql]
 ----
 ----
-include::{examples-dir}/src/main/resources/oauth2-authorization-schema.sql[]
+CREATE TABLE authorization (
+    id varchar(255) NOT NULL,
+    registeredClientId varchar(255) NOT NULL,
+    principalName varchar(255) NOT NULL,
+    authorizationGrantType varchar(255) NOT NULL,
+    attributes varchar(4000) DEFAULT NULL,
+    state varchar(500) DEFAULT NULL,
+    authorizationCodeValue varchar(4000) DEFAULT NULL,
+    authorizationCodeIssuedAt timestamp DEFAULT NULL,
+    authorizationCodeExpiresAt timestamp DEFAULT NULL,
+    authorizationCodeMetadata varchar(2000) DEFAULT NULL,
+    accessTokenValue varchar(4000) DEFAULT NULL,
+    accessTokenIssuedAt timestamp DEFAULT NULL,
+    accessTokenExpiresAt timestamp DEFAULT NULL,
+    accessTokenMetadata varchar(2000) DEFAULT NULL,
+    accessTokenType varchar(255) DEFAULT NULL,
+    accessTokenScopes varchar(1000) DEFAULT NULL,
+    refreshTokenValue varchar(4000) DEFAULT NULL,
+    refreshTokenIssuedAt timestamp DEFAULT NULL,
+    refreshTokenExpiresAt timestamp DEFAULT NULL,
+    refreshTokenMetadata varchar(2000) DEFAULT NULL,
+    oidcIdTokenValue varchar(4000) DEFAULT NULL,
+    oidcIdTokenIssuedAt timestamp DEFAULT NULL,
+    oidcIdTokenExpiresAt timestamp DEFAULT NULL,
+    oidcIdTokenMetadata varchar(2000) DEFAULT NULL,
+    oidcIdTokenClaims varchar(2000) DEFAULT NULL,
+    PRIMARY KEY (id)
+);
 ----
 ----
 
 
 [[authorization-consent-schema]]
 [[authorization-consent-schema]]
@@ -64,7 +106,12 @@ The following listing shows the `authorizationConsent` schema.
 .Authorization Consent Schema
 .Authorization Consent Schema
 [source,sql]
 [source,sql]
 ----
 ----
-include::{examples-dir}/src/main/resources/oauth2-authorization-consent-schema.sql[]
+CREATE TABLE authorizationConsent (
+    registeredClientId varchar(255) NOT NULL,
+    principalName varchar(255) NOT NULL,
+    authorities varchar(1000) NOT NULL,
+    PRIMARY KEY (registeredClientId, principalName)
+);
 ----
 ----
 
 
 [[create-jpa-entities]]
 [[create-jpa-entities]]
@@ -72,7 +119,8 @@ include::{examples-dir}/src/main/resources/oauth2-authorization-consent-schema.s
 
 
 The preceding schema examples provide a reference for the structure of the entities we need to create.
 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.
+[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.
 They allow the schema to be created dynamically and therefore do not require the above sql scripts to be executed manually.
 
 
 * <<client-entity>>
 * <<client-entity>>
@@ -84,33 +132,27 @@ They allow the schema to be created dynamically and therefore do not require the
 
 
 The following listing shows the `Client` entity, which is used to persist information mapped from the xref:{docs-dir}/core-model-components.adoc#registered-client[`RegisteredClient`] domain object.
 The following listing shows the `Client` entity, which is used to persist information mapped from the xref:{docs-dir}/core-model-components.adoc#registered-client[`RegisteredClient`] domain object.
 
 
+[[sample.jpa.entity.client]]
 .Client Entity
 .Client Entity
-[source,java]
-----
-include::{examples-dir}/src/main/java/sample/jpa/Client.java[tag=class]
-----
+include::code:Client[]
 
 
 [[authorization-entity]]
 [[authorization-entity]]
 === Authorization Entity
 === Authorization Entity
 
 
 The following listing shows the `Authorization` entity, which is used to persist information mapped from the xref:{docs-dir}/core-model-components.adoc#oauth2-authorization[`OAuth2Authorization`] domain object.
 The following listing shows the `Authorization` entity, which is used to persist information mapped from the xref:{docs-dir}/core-model-components.adoc#oauth2-authorization[`OAuth2Authorization`] domain object.
 
 
+[[sample.jpa.entity.authorization]]
 .Authorization Entity
 .Authorization Entity
-[source,java]
-----
-include::{examples-dir}/src/main/java/sample/jpa/Authorization.java[tag=class]
-----
+include::code:Authorization[]
 
 
 [[authorization-consent-entity]]
 [[authorization-consent-entity]]
 === Authorization Consent Entity
 === Authorization Consent Entity
 
 
 The following listing shows the `AuthorizationConsent` entity, which is used to persist information mapped from the xref:{docs-dir}/core-model-components.adoc#oauth2-authorization-consent[`OAuth2AuthorizationConsent`] domain object.
 The following listing shows the `AuthorizationConsent` entity, which is used to persist information mapped from the xref:{docs-dir}/core-model-components.adoc#oauth2-authorization-consent[`OAuth2AuthorizationConsent`] domain object.
 
 
+[[sample.jpa.entity.authorizationConsent]]
 .Authorization Consent Entity
 .Authorization Consent Entity
-[source,java]
-----
-include::{examples-dir}/src/main/java/sample/jpa/AuthorizationConsent.java[tag=class]
-----
+include::code:AuthorizationConsent[]
 
 
 [[create-spring-data-repositories]]
 [[create-spring-data-repositories]]
 == Create Spring Data repositories
 == Create Spring Data repositories
@@ -126,11 +168,9 @@ By closely examining the interfaces of each core service and reviewing the `Jdbc
 
 
 The following listing shows the `ClientRepository`, which is able to find a <<client-entity,`Client`>> by the `id` and `clientId` fields.
 The following listing shows the `ClientRepository`, which is able to find a <<client-entity,`Client`>> by the `id` and `clientId` fields.
 
 
+[[sample.jpa.repository.client]]
 .Client Repository
 .Client Repository
-[source,java]
-----
-include::{examples-dir}/src/main/java/sample/jpa/ClientRepository.java[tag=class]
-----
+include::code:ClientRepository[]
 
 
 [[authorization-repository]]
 [[authorization-repository]]
 === Authorization Repository
 === Authorization Repository
@@ -138,22 +178,18 @@ include::{examples-dir}/src/main/java/sample/jpa/ClientRepository.java[tag=class
 The following listing shows the `AuthorizationRepository`, which is able to find an <<authorization-entity,`Authorization`>> by the `id` field as well as the `state`, `authorizationCodeValue`, `accessTokenValue` and `refreshTokenValue` token fields.
 The following listing shows the `AuthorizationRepository`, which is able to find an <<authorization-entity,`Authorization`>> by the `id` field as well as the `state`, `authorizationCodeValue`, `accessTokenValue` and `refreshTokenValue` token fields.
 It also allows querying a combination of token fields.
 It also allows querying a combination of token fields.
 
 
+[[sample.jpa.repository.authorization]]
 .Authorization Repository
 .Authorization Repository
-[source,java]
-----
-include::{examples-dir}/src/main/java/sample/jpa/AuthorizationRepository.java[tag=class]
-----
+include::code:AuthorizationRepository[]
 
 
 [[authorization-consent-repository]]
 [[authorization-consent-repository]]
 === Authorization Consent Repository
 === Authorization Consent Repository
 
 
 The following listing shows the `AuthorizationConsentRepository`, which is able to find and delete an <<authorization-consent-entity,`AuthorizationConsent`>> by the `registeredClientId` and `principalName` fields that form a composite primary key.
 The following listing shows the `AuthorizationConsentRepository`, which is able to find and delete an <<authorization-consent-entity,`AuthorizationConsent`>> by the `registeredClientId` and `principalName` fields that form a composite primary key.
 
 
+[[sample.jpa.repository.authorizationConsent]]
 .Authorization Consent Repository
 .Authorization Consent Repository
-[source,java]
-----
-include::{examples-dir}/src/main/java/sample/jpa/AuthorizationConsentRepository.java[tag=class]
-----
+include::code:AuthorizationConsentRepository[]
 
 
 [[implement-core-services]]
 [[implement-core-services]]
 == Implement core services
 == Implement core services
@@ -161,7 +197,8 @@ include::{examples-dir}/src/main/java/sample/jpa/AuthorizationConsentRepository.
 With the above <<create-jpa-entities,entities>> and <<create-spring-data-repositories,repositories>>, we can begin implementing the core services.
 With the above <<create-jpa-entities,entities>> and <<create-spring-data-repositories,repositories>>, we can begin implementing the core services.
 By reviewing the `Jdbc` implementations, we can derive a minimal set of internal utilities for converting to and from string values for enumerations and reading and writing JSON data for attributes, settings, metadata and claims fields.
 By reviewing the `Jdbc` implementations, we can derive a minimal set of internal utilities for converting to and from string values for enumerations and reading and 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.
+[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.
 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.
 
 
 * <<registered-client-repository>>
 * <<registered-client-repository>>
@@ -173,30 +210,24 @@ While these examples continue to do so, you may need to split these fields out i
 
 
 The following listing shows the `JpaRegisteredClientRepository`, which uses a <<client-repository,`ClientRepository`>> for persisting a <<client-entity,`Client`>> and maps to and from the xref:{docs-dir}/core-model-components.adoc#registered-client[`RegisteredClient`] domain object.
 The following listing shows the `JpaRegisteredClientRepository`, which uses a <<client-repository,`ClientRepository`>> for persisting a <<client-entity,`Client`>> and maps to and from the xref:{docs-dir}/core-model-components.adoc#registered-client[`RegisteredClient`] domain object.
 
 
+[[sample.jpa.service.client]]
 .`RegisteredClientRepository` Implementation
 .`RegisteredClientRepository` Implementation
-[source,java]
-----
-include::{examples-dir}/src/main/java/sample/jpa/JpaRegisteredClientRepository.java[tag=class]
-----
+include::code:JpaRegisteredClientRepository[]
 
 
 [[authorization-service]]
 [[authorization-service]]
 === Authorization Service
 === Authorization Service
 
 
 The following listing shows the `JpaOAuth2AuthorizationService`, which uses an <<authorization-repository,`AuthorizationRepository`>> for persisting an <<authorization-entity,`Authorization`>> and maps to and from the xref:{docs-dir}/core-model-components.adoc#oauth2-authorization[`OAuth2Authorization`] domain object.
 The following listing shows the `JpaOAuth2AuthorizationService`, which uses an <<authorization-repository,`AuthorizationRepository`>> for persisting an <<authorization-entity,`Authorization`>> and maps to and from the xref:{docs-dir}/core-model-components.adoc#oauth2-authorization[`OAuth2Authorization`] domain object.
 
 
+[[sample.jpa.service.authorization]]
 .`OAuth2AuthorizationService` Implementation
 .`OAuth2AuthorizationService` Implementation
-[source,java]
-----
-include::{examples-dir}/src/main/java/sample/jpa/JpaOAuth2AuthorizationService.java[tag=class]
-----
+include::code:JpaOAuth2AuthorizationService[]
 
 
 [[authorization-consent-service]]
 [[authorization-consent-service]]
 === Authorization Consent Service
 === Authorization Consent Service
 
 
 The following listing shows the `JpaOAuth2AuthorizationConsentService`, which uses an <<authorization-consent-repository,`AuthorizationConsentRepository`>> for persisting an <<authorization-consent-entity,`AuthorizationConsent`>> and maps to and from the xref:{docs-dir}/core-model-components.adoc#oauth2-authorization-consent[`OAuth2AuthorizationConsent`] domain object.
 The following listing shows the `JpaOAuth2AuthorizationConsentService`, which uses an <<authorization-consent-repository,`AuthorizationConsentRepository`>> for persisting an <<authorization-consent-entity,`AuthorizationConsent`>> and maps to and from the xref:{docs-dir}/core-model-components.adoc#oauth2-authorization-consent[`OAuth2AuthorizationConsent`] domain object.
 
 
+[[sample.jpa.service.authorizationConsent]]
 .`OAuth2AuthorizationConsentService` Implementation
 .`OAuth2AuthorizationConsentService` Implementation
-[source,java]
-----
-include::{examples-dir}/src/main/java/sample/jpa/JpaOAuth2AuthorizationConsentService.java[tag=class]
-----
+include::code:JpaOAuth2AuthorizationConsentService[]