From 60b086d521dba0ec6fa9c8d65131a97aaeb9da16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Wed, 11 Feb 2026 16:48:50 +0100 Subject: [PATCH 1/5] Add current behavior test --- .../DefaultHttpClientCacheTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java index 9d06adb88..c328ae7e0 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java @@ -1,6 +1,7 @@ package com.sap.cloud.sdk.cloudplatform.connectivity; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.ArrayList; @@ -12,6 +13,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; +import lombok.SneakyThrows; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; @@ -357,6 +359,37 @@ void testInvalidatePrincipalCacheEntriesWithUserTokenExchangeDestination() assertThat(unclearedClientWithoutDestination).isSameAs(sut.tryGetHttpClient(FACTORY).get()); } + @SneakyThrows + @Test + void testHttpClientWrapperWithDestinationIsCalledWhenDestinationIsProvided() + { + final DefaultHttpDestination destination1 = DefaultHttpDestination.builder("http://foo.com").build(); + final HttpClient client1 = sut.tryGetHttpClient(destination1, FACTORY).get(); + assertThat(((HttpClientWrapper) client1).getDestination()).isSameAs(destination1); + + final DefaultHttpDestination destination2 = DefaultHttpDestination.builder("http://foo.com").build(); + final HttpClient client2 = sut.tryGetHttpClient(destination2, FACTORY).get(); + assertThat(((HttpClientWrapper) client2).getDestination()).isSameAs(destination2); + + // Verify the destinations are equal but not the same reference + assertThat(destination1).isEqualTo(destination2); + assertThat(destination1).isNotSameAs(destination2); + + // Http clients are distinct instances, since the cache key contains the destination reference and not its content + assertThat(client1).isNotSameAs(client2); + + // When using the exact same destination object, the same http-client wrapper should be returned + final HttpClient client1Again = sut.tryGetHttpClient(destination1, FACTORY).get(); + assertThat(client1Again).isSameAs(client1); + assertThat(((HttpClientWrapper) client1Again).getDestination()).isSameAs(destination1); + + // simulate garbage collection + ((HttpClientWrapper) client1).close(); + + // since client1 inherited client2 connection manager, client2 is shut down as well + assertThatCode(() -> client2.execute(new HttpGet())).hasMessage("Connection pool shut down"); + } + @Test void testPrincipalPropagationIsPrincipalIsolated() { From cfa4e6ef5406b9a0e5f1fbb7a3c0ccd7fddf1f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Wed, 11 Feb 2026 16:58:45 +0100 Subject: [PATCH 2/5] Minor test extension --- .../connectivity/DefaultHttpClientCacheTest.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java index c328ae7e0..85f6d26a3 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java @@ -361,18 +361,22 @@ void testInvalidatePrincipalCacheEntriesWithUserTokenExchangeDestination() @SneakyThrows @Test - void testHttpClientWrapperWithDestinationIsCalledWhenDestinationIsProvided() + void testHttpClientWrapperOutlivesGarbageCollector() { final DefaultHttpDestination destination1 = DefaultHttpDestination.builder("http://foo.com").build(); final HttpClient client1 = sut.tryGetHttpClient(destination1, FACTORY).get(); assertThat(((HttpClientWrapper) client1).getDestination()).isSameAs(destination1); - final DefaultHttpDestination destination2 = DefaultHttpDestination.builder("http://foo.com").build(); + final DefaultHttpDestination destination2 = + DefaultHttpDestination + .builder("http://foo.com") + .headerProviders(c -> List.of(new Header("Authorization", "Bearer foo"))) + .build(); final HttpClient client2 = sut.tryGetHttpClient(destination2, FACTORY).get(); assertThat(((HttpClientWrapper) client2).getDestination()).isSameAs(destination2); // Verify the destinations are equal but not the same reference - assertThat(destination1).isEqualTo(destination2); + assertThat(destination1).isEqualTo(destination2); // header providers are not part of the equality check assertThat(destination1).isNotSameAs(destination2); // Http clients are distinct instances, since the cache key contains the destination reference and not its content @@ -383,7 +387,7 @@ void testHttpClientWrapperWithDestinationIsCalledWhenDestinationIsProvided() assertThat(client1Again).isSameAs(client1); assertThat(((HttpClientWrapper) client1Again).getDestination()).isSameAs(destination1); - // simulate garbage collection + // simulate garbage collection on client1 ((HttpClientWrapper) client1).close(); // since client1 inherited client2 connection manager, client2 is shut down as well From 3956d753dbc3dab20bd8787775490f1004de7a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Wed, 11 Feb 2026 17:08:35 +0100 Subject: [PATCH 3/5] Improve test method name --- .../cloudplatform/connectivity/DefaultHttpClientCacheTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java index 85f6d26a3..6428e3808 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java @@ -361,7 +361,7 @@ void testInvalidatePrincipalCacheEntriesWithUserTokenExchangeDestination() @SneakyThrows @Test - void testHttpClientWrapperOutlivesGarbageCollector() + void testCachedEqualHttpClientsClosingBehavior() { final DefaultHttpDestination destination1 = DefaultHttpDestination.builder("http://foo.com").build(); final HttpClient client1 = sut.tryGetHttpClient(destination1, FACTORY).get(); From c1ca4ce404cc249ca5eac7db454ab78e7171b9fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Wed, 11 Feb 2026 17:09:41 +0100 Subject: [PATCH 4/5] Format --- .../cloudplatform/connectivity/DefaultHttpClientCacheTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java index 6428e3808..5a1372f70 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java @@ -13,7 +13,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; -import lombok.SneakyThrows; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; @@ -30,6 +29,8 @@ import com.sap.cloud.sdk.cloudplatform.tenant.Tenant; import com.sap.cloud.sdk.testutil.TestContext; +import lombok.SneakyThrows; + @Isolated class DefaultHttpClientCacheTest { From 02d94a5838f98f65cfb048aba48e5545c747fb99 Mon Sep 17 00:00:00 2001 From: I538344 Date: Thu, 16 Jul 2026 10:18:42 +0200 Subject: [PATCH 5/5] WiP --- .../connectivity/DefaultHttpDestination.java | 23 ++++++++++++++-- .../connectivity/HttpClientWrapper.java | 6 ++--- .../DefaultHttpClientCacheTest.java | 27 ++++++++++--------- .../connectivity/HttpClientWrapperTest.java | 6 ++++- .../ApacheHttpClient5Wrapper.java | 6 ++--- .../DefaultApacheHttpClient5CacheTest.java | 17 +++++++----- .../connectivity/HttpClientWrapperTest.java | 6 ++++- 7 files changed, 61 insertions(+), 30 deletions(-) diff --git a/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpDestination.java b/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpDestination.java index abf216010..da0bf30b7 100644 --- a/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpDestination.java +++ b/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpDestination.java @@ -511,8 +511,7 @@ public static Builder fromDestination( @Nonnull final Destination destination ) .getPropertyNames() .forEach(propertyName -> builder.property(propertyName, destination.get(propertyName).get())); - if( destination instanceof DefaultHttpDestination ) { - final DefaultHttpDestination httpDestination = (DefaultHttpDestination) destination; + if( destination instanceof DefaultHttpDestination httpDestination ) { builder.headers(httpDestination.customHeaders); builder .headerProviders(httpDestination.getCustomHeaderProviders().toArray(new DestinationHeaderProvider[0])); @@ -543,6 +542,7 @@ public boolean equals( @Nullable final Object o ) resolveCertificatesOnly(keyStoreSupplier.get().getOrNull()), resolveCertificatesOnly(that.keyStoreSupplier.get().getOrNull())) .append(resolveCertificatesOnly(trustStore), resolveCertificatesOnly(that.trustStore)) + .append(customHeaderProviders, that.customHeaderProviders) .isEquals(); } @@ -554,9 +554,28 @@ public int hashCode() .append(customHeaders) .append(resolveKeyStoreHashCode(keyStoreSupplier.get().getOrNull())) .append(resolveKeyStoreHashCode(trustStore)) + .append(computeHeaderProvidersHashCode(customHeaderProviders)) .toHashCode(); } + /** + * Computes a hash code for the custom header providers list. Since header providers can be lambda functions that + * don't have meaningful equals/hashCode implementations, we use the identity hash code of each provider to uniquely + * identify them. + * + * @param providers + * the list of header providers + * @return a hash code based on the identity of each provider + */ + private static int computeHeaderProvidersHashCode( @Nonnull final List providers ) + { + int result = 0; + for( final DestinationHeaderProvider provider : providers ) { + result = 31 * result + System.identityHashCode(provider); + } + return result; + } + /** * Builder class to allow for easy creation of an immutable {@code DefaultHttpDestination} instance. */ diff --git a/cloudplatform/connectivity-apache-httpclient4/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientWrapper.java b/cloudplatform/connectivity-apache-httpclient4/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientWrapper.java index e1e3739f8..2f60e4d97 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientWrapper.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientWrapper.java @@ -93,9 +93,9 @@ public String toString() HttpClientWrapper withDestination( final HttpDestinationProperties destination ) { - // explicitly check the reference equality, since equals doesn't check header providers - // this is a slight improvement, avoiding unnecessary wrapper instantiation - // in cases where destination objects are reused / served from cache + // Since equals() now includes customHeaderProviders in the equality check, + // this method will throw an exception if the destination has different header providers. + // This is the expected behavior to ensure HTTP clients are properly isolated by their configuration. if( !destination.equals(this.destination) ) { throw new ShouldNotHappenException( "This method must not be used outside of updating an instance of HttpClientWrapper for http clients served from the HttpClientCache."); diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java index 5a1372f70..1976d0c0d 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultHttpClientCacheTest.java @@ -1,7 +1,6 @@ package com.sap.cloud.sdk.cloudplatform.connectivity; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.ArrayList; @@ -182,8 +181,7 @@ void testGetClientWithDestinationUsesTenantOptionalForIsolation() } @Test - //This is a known limitation of excluding header providers in the equality check of destinations - void testGetClientReturnsSameClientForDestinationsWithOnlyDifferentHeaderProviders() + void testGetClientReturnsDifferentClientForDestinationsWithDifferentHeaderProviders() { final Header header1 = new Header("foo", "bar"); final Header header2 = new Header("foo1", "bar1"); @@ -196,25 +194,28 @@ void testGetClientReturnsSameClientForDestinationsWithOnlyDifferentHeaderProvide final DefaultHttpDestination secondDestination = DefaultHttpDestination - .fromDestination(firstDestination) + .builder("http://some-uri") .headerProviders(( any ) -> Collections.singletonList(header2)) .build(); + // Verify that destinations with different header providers are not equal + assertThat(firstDestination).isNotEqualTo(secondDestination); + final HttpClientWrapper client1 = (HttpClientWrapper) sut.tryGetHttpClient(firstDestination, FACTORY).get(); final HttpClientWrapper client2 = (HttpClientWrapper) sut.tryGetHttpClient(secondDestination, FACTORY).get(); assertThat(client1.getDestination()).isSameAs(firstDestination); assertThat(client2.getDestination()).isSameAs(secondDestination); + // Each client should be a distinct instance now + assertThat(client1).isNotSameAs(client2); + final HttpUriRequest request1 = client1.wrapRequest(new HttpGet()); final HttpUriRequest request2 = client2.wrapRequest(new HttpGet()); - // This behavior is to be improved by https://github.com/SAP/cloud-sdk-java-backlog/issues/396 + // Each destination's header provider should only add its own headers assertThat(request1.getAllHeaders()).containsExactly(new HttpClientWrapper.ApacheHttpHeader(header1)); - assertThat(request2.getAllHeaders()) - .containsExactly( - new HttpClientWrapper.ApacheHttpHeader(header1), - new HttpClientWrapper.ApacheHttpHeader(header2)); + assertThat(request2.getAllHeaders()).containsExactly(new HttpClientWrapper.ApacheHttpHeader(header2)); } @Test @@ -376,8 +377,8 @@ void testCachedEqualHttpClientsClosingBehavior() final HttpClient client2 = sut.tryGetHttpClient(destination2, FACTORY).get(); assertThat(((HttpClientWrapper) client2).getDestination()).isSameAs(destination2); - // Verify the destinations are equal but not the same reference - assertThat(destination1).isEqualTo(destination2); // header providers are not part of the equality check + // Verify the destinations are not equal due to different header providers + assertThat(destination1).isNotEqualTo(destination2); // header providers are now included in the equality check assertThat(destination1).isNotSameAs(destination2); // Http clients are distinct instances, since the cache key contains the destination reference and not its content @@ -391,8 +392,8 @@ void testCachedEqualHttpClientsClosingBehavior() // simulate garbage collection on client1 ((HttpClientWrapper) client1).close(); - // since client1 inherited client2 connection manager, client2 is shut down as well - assertThatCode(() -> client2.execute(new HttpGet())).hasMessage("Connection pool shut down"); + // since client1 did not inherit client2 connection manager, client2 is not shut down + client2.execute(new HttpGet()); } @Test diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientWrapperTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientWrapperTest.java index 736578b8a..2e0ce45f5 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientWrapperTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientWrapperTest.java @@ -22,9 +22,13 @@ void testDestinationWrapping() final DefaultHttpDestination thirdDestination = DefaultHttpDestination.builder("http://bar.com").build(); final HttpClientWrapper sut = new HttpClientWrapper(mock(CloseableHttpClient.class), firstDestination); + // withDestination returns the same wrapper instance when the destination reference is identical assertThat(sut.withDestination(firstDestination)).isSameAs(sut); - assertThat(sut.withDestination(firstDestination)).isNotSameAs(sut.withDestination(secondDestination)); + // withDestination throws an exception when destinations are not equal (different header providers) + assertThatThrownBy(() -> sut.withDestination(secondDestination)).isInstanceOf(ShouldNotHappenException.class); + + // withDestination throws an exception when destinations have different URIs assertThatThrownBy(() -> sut.withDestination(thirdDestination)).isInstanceOf(ShouldNotHappenException.class); } } diff --git a/cloudplatform/connectivity-apache-httpclient5/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ApacheHttpClient5Wrapper.java b/cloudplatform/connectivity-apache-httpclient5/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ApacheHttpClient5Wrapper.java index e7e48783e..e4feef9ab 100644 --- a/cloudplatform/connectivity-apache-httpclient5/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ApacheHttpClient5Wrapper.java +++ b/cloudplatform/connectivity-apache-httpclient5/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ApacheHttpClient5Wrapper.java @@ -78,9 +78,9 @@ public void close( final CloseMode closeMode ) ApacheHttpClient5Wrapper withDestination( final HttpDestinationProperties destination ) { - // explicitly check the reference equality, since equals doesn't check header providers - // this is a slight improvement, avoiding unnecessary wrapper instantiation - // in cases where destination objects are reused / served from cache + // Since equals() now includes customHeaderProviders in the equality check, + // this method will throw an exception if the destination has different header providers. + // This is the expected behavior to ensure HTTP clients are properly isolated by their configuration. if( !destination.equals(this.destination) ) { throw new ShouldNotHappenException( "This method must not be used outside of updating an instance of ApacheHttpClient5Wrapper for http clients served from the ApacheHttpClient5Cache."); diff --git a/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultApacheHttpClient5CacheTest.java b/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultApacheHttpClient5CacheTest.java index 7295ec9d9..44d92f5bd 100644 --- a/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultApacheHttpClient5CacheTest.java +++ b/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/DefaultApacheHttpClient5CacheTest.java @@ -348,8 +348,7 @@ void testInvalidatePrincipalCacheEntriesWithUserTokenExchangeDestination() } @Test - //This is a known limitation of excluding header providers in the equality check of destinations - void testGetClientReturnsSameClientForDestinationsWithOnlyDifferentHeaderProviders() + void testGetClientReturnsDifferentClientForDestinationsWithDifferentHeaderProviders() { final Header header1 = new Header("foo", "bar"); final Header header2 = new Header("foo1", "bar1"); @@ -362,10 +361,13 @@ void testGetClientReturnsSameClientForDestinationsWithOnlyDifferentHeaderProvide final DefaultHttpDestination secondDestination = DefaultHttpDestination - .fromDestination(firstDestination) + .builder("http://some-uri") .headerProviders(( any ) -> Collections.singletonList(header2)) .build(); + // Verify that destinations with different header providers are not equal + assertThat(firstDestination).isNotEqualTo(secondDestination); + final ApacheHttpClient5Wrapper client1 = (ApacheHttpClient5Wrapper) sut.tryGetHttpClient(firstDestination, FACTORY).get(); final ApacheHttpClient5Wrapper client2 = @@ -374,6 +376,9 @@ void testGetClientReturnsSameClientForDestinationsWithOnlyDifferentHeaderProvide assertThat(client1.getDestination()).isSameAs(firstDestination); assertThat(client2.getDestination()).isSameAs(secondDestination); + // Each client should be a distinct instance now + assertThat(client1).isNotSameAs(client2); + final ClassicHttpRequest request1 = client1.wrapRequest(new HttpGet("/")); final ClassicHttpRequest request2 = client2.wrapRequest(new HttpGet("/")); @@ -382,15 +387,13 @@ void testGetClientReturnsSameClientForDestinationsWithOnlyDifferentHeaderProvide request1.headerIterator().forEachRemaining(headersRequest1::add); request2.headerIterator().forEachRemaining(headersRequest2::add); - // recursive comparison because BasicHeader doesn't implement equals/hashCode + // Each destination's header provider should only add its own headers assertThat(headersRequest1) .usingRecursiveFieldByFieldElementComparator() .containsExactly(new BasicHeader(header1.getName(), header1.getValue())); assertThat(headersRequest2) .usingRecursiveFieldByFieldElementComparator() - .containsExactly( - new BasicHeader(header1.getName(), header1.getValue()), - new BasicHeader(header2.getName(), header2.getValue())); + .containsExactly(new BasicHeader(header2.getName(), header2.getValue())); } @Test diff --git a/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientWrapperTest.java b/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientWrapperTest.java index 154a584f4..d07128acc 100644 --- a/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientWrapperTest.java +++ b/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientWrapperTest.java @@ -24,9 +24,13 @@ void testDestinationWrapping() final ApacheHttpClient5Wrapper sut = new ApacheHttpClient5Wrapper(mock(CloseableHttpClient.class), firstDestination, mock(RequestConfig.class)); + // withDestination returns the same wrapper instance when the destination reference is identical assertThat(sut.withDestination(firstDestination)).isSameAs(sut); - assertThat(sut.withDestination(firstDestination)).isNotSameAs(sut.withDestination(secondDestination)); + // withDestination throws an exception when destinations are not equal (different header providers) + assertThatThrownBy(() -> sut.withDestination(secondDestination)).isInstanceOf(ShouldNotHappenException.class); + + // withDestination throws an exception when destinations have different URIs assertThatThrownBy(() -> sut.withDestination(thirdDestination)).isInstanceOf(ShouldNotHappenException.class); } }