{ "assetKey": "a11-f002-pool-route-exceeds-total-shape", "kind": "terminal", "command": "set -e\nD=$(mktemp -d); trap 'rm -rf \"$D\"' EXIT\nH=/shared/codebase/clean-architecture-backend-template/src/adapter/outbound/httpclient\nJAR=$H/build/libs/httpclient-0.0.1+21234e38cdb9.jar\njava -version 2>&1 | head -1\njavac -encoding UTF-8 -cp \"$JAR\" -d \"$D\" \\\n \"$H/src/testkit/java/dev/caskeleton/adapter/outbound/httpclient/testkit/ClientProfiles.java\"\ncat > \"$D/PoolViolationProbe.java\" <<'JAVA'\nimport dev.caskeleton.adapter.outbound.httpclient.profile.ClientProfile;\nimport dev.caskeleton.adapter.outbound.httpclient.profile.ClientProfileValidator;\nimport dev.caskeleton.adapter.outbound.httpclient.profile.ClientProfileViolation;\nimport dev.caskeleton.adapter.outbound.httpclient.profile.HttpProtocol;\nimport dev.caskeleton.adapter.outbound.httpclient.profile.PoolSettings;\nimport dev.caskeleton.adapter.outbound.httpclient.profile.RuntimeEnvironment;\nimport dev.caskeleton.adapter.outbound.httpclient.profile.TransportType;\nimport dev.caskeleton.adapter.outbound.httpclient.testkit.ClientProfiles;\nimport java.time.Duration;\nimport java.util.List;\n\npublic final class PoolViolationProbe {\n\n private static PoolSettings routePool(int total, int perRoute) {\n return new PoolSettings(\n total, perRoute, 16,\n Duration.ofSeconds(2), Duration.ofSeconds(30), Duration.ofMinutes(5),\n Duration.ofSeconds(5), Duration.ofSeconds(15), Duration.ofSeconds(5),\n true, false);\n }\n\n private static PoolSettings pool(int total, int perRoute) {\n return new PoolSettings(\n total,\n perRoute,\n 16,\n Duration.ofSeconds(2),\n Duration.ofSeconds(30),\n Duration.ofMinutes(5),\n Duration.ofSeconds(5),\n Duration.ofSeconds(15),\n Duration.ofSeconds(5),\n false,\n false);\n }\n\n private static void report(String label, ClientProfile profile) {\n List found =\n new ClientProfileValidator().validate(profile, RuntimeEnvironment.PRODUCTION);\n System.out.println(\" \" + label);\n if (found.isEmpty()) {\n System.out.println(\" 위반 없음\");\n return;\n }\n for (ClientProfileViolation violation : found) {\n System.out.println(\" \" + violation);\n }\n }\n\n public static void main(String[] args) {\n System.out.println(\"[검증기가 내는 형태] 프로덕션 판정, 정렬된 위반 목록\");\n report(\"전체 20 / 경로당 5\", ClientProfiles.builder(\"payment\").pool(pool(20, 5)).build());\n report(\"전체 20 / 경로당 20 (같음)\", ClientProfiles.builder(\"payment\").pool(pool(20, 20)).build());\n report(\n \"전송만 SIMPLE 로 바꾼 프로파일\",\n ClientProfiles.builder(\"payment\").transport(TransportType.SIMPLE).build());\n report(\n \"전송 JDK + 경로 풀 요구 + HTTP/3 미승인\",\n ClientProfiles.builder(\"payment\")\n .transport(TransportType.JDK)\n .pool(routePool(20, 5))\n .protocols(java.util.Set.of(HttpProtocol.HTTP_1_1, HttpProtocol.HTTP_3))\n .build());\n System.out.println();\n\n System.out.println(\"[POOL_ROUTE_EXCEEDS_TOTAL 조건을 만들려면]\");\n try {\n PoolSettings unusable = pool(10, 20);\n System.out.println(\" 전체 10 / 경로당 20 -> 만들어짐 \" + unusable.maxConnectionsPerRoute());\n } catch (IllegalArgumentException rejected) {\n System.out.println(\n \" 전체 10 / 경로당 20 -> \" + rejected.getClass().getSimpleName() + \": \" + rejected.getMessage());\n }\n System.out.println(\" 프로파일은 이미 만들어진 PoolSettings 를 들고 있으므로,\");\n System.out.println(\" 검증기에 넘길 프로파일 자체를 만들 수 없다.\");\n System.out.println();\n\n System.out.println(\"[DUPLICATE_CLIENT_NAME 조건을 만들려면]\");\n ClientProfile one = ClientProfiles.builder(\"payment\").build();\n java.util.Map\n profiles = new java.util.HashMap<>();\n profiles.put(one.name(), one);\n profiles.put(one.name(), ClientProfiles.builder(\"payment\").build());\n System.out.println(\" 같은 이름을 두 번 넣은 맵의 크기 : \" + profiles.size());\n System.out.println(\" 검증기가 이름 중복을 세는 자리는 이 맵을 순회한다.\");\n }\n}\nJAVA\njavac -encoding UTF-8 -cp \"$JAR:$D\" -d \"$D\" \"$D/PoolViolationProbe.java\"\njava -Dstdout.encoding=UTF-8 -cp \"$JAR:$D\" PoolViolationProbe\n", "cwd": "/shared/codebase/clean-architecture-backend-template", "exitCode": 0, "executedAt": "2026-09-02T13:26:24+00:00", "sourceRevision": "21234e38cdb9a926cbc92bb97a2aee2e4a7d2916", "raw": "evidence/raw/a11-f002-pool-route-exceeds-total-shape.txt", "svg": "evidence/rendered/a11-f002-pool-route-exceeds-total-shape.svg", "rawSha256": "82912731dfe4a778b1cea2559a5c6fd712a2ac943815a024d00c7716f0034296", "lines": 20, "redaction": "none — 밀폐 탐침 실행 출력, 자격증명 없음" }