spring-runtime-mcp 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. spring_runtime_mcp/__init__.py +3 -0
  2. spring_runtime_mcp/adapters/__init__.py +1 -0
  3. spring_runtime_mcp/adapters/beans.py +159 -0
  4. spring_runtime_mcp/adapters/conditions.py +333 -0
  5. spring_runtime_mcp/adapters/config.py +295 -0
  6. spring_runtime_mcp/adapters/drift.py +790 -0
  7. spring_runtime_mcp/adapters/health.py +164 -0
  8. spring_runtime_mcp/adapters/mapping_predicates.py +201 -0
  9. spring_runtime_mcp/adapters/mappings.py +294 -0
  10. spring_runtime_mcp/adapters/migrations.py +373 -0
  11. spring_runtime_mcp/adapters/openapi.py +683 -0
  12. spring_runtime_mcp/adapters/source_catalog.py +119 -0
  13. spring_runtime_mcp/adapters/startup.py +202 -0
  14. spring_runtime_mcp/analyzers/__init__.py +1 -0
  15. spring_runtime_mcp/analyzers/bean_graph.py +172 -0
  16. spring_runtime_mcp/analyzers/condition_failures.py +359 -0
  17. spring_runtime_mcp/cli.py +248 -0
  18. spring_runtime_mcp/contracts/__init__.py +1 -0
  19. spring_runtime_mcp/contracts/definitions.py +425 -0
  20. spring_runtime_mcp/diagnostics.py +254 -0
  21. spring_runtime_mcp/models/__init__.py +1 -0
  22. spring_runtime_mcp/models/bean_graph.py +77 -0
  23. spring_runtime_mcp/models/common.py +99 -0
  24. spring_runtime_mcp/models/conditions.py +56 -0
  25. spring_runtime_mcp/models/queries.py +140 -0
  26. spring_runtime_mcp/models/source_catalog.py +35 -0
  27. spring_runtime_mcp/models/timestamps.py +71 -0
  28. spring_runtime_mcp/policy/__init__.py +1 -0
  29. spring_runtime_mcp/policy/configuration.py +32 -0
  30. spring_runtime_mcp/policy/output_guard.py +117 -0
  31. spring_runtime_mcp/policy/sanitization.py +616 -0
  32. spring_runtime_mcp/py.typed +0 -0
  33. spring_runtime_mcp/replay.py +220 -0
  34. spring_runtime_mcp/replay_data/bean_graph/README.md +26 -0
  35. spring_runtime_mcp/replay_data/bean_graph/factory-method/conditions.json +43 -0
  36. spring_runtime_mcp/replay_data/bean_graph/factory-method/source-catalog.json +54 -0
  37. spring_runtime_mcp/replay_data/bean_graph/nested-conditions/beans.json +99 -0
  38. spring_runtime_mcp/replay_data/bean_graph/nested-conditions/conditions.json +25 -0
  39. spring_runtime_mcp/replay_data/bean_graph/parent-child/beans.json +92 -0
  40. spring_runtime_mcp/replay_data/bean_graph/shape-metadata.json +32 -0
  41. spring_runtime_mcp/replay_data/bean_graph/stripe-missing/conditions.json +43 -0
  42. spring_runtime_mcp/replay_data/bean_graph/stripe-missing/source-catalog.json +54 -0
  43. spring_runtime_mcp/replay_data/conformance/README.md +41 -0
  44. spring_runtime_mcp/replay_data/conformance/boot-2.7-servlet/beans.json +92 -0
  45. spring_runtime_mcp/replay_data/conformance/boot-2.7-servlet/conditions.json +52 -0
  46. spring_runtime_mcp/replay_data/conformance/boot-2.7-servlet/configprops.json +20 -0
  47. spring_runtime_mcp/replay_data/conformance/boot-2.7-servlet/env.json +16 -0
  48. spring_runtime_mcp/replay_data/conformance/boot-2.7-servlet/flyway.json +40 -0
  49. spring_runtime_mcp/replay_data/conformance/boot-2.7-servlet/health-v2.json +14 -0
  50. spring_runtime_mcp/replay_data/conformance/boot-2.7-servlet/health-v3.json +38 -0
  51. spring_runtime_mcp/replay_data/conformance/boot-2.7-servlet/liquibase.json +30 -0
  52. spring_runtime_mcp/replay_data/conformance/boot-2.7-servlet/mappings.json +40 -0
  53. spring_runtime_mcp/replay_data/conformance/boot-2.7-servlet/openapi.json +54 -0
  54. spring_runtime_mcp/replay_data/conformance/boot-2.7-servlet/source-catalog.json +90 -0
  55. spring_runtime_mcp/replay_data/conformance/boot-2.7-servlet/startup.json +45 -0
  56. spring_runtime_mcp/replay_data/conformance/boot-3.4-servlet/beans.json +92 -0
  57. spring_runtime_mcp/replay_data/conformance/boot-3.4-servlet/conditions.json +52 -0
  58. spring_runtime_mcp/replay_data/conformance/boot-3.4-servlet/configprops.json +20 -0
  59. spring_runtime_mcp/replay_data/conformance/boot-3.4-servlet/env.json +16 -0
  60. spring_runtime_mcp/replay_data/conformance/boot-3.4-servlet/flyway.json +40 -0
  61. spring_runtime_mcp/replay_data/conformance/boot-3.4-servlet/health-v3.json +38 -0
  62. spring_runtime_mcp/replay_data/conformance/boot-3.4-servlet/liquibase.json +30 -0
  63. spring_runtime_mcp/replay_data/conformance/boot-3.4-servlet/mappings.json +40 -0
  64. spring_runtime_mcp/replay_data/conformance/boot-3.4-servlet/openapi.json +54 -0
  65. spring_runtime_mcp/replay_data/conformance/boot-3.4-servlet/source-catalog.json +90 -0
  66. spring_runtime_mcp/replay_data/conformance/boot-3.4-servlet/startup.json +45 -0
  67. spring_runtime_mcp/replay_data/conformance/boot-4.1-webflux/beans.json +92 -0
  68. spring_runtime_mcp/replay_data/conformance/boot-4.1-webflux/conditions.json +52 -0
  69. spring_runtime_mcp/replay_data/conformance/boot-4.1-webflux/configprops.json +20 -0
  70. spring_runtime_mcp/replay_data/conformance/boot-4.1-webflux/env.json +16 -0
  71. spring_runtime_mcp/replay_data/conformance/boot-4.1-webflux/flyway.json +40 -0
  72. spring_runtime_mcp/replay_data/conformance/boot-4.1-webflux/health-v3.json +38 -0
  73. spring_runtime_mcp/replay_data/conformance/boot-4.1-webflux/liquibase.json +30 -0
  74. spring_runtime_mcp/replay_data/conformance/boot-4.1-webflux/mappings.json +40 -0
  75. spring_runtime_mcp/replay_data/conformance/boot-4.1-webflux/openapi.json +54 -0
  76. spring_runtime_mcp/replay_data/conformance/boot-4.1-webflux/servlet-namespace-comparison.json +4 -0
  77. spring_runtime_mcp/replay_data/conformance/boot-4.1-webflux/source-catalog.json +90 -0
  78. spring_runtime_mcp/replay_data/conformance/boot-4.1-webflux/startup.json +45 -0
  79. spring_runtime_mcp/replay_data/conformance/contracts/springboot_analyze_startup.json +62 -0
  80. spring_runtime_mcp/replay_data/conformance/contracts/springboot_check_migrations.json +63 -0
  81. spring_runtime_mcp/replay_data/conformance/contracts/springboot_detect_drift.json +64 -0
  82. spring_runtime_mcp/replay_data/conformance/contracts/springboot_diagnose_health.json +59 -0
  83. spring_runtime_mcp/replay_data/conformance/contracts/springboot_inspect_beans.json +56 -0
  84. spring_runtime_mcp/replay_data/conformance/contracts/springboot_inspect_config.json +62 -0
  85. spring_runtime_mcp/replay_data/conformance/contracts/springboot_search_openapi.json +80 -0
  86. spring_runtime_mcp/replay_data/conformance/contracts/springboot_verify_mappings.json +58 -0
  87. spring_runtime_mcp/replay_data/conformance/faults/cases.json +63 -0
  88. spring_runtime_mcp/replay_data/conformance/faults/health-hidden.expected.json +54 -0
  89. spring_runtime_mcp/replay_data/conformance/faults/health-hidden.json +3 -0
  90. spring_runtime_mcp/replay_data/conformance/large/beans-2500.json +22506 -0
  91. spring_runtime_mcp/replay_data/conformance/manifest.json +46 -0
  92. spring_runtime_mcp/schemas/tools-contract.json +1902 -0
  93. spring_runtime_mcp/server.py +322 -0
  94. spring_runtime_mcp/services.py +44 -0
  95. spring_runtime_mcp/snapshots.py +340 -0
  96. spring_runtime_mcp/tools/__init__.py +1 -0
  97. spring_runtime_mcp/tools/analyze_startup.py +79 -0
  98. spring_runtime_mcp/tools/check_migrations.py +99 -0
  99. spring_runtime_mcp/tools/detect_drift.py +323 -0
  100. spring_runtime_mcp/tools/diagnose_health.py +88 -0
  101. spring_runtime_mcp/tools/inspect_beans.py +479 -0
  102. spring_runtime_mcp/tools/inspect_config.py +102 -0
  103. spring_runtime_mcp/tools/registry.py +48 -0
  104. spring_runtime_mcp/tools/search_openapi.py +79 -0
  105. spring_runtime_mcp/tools/support.py +166 -0
  106. spring_runtime_mcp/tools/verify_mappings.py +62 -0
  107. spring_runtime_mcp/transport/__init__.py +1 -0
  108. spring_runtime_mcp/transport/actuator_http.py +459 -0
  109. spring_runtime_mcp/transport/bounded_json.py +144 -0
  110. spring_runtime_mcp/transport/replay_files.py +71 -0
  111. spring_runtime_mcp/transport/response_gate.py +186 -0
  112. spring_runtime_mcp/transport/responses.py +82 -0
  113. spring_runtime_mcp/transport/stdio.py +44 -0
  114. spring_runtime_mcp-0.2.0.dist-info/METADATA +320 -0
  115. spring_runtime_mcp-0.2.0.dist-info/RECORD +118 -0
  116. spring_runtime_mcp-0.2.0.dist-info/WHEEL +4 -0
  117. spring_runtime_mcp-0.2.0.dist-info/entry_points.txt +2 -0
  118. spring_runtime_mcp-0.2.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,220 @@
1
+ """Fixed offline replay using the actual tool handlers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import asyncio
7
+ import os
8
+ from importlib.resources import files
9
+ from pathlib import Path
10
+ from typing import Any, NoReturn
11
+
12
+ from .adapters.source_catalog import load_source_catalog
13
+ from .models.common import AnalysisBudget, NormalizationError, ParsedObservation
14
+ from .models.source_catalog import SourceCatalog
15
+ from .policy.sanitization import SanitizerPipeline
16
+ from .policy.configuration import ConfigReadPolicy
17
+ from .snapshots import SnapshotStore
18
+ from .services import Services
19
+ from .diagnostics import failed
20
+ from .transport.bounded_json import loads_bounded
21
+ from .transport.replay_files import read_replay_file
22
+ from .transport.responses import serialize_response
23
+ from .transport.stdio import quiet_console, seal_console
24
+
25
+ _RESOURCE_ROOT = files("spring_runtime_mcp").joinpath("replay_data")
26
+ # Normal wheel installs expose filesystem resources. Keep the descriptor-based
27
+ # no-symlink reader; unsupported archive importers fail closed rather than using
28
+ # an unbounded resource read or falling back to repository fixtures.
29
+ if not isinstance(_RESOURCE_ROOT, Path):
30
+ raise NormalizationError("FIXTURE_PATH_DENIED")
31
+ REPLAY_ROOT = _RESOURCE_ROOT / "bean_graph"
32
+ CONFORMANCE_ROOT = REPLAY_ROOT.parent / "conformance"
33
+ PROFILES = ("boot-2.7-servlet", "boot-3.4-servlet", "boot-4.1-webflux")
34
+ _PROFILE_FILES = {
35
+ "beans": "beans.json",
36
+ "conditions": "conditions.json",
37
+ "mappings": "mappings.json",
38
+ "flyway": "flyway.json",
39
+ "liquibase": "liquibase.json",
40
+ "startup": "startup.json",
41
+ "openapi": "openapi.json",
42
+ "env": "env.json",
43
+ "configprops": "configprops.json",
44
+ }
45
+
46
+
47
+ class FixtureReader:
48
+ def __init__(self, bodies: dict[str, dict[str, Any]]) -> None:
49
+ self.bodies = bodies
50
+ self.calls: list[str] = []
51
+
52
+ async def read(
53
+ self, target_id: str, endpoint_id: str, *, snapshot_id: str
54
+ ) -> ParsedObservation:
55
+ if target_id != "local" or endpoint_id not in self.bodies:
56
+ raise NormalizationError("CAPABILITY_DISABLED")
57
+ self.calls.append(endpoint_id)
58
+ body = self.bodies.get(endpoint_id)
59
+ if body is None:
60
+ raise NormalizationError("CAPABILITY_DISABLED")
61
+ return ParsedObservation(
62
+ target_id,
63
+ snapshot_id,
64
+ "observation_" + endpoint_id,
65
+ "2026-10-16T00:00:00Z",
66
+ endpoint_id,
67
+ body,
68
+ )
69
+
70
+
71
+ def _profile_services(scenario: str) -> Services:
72
+ root = CONFORMANCE_ROOT / scenario
73
+ bodies: dict[str, dict[str, Any]] = {}
74
+ for endpoint, name in _PROFILE_FILES.items():
75
+ path = root / name
76
+ if path.exists():
77
+ bodies[endpoint] = loads_bounded(read_replay_file(CONFORMANCE_ROOT, path))
78
+ health = root / "health-v3.json"
79
+ if health.exists():
80
+ bodies["health"] = loads_bounded(read_replay_file(CONFORMANCE_ROOT, health))
81
+ return Services(
82
+ FixtureReader(bodies),
83
+ SourceCatalog("local", None, {}, (), ()),
84
+ SanitizerPipeline(),
85
+ SnapshotStore(),
86
+ config_policy=ConfigReadPolicy(
87
+ prefixes=frozenset({"spring", "app"}), allow_values=True, profiles=True
88
+ ),
89
+ )
90
+
91
+
92
+ def services_for(scenario: str) -> Services:
93
+ if scenario in PROFILES:
94
+ return _profile_services(scenario)
95
+ if scenario not in (
96
+ "parent-child",
97
+ "stripe-missing",
98
+ "factory-method",
99
+ "nested-conditions",
100
+ ):
101
+ raise NormalizationError("INVALID_ARGUMENT")
102
+ beans_path = REPLAY_ROOT / scenario / "beans.json"
103
+ substituted = False
104
+ if not beans_path.exists():
105
+ beans_path = REPLAY_ROOT / "parent-child/beans.json"
106
+ substituted = True
107
+ bodies = {"beans": loads_bounded(read_replay_file(REPLAY_ROOT, beans_path))}
108
+ conditions_path = REPLAY_ROOT / scenario / "conditions.json"
109
+ if conditions_path.exists():
110
+ bodies["conditions"] = loads_bounded(
111
+ read_replay_file(REPLAY_ROOT, conditions_path)
112
+ )
113
+ source_path = REPLAY_ROOT / scenario / "source-catalog.json"
114
+ catalog = (
115
+ load_source_catalog(
116
+ loads_bounded(read_replay_file(REPLAY_ROOT, source_path)),
117
+ target_id="local",
118
+ budget=AnalysisBudget(),
119
+ )
120
+ if source_path.exists()
121
+ else SourceCatalog("local", None, {}, (), ())
122
+ )
123
+ if substituted:
124
+ catalog = SourceCatalog(
125
+ catalog.target_id,
126
+ catalog.source_revision,
127
+ catalog.types,
128
+ catalog.producers,
129
+ (*catalog.gaps, "FIXTURE_SUBSTITUTED"),
130
+ )
131
+ return Services(
132
+ FixtureReader(bodies), catalog, SanitizerPipeline(), SnapshotStore()
133
+ )
134
+
135
+
136
+ class SafeArgumentParser(argparse.ArgumentParser):
137
+ def error(self, message: str) -> NoReturn:
138
+ # argparse normally quotes untrusted argv into stderr.
139
+ raise NormalizationError("INVALID_ARGUMENT")
140
+
141
+
142
+ def main() -> None:
143
+ exit_code = 0
144
+ with quiet_console():
145
+ try:
146
+ parser = SafeArgumentParser(
147
+ prog="spring-runtime-mcp-replay", description=__doc__
148
+ )
149
+ parser.add_argument(
150
+ "--scenario",
151
+ choices=(
152
+ "parent-child",
153
+ "stripe-missing",
154
+ "factory-method",
155
+ "nested-conditions",
156
+ *PROFILES,
157
+ ),
158
+ required=True,
159
+ )
160
+ parser.add_argument(
161
+ "--tool",
162
+ choices=(
163
+ "springboot_analyze_startup",
164
+ "springboot_check_migrations",
165
+ "springboot_detect_drift",
166
+ "springboot_diagnose_health",
167
+ "springboot_inspect_beans",
168
+ "springboot_inspect_config",
169
+ "springboot_search_openapi",
170
+ "springboot_verify_mappings",
171
+ ),
172
+ required=True,
173
+ )
174
+ parser.add_argument("--arguments-json", required=True)
175
+ args = parser.parse_args()
176
+ arguments = loads_bounded(args.arguments_json.encode(), max_bytes=16_384)
177
+ from .tools.registry import call_tool
178
+
179
+ result = asyncio.run(
180
+ call_tool(args.tool, arguments, services_for(args.scenario))
181
+ )
182
+ # Offline conformance dependency only; no network/SDK imports.
183
+ from jsonschema import Draft202012Validator
184
+
185
+ from .contracts.definitions import definition
186
+
187
+ Draft202012Validator(definition(args.tool)["outputSchema"]).validate(result)
188
+ except NormalizationError as exc:
189
+ result = failed(exc.code)
190
+ exit_code = 2 if exc.code == "INVALID_ARGUMENT" else 1
191
+ except (asyncio.CancelledError, KeyboardInterrupt):
192
+ result = failed("REQUEST_CANCELLED")
193
+ exit_code = 130
194
+ except SystemExit as exc:
195
+ result = failed("INVALID_ARGUMENT")
196
+ exit_code = exc.code if isinstance(exc.code, int) and exc.code != 0 else 2
197
+ except Exception:
198
+ result = failed("INTERNAL_ERROR")
199
+ exit_code = 1
200
+ try:
201
+ frame = serialize_response(result) + b"\n"
202
+ except Exception:
203
+ frame = serialize_response(failed("INTERNAL_ERROR")) + b"\n"
204
+ exit_code = 1
205
+ # Libraries never see the real protocol stream during computation.
206
+ try:
207
+ view = memoryview(frame)
208
+ while view:
209
+ view = view[os.write(1, view) :]
210
+ except OSError:
211
+ exit_code = 1
212
+ finally:
213
+ # This command owns the process console until exit, including atexit.
214
+ seal_console()
215
+ if exit_code:
216
+ raise SystemExit(exit_code)
217
+
218
+
219
+ if __name__ == "__main__":
220
+ main()
@@ -0,0 +1,26 @@
1
+ # Synthetic Bean and Condition Fixtures
2
+
3
+ These disposable, sanitized examples are authored from the ExecPlan's inline
4
+ JSON structures. They are not recordings from a running Spring Boot instance
5
+ and do not establish compatibility with any particular Boot release.
6
+
7
+ - `parent-child/beans.json`: parent lookup, aliases, local name shadowing, and
8
+ three-hop dependencies; Stripe gateway/client are intentionally absent.
9
+ - `stripe-missing/conditions.json` and `source-catalog.json`: interface-to-
10
+ implementation mapping, missing required client, and missing property at the
11
+ client's factory method. The catalog describes source expectations, not
12
+ observed runtime Beans.
13
+ - `factory-method/`: replaces the gateway component condition source with
14
+ `example.PaymentConfiguration#stripePaymentGateway`; its declared return type
15
+ is the interface, with an explicit implementation type. Reuses parent-child
16
+ Beans rather than duplicating data.
17
+ - `nested-conditions/`: ANY containing ALL and NONE, explicit condition-class
18
+ paths, and an observed `RemoteClient` for the nested positive Bean match.
19
+ - `shape-metadata.json`: documents synthetic Boot 2.7/3.x/4.x structural profiles.
20
+ Its version labels are coverage intentions, never runtime version evidence.
21
+
22
+ The shared `contexts`, `parentId`, aliases, and matched/notMatched shapes are
23
+ tested independently of media-type or framework-version inference. No secrets,
24
+ production addresses, real source files, or credentials are included. Fixture
25
+ loaders return a new object per read so mutation cannot contaminate another test.
26
+ All default tests block outbound DNS and socket connections.
@@ -0,0 +1,43 @@
1
+ {
2
+ "contexts": {
3
+ "infrastructure": {
4
+ "positiveMatches": {},
5
+ "negativeMatches": {},
6
+ "unconditionalClasses": []
7
+ },
8
+ "application": {
9
+ "parentId": "infrastructure",
10
+ "positiveMatches": {
11
+ "example.FallbackConfiguration": [
12
+ {
13
+ "condition": "OnBeanCondition",
14
+ "message": "@ConditionalOnMissingBean (types: example.StripeClient; SearchStrategy: all) did not find any beans"
15
+ }
16
+ ]
17
+ },
18
+ "negativeMatches": {
19
+ "example.StripeConfiguration#stripeClient": {
20
+ "matched": [],
21
+ "notMatched": [
22
+ {
23
+ "condition": "OnPropertyCondition",
24
+ "message": "@ConditionalOnProperty (stripe.enabled=true) did not find property 'enabled'"
25
+ }
26
+ ]
27
+ },
28
+ "example.PaymentConfiguration#stripePaymentGateway": {
29
+ "matched": [],
30
+ "notMatched": [
31
+ {
32
+ "condition": "OnBeanCondition",
33
+ "message": "@ConditionalOnBean (types: example.StripeClient; SearchStrategy: all) did not find any beans of type example.StripeClient"
34
+ }
35
+ ]
36
+ }
37
+ },
38
+ "unconditionalClasses": [
39
+ "example.OrderConfiguration"
40
+ ]
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,54 @@
1
+ {
2
+ "targetId": "local",
3
+ "sourceRevision": "workspace-a1",
4
+ "types": [
5
+ {
6
+ "name": "example.PaymentGateway",
7
+ "directSupertypes": []
8
+ },
9
+ {
10
+ "name": "example.StripePaymentGateway",
11
+ "directSupertypes": [
12
+ "example.PaymentGateway"
13
+ ]
14
+ },
15
+ {
16
+ "name": "example.StripeClient",
17
+ "directSupertypes": []
18
+ }
19
+ ],
20
+ "producers": [
21
+ {
22
+ "contextId": "application",
23
+ "beanName": "stripePaymentGateway",
24
+ "aliases": [
25
+ "paymentGateway"
26
+ ],
27
+ "declaredType": "example.PaymentGateway",
28
+ "implementationType": "example.StripePaymentGateway",
29
+ "configurationClass": "example.PaymentConfiguration",
30
+ "factoryMethod": "stripePaymentGateway",
31
+ "conditionSources": [
32
+ "example.PaymentConfiguration#stripePaymentGateway"
33
+ ],
34
+ "sourceFile": "src/main/java/example/PaymentConfiguration.java",
35
+ "sourceLine": 12
36
+ },
37
+ {
38
+ "contextId": "application",
39
+ "beanName": "stripeClient",
40
+ "aliases": [
41
+ "stripeApiClient"
42
+ ],
43
+ "declaredType": "example.StripeClient",
44
+ "implementationType": null,
45
+ "configurationClass": "example.StripeConfiguration",
46
+ "factoryMethod": "stripeClient",
47
+ "conditionSources": [
48
+ "example.StripeConfiguration#stripeClient"
49
+ ],
50
+ "sourceFile": "src/main/java/example/StripeConfiguration.java",
51
+ "sourceLine": 18
52
+ }
53
+ ]
54
+ }
@@ -0,0 +1,99 @@
1
+ {
2
+ "contexts": {
3
+ "infrastructure": {
4
+ "beans": {
5
+ "connectionFactory": {
6
+ "aliases": [],
7
+ "scope": "singleton",
8
+ "type": "example.ConnectionFactory",
9
+ "resource": "class path resource [example/InfrastructureConfiguration.class]",
10
+ "dependencies": []
11
+ },
12
+ "dataSource": {
13
+ "aliases": [],
14
+ "scope": "singleton",
15
+ "type": "example.DataSource",
16
+ "resource": "class path resource [example/InfrastructureConfiguration.class]",
17
+ "dependencies": [
18
+ "connectionFactory"
19
+ ]
20
+ },
21
+ "orderRepository": {
22
+ "aliases": [
23
+ "orderRepoAlias"
24
+ ],
25
+ "scope": "singleton",
26
+ "type": "example.OrderRepository",
27
+ "resource": "class path resource [example/InfrastructureConfiguration.class]",
28
+ "dependencies": [
29
+ "dataSource"
30
+ ]
31
+ },
32
+ "client": {
33
+ "aliases": [],
34
+ "scope": "singleton",
35
+ "type": "example.ParentClient",
36
+ "resource": null,
37
+ "dependencies": []
38
+ },
39
+ "auditService": {
40
+ "aliases": [],
41
+ "scope": "singleton",
42
+ "type": "example.AuditService",
43
+ "resource": null,
44
+ "dependencies": [
45
+ "client"
46
+ ]
47
+ }
48
+ },
49
+ "parentId": null
50
+ },
51
+ "application": {
52
+ "parentId": "infrastructure",
53
+ "beans": {
54
+ "client": {
55
+ "aliases": [],
56
+ "scope": "singleton",
57
+ "type": "example.ChildClient",
58
+ "resource": null,
59
+ "dependencies": []
60
+ },
61
+ "orderService": {
62
+ "aliases": [
63
+ "orders"
64
+ ],
65
+ "scope": "singleton",
66
+ "type": "example.OrderService",
67
+ "resource": null,
68
+ "dependencies": [
69
+ "orderRepoAlias",
70
+ "client"
71
+ ]
72
+ },
73
+ "orderController": {
74
+ "aliases": [],
75
+ "scope": "singleton",
76
+ "type": "example.OrderController",
77
+ "resource": null,
78
+ "dependencies": [
79
+ "orders"
80
+ ]
81
+ },
82
+ "stripeConfiguration": {
83
+ "aliases": [],
84
+ "scope": "singleton",
85
+ "type": "example.StripeConfiguration",
86
+ "resource": null,
87
+ "dependencies": []
88
+ },
89
+ "remoteClient": {
90
+ "aliases": [],
91
+ "scope": "singleton",
92
+ "type": "example.RemoteClient",
93
+ "resource": null,
94
+ "dependencies": []
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "contexts": {
3
+ "infrastructure": {
4
+ "positiveMatches": {},
5
+ "negativeMatches": {},
6
+ "unconditionalClasses": []
7
+ },
8
+ "application": {
9
+ "parentId": "infrastructure",
10
+ "positiveMatches": {},
11
+ "negativeMatches": {
12
+ "example.PaymentModeCondition": {
13
+ "matched": [],
14
+ "notMatched": [
15
+ {
16
+ "condition": "example.PaymentModeCondition",
17
+ "message": "AnyNestedCondition 0 matched 2 did not; NestedCondition on example.PaymentModeCondition.Card AllNestedConditions 0 matched 1 did not; NestedCondition on example.PaymentModeCondition.Card.Enabled @ConditionalOnProperty (card.enabled=true) did not find property 'enabled'; NestedCondition on example.PaymentModeCondition.Remote NoneNestedConditions 1 matched 0 did not; NestedCondition on example.PaymentModeCondition.Remote.Client @ConditionalOnBean (types: example.RemoteClient; SearchStrategy: all) found bean 'remoteClient'"
18
+ }
19
+ ]
20
+ }
21
+ },
22
+ "unconditionalClasses": []
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,92 @@
1
+ {
2
+ "contexts": {
3
+ "infrastructure": {
4
+ "beans": {
5
+ "connectionFactory": {
6
+ "aliases": [],
7
+ "scope": "singleton",
8
+ "type": "example.ConnectionFactory",
9
+ "resource": "class path resource [example/InfrastructureConfiguration.class]",
10
+ "dependencies": []
11
+ },
12
+ "dataSource": {
13
+ "aliases": [],
14
+ "scope": "singleton",
15
+ "type": "example.DataSource",
16
+ "resource": "class path resource [example/InfrastructureConfiguration.class]",
17
+ "dependencies": [
18
+ "connectionFactory"
19
+ ]
20
+ },
21
+ "orderRepository": {
22
+ "aliases": [
23
+ "orderRepoAlias"
24
+ ],
25
+ "scope": "singleton",
26
+ "type": "example.OrderRepository",
27
+ "resource": "class path resource [example/InfrastructureConfiguration.class]",
28
+ "dependencies": [
29
+ "dataSource"
30
+ ]
31
+ },
32
+ "client": {
33
+ "aliases": [],
34
+ "scope": "singleton",
35
+ "type": "example.ParentClient",
36
+ "resource": null,
37
+ "dependencies": []
38
+ },
39
+ "auditService": {
40
+ "aliases": [],
41
+ "scope": "singleton",
42
+ "type": "example.AuditService",
43
+ "resource": null,
44
+ "dependencies": [
45
+ "client"
46
+ ]
47
+ }
48
+ },
49
+ "parentId": null
50
+ },
51
+ "application": {
52
+ "parentId": "infrastructure",
53
+ "beans": {
54
+ "client": {
55
+ "aliases": [],
56
+ "scope": "singleton",
57
+ "type": "example.ChildClient",
58
+ "resource": null,
59
+ "dependencies": []
60
+ },
61
+ "orderService": {
62
+ "aliases": [
63
+ "orders"
64
+ ],
65
+ "scope": "singleton",
66
+ "type": "example.OrderService",
67
+ "resource": null,
68
+ "dependencies": [
69
+ "orderRepoAlias",
70
+ "client"
71
+ ]
72
+ },
73
+ "orderController": {
74
+ "aliases": [],
75
+ "scope": "singleton",
76
+ "type": "example.OrderController",
77
+ "resource": null,
78
+ "dependencies": [
79
+ "orders"
80
+ ]
81
+ },
82
+ "stripeConfiguration": {
83
+ "aliases": [],
84
+ "scope": "singleton",
85
+ "type": "example.StripeConfiguration",
86
+ "resource": null,
87
+ "dependencies": []
88
+ }
89
+ }
90
+ }
91
+ }
92
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "provenance": "synthetic",
3
+ "sanitized": true,
4
+ "realInstanceIntegrationVerified": false,
5
+ "scenarios": [
6
+ "parent-child",
7
+ "stripe-missing",
8
+ "factory-method",
9
+ "nested-conditions"
10
+ ],
11
+ "shapeProfiles": [
12
+ {
13
+ "bootFamily": "2.7",
14
+ "actuatorRepresentation": "v3",
15
+ "namespace": "javax",
16
+ "integrationVerified": false
17
+ },
18
+ {
19
+ "bootFamily": "3.x",
20
+ "actuatorRepresentation": "v3",
21
+ "namespace": "jakarta",
22
+ "integrationVerified": false
23
+ },
24
+ {
25
+ "bootFamily": "4.x",
26
+ "actuatorRepresentation": "v3",
27
+ "namespace": "jakarta",
28
+ "integrationVerified": false
29
+ }
30
+ ],
31
+ "notice": "Shared structural examples only. Metadata does not establish exact-version compatibility or report an observed Boot version."
32
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "contexts": {
3
+ "infrastructure": {
4
+ "positiveMatches": {},
5
+ "negativeMatches": {},
6
+ "unconditionalClasses": []
7
+ },
8
+ "application": {
9
+ "parentId": "infrastructure",
10
+ "positiveMatches": {
11
+ "example.FallbackConfiguration": [
12
+ {
13
+ "condition": "OnBeanCondition",
14
+ "message": "@ConditionalOnMissingBean (types: example.StripeClient; SearchStrategy: all) did not find any beans"
15
+ }
16
+ ]
17
+ },
18
+ "negativeMatches": {
19
+ "example.StripePaymentGateway": {
20
+ "matched": [],
21
+ "notMatched": [
22
+ {
23
+ "condition": "OnBeanCondition",
24
+ "message": "@ConditionalOnBean (types: example.StripeClient; SearchStrategy: all) did not find any beans of type example.StripeClient"
25
+ }
26
+ ]
27
+ },
28
+ "example.StripeConfiguration#stripeClient": {
29
+ "matched": [],
30
+ "notMatched": [
31
+ {
32
+ "condition": "OnPropertyCondition",
33
+ "message": "@ConditionalOnProperty (stripe.enabled=true) did not find property 'enabled'"
34
+ }
35
+ ]
36
+ }
37
+ },
38
+ "unconditionalClasses": [
39
+ "example.OrderConfiguration"
40
+ ]
41
+ }
42
+ }
43
+ }