diff --git a/dsl/java-test/java-client/src/main/java/dev/rsdlang/sample/client/jdkhttp/JDKSpecSamplesClient.java b/dsl/java-test/java-client/src/main/java/dev/rsdlang/sample/client/jdkhttp/JDKSpecSamplesClient.java index acd0595f..ee1ec743 100644 --- a/dsl/java-test/java-client/src/main/java/dev/rsdlang/sample/client/jdkhttp/JDKSpecSamplesClient.java +++ b/dsl/java-test/java-client/src/main/java/dev/rsdlang/sample/client/jdkhttp/JDKSpecSamplesClient.java @@ -146,7 +146,7 @@ import dev.rsdlang.sample.client.ScalarSubstition_ServiceService; import dev.rsdlang.sample.client.SpecSamplesClient; -public class JDKSpecSamplesClient implements SpecSamplesClient { +public class JDKSpecSamplesClient implements SpecSamplesClient, AutoCloseable { public enum ContentTypeEncoding { APPLICATION_JSON("application/json"), APPLICATION_VND_MSGPACK("application/vnd.msgpack"); @@ -160,7 +160,7 @@ public enum ContentTypeEncoding { public static class Builder { private URI baseURI; - private HttpClient httpClient; + private Supplier httpClientSupplier; private ContentTypeEncoding contentTypeEncoding; public Builder baseURI(URI baseURI) { @@ -169,7 +169,11 @@ public Builder baseURI(URI baseURI) { } public Builder httpClient(HttpClient httpClient) { - this.httpClient = httpClient; + return httpClientSupplier(() -> httpClient); + } + + public Builder httpClientSupplier(Supplier httpClientSupplier) { + this.httpClientSupplier = httpClientSupplier; return this; } @@ -182,11 +186,20 @@ public SpecSamplesClient build() { if (baseURI == null) { throw new IllegalStateException("baseURI must be set"); } - var client = (httpClient != null) ? httpClient : HttpClient.newHttpClient(); - if (contentTypeEncoding == null) { - contentTypeEncoding = ContentTypeEncoding.APPLICATION_JSON; + var contentType = contentTypeEncoding == null ? ContentTypeEncoding.APPLICATION_JSON : contentTypeEncoding; + if (httpClientSupplier == null) { + return new JDKSpecSamplesClient(baseURI, new InternalClientSupplier(), contentType); } - return new JDKSpecSamplesClient(baseURI, client, contentTypeEncoding); + return new JDKSpecSamplesClient(baseURI, httpClientSupplier, contentType); + } + } + + static class InternalClientSupplier implements Supplier { + private final HttpClient client = HttpClient.newBuilder().build(); + + @Override + public HttpClient get() { + return client; } } @@ -306,12 +319,12 @@ private static void registerServiceCreator(Class clazz, BiFunction httpClientSupplier; private final ContentTypeEncoding contentTypeEncoding; - JDKSpecSamplesClient(URI baseURI, HttpClient httpClient, ContentTypeEncoding contentTypeEncoding) { + JDKSpecSamplesClient(URI baseURI, Supplier httpClientSupplier, ContentTypeEncoding contentTypeEncoding) { this.baseURI = baseURI; - this.httpClient = httpClient; + this.httpClientSupplier = httpClientSupplier; this.contentTypeEncoding = contentTypeEncoding; } @@ -320,7 +333,7 @@ public ContentTypeEncoding contentTypeEncoding() { } public HttpClient httpClient() { - return this.httpClient; + return this.httpClientSupplier.get(); } public URI baseURI() { @@ -397,4 +410,18 @@ public RSDBlob createBlob(Path file, String mimeType) { public RSDFile createFile(Path file, String mimeType, String filename) { return _FileImpl.of(file, mimeType, filename); } + + @Override + public void close() { + if (this.httpClientSupplier instanceof InternalClientSupplier) { + var client = this.httpClientSupplier.get(); + client.close(); + } else if (this.httpClientSupplier instanceof AutoCloseable closeable) { + try { + closeable.close(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + } } diff --git a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/BinaryTypesServiceTest.java b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/BinaryTypesServiceTest.java index b1ceced8..4d2df1b3 100644 --- a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/BinaryTypesServiceTest.java +++ b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/BinaryTypesServiceTest.java @@ -32,8 +32,8 @@ static void setUp() { @AfterAll static void tearDown() { - ((JDKSpecSamplesClient) JSON).httpClient().close(); - ((JDKSpecSamplesClient) MSGPACK).httpClient().close(); + ((JDKSpecSamplesClient) JSON).close(); + ((JDKSpecSamplesClient) MSGPACK).close(); } static BinaryTypesService[] serviceProvider() { diff --git a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/BodyParameterTypesServiceTest.java b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/BodyParameterTypesServiceTest.java index 9b40184a..41c05138 100644 --- a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/BodyParameterTypesServiceTest.java +++ b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/BodyParameterTypesServiceTest.java @@ -42,8 +42,8 @@ static void setUp() { @AfterAll static void tearDown() { - ((JDKSpecSamplesClient) JSON).httpClient().close(); - ((JDKSpecSamplesClient) MSGPACK).httpClient().close(); + ((JDKSpecSamplesClient) JSON).close(); + ((JDKSpecSamplesClient) MSGPACK).close(); } static BodyParameterTypesService[] serviceProvider() { diff --git a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/HeaderParameterTypesServiceTest.java b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/HeaderParameterTypesServiceTest.java index 5a413bc2..c70136a0 100644 --- a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/HeaderParameterTypesServiceTest.java +++ b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/HeaderParameterTypesServiceTest.java @@ -40,8 +40,8 @@ static void setUp() { @AfterAll static void tearDown() { - ((JDKSpecSamplesClient) JSON).httpClient().close(); - ((JDKSpecSamplesClient) MSGPACK).httpClient().close(); + ((JDKSpecSamplesClient) JSON).close(); + ((JDKSpecSamplesClient) MSGPACK).close(); } static HeaderParameterTypesService[] serviceProvider() { diff --git a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListBodyParameterTypesServiceTest.java b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListBodyParameterTypesServiceTest.java index 14d71fb1..203ce995 100644 --- a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListBodyParameterTypesServiceTest.java +++ b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListBodyParameterTypesServiceTest.java @@ -40,8 +40,8 @@ static void setUp() { @AfterAll static void tearDown() { - ((JDKSpecSamplesClient) JSON).httpClient().close(); - ((JDKSpecSamplesClient) MSGPACK).httpClient().close(); + ((JDKSpecSamplesClient) JSON).close(); + ((JDKSpecSamplesClient) MSGPACK).close(); } static ListBodyParameterTypesService[] serviceProvider() { diff --git a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListHeaderParameterTypesServiceTest.java b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListHeaderParameterTypesServiceTest.java index ba7cefcd..b4ec118d 100644 --- a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListHeaderParameterTypesServiceTest.java +++ b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListHeaderParameterTypesServiceTest.java @@ -40,8 +40,8 @@ static void setUp() { @AfterAll static void tearDown() { - ((JDKSpecSamplesClient) JSON).httpClient().close(); - ((JDKSpecSamplesClient) MSGPACK).httpClient().close(); + ((JDKSpecSamplesClient) JSON).close(); + ((JDKSpecSamplesClient) MSGPACK).close(); } static ListHeaderParameterTypesService[] serviceProvider() { diff --git a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListQueryParameterTypesServiceTest.java b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListQueryParameterTypesServiceTest.java index 6563e43f..4a839d39 100644 --- a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListQueryParameterTypesServiceTest.java +++ b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListQueryParameterTypesServiceTest.java @@ -36,8 +36,8 @@ static void setUp() { @AfterAll static void tearDown() { - ((JDKSpecSamplesClient) JSON).httpClient().close(); - ((JDKSpecSamplesClient) MSGPACK).httpClient().close(); + ((JDKSpecSamplesClient) JSON).close(); + ((JDKSpecSamplesClient) MSGPACK).close(); } static ListQueryParameterTypesService[] serviceProvider() { diff --git a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListSampleServiceServiceTest.java b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListSampleServiceServiceTest.java index d2945303..3899eca3 100644 --- a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListSampleServiceServiceTest.java +++ b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ListSampleServiceServiceTest.java @@ -34,8 +34,8 @@ static void setUp() { @AfterAll static void tearDown() { - ((JDKSpecSamplesClient) JSON).httpClient().close(); - ((JDKSpecSamplesClient) MSGPACK).httpClient().close(); + ((JDKSpecSamplesClient) JSON).close(); + ((JDKSpecSamplesClient) MSGPACK).close(); } static ListSampleServiceService[] serviceProvider() { diff --git a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/PathParameterTypeServiceServiceTest.java b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/PathParameterTypeServiceServiceTest.java index 59056d24..c194aa5f 100644 --- a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/PathParameterTypeServiceServiceTest.java +++ b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/PathParameterTypeServiceServiceTest.java @@ -33,8 +33,8 @@ static void setUp() { @AfterAll static void tearDown() { - ((JDKSpecSamplesClient) JSON).httpClient().close(); - ((JDKSpecSamplesClient) MSGPACK).httpClient().close(); + ((JDKSpecSamplesClient) JSON).close(); + ((JDKSpecSamplesClient) MSGPACK).close(); } static PathParameterTypeServiceService[] serviceProvider() { diff --git a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/QueryParameterTypesServiceTest.java b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/QueryParameterTypesServiceTest.java index d5c8df44..b7c9e49f 100644 --- a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/QueryParameterTypesServiceTest.java +++ b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/QueryParameterTypesServiceTest.java @@ -35,8 +35,8 @@ static void setUp() { @AfterAll static void tearDown() { - ((JDKSpecSamplesClient) JSON).httpClient().close(); - ((JDKSpecSamplesClient) MSGPACK).httpClient().close(); + ((JDKSpecSamplesClient) JSON).close(); + ((JDKSpecSamplesClient) MSGPACK).close(); } static QueryParameterTypesService[] serviceProvider() { diff --git a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/SampleServiceServiceTest.java b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/SampleServiceServiceTest.java index 7b9b80e7..99cdf657 100644 --- a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/SampleServiceServiceTest.java +++ b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/SampleServiceServiceTest.java @@ -34,8 +34,8 @@ static void setUp() { @AfterAll static void tearDown() { - ((JDKSpecSamplesClient) JSON).httpClient().close(); - ((JDKSpecSamplesClient) MSGPACK).httpClient().close(); + ((JDKSpecSamplesClient) JSON).close(); + ((JDKSpecSamplesClient) MSGPACK).close(); } static SampleServiceService[] serviceProvider() { diff --git a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ScalarSubstition_ServiceServiceTest.java b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ScalarSubstition_ServiceServiceTest.java index af600f65..ed15ec17 100644 --- a/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ScalarSubstition_ServiceServiceTest.java +++ b/dsl/java-test/java-client/src/test/java/dev/rsdlang/sample/client/ScalarSubstition_ServiceServiceTest.java @@ -28,8 +28,8 @@ static void setUp() { @AfterAll static void tearDown() { - ((JDKSpecSamplesClient) JSON).httpClient().close(); - ((JDKSpecSamplesClient) MSGPACK).httpClient().close(); + ((JDKSpecSamplesClient) JSON).close(); + ((JDKSpecSamplesClient) MSGPACK).close(); } static ScalarSubstition_ServiceService[] serviceProvider() { diff --git a/dsl/packages/cli/src/java-rest-client-jdk/client.ts b/dsl/packages/cli/src/java-rest-client-jdk/client.ts index 0f29770e..8c08cc71 100644 --- a/dsl/packages/cli/src/java-rest-client-jdk/client.ts +++ b/dsl/packages/cli/src/java-rest-client-jdk/client.ts @@ -39,7 +39,10 @@ export function generateClient( const Optional = fqn('java.util.Optional'); const content = new CompositeGeneratorNode(); - content.append(`public class JDK${toCamelCaseIdentifier(generatorConfig.name)}Client implements ${Client} {`, NL); + content.append( + `public class JDK${toCamelCaseIdentifier(generatorConfig.name)}Client implements ${Client}, AutoCloseable {`, + NL, + ); content.indent(classBody => { const contentEncodings = artifactConfig.contentTypeEncodings === undefined || artifactConfig.contentTypeEncodings.length === 0 @@ -65,7 +68,7 @@ export function generateClient( const builder = toNodeTree(` public static class Builder { private URI baseURI; - private HttpClient httpClient; + private Supplier httpClientSupplier; private ContentTypeEncoding contentTypeEncoding; public Builder baseURI(URI baseURI) { @@ -74,7 +77,11 @@ export function generateClient( } public Builder httpClient(HttpClient httpClient) { - this.httpClient = httpClient; + return httpClientSupplier(() -> httpClient); + } + + public Builder httpClientSupplier(Supplier httpClientSupplier) { + this.httpClientSupplier = httpClientSupplier; return this; } @@ -87,11 +94,20 @@ export function generateClient( if (baseURI == null) { throw new IllegalStateException("baseURI must be set"); } - var client = (httpClient != null) ? httpClient : HttpClient.newHttpClient(); - if (contentTypeEncoding == null) { - contentTypeEncoding = ContentTypeEncoding.${toEnumLiteral(contentEncodings[0])}; + var contentType = contentTypeEncoding == null ? ContentTypeEncoding.${toEnumLiteral(contentEncodings[0])} : contentTypeEncoding; + if (httpClientSupplier == null) { + return new JDK${toCamelCaseIdentifier(generatorConfig.name)}Client(baseURI, new InternalClientSupplier(), contentType); } - return new JDK${toCamelCaseIdentifier(generatorConfig.name)}Client(baseURI, client, contentTypeEncoding); + return new JDK${toCamelCaseIdentifier(generatorConfig.name)}Client(baseURI, httpClientSupplier, contentType); + } + } + + static class InternalClientSupplier implements Supplier { + private final HttpClient client = HttpClient.newBuilder().build(); + + @Override + public HttpClient get() { + return client; } } @@ -181,18 +197,18 @@ export function generateClient( clBody.append('}', NL); clBody.appendNewLine(); clBody.append(`private final ${URI} baseURI;`, NL); - clBody.append(`private final ${HttpClient} httpClient;`, NL); + clBody.append(`private final ${Supplier}<${HttpClient}> httpClientSupplier;`, NL); clBody.append(`private final ContentTypeEncoding contentTypeEncoding;`, NL); clBody.appendNewLine(); clBody.append( `JDK${toCamelCaseIdentifier( generatorConfig.name, - )}Client(${URI} baseURI, ${HttpClient} httpClient, ContentTypeEncoding contentTypeEncoding) {`, + )}Client(${URI} baseURI, ${Supplier}<${HttpClient}> httpClientSupplier, ContentTypeEncoding contentTypeEncoding) {`, NL, ); clBody.indent(initBlock => { initBlock.append('this.baseURI = baseURI;', NL); - initBlock.append('this.httpClient = httpClient;', NL); + initBlock.append('this.httpClientSupplier = httpClientSupplier;', NL); initBlock.append('this.contentTypeEncoding = contentTypeEncoding;', NL); }); clBody.append('}', NL); @@ -203,7 +219,7 @@ export function generateClient( } public HttpClient httpClient() { - return this.httpClient; + return this.httpClientSupplier.get(); } public URI baseURI() { @@ -351,6 +367,24 @@ export function generateClient( } }); + const autoClose = toNodeTree(` + @Override + public void close() { + if (this.httpClientSupplier instanceof InternalClientSupplier) { + var client = this.httpClientSupplier.get(); + client.close(); + } else if (this.httpClientSupplier instanceof AutoCloseable closeable) { + try { + closeable.close(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + }`); + content.indent(clBody => { + clBody.appendNewLine(); + clBody.append(autoClose, NL); + }); content.append('}', NL); return {