diff --git a/extensions/data-plane/data-plane-http/README.md b/extensions/data-plane/data-plane-http/README.md index be2b7829c74..b0dc960f1cc 100644 --- a/extensions/data-plane/data-plane-http/README.md +++ b/extensions/data-plane/data-plane-http/README.md @@ -49,3 +49,4 @@ The table below summarizes how each parameter is retrieved for the source/sink i | Method | `DataFlowRequest` properties if method proxy enabled by the source `DataAddress`, otherwise default to `GET` | Destination `DataAddress` if present, otherwise `POST` by default | GET, POST... | | Content type | `DataFlowRequest` properties if body proxy enabled by the source `DataAddress` | Destination `DataAddress` | application/json | | Body | `DataFlowRequest` properties if body proxy enabled by the source `DataAddress` | `Part` stream fetched by the `DataSource` | "hello world!" | +| NonChunkedTransfer | Not used | Destination `DataAddress` if present, otherwise `true` by default | "false" | diff --git a/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/StreamingRequestBody.java b/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/ChunkedTransferRequestBody.java similarity index 71% rename from extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/StreamingRequestBody.java rename to extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/ChunkedTransferRequestBody.java index c7d9240b5ad..19af97fb622 100644 --- a/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/StreamingRequestBody.java +++ b/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/ChunkedTransferRequestBody.java @@ -24,13 +24,17 @@ import java.util.function.Supplier; /** - * Streams content into an OK HTTP buffered sink. + * Streams content into an OK HTTP buffered sink in chunks. + * + * Due to OkHttp implementation an extra header will be created (no-overridable) Transfer-Encoding with value chunked + * + * @see OkHttp Dcoumentation */ -public class StreamingRequestBody extends RequestBody { +public class ChunkedTransferRequestBody extends RequestBody { private final Supplier bodySupplier; private final String contentType; - public StreamingRequestBody(Supplier contentSupplier, String contentType) { + public ChunkedTransferRequestBody(Supplier contentSupplier, String contentType) { this.bodySupplier = contentSupplier; this.contentType = contentType; } diff --git a/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpRequestParams.java b/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpRequestParams.java index 045d8072ef7..de5f89c4acc 100644 --- a/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpRequestParams.java +++ b/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpRequestParams.java @@ -15,6 +15,7 @@ package org.eclipse.dataspaceconnector.dataplane.http.pipeline; import okhttp3.Request; +import okhttp3.RequestBody; import org.jetbrains.annotations.Nullable; import java.io.InputStream; @@ -26,6 +27,7 @@ public class HttpRequestParams { private static final String DEFAULT_CONTENT_TYPE = "application/octet-stream"; + private static final boolean DEFAULT_NON_CHUNKED_TRANSFER = false; private String method; private String baseUrl; @@ -33,6 +35,7 @@ public class HttpRequestParams { private String queryParams; private String contentType = DEFAULT_CONTENT_TYPE; private String body; + private boolean nonChunkedTransfer = DEFAULT_NON_CHUNKED_TRANSFER; private final Map headers = new HashMap<>(); /** @@ -54,9 +57,7 @@ public Request toRequest() { * @return HTTP request. */ public Request toRequest(@Nullable Supplier bodySupplier) { - var requestBody = (bodySupplier != null && contentType != null) ? - new StreamingRequestBody(bodySupplier, contentType) : - null; + var requestBody = createRequestBody(bodySupplier); var requestBuilder = new Request.Builder() .url(toUrl()) @@ -65,6 +66,16 @@ public Request toRequest(@Nullable Supplier bodySupplier) { return requestBuilder.build(); } + private RequestBody createRequestBody(@Nullable Supplier bodySupplier) { + if (bodySupplier == null || contentType == null) { + return null; + } + + return nonChunkedTransfer ? + new NonChunkedTransferRequestBody(bodySupplier, contentType) : new ChunkedTransferRequestBody(bodySupplier, contentType); + } + + /** * Creates a URL from the base url, path and query parameters provided in input. * @@ -128,6 +139,11 @@ public HttpRequestParams.Builder path(String path) { return this; } + public HttpRequestParams.Builder nonChunkedTransfer(boolean nonChunkedTransfer) { + params.nonChunkedTransfer = nonChunkedTransfer; + return this; + } + public HttpRequestParams build() { params.headers.forEach((s, s2) -> Objects.requireNonNull(s2, "value for header: " + s)); Objects.requireNonNull(params.baseUrl, "baseUrl"); diff --git a/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpRequestParamsSupplier.java b/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpRequestParamsSupplier.java index 8a1d90825f9..88ea9c5671c 100644 --- a/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpRequestParamsSupplier.java +++ b/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpRequestParamsSupplier.java @@ -66,10 +66,13 @@ public HttpRequestParams apply(DataFlowRequest request) { params.contentType(ct); params.body(extractBody(address, request)); }); + params.nonChunkedTransfer(extractNonChunkedTransfer(address)); return params.build(); } + protected abstract boolean extractNonChunkedTransfer(HttpDataAddress address); + @NotNull protected abstract DataAddress selectAddress(DataFlowRequest request); diff --git a/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSinkRequestParamsSupplier.java b/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSinkRequestParamsSupplier.java index 43836dd7d33..896f6a7af2d 100644 --- a/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSinkRequestParamsSupplier.java +++ b/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSinkRequestParamsSupplier.java @@ -34,6 +34,11 @@ public HttpSinkRequestParamsSupplier(Vault vault) { super(vault); } + @Override + protected boolean extractNonChunkedTransfer(HttpDataAddress address) { + return address.getNonChunkedTransfer(); + } + @Override protected @NotNull DataAddress selectAddress(DataFlowRequest request) { return request.getDestinationDataAddress(); diff --git a/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSourceRequestParamsSupplier.java b/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSourceRequestParamsSupplier.java index beaadd2e28c..e8e6809cc05 100644 --- a/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSourceRequestParamsSupplier.java +++ b/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSourceRequestParamsSupplier.java @@ -42,6 +42,11 @@ public HttpSourceRequestParamsSupplier(Vault vault) { super(vault); } + @Override + protected boolean extractNonChunkedTransfer(HttpDataAddress address) { + return false; + } + @Override protected @NotNull DataAddress selectAddress(DataFlowRequest request) { return request.getSourceDataAddress(); diff --git a/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/NonChunkedTransferRequestBody.java b/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/NonChunkedTransferRequestBody.java new file mode 100644 index 00000000000..eb5cc41b423 --- /dev/null +++ b/extensions/data-plane/data-plane-http/src/main/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/NonChunkedTransferRequestBody.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Microsoft Corporation - initial API and implementation + * + */ + +package org.eclipse.dataspaceconnector.dataplane.http.pipeline; + +import okhttp3.MediaType; +import okhttp3.RequestBody; +import okio.BufferedSink; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.io.InputStream; +import java.util.function.Supplier; + +/** + * Writes content into an OK HTTP buffered sink. + * + * The extra Transfer-Encoding is not created because the Content-Length is provided upfront. + * Note that means that the all content is loaded into memory, so this method can be used for small files (up to 50MB) for e.g. + * + * @see OkHttp Dcoumentation + */ +public class NonChunkedTransferRequestBody extends RequestBody { + private byte[] bytes; + private final String contentType; + + public NonChunkedTransferRequestBody(Supplier contentSupplier, String contentType) { + try { + this.bytes = contentSupplier.get().readAllBytes(); + } catch (IOException e) { + //do nothing + } + this.contentType = contentType; + } + + @Override + public long contentLength() { + return bytes == null ? 0 : bytes.length; + } + + @Override + public MediaType contentType() { + return MediaType.parse(contentType); + } + + @Override + public void writeTo(@NotNull BufferedSink sink) throws IOException { + if (bytes == null) { + return; + } + + try (var os = sink.outputStream()) { + os.write(bytes); + } + } +} + diff --git a/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/StreamingRequestBodyTest.java b/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/ChunkedTransferRequestBodyTest.java similarity index 87% rename from extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/StreamingRequestBodyTest.java rename to extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/ChunkedTransferRequestBodyTest.java index f812ecb89cd..86912c7a642 100644 --- a/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/StreamingRequestBodyTest.java +++ b/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/ChunkedTransferRequestBodyTest.java @@ -27,7 +27,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -class StreamingRequestBodyTest { +class ChunkedTransferRequestBodyTest { private static final Faker FAKER = new Faker(); @Test @@ -38,7 +38,7 @@ void verifyStreamingTransfer() throws IOException { when(sink.outputStream()).thenReturn(outputStream); - var body = new StreamingRequestBody(() -> new ByteArrayInputStream(content.getBytes()), HttpDataAddress.OCTET_STREAM); + var body = new ChunkedTransferRequestBody(() -> new ByteArrayInputStream(content.getBytes()), HttpDataAddress.OCTET_STREAM); body.writeTo(sink); assertThat(outputStream).hasToString(content); diff --git a/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpRequestParamsSupplierTest.java b/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpRequestParamsSupplierTest.java index 8443f387450..a520bdd8d1d 100644 --- a/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpRequestParamsSupplierTest.java +++ b/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpRequestParamsSupplierTest.java @@ -9,6 +9,7 @@ * * Contributors: * Amadeus - initial API and implementation + * Siemens - add chunked parameter * */ @@ -139,6 +140,26 @@ void verifyAbstractMethodsInvokation() throws IOException { assertThat(body.contentType()).isEqualTo(MediaType.get(supplier.contentType)); assertThat(HttpTestFixtures.formatRequestBodyAsString(body)).isEqualTo(supplier.body); assertThat(httpRequest.method()).isEqualTo(supplier.method); + assertThat(httpRequest.body().contentLength()).isEqualTo(-1L); + } + + @Test + void verifyChunkedCall() throws IOException { + var dataAddress = HttpDataAddress.Builder.newInstance() + .baseUrl("http://" + FAKER.internet().url()) + .build(); + var request = createRequest(dataAddress); + + var supplier = new TestHttpRequestParamsSupplier(vaultMock, true); + var httpRequest = supplier.apply(request).toRequest(); + + assertThat(httpRequest.url().url()).hasToString(dataAddress.getBaseUrl() + "/" + supplier.path + "?" + supplier.queryParams); + var body = httpRequest.body(); + assertThat(body).isNotNull(); + assertThat(body.contentType()).isEqualTo(MediaType.get(supplier.contentType)); + assertThat(HttpTestFixtures.formatRequestBodyAsString(body)).isEqualTo(supplier.body); + assertThat(httpRequest.method()).isEqualTo(supplier.method); + assertThat(httpRequest.body().contentLength()).isEqualTo(supplier.body.getBytes().length); } private static DataFlowRequest createRequest(DataAddress source) { @@ -156,16 +177,33 @@ public static final class TestHttpRequestParamsSupplier extends HttpRequestParam private final String queryParams; private final String contentType; private final String body; + private final boolean isOneGo; private TestHttpRequestParamsSupplier(Vault vault) { super(vault); this.method = new Random().nextBoolean() ? HttpMethod.PUT.name() : HttpMethod.POST.name(); + this.isOneGo = false; this.path = FAKER.lorem().word(); this.queryParams = FAKER.lorem().word(); this.contentType = new Random().nextBoolean() ? APPLICATION_JSON : APPLICATION_X_WWW_FORM_URLENCODED; this.body = FAKER.lorem().word(); } + private TestHttpRequestParamsSupplier(Vault vault, boolean isOneGo) { + super(vault); + this.method = new Random().nextBoolean() ? HttpMethod.PUT.name() : HttpMethod.POST.name(); + this.isOneGo = isOneGo; + this.path = FAKER.lorem().word(); + this.queryParams = FAKER.lorem().word(); + this.contentType = new Random().nextBoolean() ? APPLICATION_JSON : APPLICATION_X_WWW_FORM_URLENCODED; + this.body = FAKER.lorem().word(); + } + + @Override + protected boolean extractNonChunkedTransfer(HttpDataAddress address) { + return isOneGo; + } + @Override protected @NotNull DataAddress selectAddress(DataFlowRequest request) { return request.getSourceDataAddress(); diff --git a/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSinkRequestParamsSupplierTest.java b/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSinkRequestParamsSupplierTest.java index 8af4b4202b5..4f616fdc43c 100644 --- a/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSinkRequestParamsSupplierTest.java +++ b/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSinkRequestParamsSupplierTest.java @@ -22,6 +22,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.Random; + import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -106,4 +108,16 @@ void extractContentType() { void extractBody() { assertThat(supplier.extractPath(mock(HttpDataAddress.class), null)).isNull(); } + + @Test + void extractNonChunkedTransfer() { + var chunked = new Random().nextBoolean(); + var address = HttpDataAddress.Builder.newInstance() + .nonChunkedTransfer(chunked) + .build(); + + var result = supplier.extractNonChunkedTransfer(address); + + assertThat(result).isEqualTo(chunked); + } } \ No newline at end of file diff --git a/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSourceRequestParamsSupplierTest.java b/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSourceRequestParamsSupplierTest.java index db19a51a8cd..ffa1aa11e27 100644 --- a/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSourceRequestParamsSupplierTest.java +++ b/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/HttpSourceRequestParamsSupplierTest.java @@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test; import java.util.Map; +import java.util.Random; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -230,6 +231,18 @@ void extractBodyFilteredByProxy() { assertThat(result).isNull(); } + @Test + void extractNonChunkedTransfer() { + var chunked = new Random().nextBoolean(); + var address = HttpDataAddress.Builder.newInstance() + .nonChunkedTransfer(chunked) + .build(); + + var result = supplier.extractNonChunkedTransfer(address); + + assertThat(result).isFalse(); + } + private static DataFlowRequest createRequest(DataAddress source) { return createRequest(source, Map.of()); } diff --git a/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/NonChunkedTransferRequestBodyTest.java b/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/NonChunkedTransferRequestBodyTest.java new file mode 100644 index 00000000000..c8231b0ec24 --- /dev/null +++ b/extensions/data-plane/data-plane-http/src/test/java/org/eclipse/dataspaceconnector/dataplane/http/pipeline/NonChunkedTransferRequestBodyTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 Amadeus + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Amadeus - Initial implementation + * Siemens - add chunked parameter + * + */ + +package org.eclipse.dataspaceconnector.dataplane.http.pipeline; + +import net.datafaker.Faker; +import okio.BufferedSink; +import org.eclipse.dataspaceconnector.spi.types.domain.HttpDataAddress; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class NonChunkedTransferRequestBodyTest { + private static final Faker FAKER = new Faker(); + + @Test + void verifyTransferWhenDataAvailable() throws IOException { + var content = FAKER.lorem().word(); + var sink = mock(BufferedSink.class); + var outputStream = new ByteArrayOutputStream(); + + when(sink.outputStream()).thenReturn(outputStream); + + var body = new NonChunkedTransferRequestBody(() -> new ByteArrayInputStream(content.getBytes()), HttpDataAddress.OCTET_STREAM); + + assertThat(body.contentType().toString()).isEqualTo(HttpDataAddress.OCTET_STREAM); + assertThat(body.contentLength()).isEqualTo(content.getBytes().length); + + body.writeTo(sink); + + assertThat(outputStream).hasToString(content); + } + + @Test + void verifyTransferDataMissing() throws IOException { + var sink = mock(BufferedSink.class); + var outputStream = new ByteArrayOutputStream(); + + when(sink.outputStream()).thenReturn(outputStream); + + var body = new NonChunkedTransferRequestBody(() -> new ByteArrayInputStream(new byte[0]), HttpDataAddress.OCTET_STREAM); + + assertThat(body.contentLength()).isEqualTo(0); + + body.writeTo(sink); + + assertThat(outputStream).hasToString(""); + } + + @Test + void verifyTransferWhenThrows() throws IOException { + var sink = mock(BufferedSink.class); + var outputStream = new ByteArrayOutputStream(); + var inputStream = mock(InputStream.class); + + when(inputStream.readAllBytes()).thenThrow(IOException.class); + when(sink.outputStream()).thenReturn(outputStream); + + var body = new NonChunkedTransferRequestBody(() -> inputStream, HttpDataAddress.OCTET_STREAM); + + assertThat(body.contentLength()).isEqualTo(0); + + body.writeTo(sink); + + assertThat(outputStream).hasToString(""); + } +} diff --git a/spi/core-spi/src/main/java/org/eclipse/dataspaceconnector/spi/types/domain/HttpDataAddress.java b/spi/core-spi/src/main/java/org/eclipse/dataspaceconnector/spi/types/domain/HttpDataAddress.java index 1d770a49d3b..a0309f2134c 100644 --- a/spi/core-spi/src/main/java/org/eclipse/dataspaceconnector/spi/types/domain/HttpDataAddress.java +++ b/spi/core-spi/src/main/java/org/eclipse/dataspaceconnector/spi/types/domain/HttpDataAddress.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import org.eclipse.dataspaceconnector.common.string.StringUtils; import java.util.Map; import java.util.Objects; @@ -50,6 +51,7 @@ public class HttpDataAddress extends DataAddress { public static final String ADDITIONAL_HEADER = "header:"; public static final String CONTENT_TYPE = "contentType"; public static final String OCTET_STREAM = "application/octet-stream"; + public static final String NON_CHUNKED_TRANSFER = "nonChunkedTransfer"; public static final Set ADDITIONAL_HEADERS_TO_IGNORE = Set.of("content-type"); private HttpDataAddress() { @@ -124,6 +126,12 @@ public Map getAdditionalHeaders() { } + @JsonIgnore + public boolean getNonChunkedTransfer() { + var nonChunkedTransfer = getProperty(NON_CHUNKED_TRANSFER); + return !StringUtils.isNullOrBlank(nonChunkedTransfer) && Boolean.parseBoolean(nonChunkedTransfer); + } + @JsonPOJOBuilder(withPrefix = "") public static final class Builder extends DataAddress.Builder { @@ -206,6 +214,11 @@ public Builder contentType(String contentType) { return this; } + public Builder nonChunkedTransfer(boolean nonChunkedTransfer) { + this.property(NON_CHUNKED_TRANSFER, String.valueOf(nonChunkedTransfer)); + return this; + } + public Builder copyFrom(DataAddress other) { other.getProperties().forEach(this::property); return this; diff --git a/spi/core-spi/src/test/java/org/eclipse/dataspaceconnector/spi/types/domain/HttpDataAddressTest.java b/spi/core-spi/src/test/java/org/eclipse/dataspaceconnector/spi/types/domain/HttpDataAddressTest.java index bb209a5f403..ca645fbb183 100644 --- a/spi/core-spi/src/test/java/org/eclipse/dataspaceconnector/spi/types/domain/HttpDataAddressTest.java +++ b/spi/core-spi/src/test/java/org/eclipse/dataspaceconnector/spi/types/domain/HttpDataAddressTest.java @@ -37,6 +37,7 @@ void verifyGetProperties() { .proxyMethod("proxyMethod1") .proxyPath("proxyPath1") .path("foo/bar") + .nonChunkedTransfer(true) .method("GET") .proxyQueryParams("proxyQueryParams1") .build(); @@ -54,6 +55,7 @@ void verifyGetProperties() { assertThat(dataAddress.getContentType()).isEqualTo("application/octet-stream"); assertThat(dataAddress.getMethod()).isEqualTo("GET"); assertThat(dataAddress.getPath()).isEqualTo("foo/bar"); + assertThat(dataAddress.getNonChunkedTransfer()).isTrue(); assertThat(dataAddress.getAdditionalHeaders()).hasSize(2); assertThat(dataAddress.getAdditionalHeaders()) .containsEntry("Keep-Alive", "timeout=5, max=1000") @@ -66,6 +68,7 @@ void verifyGetDefaultValues() { assertThat(dataAddress.getType()).isEqualTo("HttpData"); assertThat(dataAddress.getAdditionalHeaders()).isEmpty(); + assertThat(dataAddress.getNonChunkedTransfer()).isFalse(); assertThat(dataAddress.getContentType()).isEqualTo("application/octet-stream"); } } \ No newline at end of file