Description
MirrorNodeRestClientImpl.doGetCall and every RestBasedPage constructor call ClientBuilder.newClient() on each request and never close the returned jakarta.ws.rs.client.Client. Each Client carries an internal thread/connection pool, so under any non-trivial load the process accumulates them until resources are exhausted. The MirrorNodeClient CDI producer is @ApplicationScoped, so a single shared Client is all that is needed.
On top of that, only HTTP 404 is handled: any other 4xx/5xx response is passed straight to readEntity(JsonObject.class), so the caller either gets the mirror-node error payload as if it were valid data or a ProcessingException with no status context. MirrorNodeRestClient.doGetCall declares throws HieroException but never actually throws it for server errors. The Spring module does not have either problem.
Response objects are never closed either (try-with-resources would be enough).
Evidence
hiero-enterprise-microprofile/src/main/java/org/hiero/microprofile/implementation/MirrorNodeRestClientImpl.java (lines 21-29)
hiero-enterprise-microprofile/src/main/java/org/hiero/microprofile/implementation/RestBasedPage.java (lines 49-57) — invoked per page in next() and first()
jakarta.ws.rs.client.Client Javadoc: "Clients are heavy-weight objects that manage the client-side communication infrastructure. Initialization as well as disposal of a Client instance may be a rather expensive operation."
Expected behavior
MirrorNodeRestClientImpl caches a single Client + root WebTarget, implements AutoCloseable, and is disposed via CDI @Disposes on the @ApplicationScoped producer.
RestBasedPage reuses that WebTarget instead of building its own Client.
- Non-404 4xx/5xx responses throw
HieroException with status + path in the message.
Response objects closed deterministically.
Description
MirrorNodeRestClientImpl.doGetCalland everyRestBasedPageconstructor callClientBuilder.newClient()on each request and never close the returnedjakarta.ws.rs.client.Client. EachClientcarries an internal thread/connection pool, so under any non-trivial load the process accumulates them until resources are exhausted. TheMirrorNodeClientCDI producer is@ApplicationScoped, so a single sharedClientis all that is needed.On top of that, only HTTP 404 is handled: any other 4xx/5xx response is passed straight to
readEntity(JsonObject.class), so the caller either gets the mirror-node error payload as if it were valid data or aProcessingExceptionwith no status context.MirrorNodeRestClient.doGetCalldeclaresthrows HieroExceptionbut never actually throws it for server errors. The Spring module does not have either problem.Responseobjects are never closed either (try-with-resources would be enough).Evidence
hiero-enterprise-microprofile/src/main/java/org/hiero/microprofile/implementation/MirrorNodeRestClientImpl.java(lines 21-29)hiero-enterprise-microprofile/src/main/java/org/hiero/microprofile/implementation/RestBasedPage.java(lines 49-57) — invoked per page innext()andfirst()jakarta.ws.rs.client.ClientJavadoc: "Clients are heavy-weight objects that manage the client-side communication infrastructure. Initialization as well as disposal of a Client instance may be a rather expensive operation."Expected behavior
MirrorNodeRestClientImplcaches a singleClient+ rootWebTarget, implementsAutoCloseable, and is disposed via CDI@Disposeson the@ApplicationScopedproducer.RestBasedPagereuses thatWebTargetinstead of building its ownClient.HieroExceptionwith status + path in the message.Responseobjects closed deterministically.