Skip to content

feat(clients/java): wrap execution, verification, calculation, analysis and query in the public API - #388

Draft
devin-ai-integration[bot] wants to merge 1 commit into
developfrom
feature/java-client-runtime-api
Draft

devin-ai-integration[bot] wants to merge 1 commit into
developfrom
feature/java-client-runtime-api

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

What and why

The Java client stopped at the v1 surface (parse, symbols, eval, instantiate) although the service already serves the runtime RPCs and the generated messages ship in the jar. A JVM host — a modelling tool that wants to run, verify or analyse the model it draws — had no typed way to reach them. This wraps them, keeping the client's contract: immutable records, no generated protobuf type in the public API, unchecked exceptions split between "the call was refused" and "the answer reports a model failure".

Model gains:

ActionRun     executeAction(String id[, Map<String,Value> inputs, ExecutionOptions opts]);
Exploration   exploreAction(String id[, Map<String,Value> inputs, ExecutionOptions opts]);
StateRun      executeState(String id, List<String> events, ExecutionOptions opts);
Exploration   exploreState(String id, List<String> events, ExecutionOptions opts);
Verification  verifyConstraint(String id[, String subjectId]);
Verification  verifyRequirement(String id);
Satisfaction  verifySatisfaction([String scopeId]);
Validation    validateInstance(String id);
Calculation   evaluateCalc(String id, List<Value> args);
Analysis      runAnalysis(String id[, AnalysisOptions opts]);
Exploration   exploreAnalysis(String id, AnalysisOptions opts);
List<QueryElement> query(Query q);
List<QueryElement> queryOslc(String oslc);
Model         withEngine(String engine);   Optional<String> engine();

and Connection gains List<EngineInfo> listEngines(). Result records: ActionRun, StateRun, Exploration/Outcome, Verification/Verdict/VerificationVerdict, Satisfaction, Validation, Calculation, Analysis/CaseEvaluation, Standing (engine, strength, bounds), QueryElement, EngineInfo; options: ExecutionOptions, AnalysisOptions, Query/Condition.

Semantics worth knowing:

  • A false verdict is an answer, not a failure: verifyConstraint returns holds() == false with decided() == true. Only a verdict the service could not evaluate carries error and a FailureReason (EVALUATION, WRONG_KIND, AMBIGUOUS_SUBJECT; an enum value this client does not know maps to UNKNOWN).
  • ModelException now carries failureReason(). runAnalysis throws AnalysisException extends ModelException whose partial() holds the outputs, verdicts and evaluations computed before the failure; a failure with nothing computed stays a plain ModelException.
  • Every capability the RPCs depend on (VERIFICATION, VERIFICATION_VERDICTS, CASE_EVALUATIONS, QUERY, OSLC_QUERY, SCHEDULE, SCHEDULE_EXPLORE, PERFORMER, FINAL_TIME, ENGINES) is checked before the call, so an older service fails with CapabilityException rather than a wire error. finalTime is OptionalDouble.empty() unless the service reports FINAL_TIME.
  • Protos gains the public → protobuf direction for Value (every variant, including quantities, vectors, tensors, sets, metaobjects) so requests can carry public values.

The conformance runner (opensysml-conformance) covers the ten RPCs through the public API and renders the public results back to protobuf for comparison, so the scenarios test the client's conversions rather than bypass them. A request the public API cannot express (a malformed value the client would itself refuse to read) is recorded as a skip with that reason instead of a transport failure. SuiteTest now also asserts that no covered RPC is skipped as uncovered and every covered RPC has a passing scenario, so a regression cannot hide as a skip.

Docs: docs/reference/java-api.md, docs/reference/clients.md, docs/guide/09-clients.md, clients/java/README.md and the README rows describe the new surface and drop the statements that these operations were out of scope; the remaining gaps (edit API, ParseSources, Convert, RunSweep, the document RPCs) are still listed.

How it was verified

  • mvn -f clients/java/pom.xml test -Dopensysml.requireService=true — 200 client tests, 36 conformance tests, including ApiIntegrationTest running every new operation against the real bin/sysml-grpc (false-but-decided verdicts, wrong-kind failures, partial and no-data analysis failures, exploration budgets, engine-bound models, structured and OSLC queries).
  • Java conformance runner against bin/sysml-grpc over connect and connect-json: 134 scenarios per protocol, 94 passed, 0 failed, 40 skipped, 0 in error (was 25 passed / 34 skipped of 59). Mutation runs (perturb-reals, truncate-lists, rewrite-strings) fail scenarios as expected.
  • make build, gofmt -l ., go vet ./..., make lint, make docs-check, go run ./cmd/doc-counts -check clean. No Go source changes; go test -race -timeout 30m ./... passes.

Checklist

  • make test and make lint pass locally
  • Tests added or updated for the change
  • Documentation extended where it already covers the surface (see CONTRIBUTING.md)
  • Changelog entry added as changes/unreleased/<slug>.<section>.md, not as an edit to CHANGELOG.md
  • baselines regenerated and make docs-counts run if a gate count moved (compliance rows need nothing: the census is counted at docs build)
  • No internal work-item labels (waves, slices, F4, K5) in the body, docs, or changelog

…is and query in the public API

Model gains executeAction/executeState with exploreAction/exploreState, verifyConstraint/verifyRequirement/verifySatisfaction/validateInstance, evaluateCalc, runAnalysis/exploreAnalysis, query/queryOslc and withEngine; Connection gains listEngines. Each answers an immutable record with no generated protobuf type in the public API. A false verdict is a decided answer, not an exception; ModelException carries a FailureReason and AnalysisException.partial() keeps what a failed analysis computed.

The Java conformance runner covers the new RPCs through the public API, rendering results back to protobuf, so 94 of 134 scenarios run per protocol. Unit tests cover the result types and both conversion directions; ApiIntegrationTest runs each operation against the real service binary.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant