The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.
Follows the import procedure in README.md.
source/ the originating repository verbatim — 78 documents, 28 SVGs,
8 manifests, plus .source-revision recording the commit
final/ the SSOT
document.md 729 lines written from the 29 experiment documents, not
concatenated: what was predicted, what was measured, and
where the measurement itself was wrong
evidence/raw 125 outputs, flattened to <experiment>__<file> because
the originals collided (01-baseline.txt appeared three
times) and the audit only globs the top level
evidence/meta one per raw file; command and exitCode are null and the
README says why rather than inventing them
evidence/browser 22 captures
assets/ three diagrams through techviz
.techviz/ their VizSpecs
A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.
Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.
verify-pipeline.py passes. audit-records.py reports no issues.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
521 lines
45 KiB
Plaintext
521 lines
45 KiB
Plaintext
Sub-scope 01 (cache-redis) governance + sdk/config — manifest and negative-space probes
|
|
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
|
|
generatedAt=2026-08-30T03:59:48+00:00
|
|
cwd=/shared/codebase/clean-architecture-backend-template/src
|
|
|
|
=== OWNED FILES ===
|
|
d7d9299d8b8d61386d14f09d8c50da1dad758efa CLAUDE.md 143
|
|
8598f863777600267efdac00e5624d96d6ceec8f README.md 381
|
|
99c8f5bede105ee16ac9312c9aee055c16900076 build.gradle 202
|
|
062d16a37189b5de4bae45f3a05424504efda198 gradle.lockfile 164
|
|
e4b23adfdf4fe19b64c9d29c58bdd4d721fceba1 src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/ConfiguredRedisPermitVerifier.java 94
|
|
08397249ba133ab758419f95af9c52ce9ccd17a9 src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/ConfiguredRedisPolicyAuthority.java 106
|
|
c114b289e2da0b2afd60104af8c50f1561d070b6 src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/GrantedAdvancedOperationPermit.java 24
|
|
d474a8d29be05c0e6e7eb836736ebd3625936012 src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/GrantedMultiKeyPermit.java 21
|
|
c4c3b611267c35a0721413acba22cc773914bc06 src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/GrantedPersistentKeyPermit.java 21
|
|
0bb89c573b6c80d71f0f9122374e7639acd9b57b src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbe.java 176
|
|
5c008151853a73ff417482f803602ba6f6418b61 src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCorrectnessRoles.java 62
|
|
929a59fa7035c717447b72eac36cdeb57c2e0513 src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCredentialResolver.java 125
|
|
5e1ec779b058125188a7e4b86150935f0df37a52 src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisHealthContributor.java 88
|
|
a699afb72b41717d121dcff3778555da2ab18ea1 src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisSdkAutoConfiguration.java 397
|
|
2f577f0c64e7d108b9e7d477ccc61010e3da852b src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisSdkSettings.java 959
|
|
9ac874da2ffd3f901e168aaa3c20e019ae9922bb src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbe.java 142
|
|
47656d4826960bf5b4717d44569527a3ead037cf src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/LiveRedisCompositionTest.java 176
|
|
10a77ad0f8096326079ae25358863840616084b8 src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/LiveRedisTlsTest.java 141
|
|
3a266c797630d7cf8c5e917f759c8edbbf4ba675 src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java 158
|
|
e3ff2763675b302239deee9fbb6cb31d0b526a94 src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisPermitProvenanceTest.java 87
|
|
6e97086762eb93705c72b009d970002dbd882fd8 src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisSdkAutoConfigurationTest.java 447
|
|
6b576bbf04cee7791e7c688c9fb910e39935d24d src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisSdkSettingsTest.java 201
|
|
8bea0f7148c054e816fe876ff4731b3961933a32 src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java 145
|
|
ebb0ed7ab8900c0007582e96351ff8bbfd7bb0ad src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RequiredWhenIsEnforcedTest.java 152
|
|
223a63b5cefb8be4169e068f5f6404e16a7c2a7f src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 1
|
|
1f51d1352a6a3f515b3d1cf4d40aed4f120d42de src/main/resources/redis-sdk/redis-command-policy.yml 1406
|
|
|
|
=== 8.4 README readiness 표 vs 실제 소스 ===
|
|
$ sed -n '23,41p' adapter/outbound/cache-redis/README.md
|
|
| Capability | API 구현 | Spring composition 구현 | 실서버 qualification |
|
|
| --- | --- | --- | --- |
|
|
| Redis SDK typed API (`…cache.redis.sdk`) | 있음 | settings bind + validate 까지만 | 없음 |
|
|
| Topology client / connection lifecycle | 없음 | 없음 | 없음 |
|
|
| cache / session / idempotency / rate limit / lease semantic port | 없음 | 없음 | 없음 |
|
|
| role-aware health·readiness contributor | 없음 | 없음 | 없음 |
|
|
|
|
즉 현재 `APP_REDIS_ENABLED=true`가 하는 일은 `RedisSdkSettings`를 bind하고 cross-field 규칙을
|
|
fail-fast로 검증하는 것까지다. client, connection, gateway, semantic adapter, health contributor는
|
|
아직 조립되지 않는다. 남은 단계와 순서는
|
|
`docs/superpowers/plans/2026-08-10-redis-optionality-and-composition.md`에 있다.
|
|
|
|
readiness registry에도 `selected` card가 없으므로 Redis R2 release claim은 없다. 아래 절들은
|
|
이전 세대 semantic adapter 세트의 설계 결정을 기록한 것이며, 그 코드는 현재 이 leaf에 없다.
|
|
복구 범위는 위 plan의 Phase E가 소유한다.
|
|
|
|
모듈은 Lettuce connection lifecycle,
|
|
finite command timeout, reconnect replay 차단, finite request queue/admission, positive/negative
|
|
TTL, absolute soft/hard expiry, deterministic bounded TTL jitter, digest-protected v2 binary
|
|
exit=0
|
|
|
|
--- 'Topology client / connection lifecycle: 없음' 대조 ---
|
|
$ git ls-files 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/connection' | xargs wc -l
|
|
75 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/connection/RedisConnectionKind.java
|
|
28 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/connection/RedisConnectionLease.java
|
|
142 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/connection/RedisConnectionRegistry.java
|
|
32 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/connection/RedisCredentialRole.java
|
|
44 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/connection/RedisLease.java
|
|
83 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/connection/RedisRuntimeClient.java
|
|
316 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/connection/RedisRuntimeOwner.java
|
|
600 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/connection/RedisTopologyClientFactory.java
|
|
153 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/connection/SentinelFailoverObserver.java
|
|
1473 total
|
|
exit=0
|
|
|
|
--- 'semantic port: 없음' / '그 코드는 현재 이 leaf에 없다' 대조 ---
|
|
$ git ls-files 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/cache' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/lease' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime' 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/keyspace' | xargs wc -l
|
|
213 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/cache/CacheEnvelope.java
|
|
428 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/cache/RedisCacheRegionAdapter.java
|
|
306 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency/IdempotencyScripts.java
|
|
529 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency/RedisIdempotencyStoreAdapter.java
|
|
106 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/keyspace/CapabilityKeyspace.java
|
|
203 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/lease/LeaseScripts.java
|
|
403 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/lease/RedisDistributedLeaseAdapter.java
|
|
49 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit/RateLimitKeys.java
|
|
280 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit/RateLimitScripts.java
|
|
187 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit/RedisEdgeRateLimitAdapter.java
|
|
81 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RealtimeKeys.java
|
|
301 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RedisConnectionRegistryAdapter.java
|
|
133 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RedisEphemeralFanoutAdapter.java
|
|
76 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RegistrationCodec.java
|
|
3295 total
|
|
exit=0
|
|
|
|
--- 'role-aware health contributor: 없음' 대조 ---
|
|
$ git ls-files 'adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config' | grep -i 'health\|role' | xargs wc -l
|
|
62 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCorrectnessRoles.java
|
|
88 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisHealthContributor.java
|
|
150 total
|
|
exit=0
|
|
|
|
=== 8.4b build.gradle의 'Zero imports' 주장 3건 대조 ===
|
|
$ sed -n '6,16p;33,39p' adapter/outbound/cache-redis/build.gradle
|
|
dependencies {
|
|
// Registered edges the semantic port adapters need. The SDK itself imports nothing from them
|
|
// today (0 imports across main source) — the semantic cache/session/idempotency/rate-limit
|
|
// adapters that did were removed and are restored by Phase E of
|
|
// docs/superpowers/plans/2026-08-10-redis-optionality-and-composition.md. They stay declared
|
|
// because that restoration is the module's stated responsibility, not because anything here
|
|
// compiles against them.
|
|
implementation project(':application-core')
|
|
implementation project(':shared-contract')
|
|
implementation project(':adapter:outbound:support')
|
|
|
|
// Deliberately absent:
|
|
// org.springframework.data:spring-data-redis — the SDK owns its own typed API and command
|
|
// policy on purpose; routing through Spring Data would reintroduce the untyped, unguarded
|
|
// command surface the catalog exists to prevent. Zero imports.
|
|
// io.micrometer:micrometer-core — observation leaves this leaf as RedisObservation through a
|
|
// Consumer sink; binding it to a meter registry belongs to the composition root, not here.
|
|
// Zero imports.
|
|
exit=0
|
|
|
|
--- application-core / shared-contract / support import 실측 ---
|
|
$ git grep -c 'import dev.caskeleton.application\.' -- 'adapter/outbound/cache-redis/src/main' | head -20
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/cache/RedisCacheRegionAdapter.java:9
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/idempotency/RedisIdempotencyStoreAdapter.java:18
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/lease/RedisDistributedLeaseAdapter.java:10
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RealtimeKeys.java:2
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RedisConnectionRegistryAdapter.java:5
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RedisEphemeralFanoutAdapter.java:3
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/realtime/RegistrationCodec.java:4
|
|
exit=0
|
|
|
|
$ git grep -l 'import dev.caskeleton.shared\.' -- 'adapter/outbound/cache-redis/src/main' | head -20
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit/RateLimitKeys.java
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit/RateLimitScripts.java
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/ratelimit/RedisEdgeRateLimitAdapter.java
|
|
exit=0
|
|
|
|
$ git grep -l 'import dev.caskeleton.adapter.outbound.support' -- 'adapter/outbound/cache-redis/src/main' | head
|
|
exit=0
|
|
|
|
--- spring-data-redis / micrometer import 실측 ---
|
|
$ git grep -c 'org.springframework.data.redis\|io.micrometer' -- 'adapter/outbound/cache-redis/src/main'
|
|
exit=1
|
|
|
|
=== 8.1 조립: auto-configuration이 실제로 만드는 bean ===
|
|
$ cat adapter/outbound/cache-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
|
|
dev.caskeleton.adapter.outbound.cache.redis.sdk.config.RedisSdkAutoConfiguration
|
|
exit=0
|
|
|
|
$ grep -n '@Bean\|@Conditional\|class \|record ' adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisSdkAutoConfiguration.java
|
|
35: * <p>{@code app.redis.enabled} is the whole switch. While it is false this class contributes
|
|
54:@ConditionalOnProperty(prefix = "app.redis", name = "enabled", havingValue = "true")
|
|
55:// Registers the binding post-processor that populates the @ConfigurationProperties @Bean below.
|
|
59:public class RedisSdkAutoConfiguration {
|
|
83: @Bean
|
|
101: @Bean
|
|
156: @Bean
|
|
226: @Bean
|
|
273: @Bean(destroyMethod = "close")
|
|
297: @Bean(RedisCorrectnessRoles.OPTIONAL_HEALTH_CONTRIBUTOR)
|
|
324: @Bean(RedisCorrectnessRoles.REQUIRED_HEALTH_CONTRIBUTOR)
|
|
325: @Conditional(RedisCorrectnessRoleBound.class)
|
|
344: static final class RedisCorrectnessRoleBound implements Condition {
|
|
364: public record RedisResolvedCredentials(
|
|
391: public record RedisSdkSettingsValidation(List<String> warnings) {
|
|
exit=0
|
|
|
|
=== 8.2 활성화 게이트 ===
|
|
$ grep -rn 'APP_REDIS_ENABLED\|app.cache.redis\|matchIfMissing\|ConditionalOnProperty' adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/*.java | head -30
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisSdkAutoConfiguration.java:18:import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisSdkAutoConfiguration.java:54:@ConditionalOnProperty(prefix = "app.redis", name = "enabled", havingValue = "true")
|
|
exit=0
|
|
|
|
=== 8.3 permit 타입 3종 ===
|
|
$ cat adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/GrantedAdvancedOperationPermit.java adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/GrantedPersistentKeyPermit.java adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/GrantedMultiKeyPermit.java
|
|
package dev.caskeleton.adapter.outbound.cache.redis.sdk.config;
|
|
|
|
import dev.caskeleton.adapter.outbound.cache.redis.sdk.api.command.AdvancedOperationPermit;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* The only advanced permit implementation the verifier accepts.
|
|
*
|
|
* <p>Package private on purpose: application code can implement the public interface, but it cannot
|
|
* construct this type, and the verifier checks the concrete type as well as the signature.
|
|
*
|
|
* @param policyName the approved policy name
|
|
* @param issuerId identity of the issuing authority instance
|
|
* @param signature signature the issuing authority computed over the policy name
|
|
*/
|
|
record GrantedAdvancedOperationPermit(String policyName, String issuerId, String signature)
|
|
implements AdvancedOperationPermit {
|
|
|
|
GrantedAdvancedOperationPermit {
|
|
Objects.requireNonNull(policyName, "policyName must be non-null");
|
|
Objects.requireNonNull(issuerId, "issuerId must be non-null");
|
|
Objects.requireNonNull(signature, "signature must be non-null");
|
|
}
|
|
}
|
|
package dev.caskeleton.adapter.outbound.cache.redis.sdk.config;
|
|
|
|
import dev.caskeleton.adapter.outbound.cache.redis.sdk.api.command.PersistentKeyPermit;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* The only persistent-key permit implementation the verifier accepts.
|
|
*
|
|
* @param policyName the approved policy name
|
|
* @param issuerId identity of the issuing authority instance
|
|
* @param signature signature the issuing authority computed over the policy name
|
|
*/
|
|
record GrantedPersistentKeyPermit(String policyName, String issuerId, String signature)
|
|
implements PersistentKeyPermit {
|
|
|
|
GrantedPersistentKeyPermit {
|
|
Objects.requireNonNull(policyName, "policyName must be non-null");
|
|
Objects.requireNonNull(issuerId, "issuerId must be non-null");
|
|
Objects.requireNonNull(signature, "signature must be non-null");
|
|
}
|
|
}
|
|
package dev.caskeleton.adapter.outbound.cache.redis.sdk.config;
|
|
|
|
import dev.caskeleton.adapter.outbound.cache.redis.sdk.api.command.MultiKeyPermit;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* The only multi-key permit implementation the verifier accepts.
|
|
*
|
|
* @param policyName the approved policy name
|
|
* @param issuerId identity of the issuing authority instance
|
|
* @param signature signature the issuing authority computed over the policy name
|
|
*/
|
|
record GrantedMultiKeyPermit(String policyName, String issuerId, String signature)
|
|
implements MultiKeyPermit {
|
|
|
|
GrantedMultiKeyPermit {
|
|
Objects.requireNonNull(policyName, "policyName must be non-null");
|
|
Objects.requireNonNull(issuerId, "issuerId must be non-null");
|
|
Objects.requireNonNull(signature, "signature must be non-null");
|
|
}
|
|
}
|
|
exit=0
|
|
|
|
=== 8.4c config test 목록 ===
|
|
$ git ls-files 'adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config' | xargs -n1 basename
|
|
LiveRedisCompositionTest.java
|
|
LiveRedisTlsTest.java
|
|
RedisCapabilityProbeTest.java
|
|
RedisPermitProvenanceTest.java
|
|
RedisSdkAutoConfigurationTest.java
|
|
RedisSdkSettingsTest.java
|
|
RedisStartupProbeTest.java
|
|
RequiredWhenIsEnforcedTest.java
|
|
exit=0
|
|
|
|
$ git grep -h ' void [a-z]' -- 'adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config' | sed 's/^ *//' | head -60
|
|
void aWrongPasswordIsRefused() throws Exception {
|
|
void theModeProducesOneMatchingClient() {
|
|
void aLeaseReachesTheServer() throws Exception {
|
|
void theOptionalContributorReportsUp() {
|
|
void closingTheContextTearsEverythingDown() {
|
|
void aFilesystemTrustReferenceWorks() {
|
|
void aClasspathTrustReferenceWorks() throws IOException {
|
|
void unreadableTrustMaterialFailsAtStartup() {
|
|
void plaintextAgainstATlsOnlyServerFails() {
|
|
void redisSevenTwoHasNoHashFieldExpiration() {
|
|
void redisSevenFourGainsHashFieldExpiration() {
|
|
void aNewEnoughVersionWithoutTheCommandIsNotACapability() {
|
|
void anExplicitlyEnabledCapabilityThatIsAbsentFailsStartup() {
|
|
void aServerBelowTheBaselineFailsStartup() {
|
|
void clusterWithANonZeroDatabaseFailsStartup() {
|
|
void refusesAReplicatedDeploymentThatCannotKeepTheWritesItAcknowledges() {
|
|
void acceptsAReplicatedDeploymentWithAWriteGuarantee() {
|
|
void rejectsAReplicaCountWithNoLagBound() {
|
|
void allowsTheLossOnlyWhenTheDeploymentDeclaredIt() {
|
|
void doesNotRequireAWriteGuaranteeFromStandalone() {
|
|
void acceptsAPermitTheAuthorityIssued() {
|
|
void rejectsAPermitTheCallerImplementedItself() {
|
|
void rejectsAPermitIssuedForADifferentPolicy() {
|
|
void rejectsAPermitIssuedByAnotherAuthorityInstance() {
|
|
void refusesToIssueAPolicyConfigurationDidNotEnable() {
|
|
void aPermitCarriesNoAuthorityMaterialInItsPolicyName() {
|
|
void absentSwitchRegistersNothing() {
|
|
void disabledRegistersNothing() {
|
|
void disabledIgnoresMalformedRedisConfiguration() {
|
|
void disabledNeverAsksForASecretOrAConnection() {
|
|
void enabledResolvesEachConfiguredRoleOnce() {
|
|
void enabledBindsSettings() {
|
|
void enabledRejectsClusterWithANonZeroDatabase() {
|
|
void enabledRejectsAnUnboundedBlock() {
|
|
void enabledRejectsARawGatewayWithoutAnAllowlist() {
|
|
void enabledRejectsAMissingRawAllowlistResource() {
|
|
void enabledAcceptsAReadableRawAllowlistResource() {
|
|
void standaloneWithSeveralNodesIsRefused() {
|
|
void sentinelWithoutAMasterNameIsRefused() {
|
|
void enabledWithoutAnApplicationCredentialIsRefused() {
|
|
void anonymousAccessCanBeDeclared() {
|
|
void configuredAccountsAreResolvedPerRole() {
|
|
void anUnresolvableCredentialReferenceFailsAtStartup() {
|
|
void aLiteralCredentialIsRefused() {
|
|
void clusterBuildsAClusterClient() {
|
|
void theRuntimeOwnerFollowsTheContext() {
|
|
void enabledRejectsAnAdminPlaneWithoutItsOwnCredential() {
|
|
void clusterRejectsDatabaseOtherThanZero() {
|
|
void standaloneAcceptsANonZeroDatabase() {
|
|
void namespaceTokensAreValidatedAtStartup() {
|
|
void aFastTimeoutAboveTheGuardrailWarnsAndFarAboveItFails() {
|
|
void blockingMustNeverBeUnbounded() {
|
|
void theRawGatewayRequiresAnAllowlistAndItsOwnCredential() {
|
|
void theAdminPlaneRequiresItsOwnCredential() {
|
|
void aClientCertificateWithoutItsKeyIsRefusedAtStartup() {
|
|
void oneWayTlsNeedsNoClientCertificateAndNoTrustMaterial() {
|
|
void advancedPoliciesCannotBeConfiguredWhileAdvancedOperationsAreDisabled() {
|
|
void defaultsMatchTheDesignGuardrails() {
|
|
void authenticationIsRequiredUnlessAnonymousIsDeclared() {
|
|
void aSingleAccountDeploymentIsToldThatScriptingRunsAsTheApplicationAccount() {
|
|
exit=0
|
|
|
|
|
|
=== 8.1d reachability: startup probe / capability probe / permit authority ===
|
|
$ git grep -n 'RedisStartupProbe\|RedisCapabilityProbe' -- . | grep -v 'sdk/config/RedisStartupProbe.java' | grep -v 'sdk/config/RedisCapabilityProbe.java'
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisSdkSettings.java:888: * signal exists for it; see {@link RedisCapabilityProbe#requireWriteDurability}.
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java:17:class RedisCapabilityProbeTest {
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java:19: private final RedisCapabilityProbe probe = new RedisCapabilityProbe();
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java:28: RedisCapabilityProbeTest::everyCommand,
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java:42: RedisCapabilityProbeTest::everyCommand,
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java:86: RedisCapabilityProbeTest::everyCommand,
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java:100: RedisCapabilityProbeTest::everyCommand,
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:16:class RedisStartupProbeTest {
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:18: private final RedisStartupProbe probe = new RedisStartupProbe(new RedisCapabilityProbe());
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:53: RedisStartupProbe.ServerFacts.from(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:71: RedisStartupProbe.ServerFacts.from(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:85: RedisStartupProbe.ServerFacts.from(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:99: RedisStartupProbe.ServerFacts.from(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:113: RedisStartupProbe.ServerFacts.from(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:124: RedisStartupProbe.ServerFacts.from(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:139: RedisStartupProbe.ServerFacts.from(
|
|
exit=0
|
|
|
|
$ git grep -n 'ConfiguredRedisPolicyAuthority\|ConfiguredRedisPermitVerifier' -- . | grep -v 'sdk/config/ConfiguredRedis'
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisPermitProvenanceTest.java:17: private final ConfiguredRedisPolicyAuthority authority =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisPermitProvenanceTest.java:18: new ConfiguredRedisPolicyAuthority(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisPermitProvenanceTest.java:21: private final ConfiguredRedisPermitVerifier verifier =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisPermitProvenanceTest.java:22: new ConfiguredRedisPermitVerifier(authority, RedisDeploymentMode.STANDALONE);
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisPermitProvenanceTest.java:64: ConfiguredRedisPolicyAuthority other =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisPermitProvenanceTest.java:65: new ConfiguredRedisPolicyAuthority(List.of("collection-full-read"));
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/command/CommandPolicyGuardTest.java:23:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPermitVerifier;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/command/CommandPolicyGuardTest.java:24:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPolicyAuthority;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/command/CommandPolicyGuardTest.java:39: private final ConfiguredRedisPolicyAuthority authority =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/command/CommandPolicyGuardTest.java:40: new ConfiguredRedisPolicyAuthority(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/command/CommandPolicyGuardTest.java:266: new ConfiguredRedisPermitVerifier(authority, mode),
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/command/ObservationIsolationTest.java:18:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPermitVerifier;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/command/ObservationIsolationTest.java:19:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPolicyAuthority;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/command/ObservationIsolationTest.java:43: private final ConfiguredRedisPolicyAuthority authority =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/command/ObservationIsolationTest.java:44: new ConfiguredRedisPolicyAuthority(List.of());
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/command/ObservationIsolationTest.java:49: new ConfiguredRedisPermitVerifier(authority, RedisDeploymentMode.STANDALONE),
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/LiveRedisOperationsFixture.java:12:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPermitVerifier;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/LiveRedisOperationsFixture.java:13:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPolicyAuthority;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/LiveRedisOperationsFixture.java:67: final ConfiguredRedisPolicyAuthority authority =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/LiveRedisOperationsFixture.java:68: new ConfiguredRedisPolicyAuthority(ENABLED_POLICIES);
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/LiveRedisOperationsFixture.java:123: ConfiguredRedisPermitVerifier verifier =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/LiveRedisOperationsFixture.java:124: new ConfiguredRedisPermitVerifier(authority, endpoint.mode());
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisOperationsFixture.java:12:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPermitVerifier;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisOperationsFixture.java:13:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPolicyAuthority;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisOperationsFixture.java:67: final ConfiguredRedisPolicyAuthority authority =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisOperationsFixture.java:68: new ConfiguredRedisPolicyAuthority(ENABLED_POLICIES);
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisOperationsFixture.java:149: ConfiguredRedisPermitVerifier verifier =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisOperationsFixture.java:150: new ConfiguredRedisPermitVerifier(authority, RedisDeploymentMode.STANDALONE);
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisTransactionContractTest.java:17:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPermitVerifier;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisTransactionContractTest.java:18:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPolicyAuthority;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisTransactionContractTest.java:58: private final ConfiguredRedisPolicyAuthority authority =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisTransactionContractTest.java:59: new ConfiguredRedisPolicyAuthority(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisTransactionContractTest.java:84: ConfiguredRedisPermitVerifier verifier =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisTransactionContractTest.java:85: new ConfiguredRedisPermitVerifier(authority, RedisDeploymentMode.STANDALONE);
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisTransactionSlotContractTest.java:18:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPermitVerifier;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisTransactionSlotContractTest.java:19:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPolicyAuthority;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisTransactionSlotContractTest.java:63: private final ConfiguredRedisPolicyAuthority authority =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisTransactionSlotContractTest.java:64: new ConfiguredRedisPolicyAuthority(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisTransactionSlotContractTest.java:78: ConfiguredRedisPermitVerifier verifier =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/lettuce/operations/RedisTransactionSlotContractTest.java:79: new ConfiguredRedisPermitVerifier(authority, RedisDeploymentMode.CLUSTER);
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/programmability/LiveRedisClusterTransactionTest.java:20:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPermitVerifier;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/programmability/LiveRedisClusterTransactionTest.java:21:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.ConfiguredRedisPolicyAuthority;
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/programmability/LiveRedisClusterTransactionTest.java:110: ConfiguredRedisPolicyAuthority authority =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/programmability/LiveRedisClusterTransactionTest.java:111: new ConfiguredRedisPolicyAuthority(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/programmability/LiveRedisClusterTransactionTest.java:116: ConfiguredRedisPermitVerifier verifier =
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/programmability/LiveRedisClusterTransactionTest.java:117: new ConfiguredRedisPermitVerifier(authority, endpoint.mode());
|
|
exit=0
|
|
|
|
$ git grep -n 'requireWriteDurability\|\.confirm(' -- 'adapter/outbound/cache-redis/src'
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbe.java:133: public void requireWriteDurability(
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisSdkSettings.java:888: * signal exists for it; see {@link RedisCapabilityProbe#requireWriteDurability}.
|
|
adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbe.java:61: probe.requireWriteDurability(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java:113: assertThatThrownBy(() -> probe.requireWriteDurability(mode, 0, 10, false))
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java:122: probe.requireWriteDurability(RedisDeploymentMode.SENTINEL, 1, 10, false);
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java:123: probe.requireWriteDurability(RedisDeploymentMode.CLUSTER, 2, 5, false);
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java:133: assertThatThrownBy(() -> probe.requireWriteDurability(mode, 2, 0, false))
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java:142: probe.requireWriteDurability(RedisDeploymentMode.SENTINEL, 0, 0, true);
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisCapabilityProbeTest.java:148: probe.requireWriteDurability(RedisDeploymentMode.STANDALONE, 0, 0, false);
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:51: probe.confirm(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:69: probe.confirm(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:83: probe.confirm(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:97: probe.confirm(
|
|
adapter/outbound/cache-redis/src/test/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisStartupProbeTest.java:137: probe.confirm(
|
|
exit=0
|
|
|
|
=== 8.1e app-bootstrap가 RedisCorrectnessRoles를 실제로 읽는가 ===
|
|
$ git grep -rn 'RedisCorrectnessRoles\|redisRequired\|redisOptional' -- app-bootstrap | head -20
|
|
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessor.java:3:import dev.caskeleton.adapter.outbound.cache.redis.sdk.config.RedisCorrectnessRoles;
|
|
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessor.java:20: * contributor 'redisRequired' in group 'readiness' does not exist}. So a static {@code
|
|
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessor.java:21: * readiness.include} listing {@code redisRequired} is not "tolerated when Redis is off" — it is a
|
|
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessor.java:30: * <p>Hence this post-processor. It reads {@link RedisCorrectnessRoles} — the identical predicate
|
|
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessor.java:45: if (!redisEnabled(environment) || !RedisCorrectnessRoles.anySelected(environment)) {
|
|
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessor.java:54: if (!members.add(RedisCorrectnessRoles.REQUIRED_HEALTH_CONTRIBUTOR)) {
|
|
app-bootstrap/src/main/resources/application.yml:272: # unconditional contributors, and the one conditional member — `redisRequired` — is appended
|
|
app-bootstrap/src/main/resources/application.yml:292: # `redisRequired` is NOT listed here, and must not be: group membership does not tolerate a
|
|
app-bootstrap/src/main/resources/application.yml:295: # startup with "Included health contributor 'redisRequired' in group 'readiness' does not
|
|
app-bootstrap/src/main/resources/application.yml:298: # `redisOptional` is never appended: a cache outage is reported as degraded detail and never
|
|
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessorTest.java:107: assertThat(readiness.isMember("redisRequired"))
|
|
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessorTest.java:110: assertThat(context.getBeansOfType(HealthIndicator.class)).doesNotContainKey("redisRequired");
|
|
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessorTest.java:123: .containsKey("redisOptional")
|
|
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessorTest.java:124: .doesNotContainKey("redisRequired");
|
|
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessorTest.java:125: assertThat(readiness.isMember("redisRequired")).isFalse();
|
|
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessorTest.java:126: assertThat(readiness.isMember("redisOptional"))
|
|
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessorTest.java:139: assertThat(context.getBeansOfType(HealthIndicator.class)).containsKey("redisRequired");
|
|
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessorTest.java:140: assertThat(readiness.isMember("redisRequired"))
|
|
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/runtime/RedisReadinessGroupPostProcessorTest.java:166: .isMember("redisRequired"))
|
|
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/runtime/RuntimeHealthLifecycleContractTest.java:98: // The shipped file names only contributors that always exist. Both `redisRequired` and `db` are
|
|
exit=0
|
|
|
|
=== 8.2b RedisSdkSettings.validate 규칙 목록 ===
|
|
$ grep -n 'private void require\|violations.add\|warnings.add\|throw new IllegalStateException' adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisSdkSettings.java | head -60
|
|
61: throw new IllegalStateException("Cluster supports database 0 only");
|
|
64: throw new IllegalStateException("database index must not be negative");
|
|
67: throw new IllegalStateException("at least one Redis node must be configured");
|
|
77: throw new IllegalStateException("blocking commands must not be unbounded");
|
|
80: throw new IllegalStateException("dedicated connection lanes need a positive ceiling");
|
|
84: throw new IllegalStateException(
|
|
95: throw new IllegalStateException(
|
|
101: warnings.add(
|
|
110: throw new IllegalStateException("the raw gateway requires an allowlist resource");
|
|
114: throw new IllegalStateException(
|
|
120: throw new IllegalStateException(
|
|
125: throw new IllegalStateException(
|
|
138: throw new IllegalStateException(name + " timeout must be positive");
|
|
141: throw new IllegalStateException(
|
|
145: warnings.add(
|
|
255: throw new IllegalStateException(
|
|
268: throw new IllegalStateException("every Redis SDK limit must be positive");
|
|
409: throw new IllegalStateException(
|
|
418: warnings.add(
|
|
426: warnings.add(
|
|
570: throw new IllegalStateException("the client name must not be blank");
|
|
578: throw new IllegalStateException("the shutdown quiet period must not be negative");
|
|
581: throw new IllegalStateException(
|
|
589: throw new IllegalStateException(name + " timeout must be positive");
|
|
658: throw new IllegalStateException("cluster maximum redirects must be positive");
|
|
663: throw new IllegalStateException("the cluster topology refresh period must be positive");
|
|
694: throw new IllegalStateException("every Redis capacity ceiling must be positive");
|
|
748: throw new IllegalStateException("the pub/sub buffer capacity must be positive");
|
|
751: throw new IllegalStateException(
|
|
exit=0
|
|
|
|
$ grep -n 'public List<String> validate' -A 40 adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisSdkSettings.java | head -60
|
|
58: public List<String> validate() {
|
|
59- List<String> warnings = new ArrayList<>();
|
|
60- if (mode == RedisDeploymentMode.CLUSTER && database != 0) {
|
|
61- throw new IllegalStateException("Cluster supports database 0 only");
|
|
62- }
|
|
63- if (database < 0) {
|
|
64- throw new IllegalStateException("database index must not be negative");
|
|
65- }
|
|
66- if (nodes == null || nodes.isEmpty()) {
|
|
67- throw new IllegalStateException("at least one Redis node must be configured");
|
|
68- }
|
|
69- namespace.validate();
|
|
70- limits.validate();
|
|
71- validateTimeout("fast", timeout.getFast(), warnings);
|
|
72- validateTimeout("collection", timeout.getCollection(), warnings);
|
|
73- validateTimeout("script", timeout.getScript(), warnings);
|
|
74- validateTimeout("batch", timeout.getBatch(), warnings);
|
|
75- validateTimeout("admin", timeout.getAdmin(), warnings);
|
|
76- if (blocking.getMaxBlock().isZero() || blocking.getMaxBlock().isNegative()) {
|
|
77- throw new IllegalStateException("blocking commands must not be unbounded");
|
|
78- }
|
|
79- if (blocking.getMaxConnections() < 1 || transaction.getMaxConnections() < 1) {
|
|
80- throw new IllegalStateException("dedicated connection lanes need a positive ceiling");
|
|
81- }
|
|
82- if (mode == RedisDeploymentMode.SENTINEL
|
|
83- && (sentinel.getMasterName() == null || sentinel.getMasterName().isBlank())) {
|
|
84- throw new IllegalStateException(
|
|
85- "app.redis.sentinel.master-name is required when app.redis.mode=sentinel: a Sentinel"
|
|
86- + " deployment must name the monitored primary; without it the client cannot resolve"
|
|
87- + " a primary at all, let alone follow a promotion");
|
|
88- }
|
|
89- // A certificate without its key cannot build a key manager. Refused here rather than at the
|
|
90- // first connection, where it surfaced as a NullPointerException from inside the SSL options.
|
|
91- if (tls.isEnabled()
|
|
92- && tls.getClientCertificateResource() != null
|
|
93- && !tls.getClientCertificateResource().isBlank()
|
|
94- && (tls.getClientKeyReference() == null || tls.getClientKeyReference().isBlank())) {
|
|
95- throw new IllegalStateException(
|
|
96- "app.redis.tls.client-key-reference is required when"
|
|
97- + " app.redis.tls.client-certificate-resource is configured: mutual TLS presents a"
|
|
98- + " certificate, and a certificate without its private key cannot be presented");
|
|
exit=0
|
|
|
|
=== 8.3b raw allowlist 기본 리소스가 실재하는가 ===
|
|
$ grep -n 'raw-command-allowlist\|policyResource' adapter/outbound/cache-redis/src/main/java/dev/caskeleton/adapter/outbound/cache/redis/sdk/config/RedisSdkSettings.java | head
|
|
800: private String policyResource = "classpath:redis-sdk/raw-command-allowlist.yml";
|
|
812: return policyResource;
|
|
815: public void setPolicyResource(String policyResource) {
|
|
816: this.policyResource = policyResource;
|
|
exit=0
|
|
|
|
$ git ls-files | grep -i 'raw-command-allowlist' | head
|
|
exit=0
|
|
|
|
$ git ls-files 'adapter/outbound/cache-redis/src/main/resources'
|
|
adapter/outbound/cache-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
|
|
adapter/outbound/cache-redis/src/main/resources/redis-sdk/redis-command-policy.yml
|
|
exit=0
|
|
|