Skip to content

Commit 2e62099

Browse files
committed
Rewrite CloseableHttpResponse to ClassicHttpResponse and use executeOpen
When using CloseableHttpResponse and execute() with a response handler, the http connection was closed after the response handler terminated. Returning the http response was not feasible because the http connection was closed and thus so was the InputStream with the content of the response. Using executeOpen() keeps the connection open and makes it possible to return the response object for later use. The InputStream remains open and unconsumed. The caller, howevever, is now responsible for closing the InputStream and by extension also the Http connection. This is easily done as pointed out in the examples with a try-with-resources.
1 parent 96c00c4 commit 2e62099

10 files changed

Lines changed: 52 additions & 60 deletions

File tree

src/main/java/no/digipost/api/client/DigipostClient.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@
5757
import no.digipost.api.client.tag.TagApi;
5858
import no.digipost.api.client.util.JAXBContextUtils;
5959
import no.digipost.http.client.HttpClientFactory;
60-
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
6160
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
61+
import org.apache.hc.core5.http.ClassicHttpResponse;
6262
import org.slf4j.Logger;
6363
import org.slf4j.LoggerFactory;
6464

@@ -145,7 +145,7 @@ public OngoingDelivery.ForPrintOnly createPrintOnlyMessage(final Message printMe
145145
}
146146

147147
public IdentificationResult identifyRecipient(final Identification identification) {
148-
try (CloseableHttpResponse response = messageApi.identifyRecipient(identification)) {
148+
try (ClassicHttpResponse response = messageApi.identifyRecipient(identification)) {
149149
checkResponse(response, eventLogger);
150150
return JAXBContextUtils.unmarshal(jaxbContext, response.getEntity().getContent(), IdentificationResult.class);
151151
} catch (IOException e) {
@@ -330,7 +330,7 @@ public SharedDocumentContent getSharedDocumentContent(URI uri) {
330330
return sharedDocumentsApi.getSharedDocumentContent(uri);
331331
}
332332

333-
public CloseableHttpResponse stopSharing(SenderId senderId, URI uri) {
333+
public ClassicHttpResponse stopSharing(SenderId senderId, URI uri) {
334334
return sharedDocumentsApi.stopSharing(senderId, uri);
335335
}
336336

src/main/java/no/digipost/api/client/archive/ArchiveApi.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import no.digipost.api.client.representations.archive.ArchiveDocument;
2121
import no.digipost.api.client.representations.archive.ArchiveDocumentContent;
2222
import no.digipost.api.client.representations.archive.Archives;
23-
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
23+
import org.apache.hc.core5.http.ClassicHttpResponse;
2424
import org.apache.hc.core5.http.HttpEntity;
2525

2626
import java.io.ByteArrayInputStream;
@@ -32,7 +32,7 @@ public interface ArchiveApi {
3232

3333
Archives getArchives(SenderId senderId);
3434

35-
CloseableHttpResponse sendMultipartArchive(HttpEntity build);
35+
ClassicHttpResponse sendMultipartArchive(HttpEntity build);
3636

3737
Archive getArchiveDocuments(URI uri);
3838

src/main/java/no/digipost/api/client/delivery/MessageDeliveryApi.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import no.digipost.api.client.representations.accounts.UserAccount;
2626
import no.digipost.api.client.representations.accounts.UserInformation;
2727
import no.digipost.api.client.representations.sender.SenderInformation;
28-
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
28+
import org.apache.hc.core5.http.ClassicHttpResponse;
2929
import org.apache.hc.core5.http.HttpEntity;
3030

3131
import java.net.URI;
@@ -49,35 +49,35 @@ public interface MessageDeliveryApi {
4949
/**
5050
* Oppretter og sender en multipartforsendelse
5151
*/
52-
CloseableHttpResponse sendMultipartMessage(HttpEntity multipart);
52+
ClassicHttpResponse sendMultipartMessage(HttpEntity multipart);
5353

5454
/**
5555
* Legger til ytterligere data til et dokument.
5656
* Det er en forutsetning at dokumentet har datatype fra tidligere.
5757
*/
58-
CloseableHttpResponse addData(AddDataLink document, AdditionalData data);
58+
ClassicHttpResponse addData(AddDataLink document, AdditionalData data);
5959

6060
Recipients search(String searchString);
6161

6262
Autocomplete searchSuggest(String searchString);
6363

64-
CloseableHttpResponse identifyRecipient(Identification identification);
64+
ClassicHttpResponse identifyRecipient(Identification identification);
6565

6666
/**
6767
* Sjekker hvis spesifisert mottaker er Digipost-bruker.
6868
* Returnerer då også publik del av krypteringsnøkkel for Digipost-bruker.
6969
* Nøkkelen brukes for å kryptere dokument-innhold for dokumenter som
7070
* skal prekrypteres.
7171
*/
72-
CloseableHttpResponse identifyAndGetEncryptionKey(Identification identification);
72+
ClassicHttpResponse identifyAndGetEncryptionKey(Identification identification);
7373

7474

75-
CloseableHttpResponse getEncryptionKey(URI location);
75+
ClassicHttpResponse getEncryptionKey(URI location);
7676

7777
/**
7878
* Henter public krypteringsnøkkel i x509 format for forsendelser som skal sendes til print.
7979
*/
80-
CloseableHttpResponse getEncryptionCertificateForPrint();
80+
ClassicHttpResponse getEncryptionCertificateForPrint();
8181

8282
/**
8383
* Henter informasjon om en faktisk avsender av en melding, altså

src/main/java/no/digipost/api/client/internal/ApiServiceImpl.java

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,14 @@
7676
import org.apache.hc.client5.http.classic.methods.HttpPost;
7777
import org.apache.hc.client5.http.classic.methods.HttpPut;
7878
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
79-
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
8079
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
8180
import org.apache.hc.core5.http.ClassicHttpRequest;
81+
import org.apache.hc.core5.http.ClassicHttpResponse;
8282
import org.apache.hc.core5.http.ContentType;
8383
import org.apache.hc.core5.http.Header;
8484
import org.apache.hc.core5.http.HttpEntity;
8585
import org.apache.hc.core5.http.HttpHeaders;
8686
import org.apache.hc.core5.http.HttpStatus;
87-
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
8887
import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
8988
import org.apache.hc.core5.http.protocol.HttpContext;
9089
import org.apache.hc.core5.http.protocol.HttpCoreContext;
@@ -164,7 +163,7 @@ public EntryPoint getEntryPoint() {
164163

165164

166165
@Override
167-
public CloseableHttpResponse sendMultipartMessage(HttpEntity multipart) {
166+
public ClassicHttpResponse sendMultipartMessage(HttpEntity multipart) {
168167
MultipartNoLengthCheckHttpEntity multipartLengthCheckHttpEntity = new MultipartNoLengthCheckHttpEntity(multipart);
169168

170169
EntryPoint entryPoint = getEntryPoint();
@@ -179,7 +178,7 @@ public CloseableHttpResponse sendMultipartMessage(HttpEntity multipart) {
179178
}
180179

181180
@Override
182-
public CloseableHttpResponse sendMultipartArchive(HttpEntity multipart) {
181+
public ClassicHttpResponse sendMultipartArchive(HttpEntity multipart) {
183182
MultipartNoLengthCheckHttpEntity multipartLengthCheckHttpEntity = new MultipartNoLengthCheckHttpEntity(multipart);
184183

185184
EntryPoint entryPoint = getEntryPoint();
@@ -213,20 +212,20 @@ public InputStream getArchiveDocumentContentStream(URI uri) {
213212
}
214213

215214
@Override
216-
public CloseableHttpResponse identifyAndGetEncryptionKey(Identification identification) {
215+
public ClassicHttpResponse identifyAndGetEncryptionKey(Identification identification) {
217216
EntryPoint entryPoint = getEntryPoint();
218217
return sendDigipostMedia(identification, entryPoint.getIdentificationWithEncryptionKeyUri().getPath());
219218
}
220219

221220
@Override
222-
public CloseableHttpResponse getEncryptionKey(URI location) {
221+
public ClassicHttpResponse getEncryptionKey(URI location) {
223222
HttpGet httpGet = new HttpGet(location);
224223
httpGet.setHeader(Accept_DIGIPOST_MEDIA_TYPE_V8);
225224
return send(httpGet);
226225
}
227226

228227
@Override
229-
public CloseableHttpResponse getEncryptionCertificateForPrint() {
228+
public ClassicHttpResponse getEncryptionCertificateForPrint() {
230229
EntryPoint entryPoint = getEntryPoint();
231230

232231
HttpGet httpGet = new HttpGet(digipostUrl.resolve(entryPoint.getPrintEncryptionCertificate().getPath()));
@@ -235,7 +234,7 @@ public CloseableHttpResponse getEncryptionCertificateForPrint() {
235234
}
236235

237236
@Override
238-
public CloseableHttpResponse addData(AddDataLink addDataLink, AdditionalData data) {
237+
public ClassicHttpResponse addData(AddDataLink addDataLink, AdditionalData data) {
239238
return sendDigipostMedia(data, addDataLink.getPath());
240239
}
241240

@@ -300,7 +299,7 @@ public Autocomplete searchSuggest(String searchString) {
300299
}
301300

302301
@Override
303-
public CloseableHttpResponse identifyRecipient(Identification identification) {
302+
public ClassicHttpResponse identifyRecipient(Identification identification) {
304303
return sendDigipostMedia(identification, getEntryPoint().getIdentificationUri().getPath());
305304
}
306305

@@ -309,7 +308,7 @@ private EntryPoint fetchEntryPoint(Optional<SenderId> senderId) throws IOExcepti
309308
httpGet.setHeader(Accept_DIGIPOST_MEDIA_TYPE_V8);
310309
final HttpCoreContext httpCoreContext = HttpCoreContext.create();
311310
httpCoreContext.setAttribute(ResponseSignatureInterceptor.NOT_SIGNED_RESPONSE, true);
312-
try (CloseableHttpResponse response = send(httpGet, httpCoreContext)) {
311+
try (ClassicHttpResponse response = send(httpGet, httpCoreContext)) {
313312

314313
if (response.getCode() == HttpStatus.SC_OK) {
315314
return unmarshal(jaxbContext, response.getEntity().getContent(), EntryPoint.class);
@@ -391,7 +390,7 @@ public Archive addUniqueUUIDToArchiveDocument(SenderId senderId, UUID uuid, UUID
391390
newuuid, document.getFileName(), document.getFileType(), document.getContentType()
392391
);
393392

394-
try (CloseableHttpResponse response = sendDigipostMedia(nyttDokument, addUniqeUUIDUri.getPath())) {
393+
try (ClassicHttpResponse response = sendDigipostMedia(nyttDokument, addUniqeUUIDUri.getPath())) {
395394
checkResponse(response, eventLogger);
396395

397396
archive.getDocuments().addAll(unmarshal(jaxbContext, response.getEntity().getContent(), Archive.class).getDocuments());
@@ -450,7 +449,7 @@ public UserAccount createOrActivateUserAccount(SenderId senderId, UserInformatio
450449
@Override
451450
public Batch createBatch(UUID batchUUID) {
452451
final URI createBatch = getEntryPoint().getCreateBatch();
453-
try (CloseableHttpResponse response = sendDigipostMedia(new Batch(batchUUID.toString()), createBatch.toString())) {
452+
try (ClassicHttpResponse response = sendDigipostMedia(new Batch(batchUUID.toString()), createBatch.toString())) {
454453
checkResponse(response, eventLogger);
455454
return JAXBContextUtils.unmarshal(jaxbContext, response.getEntity().getContent(), Batch.class);
456455
} catch (IOException e) {
@@ -478,7 +477,7 @@ public void cancelBatch(Batch batch) {
478477
@Override
479478
public void addTag(Tag tag) {
480479
URI uri = getEntryPoint().getAddTagUri();
481-
try (CloseableHttpResponse response = sendDigipostMedia(tag, uri.getPath())) {
480+
try (ClassicHttpResponse response = sendDigipostMedia(tag, uri.getPath())) {
482481
checkResponse(response, eventLogger);
483482
} catch (IOException e) {
484483
throw new DigipostClientException(ErrorCode.GENERAL_ERROR, e);
@@ -488,7 +487,7 @@ public void addTag(Tag tag) {
488487
@Override
489488
public void removeTag(Tag tag) {
490489
URI uri = getEntryPoint().getRemoveTagUri();
491-
try (CloseableHttpResponse response = sendDigipostMedia(tag, uri.getPath())) {
490+
try (ClassicHttpResponse response = sendDigipostMedia(tag, uri.getPath())) {
492491
checkResponse(response, eventLogger);
493492
} catch (IOException e) {
494493
throw new DigipostClientException(ErrorCode.GENERAL_ERROR, e);
@@ -522,7 +521,7 @@ public SharedDocumentContent getSharedDocumentContent(URI uri) {
522521
}
523522

524523
@Override
525-
public CloseableHttpResponse stopSharing(SenderId senderId, URI uri) {
524+
public ClassicHttpResponse stopSharing(SenderId senderId, URI uri) {
526525
DataType dataType = new ShareDocumentsRequestSharingStopped();
527526
AdditionalData data = AdditionalData.Builder
528527
.newAdditionalData(dataType)
@@ -570,7 +569,7 @@ private <R> R request(ClassicHttpRequest request, Class<R> entityType, Header ..
570569
R responseStream = (R) safelyOfferEntityStreamExternally(send(request), eventLogger);
571570
return responseStream;
572571
} else {
573-
try (CloseableHttpResponse response = send(request)) {
572+
try (ClassicHttpResponse response = send(request)) {
574573
checkResponse(response, eventLogger);
575574
return unmarshal(response.getEntity().getContent(), entityType);
576575
} catch (IOException e) {
@@ -580,24 +579,20 @@ private <R> R request(ClassicHttpRequest request, Class<R> entityType, Header ..
580579

581580
}
582581

583-
private CloseableHttpResponse send(ClassicHttpRequest request){
582+
private ClassicHttpResponse send(ClassicHttpRequest request) {
584583
return send(request, null);
585584
}
586585

587-
private CloseableHttpResponse send(ClassicHttpRequest request, HttpContext context){
586+
private ClassicHttpResponse send(ClassicHttpRequest request, HttpContext context) {
588587
try {
589588
request.setHeader(X_Digipost_UserId, brokerId.stringValue());
590-
if (context == null) {
591-
return httpClient.execute(request, responseHandler());
592-
} else {
593-
return httpClient.execute(request, context, responseHandler());
594-
}
589+
return httpClient.executeOpen(null, request, context);
595590
} catch (IOException e) {
596591
throw asUnchecked(e);
597592
}
598593
}
599594

600-
private CloseableHttpResponse sendDigipostMedia(Object data, String uri) {
595+
private ClassicHttpResponse sendDigipostMedia(Object data, String uri) {
601596
HttpPost httpPost = new HttpPost(digipostUrl.resolve(uri));
602597
httpPost.setHeader(Accept_DIGIPOST_MEDIA_TYPE_V8);
603598
httpPost.setHeader(Content_Type_DIGIPOST_MEDIA_TYPE_V8);
@@ -606,15 +601,4 @@ private CloseableHttpResponse sendDigipostMedia(Object data, String uri) {
606601
httpPost.setEntity(new ByteArrayEntity(bao.toByteArray(), ContentType.create(DIGIPOST_MEDIA_TYPE_V8)));
607602
return send(httpPost);
608603
}
609-
610-
private HttpClientResponseHandler<CloseableHttpResponse> responseHandler() {
611-
return response -> {
612-
if (response instanceof CloseableHttpResponse) {
613-
return (CloseableHttpResponse) response;
614-
} else {
615-
throw new DigipostClientException(ErrorCode.GENERAL_ERROR,
616-
"Expected response to be instance of CloseableHttpResponse, but got " + response.getClass().getName());
617-
}
618-
};
619-
}
620604
}

src/main/java/no/digipost/api/client/internal/delivery/ArchiveDeliverer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.hc.client5.http.entity.mime.HttpMultipartMode;
3131
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
3232
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
33+
import org.apache.hc.core5.http.ClassicHttpResponse;
3334
import org.apache.hc.core5.http.ContentType;
3435
import org.slf4j.Logger;
3536
import org.slf4j.LoggerFactory;
@@ -99,7 +100,7 @@ public Archive sendMultipartMessage(Archive archive, Map<UUID, DocumentContent>
99100
.addField("Content-Disposition", "attachment;" + " filename=\"" + document.uuid.toString() + "\"").build());
100101
}
101102
eventLogger.log("*** STARTER INTERAKSJON MED API: Arkiverer filer ***");
102-
try (CloseableHttpResponse response = apiService.sendMultipartArchive(multipartEntity.build())) {
103+
try (ClassicHttpResponse response = apiService.sendMultipartArchive(multipartEntity.build())) {
103104
checkResponse(response, eventLogger);
104105

105106
eventLogger.log("Arkivdokumentet ble sendt. Status: [" + response + "]");

src/main/java/no/digipost/api/client/internal/delivery/MessageDeliverer.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
import org.apache.hc.client5.http.entity.mime.FormBodyPartBuilder;
4545
import org.apache.hc.client5.http.entity.mime.HttpMultipartMode;
4646
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
47-
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
47+
import org.apache.hc.core5.http.ClassicHttpResponse;
4848
import org.apache.hc.core5.http.ContentType;
4949
import org.slf4j.Logger;
5050
import org.slf4j.LoggerFactory;
@@ -155,7 +155,7 @@ public MessageDelivery sendMultipartMessage(Message message, Map<UUID, DocumentC
155155
.addField("Content-Disposition", "attachment;" + " filename=\"" + document.uuid.toString() + "\"").build());
156156
}
157157
eventLogger.log("*** STARTER INTERAKSJON MED API: SENDER MELDING MED ID " + singleChannelMessage.messageId + " ***");
158-
try (CloseableHttpResponse response = apiService.sendMultipartMessage(multipartEntity.build())) {
158+
try (ClassicHttpResponse response = apiService.sendMultipartMessage(multipartEntity.build())) {
159159
checkResponse(response, eventLogger);
160160

161161
eventLogger.log("Brevet ble sendt. Status: [" + response + "]");
@@ -174,7 +174,7 @@ public MessageDelivery sendMultipartMessage(Message message, Map<UUID, DocumentC
174174

175175
public void addData(AddDataLink addDataLink, AdditionalData data) {
176176
eventLogger.log("*** STARTER INTERAKSJON MED API: LEGGER TIL DATA PÅ DOKUMENT ***");
177-
try (CloseableHttpResponse response = apiService.addData(addDataLink, data)) {
177+
try (ClassicHttpResponse response = apiService.addData(addDataLink, data)) {
178178

179179
checkResponse(response, eventLogger);
180180

@@ -193,7 +193,7 @@ public void addData(AddDataLink addDataLink, AdditionalData data) {
193193
public InputStream fetchKeyAndEncrypt(Document document, InputStream content) {
194194
checkThatMessageCanBePreEncrypted(document);
195195

196-
try(CloseableHttpResponse encryptionKeyResponse = apiService.getEncryptionKey(document.getEncryptionKeyLink().getUri())){
196+
try(ClassicHttpResponse encryptionKeyResponse = apiService.getEncryptionKey(document.getEncryptionKeyLink().getUri())){
197197
checkResponse(encryptionKeyResponse, eventLogger);
198198

199199
EncryptionKey key = unmarshal(jaxbContext, encryptionKeyResponse.getEntity().getContent(), EncryptionKey.class);
@@ -205,7 +205,7 @@ public InputStream fetchKeyAndEncrypt(Document document, InputStream content) {
205205
}
206206

207207
public IdentificationResultWithEncryptionKey identifyAndGetEncryptionKey(Identification identification) {
208-
try(CloseableHttpResponse response = apiService.identifyAndGetEncryptionKey(identification)){
208+
try(ClassicHttpResponse response = apiService.identifyAndGetEncryptionKey(identification)){
209209
checkResponse(response, eventLogger);
210210
IdentificationResultWithEncryptionKey result =
211211
unmarshal(jaxbContext, response.getEntity().getContent(), IdentificationResultWithEncryptionKey.class);
@@ -228,7 +228,7 @@ public X509Certificate getEncryptionCertificateForPrint() {
228228

229229
if (ZERO.equals(config.printKeyCacheTimeToLive) || between(printKeyCachedTime, now).compareTo(config.printKeyCacheTimeToLive) > 0) {
230230
eventLogger.log("*** STARTER INTERAKSJON MED API: HENT KRYPTERINGSNØKKEL FOR PRINT ***");
231-
try (CloseableHttpResponse response = apiService.getEncryptionCertificateForPrint()) {
231+
try (ClassicHttpResponse response = apiService.getEncryptionCertificateForPrint()) {
232232
checkResponse(response, eventLogger);
233233
EncryptionCertificate encryptionCertificate = unmarshal(jaxbContext, response.getEntity().getContent(), EncryptionCertificate.class);
234234
cachedPrintCertificate = encryptionCertificate.getX509Certificate();

src/main/java/no/digipost/api/client/internal/http/response/HttpResponseUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ public final class HttpResponseUtils {
5050
*
5151
* @return the stream containing the entity of the response.
5252
*/
53-
public static InputStream safelyOfferEntityStreamExternally(CloseableHttpResponse response, EventLogger eventLogger) {
53+
public static InputStream safelyOfferEntityStreamExternally(ClassicHttpResponse response, EventLogger eventLogger) {
5454
HttpEntity entity = null;
5555
try {
5656
checkResponse(response, eventLogger);
5757
entity = response.getEntity();
5858
return entity.getContent();
5959
} catch (IOException | RuntimeException e) {
60-
try (CloseableHttpResponse autoClosed = response) {
60+
try (ClassicHttpResponse autoClosed = response) {
6161
EntityUtils.consume(entity);
6262
} catch (IOException | RuntimeException entityConsumptionException) {
6363
e.addSuppressed(entityConsumptionException);

0 commit comments

Comments
 (0)