Repository navigation
SDK de Java: API bloqueante (SRE, DLS, webhooks y mocks) - #1
Conversation
El .proto se copia byte a byte de caerus-back, que es privado, y su README registra commit y SHA-256 para poder comparar. El build lo copia a target, cambia el java_package a dev.caerus.sdk.internal.proto y genera desde ahi: las clases generadas quedan marcadas como internas y no chocan con las del motor si alguien tiene las dos en el classpath. Java 17 como minimo, protobuf 3.25 para no forzarle a nadie la 4.x (es la que pide grpc-java), y la version del jar inyectada desde el pom.
CaerusError es unchecked para que un solo catch alcance, con code, reason y requestId como en TypeScript. El reason se lee del ErrorInfo del trailer y nunca lanza: un trailer roto deja el error como estaba en vez de taparlo con otro. Cada llamada lleva su API Key, un x-request-id propio y un deadline. No hay reintentos. Un solo nucleo asincrono sobre grpc-java, para que la API asincrona de la etapa 2 sea una fachada y no una segunda implementacion. Dos tests cuidan las reglas: nada de protobuf, gRPC, Gson ni del paquete internal aparece en una firma publica, y el codigo no lleva comentarios.
Mismos metodos que en TypeScript, con builders en lugar de objetos de opciones y una sobrecarga sin opciones para cada uno. Valida antes de llamar y nombra el argumento; un take o un extend que vuelven en un estado que no sirven lanzan ConflictError, y un estado desconocido lanza en vez de adivinar. La metadata viaja como JSON y vuelve como Map; los tiempos en cero vuelven vacios, nunca como 1970. InMemoryCaerusClient copia al de TypeScript y ademas es thread-safe, porque en Java los tests usan hilos de verdad. Los tests de TypeScript portados corren contra un servidor gRPC real en 127.0.0.1, no contra un stub.
acquireLock consume el stream: avisa onQueued una sola vez y nunca despues de conceder, corta con un AbortSignal y convierte un DENIED en LockDeniedError. Sin timeout propio usa el deadline del cliente, como en TypeScript. withTransaction renueva desde un ScheduledExecutorService del cliente (Java 17 no tiene virtual threads) que se apaga en close(), suelta los locks en el finally y lanza la perdida de la transaccion aunque el callback haya terminado bien. Una excepcion checked del callback sale tal cual. El cliente en memoria responde OK al soltar un lock que no existe, como el motor, en lugar de lanzar DlsNotFoundError como el de TypeScript.
HMAC-SHA256 sobre el cuerpo crudo, comparado en tiempo constante y con cinco minutos de tolerancia. El vector cruzado de TypeScript y del motor da la misma firma byte a byte. Cada evento tiene su record y un tipo que el SDK no conoce llega como UnknownEventData, para que un evento nuevo del motor no rompa a nadie.
Los tests de TypeScript contra el mock pasaban las dos veces que el SDK tuvo un bug de contrato, asi que esto no es opcional. Corre con mvn test -Plive y CAERUS_API_KEY; queda fuera de mvn verify. Contra el motor hospedado pasaron los escenarios de lectura compartida, deadlock de dos y de tres, cola con onQueued, deadline del cliente, transaccion cerrada, renovacion, fencing tokens, API Key invalida y requestId. Faltan las plantillas FAIL, ALERT y una de recursos para el resto.
paridad.md deja escrito que cambia por ser Java y que se decidio con cada inconsistencia del SDK de TypeScript, para que la proxima version no las redescubra.
El escenario contaba cuantas transacciones abortaba el motor por deadlock y daba bien con cero, pero tambien daba cero cuando la plantilla no existia y las dos fallaban por NOT_FOUND. Ahora la unica falla aceptada es el timeout. El SRE en vivo paso entero contra la plantilla butaca, salvo updateResource, que esa plantilla exige con clave de idempotencia: el test ahora la manda.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Transaction renewal races, cancellation gaps, webhook byte handling, and in-memory DLS parity defects can produce incorrect runtime behavior.
Review effort: Balanced
Findings: 5
Open (6)
Unknown requested lock mode defaults incorrectly to exclusive · New In-memory client ignores acquisition idempotency keys · New Acquisition does not observe transaction-loss cancellation · New Overlapping renewals violate fixed-rate scheduling invariant · New HMAC verification corrupts malformed UTF-8 payloads · New Document terminal replay conflicts instead of returned statuses · New
What changed in this PR
Introduces the first blocking Java SDK for Caerus, covering SRE, DLS, webhooks, in-memory clients, generated gRPC contracts, documentation, and verification.
Changes:
- Adds blocking SRE and DLS APIs with typed models and errors.
- Adds webhook verification and typed event decoding.
- Adds mocks, contract tests, live tests, Maven build, and CI.
| File | Description |
|---|---|
.gitattributes |
Preserves proto checksums. |
.gitignore |
Excludes local artifacts. |
.github/workflows/tests.yml |
Runs Maven verification. |
LICENSE |
Adds MIT license. |
README.md |
Documents SDK usage. |
pom.xml |
Configures Java, gRPC, and tests. |
proto/README.md |
Documents proto provenance. |
proto/dls_service.proto |
Defines DLS contract. |
proto/sre_service.proto |
Defines SRE contract. |
docs/errores.md |
Documents error handling. |
docs/paridad.md |
Records TypeScript parity. |
docs/verificacion-en-vivo.md |
Documents live verification. |
src/main/resources/dev/caerus/sdk/version.properties |
Exposes build version. |
src/main/java/dev/caerus/sdk/AbortController.java |
Controls cancellation. |
src/main/java/dev/caerus/sdk/AbortSignal.java |
Publishes cancellation state. |
src/main/java/dev/caerus/sdk/CaerusError.java |
Defines base SDK error. |
src/main/java/dev/caerus/sdk/CaerusErrorOptions.java |
Configures error details. |
src/main/java/dev/caerus/sdk/CaerusLogger.java |
Defines logging callback. |
src/main/java/dev/caerus/sdk/CaerusSdk.java |
Exposes SDK constants. |
src/main/java/dev/caerus/sdk/ErrorCode.java |
Defines error categories. |
src/main/java/dev/caerus/sdk/ErrorReason.java |
Defines engine reasons. |
src/main/java/dev/caerus/sdk/internal/ClientProfile.java |
Defines client profiles. |
src/main/java/dev/caerus/sdk/internal/ClientSettings.java |
Resolves client configuration. |
src/main/java/dev/caerus/sdk/internal/ErrorDetails.java |
Decodes gRPC errors. |
src/main/java/dev/caerus/sdk/internal/Futures.java |
Bridges asynchronous operations. |
src/main/java/dev/caerus/sdk/internal/GrpcTransport.java |
Implements gRPC transport. |
src/main/java/dev/caerus/sdk/internal/Json.java |
Provides JSON utilities. |
src/main/java/dev/caerus/sdk/internal/StderrLogger.java |
Implements default logging. |
src/main/java/dev/caerus/sdk/sre/AuthenticationError.java |
Adds SRE authentication error. |
src/main/java/dev/caerus/sdk/sre/CaerusClient.java |
Implements blocking SRE client. |
src/main/java/dev/caerus/sdk/sre/CaerusClientOptions.java |
Configures SRE clients. |
src/main/java/dev/caerus/sdk/sre/ConfirmOptions.java |
Configures confirmations. |
src/main/java/dev/caerus/sdk/sre/ConflictError.java |
Adds SRE conflict error. |
src/main/java/dev/caerus/sdk/sre/CreateResourceOptions.java |
Configures resource creation. |
src/main/java/dev/caerus/sdk/sre/GetResourcesByGroupOptions.java |
Configures group pagination. |
src/main/java/dev/caerus/sdk/sre/Handles.java |
Builds resource handles. |
src/main/java/dev/caerus/sdk/sre/HolderNotActiveError.java |
Adds inactive-holder error. |
src/main/java/dev/caerus/sdk/sre/HolderSort.java |
Defines holder ordering. |
src/main/java/dev/caerus/sdk/sre/InMemoryCaerusClient.java |
Implements in-memory SRE. |
src/main/java/dev/caerus/sdk/sre/ListResourceHoldersOptions.java |
Configures holder queries. |
src/main/java/dev/caerus/sdk/sre/MockMethod.java |
Identifies mocked methods. |
src/main/java/dev/caerus/sdk/sre/MockOptions.java |
Configures SRE mocks. |
src/main/java/dev/caerus/sdk/sre/MockResourceSeed.java |
Defines mock resources. |
src/main/java/dev/caerus/sdk/sre/MockSnapshot.java |
Captures mock state. |
src/main/java/dev/caerus/sdk/sre/OutOfStockError.java |
Adds stock error. |
src/main/java/dev/caerus/sdk/sre/PooledResource.java |
Defines pooled operations. |
src/main/java/dev/caerus/sdk/sre/Resource.java |
Models resources. |
src/main/java/dev/caerus/sdk/sre/ResourceHasActiveHoldsError.java |
Adds active-holds error. |
src/main/java/dev/caerus/sdk/sre/ResourceHasQueuedRequestsError.java |
Adds queued-requests error. |
src/main/java/dev/caerus/sdk/sre/ResourceHolder.java |
Models resource holders. |
src/main/java/dev/caerus/sdk/sre/ResourceHolderPage.java |
Models holder pages. |
src/main/java/dev/caerus/sdk/sre/ResourceHolderStatus.java |
Defines holder states. |
src/main/java/dev/caerus/sdk/sre/ResourceNotFoundError.java |
Adds resource error. |
src/main/java/dev/caerus/sdk/sre/ResourcePage.java |
Models resource pages. |
src/main/java/dev/caerus/sdk/sre/SharedResourceApi.java |
Defines blocking SRE API. |
src/main/java/dev/caerus/sdk/sre/SreCore.java |
Implements SRE requests. |
src/main/java/dev/caerus/sdk/sre/SreErrors.java |
Maps SRE errors. |
src/main/java/dev/caerus/sdk/sre/SreMapping.java |
Maps SRE models. |
src/main/java/dev/caerus/sdk/sre/TakeOptions.java |
Configures reservations. |
src/main/java/dev/caerus/sdk/sre/TimeoutError.java |
Adds SRE timeout error. |
src/main/java/dev/caerus/sdk/sre/UnitaryResource.java |
Defines unitary operations. |
src/main/java/dev/caerus/sdk/sre/UpdateResourceOptions.java |
Configures resource updates. |
src/main/java/dev/caerus/sdk/sre/Validation.java |
Validates SRE inputs. |
src/main/java/dev/caerus/sdk/sre/ValidationError.java |
Adds validation error. |
src/main/java/dev/caerus/sdk/dls/AcquireLockOptions.java |
Configures lock acquisition. |
src/main/java/dev/caerus/sdk/dls/ActiveLockHolder.java |
Models active holders. |
src/main/java/dev/caerus/sdk/dls/BeginTransactionOptions.java |
Configures transactions. |
src/main/java/dev/caerus/sdk/dls/DeadlockAbortedError.java |
Adds deadlock error. |
src/main/java/dev/caerus/sdk/dls/DlsApi.java |
Defines blocking DLS API. |
src/main/java/dev/caerus/sdk/dls/DlsAuthenticationError.java |
Adds DLS authentication error. |
src/main/java/dev/caerus/sdk/dls/DlsClient.java |
Implements blocking DLS client. |
src/main/java/dev/caerus/sdk/dls/DlsClientOptions.java |
Configures DLS clients. |
src/main/java/dev/caerus/sdk/dls/DlsConflictError.java |
Adds DLS conflict error. |
src/main/java/dev/caerus/sdk/dls/DlsCore.java |
Implements DLS transport logic. |
src/main/java/dev/caerus/sdk/dls/DlsError.java |
Defines base DLS error. |
src/main/java/dev/caerus/sdk/dls/DlsErrors.java |
Maps DLS errors. |
src/main/java/dev/caerus/sdk/dls/DlsMapping.java |
Maps DLS models. |
src/main/java/dev/caerus/sdk/dls/DlsNotFoundError.java |
Adds DLS not-found error. |
src/main/java/dev/caerus/sdk/dls/DlsOperations.java |
Defines internal DLS operations. |
src/main/java/dev/caerus/sdk/dls/DlsTimeoutError.java |
Adds DLS timeout error. |
src/main/java/dev/caerus/sdk/dls/DlsValidationError.java |
Adds DLS validation error. |
src/main/java/dev/caerus/sdk/dls/InMemoryDlsClient.java |
Implements in-memory DLS. |
src/main/java/dev/caerus/sdk/dls/LockAcquisitionCancelledError.java |
Adds cancellation error. |
src/main/java/dev/caerus/sdk/dls/LockAlreadyHeldError.java |
Adds duplicate-lock error. |
src/main/java/dev/caerus/sdk/dls/LockDeniedError.java |
Adds denial error. |
src/main/java/dev/caerus/sdk/dls/LockHolder.java |
Models acquired locks. |
src/main/java/dev/caerus/sdk/dls/LockMode.java |
Defines lock modes. |
src/main/java/dev/caerus/sdk/dls/LockModeMismatchError.java |
Adds mode error. |
src/main/java/dev/caerus/sdk/dls/LockStatus.java |
Defines lock states. |
src/main/java/dev/caerus/sdk/dls/LockStatusResponse.java |
Models lock status. |
src/main/java/dev/caerus/sdk/dls/Transaction.java |
Models transactions. |
src/main/java/dev/caerus/sdk/dls/TransactionCallback.java |
Defines transaction callbacks. |
src/main/java/dev/caerus/sdk/dls/TransactionContext.java |
Defines transaction scope API. |
src/main/java/dev/caerus/sdk/dls/TransactionLockInfo.java |
Models transaction locks. |
src/main/java/dev/caerus/sdk/dls/TransactionNotActiveError.java |
Adds inactive-transaction error. |
src/main/java/dev/caerus/sdk/dls/TransactionOptions.java |
Configures transaction scopes. |
src/main/java/dev/caerus/sdk/dls/TransactionScope.java |
Manages renewal and cleanup. |
src/main/java/dev/caerus/sdk/dls/TransactionStatusResponse.java |
Models transaction status. |
src/main/java/dev/caerus/sdk/webhooks/CaerusEvent.java |
Models webhook envelopes. |
src/main/java/dev/caerus/sdk/webhooks/CaerusSignatureError.java |
Adds signature error. |
src/main/java/dev/caerus/sdk/webhooks/CaerusWebhookExpiredError.java |
Adds expiry error. |
src/main/java/dev/caerus/sdk/webhooks/CaerusWebhookPayloadError.java |
Adds payload error. |
src/main/java/dev/caerus/sdk/webhooks/DeadlockDetectedData.java |
Models deadlock events. |
src/main/java/dev/caerus/sdk/webhooks/EventData.java |
Defines event-data hierarchy. |
src/main/java/dev/caerus/sdk/webhooks/EventTypes.java |
Dispatches event types. |
src/main/java/dev/caerus/sdk/webhooks/JsonFields.java |
Extracts webhook fields. |
src/main/java/dev/caerus/sdk/webhooks/LockAbandonedData.java |
Models abandoned locks. |
src/main/java/dev/caerus/sdk/webhooks/LockAcquireFailedData.java |
Models acquisition failures. |
src/main/java/dev/caerus/sdk/webhooks/LockAcquiredData.java |
Models lock acquisition. |
src/main/java/dev/caerus/sdk/webhooks/LockReleasedData.java |
Models lock release. |
src/main/java/dev/caerus/sdk/webhooks/ResourceConfirmedData.java |
Models confirmations. |
src/main/java/dev/caerus/sdk/webhooks/ResourceCreatedData.java |
Models resource creation. |
src/main/java/dev/caerus/sdk/webhooks/ResourceDeletedData.java |
Models resource deletion. |
src/main/java/dev/caerus/sdk/webhooks/ResourceExpiredData.java |
Models reservation expiry. |
src/main/java/dev/caerus/sdk/webhooks/ResourceExtendedData.java |
Models reservation extension. |
src/main/java/dev/caerus/sdk/webhooks/ResourceQueuedData.java |
Models queued reservations. |
src/main/java/dev/caerus/sdk/webhooks/ResourceReleasedData.java |
Models reservation release. |
src/main/java/dev/caerus/sdk/webhooks/ResourceTakeFailedData.java |
Models reservation failures. |
src/main/java/dev/caerus/sdk/webhooks/ResourceTakenData.java |
Models reservations. |
src/main/java/dev/caerus/sdk/webhooks/ResourceUpdatedData.java |
Models resource updates. |
src/main/java/dev/caerus/sdk/webhooks/TransactionAbortedData.java |
Models transaction aborts. |
src/main/java/dev/caerus/sdk/webhooks/TransactionCompletedData.java |
Models transaction completion. |
src/main/java/dev/caerus/sdk/webhooks/TransactionExpiredData.java |
Models transaction expiry. |
src/main/java/dev/caerus/sdk/webhooks/TransactionRenewedData.java |
Models transaction renewal. |
src/main/java/dev/caerus/sdk/webhooks/TransactionStartedData.java |
Models transaction start. |
src/main/java/dev/caerus/sdk/webhooks/UnknownEventData.java |
Preserves unknown events. |
src/main/java/dev/caerus/sdk/webhooks/Webhooks.java |
Verifies and decodes webhooks. |
src/test/java/dev/caerus/sdk/NoCommentsTest.java |
Enforces source policy. |
src/test/java/dev/caerus/sdk/PublicApiTest.java |
Guards public API boundaries. |
src/test/java/dev/caerus/sdk/dls/DlsClientOptionsTest.java |
Tests DLS configuration. |
src/test/java/dev/caerus/sdk/dls/DlsClientRealTest.java |
Tests DLS transport behavior. |
src/test/java/dev/caerus/sdk/dls/DlsErrorReasonsTest.java |
Tests DLS error mapping. |
src/test/java/dev/caerus/sdk/dls/DlsMappingTest.java |
Tests DLS mappings. |
src/test/java/dev/caerus/sdk/dls/DlsMethodsTest.java |
Tests DLS methods. |
src/test/java/dev/caerus/sdk/dls/DlsMockTest.java |
Tests in-memory DLS. |
src/test/java/dev/caerus/sdk/dls/DlsOnQueuedTest.java |
Tests queue callbacks. |
src/test/java/dev/caerus/sdk/dls/DlsTestClients.java |
Provides DLS test helpers. |
src/test/java/dev/caerus/sdk/internal/GeneratedContractTest.java |
Guards generated contracts. |
src/test/java/dev/caerus/sdk/internal/RequestIdTest.java |
Tests request IDs. |
src/test/java/dev/caerus/sdk/live/Live.java |
Configures live tests. |
src/test/java/dev/caerus/sdk/live/LiveDlsTest.java |
Verifies hosted DLS. |
src/test/java/dev/caerus/sdk/live/LiveSreTest.java |
Verifies hosted SRE. |
src/test/java/dev/caerus/sdk/sre/ClientOptionsTest.java |
Tests SRE configuration. |
src/test/java/dev/caerus/sdk/sre/ErrorReasonsTest.java |
Tests SRE error mapping. |
src/test/java/dev/caerus/sdk/sre/MethodsTest.java |
Tests SRE methods. |
src/test/java/dev/caerus/sdk/sre/MockTest.java |
Tests in-memory SRE. |
src/test/java/dev/caerus/sdk/sre/TimestampsAndTerminalTest.java |
Tests timestamps and states. |
src/test/java/dev/caerus/sdk/sre/TransportTest.java |
Tests SRE transport. |
src/test/java/dev/caerus/sdk/support/FakeDlsEngine.java |
Provides fake DLS server. |
src/test/java/dev/caerus/sdk/support/FakeEngine.java |
Provides fake SRE server. |
src/test/java/dev/caerus/sdk/support/GrpcErrors.java |
Builds test gRPC errors. |
src/test/java/dev/caerus/sdk/support/RealTrailers.java |
Supplies captured trailers. |
src/test/java/dev/caerus/sdk/support/RecordingServer.java |
Records test RPCs. |
src/test/java/dev/caerus/sdk/webhooks/WebhooksInteropTest.java |
Tests webhook interoperability. |
src/test/java/dev/caerus/sdk/webhooks/WebhooksTest.java |
Tests webhook behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| List<TransactionLockInfo> locks = response.getLocksList().stream() | ||
| .map(lock -> new TransactionLockInfo( | ||
| lock.getNamespace(), | ||
| lock.getLockKey(), | ||
| DlsMapping.toLockMode(lock.getRequestedModeValue()).orElse(LockMode.EXCLUSIVE), | ||
| DlsMapping.toLockStatus(lock.getStatusValue()))) |
There was a problem hiding this comment.
Se deja así a propósito. El motor trata un modo sin especificar como EXCLUSIVE (ZooKeeperDistributedLockAdapter: safeMode = LockModeDto.EXCLUSIVE cuando llega null o MODE_UNSPECIFIED), así que informarlo como EXCLUSIVE refleja lo que el motor aplicó. Además es lo que hace el SDK de TypeScript, y la API pública tiene que ser la misma en los dos. Queda anotado en docs/paridad.md.
| AcquireLockOptions resolved = options == null ? AcquireLockOptions.none() : options; | ||
| if (resolved.signal().map(signal -> signal.aborted()).orElse(false)) { | ||
| throw DlsErrors.abortedByUser(null); | ||
| } |
There was a problem hiding this comment.
Corregido en f00d091. Verificado contra el motor: con la misma clave en la misma transacción devuelve el mismo lockId y fencing token, y con otra clave responde LOCK_ALREADY_HELD_EXCLUSIVELY. El mock ahora hace las dos cosas, y hay un escenario en vivo (anIdempotencyKeyReplaysTheLockAndAnotherKeyIsAlreadyHeld) que lo comprueba contra el motor.
| AbortSignal signal = given.signal() | ||
| .or(options::signal) | ||
| .orElse(lostController.signal()); |
There was a problem hiding this comment.
Corregido en f00d091. Ahora la espera escucha las dos señales: la propia (o la de las opciones de la transacción) y la de pérdida de la transacción. Tests nuevos: losingTheTransactionAlsoCutsAWaitThatBringsItsOwnSignal e itsOwnSignalStillCutsTheWaitInsideATransaction.
| heartbeat = operations.renewalScheduler().scheduleAtFixedRate( | ||
| () -> renew(lifetime), interval, interval, TimeUnit.MILLISECONDS); |
There was a problem hiding this comment.
Corregido en f00d091. Si una renovación sigue en vuelo, el siguiente latido se saltea. Test nuevo: aSlowRenewalIsNeverOverlappedByTheNextOne (renovación de 2,5 s con intervalo de 1 s: nunca hay más de una a la vez).
| public CaerusEvent constructEvent(byte[] payload, String signatureHeader, String secret, long toleranceSeconds) { | ||
| String raw = payload == null ? "" : new String(payload, StandardCharsets.UTF_8); | ||
| return constructEvent(raw, signatureHeader, secret, toleranceSeconds); |
There was a problem hiding this comment.
Corregido en f00d091. La firma se calcula sobre timestamp + "." y los bytes crudos; después se decodifica en UTF-8 estricto, y un cuerpo inválido da CaerusWebhookPayloadError. Test nuevo: verifiesTheSignatureOverTheRawBytesEvenWhenTheyAreNotValidUtf8.
| Significa que la llamada pasó su deadline. Si el servidor llegó a hacer el trabajo, no se | ||
| sabe. Reintentar con la misma clave de idempotencia devuelve el holder que ya existía; mirá | ||
| su `status()`, porque puede volver terminado. |
There was a problem hiding this comment.
Corregido en f00d091: la guía ahora dice que un reintento sobre un holder terminado lanza ConflictError, y que para ver en qué quedó se usa getResourceHolder.
Una espera de acquireLock con senal propia dentro de withTransaction ahora tambien se corta si la transaccion se pierde; antes la senal propia reemplazaba a la de la transaccion y la espera quedaba colgada hasta el deadline. Una renovacion lenta ya no se superpone con la siguiente. La firma de un webhook se calcula sobre los bytes crudos: un cuerpo autentico con UTF-8 invalido daba error de firma en vez de error de contenido. InMemoryDlsClient replica al motor con la clave de idempotencia: la misma clave en la misma transaccion devuelve el mismo lock y otra clave da LOCK_ALREADY_HELD_EXCLUSIVELY, verificado contra el motor. La guia de errores ya no promete que un reintento devuelve un holder terminado: lanza ConflictError.


Primera etapa del SDK de Java: la API bloqueante completa, espejo de
@caerus-dev/sdk0.5.0.Qué trae
CaerusClient), DLS (DlsClient, conwithTransaction, renovación automática, cola,onQueuedy cancelación) y webhooks.InMemoryCaerusClient,InMemoryDlsClient) que implementan las mismas interfaces y son thread-safe.io.github.caerus-dev:caerus-sdk, paquetedev.caerus.sdk..protodecaerus-back(commit y SHA-256 enproto/README.md), con el paquete Java movido adev.caerus.sdk.internal.protopara que no choque con las clases del motor.Cómo se verificó
mvn verify: 366 tests contra un servidor gRPC real en127.0.0.1. Son los de TypeScript portados más tests de concurrencia con hilos.internalaparece en una firma pública (se probó metiendo una filtración a propósito), y el código no lleva comentarios.mvn test -Plive), en verde:butaca: crear, tomar con idempotencia, extender, quedarse sin stock, confirmar, borrar con holders, buscar por grupo, actualizar stock.onQueued, deadline del cliente, transacción cerrada, renovación, fencing tokens crecientes.requestIden los errores.FAILyALERT, que todavía no existen en el entorno.Diferencias con el SDK de TypeScript
Están en
docs/paridad.md: qué cambia por ser Java y qué se decidió con cada inconsistencia del SDK de TS. La única que cambia comportamiento es queInMemoryDlsClient.releaseLockde un lock inexistente no lanza error, igual que el motor. Se va a proponer el mismo cambio para TS.Lo que viene
La API asíncrona (
CompletableFuture) sobre el mismo núcleo, antes de 1.0, y la publicación en Maven Central.