Repository navigation
Conversation
Three related resilience fixes for long-held sessions: - Wrap causes with %w (not %v) when labeling errors as ErrTransport, so callers can still match context.Canceled, os.ErrDeadlineExceeded, and transport.ErrClosed through the chain. Same fix in translate(). - Propagate server-side conversation deallocation upward. An ABAP short dump or MESSAGE ends the CPI-C conversation gracefully (APPC RC 18) while the call itself returns a normal result or *ABAPException; the dead conversation then exploded on the *next* call as "cpic session: session is closed". Managed.SessionClosed() now exposes the state; a pinned Session discards its lease immediately, and the pooled path discards instead of releasing so the dead conn never re-enters the pool. - Fail metadata lookups cleanly. A denied or failed recursive graph fetch was swallowed (encoding then proceeded on a possibly dead conversation) and the failure was cached on the Client forever. planLayoutOn now propagates the error, naming the metadata lookup, whenever the conversation did not survive it; graphCache retains successes only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Sascha Bauer <github@saschabauer.eu>
…sponse Client.SeedMetadata pre-fills the interface and graph caches from a stored RFC_METADATA_GET DEEP response, so a seeded function can be called without any runtime metadata lookup. CheckSeed validates a seed payload without a client. Both flow through the same normalization as live responses, all-or-nothing: a seed that does not fully resolve leaves the caches untouched and returns ErrSeed. This gives generic clients parity with callers that know a contract statically: on systems where S_RFC denies RFC_METADATA_GET and RFC_GET_STRUCTURE_DEFINITION, a seeded function (e.g. the ADT REST tunnel endpoint) still works with authorization for the endpoint alone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Sascha Bauer <github@saschabauer.eu>
Add a second capture of RFC_METADATA_GET (DEEP) for SADT_REST_RFC_ENDPOINT, taken on an ECC system (SAP_BASIS 740, kernel 742, Unicode), next to the existing S/4HANA one (SAP_BASIS 816). TestSeedIsTheSameAcrossReleases seeds both and requires the same function interface and the same type graph, ignoring only the DDIC activation timestamps. The 740 capture differs only in those timestamps and in lacking the EX_FUNCTIONS, EX_TYPES and EX_TYPE_ERRORS tables, which later releases return empty. The test fails when a field offset in either capture is changed. The existing fixture's comment said "NW 7.5x"; it was captured on SAP_BASIS 816. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Sascha Bauer <github@saschabauer.eu>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
vibing-steampunk reaches ADT over classic RFC through
SADT_REST_RFC_ENDPOINT, the same tunnel Eclipse ADT uses. On systems where HTTPS is not reachable and S_RFC is narrow, that tunnel is the only way in, and today it fails before the first request: open-rfc-go looks up the endpoint's interface at runtime, and those lookups are not authorized.This PR is the library half of making that work:
RFC_METADATA_GET. vsp will embed theSADT_REST_RFC_ENDPOINTseed and needs nothing else from this repository.session is closed, which hides the real cause.The vsp half is small once this is released: bump the dependency and seed every client in
saprfc.Open. A follow-up vsp PR would carry ADT over RFC for all commands, not only the debugger.Three commits, in this order. The second needs the first: it fills the graph cache in the shape the first commit introduces. The third adds a second capture and a test across releases.
1.
fix(rfc): surface dead conversations instead of failing one call later%winstead of%vwhen an error is labelledErrTransport, so callers can still matchcontext.Canceled,os.ErrDeadlineExceededandtransport.ErrClosed. Same fix intranslate().MESSAGEends the CPI-C conversation gracefully (APPC RC 18) while the call itself returns a normal result or*ABAPException. Until now the dead conversation failed on the next call ascpic session: session is closed.Managed.SessionClosed()now exposes the state. A pinnedSessiondrops its lease at once, and the pooled path discards the connection instead of releasing it.Clientfor good.planLayoutOnnow returns the error and names the metadata lookup whenever the conversation did not survive it.graphCachekeeps successes only.2.
feat(rfc): seed function metadata from a capturedRFC_METADATA_GETresponseProblem. To call a function module, the client discovers its interface at runtime through
RFC_GET_FUNCTION_INTERFACEandRFC_METADATA_GET(fallbackRFC_GET_STRUCTURE_DEFINITION). On systems with a narrow S_RFC authorization, S_RFC refuses exactly those lookups, even though the target function itself is authorized. The gateway then drops the conversation instead of returning a clean authorization error.We observed this on a system where the only authorized entry point is
SADT_REST_RFC_ENDPOINT. SU53 shows denials for:RFC_METADATARFC_METADATA_GETRFC_GET_STRUCTURE_DEFINITIONEclipse ADT works on the same system, because it knows the
SADT_REST_RFC_ENDPOINTcontract statically.Change.
(*Client).SeedMetadata(raw []byte) errorpre-fills the function and graph caches from a capturedRFC_METADATA_GETresponse (DEEP = 'X', one function).FunctionInterfaceandCallthen serve that function without a metadata call.CheckSeed(raw []byte) errorvalidates a capture without a client, for tests of embedded seeds.rfc/testdata/sadt_rest_rfc_endpoint.jsonis a capture of the SAP-ownedSADT_REST_*DDIC structures. It contains no host, user or customer data.Trade-off. A seed pins the client to the captured contract. If SAP changed the structure incompatibly, requests would be encoded wrongly instead of failing the lookup. The
SADT_REST_*DDIC objects have been unchanged since 2020.3.
test(rfc): the SADT seed is the same on SAP_BASIS 740 and 816The same
RFC_METADATA_GETcall was repeated on three systems and compared field by field (type, INTLEN, INTLEN_UC, OFFSET, OFFSET_UC, TABLENGTH):The 740 response differs only in the DDIC activation timestamps and in lacking the
EX_FUNCTIONS,EX_TYPESandEX_TYPE_ERRORStables, which later releases return empty. It is added asrfc/testdata/sadt_rest_rfc_endpoint_740.json.TestSeedIsTheSameAcrossReleasesseeds both captures and requires the same interface and type graph, ignoring only the timestamps. It fails when a field offset in either capture is changed.Not covered: systems on a SAP_BASIS older than the one ADT runs on (7.31/7.40), which do not have
SADT_REST_RFC_ENDPOINTat all, and non-Unicode systems.Tests
Run on this branch, rebased on
main(274c0c9), Linux amd64, Go 1.26.8,GOTOOLCHAIN=local:gofmt -l .: cleango vet ./...: cleango test -race -shuffle=on ./...: 29 packages ok, 630 tests passed, 0 failed, 9 skippedNew tests:
rfc/deadconversation_test.go,rfc/seed_test.go(includingTestSeedIsTheSameAcrossReleases, with the 740 capture inrfc/testdata/sadt_rest_rfc_endpoint_740.json).Request
Could this go into a tagged release (for example v0.3.0)? The vsp PR follows as soon as there is a version to depend on.
🤖 Generated with Claude Code