diff --git a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/GlobalPartitionEndpointManagerForPPAFUnitTests.java b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/GlobalPartitionEndpointManagerForPPAFUnitTests.java index c2ef4713edb8..06a72c3395b5 100644 --- a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/GlobalPartitionEndpointManagerForPPAFUnitTests.java +++ b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/GlobalPartitionEndpointManagerForPPAFUnitTests.java @@ -14,7 +14,6 @@ import com.azure.cosmos.implementation.ResourceType; import com.azure.cosmos.implementation.RxDocumentServiceRequest; import com.azure.cosmos.implementation.SerializationDiagnosticsContext; -import com.azure.cosmos.implementation.apachecommons.collections.list.UnmodifiableList; import com.azure.cosmos.implementation.guava25.collect.ImmutableList; import com.azure.cosmos.implementation.perPartitionAutomaticFailover.GlobalPartitionEndpointManagerForPerPartitionAutomaticFailover; import com.azure.cosmos.implementation.perPartitionAutomaticFailover.PartitionLevelAutomaticFailoverInfo; @@ -87,12 +86,12 @@ public void beforeClass() { .collect(Collectors.toList()); Mockito.when(this.singleWriteAccountGlobalEndpointManagerMock.getAvailableReadRoutingContexts()).thenReturn(availableReadRegionalRoutingContexts); - Mockito.when(this.singleWriteAccountGlobalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn(new UnmodifiableList<>(availableReadRegionalRoutingContexts)); + Mockito.when(this.singleWriteAccountGlobalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(availableReadRegionalRoutingContexts)); Mockito.when(this.singleWriteAccountGlobalEndpointManagerMock.canUseMultipleWriteLocations()).thenReturn(false); Mockito.when(this.singleWriteAccountGlobalEndpointManagerMock.canUseMultipleWriteLocations(Mockito.any())).thenReturn(false); Mockito.when(this.multiWriteAccountGlobalEndpointManagerMock.getAvailableReadRoutingContexts()).thenReturn(availableReadRegionalRoutingContexts); - Mockito.when(this.multiWriteAccountGlobalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn(new UnmodifiableList<>(availableReadRegionalRoutingContexts)); + Mockito.when(this.multiWriteAccountGlobalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(availableReadRegionalRoutingContexts)); Mockito.when(this.multiWriteAccountGlobalEndpointManagerMock.canUseMultipleWriteLocations()).thenReturn(true); Mockito.when(this.multiWriteAccountGlobalEndpointManagerMock.canUseMultipleWriteLocations(Mockito.any())).thenReturn(true); } diff --git a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/GlobalPartitionEndpointManagerForPPCBUnitTests.java b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/GlobalPartitionEndpointManagerForPPCBUnitTests.java index cc7d589836eb..a6a78f9523a8 100644 --- a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/GlobalPartitionEndpointManagerForPPCBUnitTests.java +++ b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/GlobalPartitionEndpointManagerForPPCBUnitTests.java @@ -14,7 +14,6 @@ import com.azure.cosmos.implementation.ResourceType; import com.azure.cosmos.implementation.RxDocumentServiceRequest; import com.azure.cosmos.implementation.SerializationDiagnosticsContext; -import com.azure.cosmos.implementation.apachecommons.collections.list.UnmodifiableList; import com.azure.cosmos.implementation.perPartitionAutomaticFailover.PerPartitionAutomaticFailoverInfoHolder; import com.azure.cosmos.implementation.perPartitionCircuitBreaker.GlobalPartitionEndpointManagerForPerPartitionCircuitBreaker; import com.azure.cosmos.implementation.perPartitionCircuitBreaker.LocationHealthStatus; @@ -214,8 +213,8 @@ public void recordHealthyToHealthyWithFailuresStatusTransition(String partitionL maxExclusive, LocationEastUs2EndpointToLocationPair.getKey()); - Mockito.when(this.globalEndpointManagerMock.getReadEndpoints()).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); - Mockito.when(this.globalEndpointManagerMock.getWriteEndpoints()).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getReadEndpoints()).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getWriteEndpoints()).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); globalPartitionEndpointManagerForCircuitBreaker .handleLocationExceptionForPartitionKeyRange(request, new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getKey()), false); @@ -284,8 +283,8 @@ public void recordHealthyWithFailuresToUnavailableStatusTransition(String partit maxExclusive, LocationEastUs2EndpointToLocationPair.getKey()); - Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); - Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); int exceptionCountToHandle = globalPartitionEndpointManagerForCircuitBreaker.getConsecutiveExceptionBasedCircuitBreaker().getAllowedExceptionCountToMaintainStatus(LocationHealthStatus.HealthyWithFailures, readOperationTrue); @@ -361,8 +360,8 @@ public void recordUnavailableToHealthyTentativeStatusTransition(String partition maxExclusive, LocationEastUs2EndpointToLocationPair.getKey()); - Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); - Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); int exceptionCountToHandle = globalPartitionEndpointManagerForCircuitBreaker.getConsecutiveExceptionBasedCircuitBreaker().getAllowedExceptionCountToMaintainStatus(LocationHealthStatus.HealthyWithFailures, readOperationTrue); @@ -449,8 +448,8 @@ public void recordHealthyTentativeToHealthyStatusTransition(String partitionLeve maxExclusive, LocationEastUs2EndpointToLocationPair.getKey()); - Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); - Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); int exceptionCountToHandle = globalPartitionEndpointManagerForCircuitBreaker.getConsecutiveExceptionBasedCircuitBreaker().getAllowedExceptionCountToMaintainStatus(LocationHealthStatus.HealthyWithFailures, readOperationTrue); @@ -545,8 +544,8 @@ public void recordHealthyTentativeToUnavailableTransition(String partitionLevelC maxExclusive, LocationEastUs2EndpointToLocationPair.getKey()); - Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); - Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); int exceptionCountToHandle = globalPartitionEndpointManagerForCircuitBreaker.getConsecutiveExceptionBasedCircuitBreaker().getAllowedExceptionCountToMaintainStatus(LocationHealthStatus.HealthyWithFailures, readOperationTrue); @@ -639,8 +638,8 @@ public void allRegionsUnavailableHandling(String partitionLevelCircuitBreakerCon maxExclusive, LocationEastUs2EndpointToLocationPair.getKey()); - Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); - Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); int exceptionCountToHandle = globalPartitionEndpointManagerForCircuitBreaker @@ -724,8 +723,8 @@ public void multiContainerBothWithSinglePartitionHealthyToUnavailableHandling(St maxExclusive, LocationEastUs2EndpointToLocationPair.getKey()); - Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); - Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); int exceptionCountToHandle = globalPartitionEndpointManagerForCircuitBreaker.getConsecutiveExceptionBasedCircuitBreaker().getAllowedExceptionCountToMaintainStatus(LocationHealthStatus.HealthyWithFailures, readOperationTrue); @@ -821,8 +820,8 @@ public void allRegionsUnavailableHandlingWithMultiThreading(String partitionLeve .map(uriStringPair -> new RegionalRoutingContext(uriStringPair.getLeft())) .collect(Collectors.toList()); - Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); - Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn((UnmodifiableList) UnmodifiableList.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); + Mockito.when(this.globalEndpointManagerMock.getApplicableReadRegionalRoutingContexts(Mockito.anyList())).thenReturn(Collections.unmodifiableList(applicableReadWriteEndpoints)); RxDocumentServiceRequest requestCentralUs = constructRxDocumentServiceRequestInstance( readOperationTrue ? OperationType.Read : OperationType.Create, diff --git a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/ProactiveConnectionManagementTest.java b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/ProactiveConnectionManagementTest.java index 2c17b8733bf2..54113b85c49d 100644 --- a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/ProactiveConnectionManagementTest.java +++ b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/ProactiveConnectionManagementTest.java @@ -15,7 +15,6 @@ import com.azure.cosmos.implementation.RxDocumentServiceRequest; import com.azure.cosmos.implementation.TestConfigurations; import com.azure.cosmos.implementation.Utils; -import com.azure.cosmos.implementation.apachecommons.collections.list.UnmodifiableList; import com.azure.cosmos.implementation.apachecommons.lang.tuple.ImmutablePair; import com.azure.cosmos.implementation.caches.AsyncCache; import com.azure.cosmos.implementation.caches.AsyncCacheNonBlocking; @@ -181,7 +180,7 @@ public void openConnectionsAndInitCachesWithContainer(ProactiveConnectionManagem cosmosAsyncContainer.openConnectionsAndInitCaches(proactiveConnectionRegionCount).block(); - UnmodifiableList readEndpoints = + List readEndpoints = globalEndpointManager.getReadEndpoints(); List proactiveConnectionEndpoints = readEndpoints.subList( @@ -345,7 +344,7 @@ public void openConnectionsAndInitCachesWithCosmosClient_And_PerContainerConnect ConcurrentHashMap routingMap = getRoutingMap(rxDocumentClient); ConcurrentHashMap collectionInfoByNameMap = getCollectionInfoByNameMap(rxDocumentClient); Set endpoints = ConcurrentHashMap.newKeySet(); - UnmodifiableList readEndpoints = globalEndpointManager.getReadEndpoints(); + List readEndpoints = globalEndpointManager.getReadEndpoints(); List proactiveConnectionEndpoints = readEndpoints.subList( 0, @@ -495,7 +494,7 @@ public void openConnectionsAndInitCachesWithCosmosClient_And_PerContainerConnect ConcurrentHashMap routingMap = getRoutingMap(rxDocumentClient); ConcurrentHashMap collectionInfoByNameMap = getCollectionInfoByNameMap(rxDocumentClient); Set endpoints = ConcurrentHashMap.newKeySet(); - UnmodifiableList readEndpoints = globalEndpointManager.getReadEndpoints(); + List readEndpoints = globalEndpointManager.getReadEndpoints(); List proactiveConnectionEndpoints = readEndpoints.subList( 0, Math.min(readEndpoints.size(), proactiveContainerInitConfig.getProactiveConnectionRegionsCount())) @@ -666,7 +665,7 @@ public void openConnectionsAndInitCachesWithCosmosClient_And_PerContainerConnect ConcurrentHashMap routingMap = getRoutingMap(rxDocumentClient); ConcurrentHashMap collectionInfoByNameMap = getCollectionInfoByNameMap(rxDocumentClient); Set endpoints = ConcurrentHashMap.newKeySet(); - UnmodifiableList readEndpoints = globalEndpointManager.getReadEndpoints(); + List readEndpoints = globalEndpointManager.getReadEndpoints(); List proactiveConnectionEndpoints = readEndpoints.subList( 0, Math.min(readEndpoints.size(), proactiveContainerInitConfig.getProactiveConnectionRegionsCount())) diff --git a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/RegionScopedSessionContainerConcurrencyTest.java b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/RegionScopedSessionContainerConcurrencyTest.java index 2512f9bd3508..bff1a75db913 100644 --- a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/RegionScopedSessionContainerConcurrencyTest.java +++ b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/RegionScopedSessionContainerConcurrencyTest.java @@ -4,7 +4,6 @@ package com.azure.cosmos.implementation; import com.azure.cosmos.GatewayTestUtils; -import com.azure.cosmos.implementation.apachecommons.collections.list.UnmodifiableList; import com.azure.cosmos.implementation.guava25.collect.ImmutableList; import com.azure.cosmos.implementation.routing.RegionalRoutingContext; import com.azure.cosmos.models.ModelBridgeInternal; @@ -21,6 +20,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -253,8 +253,8 @@ public void concurrentSetAndResolveTokens(String profileName, for (URI u : orderedReadEndpoints) { endpointBuilder.add(new RegionalRoutingContext(u)); } - UnmodifiableList endpoints = - new UnmodifiableList<>(endpointBuilder.build()); + List endpoints = + Collections.unmodifiableList(endpointBuilder.build()); Mockito.when(globalEndpointManagerMock.getReadEndpoints()).thenReturn(endpoints); Mockito.when(globalEndpointManagerMock.getRegionName(Mockito.eq(EAST_US), Mockito.any())) diff --git a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/RegionScopedSessionContainerTest.java b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/RegionScopedSessionContainerTest.java index d1fb33e71dae..24639e3b5c67 100644 --- a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/RegionScopedSessionContainerTest.java +++ b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/RegionScopedSessionContainerTest.java @@ -5,7 +5,6 @@ import com.azure.cosmos.BridgeInternal; import com.azure.cosmos.GatewayTestUtils; -import com.azure.cosmos.implementation.apachecommons.collections.list.UnmodifiableList; import com.azure.cosmos.implementation.guava25.collect.ImmutableList; import com.azure.cosmos.implementation.guava25.collect.ImmutableMap; import com.azure.cosmos.implementation.routing.RegionalRoutingContext; @@ -26,6 +25,7 @@ import java.net.URI; import java.util.Arrays; import java.util.HashMap; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Random; @@ -377,7 +377,7 @@ public void sessionContainer() throws Exception { int numPartitionKeyRangeIds = 5; String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -441,7 +441,7 @@ public void setSessionToken_NoSessionTokenForPartitionKeyRangeId() throws Except GlobalEndpointManager globalEndpointManagerMock = Mockito.mock(GlobalEndpointManager.class); ISessionContainer sessionContainer = new RegionScopedSessionContainer("127.0.0.1", false, globalEndpointManagerMock); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -508,7 +508,7 @@ public void setSessionToken_MergeOldWithNew() throws Exception { GlobalEndpointManager globalEndpointManagerMock = Mockito.mock(GlobalEndpointManager.class); RegionScopedSessionContainer sessionContainer = new RegionScopedSessionContainer("127.0.0.1", false, globalEndpointManagerMock); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -569,7 +569,7 @@ public void resolveGlobalSessionTokenReturnsEmptyStringOnCacheMiss() { GlobalEndpointManager globalEndpointManagerMock = Mockito.mock(GlobalEndpointManager.class); RegionScopedSessionContainer sessionContainer = new RegionScopedSessionContainer("127.0.0.1", false, globalEndpointManagerMock); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -601,7 +601,7 @@ public void resolveGlobalSessionTokenReturnsTokenMapUsingName() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -647,7 +647,7 @@ public void resolveGlobalSessionTokenReturnsTokenMapUsingResourceId() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -695,7 +695,7 @@ public void resolveLocalSessionTokenReturnsTokenMapUsingName() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -739,7 +739,7 @@ public void resolveLocalSessionTokenReturnsTokenMapUsingResourceId() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -788,7 +788,7 @@ public void resolveLocalSessionTokenReturnsNullOnPartitionMiss() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -833,7 +833,7 @@ public void resolveLocalSessionTokenReturnsNullOnCollectionMiss() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -876,7 +876,7 @@ public void resolvePartitionLocalSessionTokenReturnsTokenOnParentMatch() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -922,7 +922,7 @@ public void clearTokenByCollectionFullNameRemovesToken() { URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); String unparsedSessionToken = "range_0:1#100#1=20#2=5#3=30"; - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -985,7 +985,7 @@ public void clearTokenByResourceIdRemovesToken() { String unparsedSessionToken = "range_0:1#100#1=20#2=5#3=30"; - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -1049,7 +1049,7 @@ public void clearTokenKeepsUnmatchedCollection() { URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); String unparsedSessionToken = "range_0:1#100#1=20#2=5#3=30"; - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -1108,7 +1108,7 @@ public void setSessionTokenSetsTokenWhenRequestIsntNameBased() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -1150,7 +1150,7 @@ public void setSessionTokenGivesPriorityToOwnerFullNameOverResourceAddress() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -1197,7 +1197,7 @@ public void setSessionTokenIgnoresOwnerIdWhenRequestIsntNameBased() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -1251,7 +1251,7 @@ public void setSessionTokenGivesPriorityToOwnerIdOverResourceIdWhenRequestIsName String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -1319,7 +1319,7 @@ public void setSessionTokenDoesntOverwriteHigherLSN() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -1367,7 +1367,7 @@ public void setSessionTokenOverwriteLowerLSN() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -1414,7 +1414,7 @@ public void setSessionTokenDoesNothingOnEmptySessionTokenHeader() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -1510,7 +1510,7 @@ public void useParentSessionTokenAfterSplit() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -1562,7 +1562,7 @@ public void useParentSessionTokenAfterMerge() { String regionContacted = LocationEastUsEndpointToLocationPair.getRight(); URI locationEndpointContacted = LocationEastUsEndpointToLocationPair.getLeft(); - UnmodifiableList endpoints = new UnmodifiableList<>( + List endpoints = Collections.unmodifiableList( ImmutableList.of( new RegionalRoutingContext(LocationEastUsEndpointToLocationPair.getLeft()), new RegionalRoutingContext(LocationEastUs2EndpointToLocationPair.getLeft()), @@ -1683,7 +1683,7 @@ public void resolvePartitionLocalSessionToken( .when(globalEndpointManagerMock.getLatestDatabaseAccount()) .thenReturn(databaseAccount); - UnmodifiableList readEndpointsInUnmodifiableList = new UnmodifiableList<>(consolidatedReadRegionalEndpointRoutingContexts); + List readEndpointsInUnmodifiableList = Collections.unmodifiableList(consolidatedReadRegionalEndpointRoutingContexts); Mockito .when(globalEndpointManagerMock.getReadEndpoints()) @@ -1691,7 +1691,7 @@ public void resolvePartitionLocalSessionToken( Mockito .when(globalEndpointManagerMock.getApplicableWriteRegionalRoutingContexts(Mockito.anyList())) - .thenReturn(new UnmodifiableList<>(consolidatedWriteRegionalEndpointRoutingContexts)); + .thenReturn(Collections.unmodifiableList(consolidatedWriteRegionalEndpointRoutingContexts)); Mockito .when(globalEndpointManagerMock.canUseMultipleWriteLocations(Mockito.any())) diff --git a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/directconnectivity/GlobalAddressResolverTest.java b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/directconnectivity/GlobalAddressResolverTest.java index 331be53cc7af..5510ab3e4476 100644 --- a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/directconnectivity/GlobalAddressResolverTest.java +++ b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/directconnectivity/GlobalAddressResolverTest.java @@ -19,7 +19,6 @@ import com.azure.cosmos.implementation.RxDocumentServiceRequest; import com.azure.cosmos.implementation.UserAgentContainer; import com.azure.cosmos.implementation.Utils; -import com.azure.cosmos.implementation.apachecommons.collections.list.UnmodifiableList; import com.azure.cosmos.implementation.apachecommons.lang.tuple.ImmutablePair; import com.azure.cosmos.implementation.caches.RxCollectionCache; import com.azure.cosmos.implementation.caches.RxPartitionKeyRangeCache; @@ -39,6 +38,7 @@ import java.net.URI; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.UUID; @@ -82,13 +82,13 @@ public void before_GlobalAddressResolverTest() throws Exception { readEndPointList.add(new RegionalRoutingContext(urlforRead1)); readEndPointList.add(new RegionalRoutingContext(urlforRead2)); readEndPointList.add(new RegionalRoutingContext(urlforRead3)); - UnmodifiableList readList = new UnmodifiableList<>(readEndPointList); + List readList = Collections.unmodifiableList(readEndPointList); List writeEndPointList = new ArrayList<>(); writeEndPointList.add(new RegionalRoutingContext(urlforWrite1)); writeEndPointList.add(new RegionalRoutingContext(urlforWrite2)); writeEndPointList.add(new RegionalRoutingContext(urlforWrite3)); - UnmodifiableList writeList = new UnmodifiableList<>(writeEndPointList); + List writeList = Collections.unmodifiableList(writeEndPointList); Mockito.when(endpointManager.getReadEndpoints()).thenReturn(readList); Mockito.when(endpointManager.getWriteEndpoints()).thenReturn(writeList); @@ -157,7 +157,7 @@ public void submitOpenConnectionTasksAndInitCaches() { Mockito .when(endpointManager.getReadEndpoints()) - .thenReturn(new UnmodifiableList<>( + .thenReturn(Collections.unmodifiableList( Arrays.asList(new RegionalRoutingContext(urlforRead1), new RegionalRoutingContext(urlforRead2)))); DocumentCollection documentCollection = new DocumentCollection(); diff --git a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/routing/LocationCacheTest.java b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/routing/LocationCacheTest.java index 4d0680e60318..ba42d7ba6f04 100644 --- a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/routing/LocationCacheTest.java +++ b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/routing/LocationCacheTest.java @@ -7,7 +7,6 @@ import com.azure.cosmos.DirectConnectionConfig; import com.azure.cosmos.implementation.ConnectionPolicy; import com.azure.cosmos.implementation.LifeCycleUtils; -import com.azure.cosmos.implementation.apachecommons.collections.list.UnmodifiableList; import com.azure.cosmos.implementation.DatabaseAccount; import com.azure.cosmos.implementation.DatabaseAccountLocation; import com.azure.cosmos.implementation.Configs; @@ -76,7 +75,7 @@ public int getUnavailableLocationsExpirationTimeInSeconds() { } }; - private UnmodifiableList preferredLocations; + private List preferredLocations; private DatabaseAccount databaseAccount; private LocationCache cache; private GlobalEndpointManager endpointManager; @@ -589,8 +588,8 @@ private void initialize(boolean useMultipleWriteLocations, this.databaseAccount = LocationCacheTest.createDatabaseAccount(useMultipleWriteLocations); this.preferredLocations = isPreferredLocationsListEmpty ? - new UnmodifiableList<>(Collections.emptyList()) : - new UnmodifiableList<>(ImmutableList.of("location1", "location2", "location3")); + Collections.unmodifiableList(Collections.emptyList()) : + Collections.unmodifiableList(ImmutableList.of("location1", "location2", "location3")); connectionPolicy.setPreferredRegions(this.preferredLocations); @@ -666,8 +665,8 @@ private void validateLocationCacheAsync( endpointDiscoveryEnabled, isPreferredListEmpty); - UnmodifiableList currentWriteEndpoints = this.cache.getWriteEndpoints(); - UnmodifiableList currentReadEndpoints = this.cache.getReadEndpoints(); + List currentWriteEndpoints = this.cache.getWriteEndpoints(); + List currentReadEndpoints = this.cache.getReadEndpoints(); for (int i = 0; i < readLocationIndex; i++) { this.cache.markEndpointUnavailableForRead(createUrl(Iterables.get(this.databaseAccount.getReadableLocations(), i).getEndpoint())); this.endpointManager.markEndpointUnavailableForRead(createUrl(Iterables.get(this.databaseAccount.getReadableLocations(), i).getEndpoint()));; @@ -897,7 +896,7 @@ private void validateRequestEndpointResolution( // If current write endpoint is unavailable, write endpoints order doesn't change // ALL write requests flip-flop between current write and alternate write endpoint - UnmodifiableList writeEndpoints = this.cache.getWriteEndpoints(); + List writeEndpoints = this.cache.getWriteEndpoints(); assertThat(new RegionalRoutingContext(firstAvailableWriteEndpoint)).isEqualTo(writeEndpoints.get(0)); assertThat(new RegionalRoutingContext(secondAvailableWriteEndpoint)).isEqualTo(this.resolveEndpointForWriteRequest(ResourceType.Document, true)); diff --git a/sdk/cosmos/azure-cosmos/benchmark-results/1t-c1-ReadThroughput-r1.png b/sdk/cosmos/azure-cosmos/benchmark-results/1t-c1-ReadThroughput-r1.png new file mode 100644 index 000000000000..ae6dc94d1d1d Binary files /dev/null and b/sdk/cosmos/azure-cosmos/benchmark-results/1t-c1-ReadThroughput-r1.png differ diff --git a/sdk/cosmos/azure-cosmos/benchmark-results/1t-c128-ReadThroughput-r1.png b/sdk/cosmos/azure-cosmos/benchmark-results/1t-c128-ReadThroughput-r1.png new file mode 100644 index 000000000000..fc04d7928a78 Binary files /dev/null and b/sdk/cosmos/azure-cosmos/benchmark-results/1t-c128-ReadThroughput-r1.png differ diff --git a/sdk/cosmos/azure-cosmos/benchmark-results/1t-c32-ReadThroughput-r1.png b/sdk/cosmos/azure-cosmos/benchmark-results/1t-c32-ReadThroughput-r1.png new file mode 100644 index 000000000000..07192bf721d7 Binary files /dev/null and b/sdk/cosmos/azure-cosmos/benchmark-results/1t-c32-ReadThroughput-r1.png differ diff --git a/sdk/cosmos/azure-cosmos/benchmark-results/30t-c5-ReadThroughput-r1.png b/sdk/cosmos/azure-cosmos/benchmark-results/30t-c5-ReadThroughput-r1.png new file mode 100644 index 000000000000..1f3d0223d8c5 Binary files /dev/null and b/sdk/cosmos/azure-cosmos/benchmark-results/30t-c5-ReadThroughput-r1.png differ diff --git a/sdk/cosmos/azure-cosmos/benchmark-results/summary-throughput.png b/sdk/cosmos/azure-cosmos/benchmark-results/summary-throughput.png new file mode 100644 index 000000000000..a31ac19ae936 Binary files /dev/null and b/sdk/cosmos/azure-cosmos/benchmark-results/summary-throughput.png differ diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/ClientRetryPolicy.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/ClientRetryPolicy.java index 4a5b2f409df7..e2ad58a8310a 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/ClientRetryPolicy.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/ClientRetryPolicy.java @@ -6,7 +6,6 @@ import com.azure.cosmos.CosmosDiagnostics; import com.azure.cosmos.CosmosException; import com.azure.cosmos.ThrottlingRetryOptions; -import com.azure.cosmos.implementation.apachecommons.collections.list.UnmodifiableList; import com.azure.cosmos.implementation.perPartitionCircuitBreaker.GlobalPartitionEndpointManagerForPerPartitionCircuitBreaker; import com.azure.cosmos.implementation.directconnectivity.WebExceptionUtility; import com.azure.cosmos.implementation.faultinjection.FaultInjectionRequestContext; @@ -18,6 +17,7 @@ import java.net.URI; import java.time.Duration; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import static com.azure.cosmos.implementation.guava25.base.Preconditions.checkNotNull; @@ -241,7 +241,7 @@ private ShouldRetryResult shouldRetryOnSessionNotAvailable(RxDocumentServiceRequ return ShouldRetryResult.noRetry(); } else { if (this.canUseMultipleWriteLocations) { - UnmodifiableList endpoints = + List endpoints = this.isReadRequest ? this.globalEndpointManager.getApplicableReadRegionalRoutingContexts(request) : this.globalEndpointManager.getApplicableWriteRegionalRoutingContexts(request); diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/GlobalEndpointManager.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/GlobalEndpointManager.java index 57076de28d52..0475e19bcd4a 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/GlobalEndpointManager.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/GlobalEndpointManager.java @@ -3,7 +3,6 @@ package com.azure.cosmos.implementation; -import com.azure.cosmos.implementation.apachecommons.collections.list.UnmodifiableList; import com.azure.cosmos.implementation.routing.LocationCache; import com.azure.cosmos.implementation.routing.LocationHelper; import com.azure.cosmos.implementation.routing.RegionalRoutingContext; @@ -95,32 +94,32 @@ public void init() { startRefreshLocationTimerAsync(true).block(maxInitializationTime); } - public UnmodifiableList getReadEndpoints() { + public List getReadEndpoints() { // readonly return this.locationCache.getReadEndpoints(); } - public UnmodifiableList getWriteEndpoints() { + public List getWriteEndpoints() { //readonly return this.locationCache.getWriteEndpoints(); } - public UnmodifiableList getApplicableReadRegionalRoutingContexts(RxDocumentServiceRequest request) { + public List getApplicableReadRegionalRoutingContexts(RxDocumentServiceRequest request) { // readonly return this.locationCache.getApplicableReadRegionRoutingContexts(request); } - public UnmodifiableList getApplicableWriteRegionalRoutingContexts(RxDocumentServiceRequest request) { + public List getApplicableWriteRegionalRoutingContexts(RxDocumentServiceRequest request) { //readonly return this.locationCache.getApplicableWriteRegionRoutingContexts(request); } - public UnmodifiableList getApplicableReadRegionalRoutingContexts(List excludedRegions) { + public List getApplicableReadRegionalRoutingContexts(List excludedRegions) { // readonly return this.locationCache.getApplicableReadRegionRoutingContexts(excludedRegions, Collections.emptyList()); } - public UnmodifiableList getApplicableWriteRegionalRoutingContexts(List excludedRegions) { + public List getApplicableWriteRegionalRoutingContexts(List excludedRegions) { //readonly return this.locationCache.getApplicableWriteRegionRoutingContexts(excludedRegions, Collections.emptyList()); } diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentServiceRequest.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentServiceRequest.java index 3e4cd5547a65..2a5eb38229dc 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentServiceRequest.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentServiceRequest.java @@ -183,7 +183,7 @@ private RxDocumentServiceRequest(DiagnosticsClientContext clientContext, this.forceNameCacheRefresh = false; this.resourceType = resourceType; this.contentAsByteArray = toByteArray(byteBuffer); - this.headers = headers != null ? headers : new HashMap<>(); + this.headers = headers != null ? headers : new HashMap<>(32); this.activityId = UUIDs.nonBlockingRandomUUID(); this.isFeed = false; this.isNameBased = isNameBased; @@ -217,7 +217,7 @@ private RxDocumentServiceRequest(DiagnosticsClientContext clientContext, this.operationType = operationType; this.resourceType = resourceType; this.requestContext.sessionToken = null; - this.headers = headers != null ? headers : new HashMap<>(); + this.headers = headers != null ? headers : new HashMap<>(32); this.activityId = UUIDs.nonBlockingRandomUUID(); this.isFeed = false; diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxGatewayStoreModel.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxGatewayStoreModel.java index 42172026ad5b..3ee18f99d61f 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxGatewayStoreModel.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxGatewayStoreModel.java @@ -238,7 +238,7 @@ public StoreResponse unwrapToStoreResponse( return new StoreResponse( endpoint, statusCode, - HttpUtils.unescape(headers.toLowerCaseMap()), + headers, new ByteBufInputStream(retainedContent, true), size); } else { @@ -248,7 +248,7 @@ public StoreResponse unwrapToStoreResponse( return new StoreResponse( endpoint, statusCode, - HttpUtils.unescape(headers.toLowerCaseMap()), + headers, null, 0); } @@ -343,7 +343,7 @@ private Mono performRequestInternalCore(RxDocumentSer } private HttpHeaders getHttpRequestHeaders(Map headers) { - HttpHeaders httpHeaders = new HttpHeaders(this.defaultHeaders.size()); + HttpHeaders httpHeaders = new HttpHeaders(this.defaultHeaders.size() + (headers != null ? headers.size() : 0)); // Add default headers. for (Entry entry : this.defaultHeaders.entrySet()) { if (!headers.containsKey(entry.getKey())) { diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/HttpUtils.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/HttpUtils.java index 2e5d27ac03dd..48d0ef3d6eb8 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/HttpUtils.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/HttpUtils.java @@ -7,6 +7,7 @@ import com.azure.cosmos.implementation.HttpConstants; import com.azure.cosmos.implementation.Strings; import com.azure.cosmos.implementation.apachecommons.lang.StringUtils; +import com.azure.cosmos.implementation.http.HttpHeader; import com.azure.cosmos.implementation.http.HttpHeaders; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,14 +52,14 @@ public static String urlDecode(String url) { public static Map asMap(HttpHeaders headers) { if (headers == null) { - return new HashMap<>(); + return new HashMap<>(4); } HashMap map = new HashMap<>(headers.size()); - for (Entry entry : headers.toMap().entrySet()) { - if (entry.getKey().equals(HttpConstants.HttpHeaders.OWNER_FULL_NAME)) { - map.put(entry.getKey(), HttpUtils.urlDecode(entry.getValue())); + for (HttpHeader header : headers) { + if (header.name().equals(HttpConstants.HttpHeaders.OWNER_FULL_NAME)) { + map.put(header.name(), HttpUtils.urlDecode(header.value())); } else { - map.put(entry.getKey(), entry.getValue()); + map.put(header.name(), header.value()); } } return map; diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/JsonNodeStorePayload.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/JsonNodeStorePayload.java index bbf642ba667a..1e504c8007ee 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/JsonNodeStorePayload.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/JsonNodeStorePayload.java @@ -18,6 +18,7 @@ import java.nio.charset.CodingErrorAction; import java.nio.charset.StandardCharsets; import java.util.Base64; +import java.util.HashMap; import java.util.Map; public class JsonNodeStorePayload implements StorePayload { @@ -36,6 +37,25 @@ public JsonNodeStorePayload(ByteBufInputStream bufferStream, int readableBytes, } } + /** + * Creates a JsonNodeStorePayload using pre-populated header arrays instead of a Map. + * The Map is constructed lazily only if needed for error reporting. + */ + public JsonNodeStorePayload( + ByteBufInputStream bufferStream, + int readableBytes, + String[] headerNames, + String[] headerValues) { + + if (readableBytes > 0) { + this.responsePayloadSize = readableBytes; + this.jsonValue = fromJsonWithArrayHeaders(bufferStream, readableBytes, headerNames, headerValues); + } else { + this.responsePayloadSize = 0; + this.jsonValue = null; + } + } + private static JsonNode fromJson(ByteBufInputStream bufferStream, int readableBytes, Map responseHeaders) { byte[] bytes = new byte[readableBytes]; try { @@ -67,6 +87,51 @@ private static JsonNode fromJson(ByteBufInputStream bufferStream, int readableBy } } + private static JsonNode fromJsonWithArrayHeaders( + ByteBufInputStream bufferStream, + int readableBytes, + String[] headerNames, + String[] headerValues) { + + byte[] bytes = new byte[readableBytes]; + try { + bufferStream.read(bytes); + return Utils.getSimpleObjectMapper().readTree(bytes); + } catch (IOException e) { + // Build Map lazily only on error (extremely rare in production) + Map responseHeaders = buildHeaderMap(headerNames, headerValues); + if (fallbackCharsetDecoder != null) { + logger.warn("Unable to parse JSON, fallback to use customized charset decoder.", e); + return fromJsonWithFallbackCharsetDecoder(bytes, responseHeaders); + } else { + String baseErrorMessage = "Failed to parse JSON document. No fallback charset decoder configured."; + + if (Configs.isNonParseableDocumentLoggingEnabled()) { + String documentSample = Base64.getEncoder().encodeToString(bytes); + logger.error(baseErrorMessage + " " + "Document in Base64 format: [" + documentSample + "]", e); + } else { + logger.error(baseErrorMessage); + } + + IllegalStateException innerException = new IllegalStateException("Unable to parse JSON.", e); + + throw Utils.createCosmosException( + HttpConstants.StatusCodes.BADREQUEST, + HttpConstants.SubStatusCodes.FAILED_TO_PARSE_SERVER_RESPONSE, + innerException, + responseHeaders); + } + } + } + + private static Map buildHeaderMap(String[] headerNames, String[] headerValues) { + Map map = new HashMap<>(headerNames.length * 4 / 3 + 1); + for (int i = 0; i < headerNames.length; i++) { + map.put(headerNames[i], headerValues[i]); + } + return map; + } + private static JsonNode fromJsonWithFallbackCharsetDecoder(byte[] bytes, Map responseHeaders) { try { String sanitizedJson = fallbackCharsetDecoder.decode(ByteBuffer.wrap(bytes)).toString(); diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/StoreResponse.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/StoreResponse.java index 10c7f40e9ae3..9e8842f5da7a 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/StoreResponse.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/StoreResponse.java @@ -9,6 +9,7 @@ import com.azure.cosmos.implementation.directconnectivity.rntbd.RntbdChannelAcquisitionTimeline; import com.azure.cosmos.implementation.directconnectivity.rntbd.RntbdChannelStatistics; import com.azure.cosmos.implementation.directconnectivity.rntbd.RntbdEndpointStatistics; +import com.azure.cosmos.implementation.http.HttpHeaders; import com.fasterxml.jackson.databind.JsonNode; import io.netty.buffer.ByteBufInputStream; import io.netty.util.IllegalReferenceCountException; @@ -68,7 +69,7 @@ public StoreResponse( } this.status = status; - replicaStatusList = new HashMap<>(); + replicaStatusList = new HashMap<>(4); if (contentStream != null) { try { this.responsePayload = new JsonNodeStorePayload(contentStream, responsePayloadLength, headerMap); @@ -87,6 +88,57 @@ public StoreResponse( } } + /** + * Creates a StoreResponse directly from HttpHeaders, avoiding intermediate HashMap allocation. + * Header names are stored as lowercase keys (matching HttpHeaders internal representation). + * The OWNER_FULL_NAME header value is URL-decoded inline. + */ + public StoreResponse( + String endpoint, + int status, + HttpHeaders httpHeaders, + ByteBufInputStream contentStream, + int responsePayloadLength) { + + checkArgument((contentStream == null) == (responsePayloadLength == 0), + "Parameter 'contentStream' must be consistent with 'responsePayloadLength'."); + requestTimeline = RequestTimeline.empty(); + + int headerCount = httpHeaders.size(); + responseHeaderNames = new String[headerCount]; + responseHeaderValues = new String[headerCount]; + this.endpoint = endpoint != null ? endpoint : ""; + + httpHeaders.populateLowerCaseHeaders(responseHeaderNames, responseHeaderValues); + + // URL-decode OWNER_FULL_NAME header value inline (replaces HttpUtils.unescape) + for (int i = 0; i < headerCount; i++) { + if (HttpConstants.HttpHeaders.OWNER_FULL_NAME.equals(responseHeaderNames[i])) { + responseHeaderValues[i] = HttpUtils.urlDecode(responseHeaderValues[i]); + break; + } + } + + this.status = status; + replicaStatusList = new HashMap<>(4); + if (contentStream != null) { + try { + this.responsePayload = new JsonNodeStorePayload( + contentStream, responsePayloadLength, responseHeaderNames, responseHeaderValues); + } finally { + try { + contentStream.close(); + } catch (Throwable e) { + if (!(e instanceof IllegalReferenceCountException)) { + logger.warn("Failed to close content stream. This may cause a Netty ByteBuf leak.", e); + } + } + } + } else { + this.responsePayload = null; + } + } + private StoreResponse( String endpoint, int status, @@ -108,7 +160,7 @@ private StoreResponse( } this.status = status; - replicaStatusList = new HashMap<>(); + replicaStatusList = new HashMap<>(4); this.responsePayload = responsePayload; } @@ -310,7 +362,7 @@ public void setFaultInjectionRuleEvaluationResults(List results) { public StoreResponse withRemappedStatusCode(int newStatusCode, double additionalRequestCharge) { - Map headers = new HashMap<>(); + Map headers = new HashMap<>(this.responseHeaderNames.length * 4 / 3 + 1); for (int i = 0; i < this.responseHeaderNames.length; i++) { String headerName = this.responseHeaderNames[i]; if (headerName.equalsIgnoreCase(HttpConstants.HttpHeaders.REQUEST_CHARGE)) { diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/http/HttpHeaders.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/http/HttpHeaders.java index 7090bd453a51..ff3873a41a51 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/http/HttpHeaders.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/http/HttpHeaders.java @@ -24,7 +24,7 @@ public class HttpHeaders implements Iterable, JsonSerializable { * Create an empty HttpHeaders instance. */ public HttpHeaders() { - this.headers = new HashMap<>(); + this.headers = new HashMap<>(16); } /** @@ -66,7 +66,7 @@ public int size() { * @return this HttpHeaders */ public HttpHeaders set(String name, String value) { - final String headerKey = name.toLowerCase(Locale.ROOT); + final String headerKey = isAsciiLowerCase(name) ? name : name.toLowerCase(Locale.ROOT); if (value == null) { headers.remove(headerKey); } else { @@ -100,10 +100,20 @@ public String[] values(String name) { } private HttpHeader getHeader(String headerName) { - final String headerKey = headerName.toLowerCase(Locale.ROOT); + final String headerKey = isAsciiLowerCase(headerName) ? headerName : headerName.toLowerCase(Locale.ROOT); return headers.get(headerKey); } + private static boolean isAsciiLowerCase(String s) { + for (int i = 0, len = s.length(); i < len; i++) { + char c = s.charAt(i); + if (c >= 'A' && c <= 'Z') { + return false; + } + } + return true; + } + /** * Get {@link Map} representation of the HttpHeaders collection. * @@ -130,6 +140,22 @@ public Map toLowerCaseMap() { return result; } + /** + * Populates the provided arrays with lowercased header names and their values + * directly from the internal map, avoiding intermediate HashMap allocation. + * + * @param names array to populate with lowercased header names (must be at least size() long) + * @param values array to populate with header values (must be at least size() long) + */ + public void populateLowerCaseHeaders(String[] names, String[] values) { + int i = 0; + for (Map.Entry entry : headers.entrySet()) { + names[i] = entry.getKey(); + values[i] = entry.getValue().value(); + i++; + } + } + @Override public Iterator iterator() { return headers.values().iterator(); diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/perPartitionCircuitBreaker/GlobalPartitionEndpointManagerForPerPartitionCircuitBreaker.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/perPartitionCircuitBreaker/GlobalPartitionEndpointManagerForPerPartitionCircuitBreaker.java index 0213f2255144..7fa83a527f64 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/perPartitionCircuitBreaker/GlobalPartitionEndpointManagerForPerPartitionCircuitBreaker.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/perPartitionCircuitBreaker/GlobalPartitionEndpointManagerForPerPartitionCircuitBreaker.java @@ -14,7 +14,6 @@ import com.azure.cosmos.implementation.PartitionKeyRangeWrapper; import com.azure.cosmos.implementation.ResourceType; import com.azure.cosmos.implementation.RxDocumentServiceRequest; -import com.azure.cosmos.implementation.apachecommons.collections.list.UnmodifiableList; import com.azure.cosmos.implementation.apachecommons.lang.StringUtils; import com.azure.cosmos.implementation.apachecommons.lang.tuple.Pair; import com.azure.cosmos.implementation.directconnectivity.GatewayAddressCache; @@ -138,7 +137,7 @@ public void handleLocationExceptionForPartitionKeyRange( if (isFailureThresholdBreached.get()) { - UnmodifiableList applicableRegionalRoutingContexts = request.isReadOnlyRequest() ? + List applicableRegionalRoutingContexts = request.isReadOnlyRequest() ? this.globalEndpointManager.getApplicableReadRegionalRoutingContexts(request.requestContext.getExcludeRegions()) : this.globalEndpointManager.getApplicableWriteRegionalRoutingContexts(request.requestContext.getExcludeRegions()); @@ -270,7 +269,7 @@ public List getUnavailableRegionsForPartitionKeyRange( } } - return UnmodifiableList.unmodifiableList(unavailableRegions); + return Collections.unmodifiableList(unavailableRegions); } catch (Exception e) { throw wrapAsCosmosException(request, e); } @@ -432,12 +431,12 @@ public boolean isPerPartitionLevelCircuitBreakingApplicable(RxDocumentServiceReq return false; } - UnmodifiableList applicableReadEndpoints = globalEndpointManager.getApplicableReadRegionalRoutingContexts(Collections.emptyList()); + List applicableReadEndpoints = globalEndpointManager.getApplicableReadRegionalRoutingContexts(Collections.emptyList()); return applicableReadEndpoints != null && applicableReadEndpoints.size() > 1; } - UnmodifiableList applicableWriteEndpoints = globalEndpointManager.getApplicableWriteRegionalRoutingContexts(Collections.emptyList()); + List applicableWriteEndpoints = globalEndpointManager.getApplicableWriteRegionalRoutingContexts(Collections.emptyList()); return applicableWriteEndpoints != null && applicableWriteEndpoints.size() > 1; } diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/routing/LocationCache.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/routing/LocationCache.java index a15fd02c68c7..44e07b69f6a9 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/routing/LocationCache.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/routing/LocationCache.java @@ -15,7 +15,6 @@ import com.azure.cosmos.implementation.RxDocumentServiceRequest; import com.azure.cosmos.implementation.Strings; import com.azure.cosmos.implementation.Utils; -import com.azure.cosmos.implementation.apachecommons.collections.list.UnmodifiableList; import com.azure.cosmos.implementation.apachecommons.collections.map.CaseInsensitiveMap; import com.azure.cosmos.implementation.apachecommons.collections.map.UnmodifiableMap; import com.azure.cosmos.implementation.apachecommons.lang.StringUtils; @@ -89,7 +88,7 @@ public LocationCache( * 2. Endpoint availability * @return */ - public UnmodifiableList getReadEndpoints() { + public List getReadEndpoints() { if (!this.locationUnavailabilityInfoByEndpoint.isEmpty() && unavailableLocationsExpirationTimePassed()) { this.updateLocationCache(); @@ -104,7 +103,7 @@ && unavailableLocationsExpirationTimePassed()) { * 2. Endpoint availability * @return */ - public UnmodifiableList getWriteEndpoints() { + public List getWriteEndpoints() { if (!this.locationUnavailabilityInfoByEndpoint.isEmpty() && unavailableLocationsExpirationTimePassed()) { this.updateLocationCache(); @@ -197,19 +196,19 @@ public RegionalRoutingContext resolveServiceEndpoint(RxDocumentServiceRequest re return this.defaultRoutingContext; } } else { - UnmodifiableList endpoints = + List endpoints = request.getOperationType().isWriteOperation()? this.getApplicableWriteRegionRoutingContexts(request) : this.getApplicableReadRegionRoutingContexts(request); return endpoints.get(locationIndex % endpoints.size()); } } - public UnmodifiableList getApplicableWriteRegionRoutingContexts(RxDocumentServiceRequest request) { + public List getApplicableWriteRegionRoutingContexts(RxDocumentServiceRequest request) { return this.getApplicableWriteRegionRoutingContexts(request, request.requestContext.getExcludeRegions(), request.requestContext.getUnavailableRegionsForPartition()); } - public UnmodifiableList getApplicableWriteRegionRoutingContexts(List excludedRegionsOnRequest, List unavailableRegionsForPartition) { + public List getApplicableWriteRegionRoutingContexts(List excludedRegionsOnRequest, List unavailableRegionsForPartition) { - UnmodifiableList writeEndpoints = this.getWriteEndpoints(); + List writeEndpoints = this.getWriteEndpoints(); Supplier excludedRegionsSupplier = this.connectionPolicy.getExcludedRegionsSupplier(); List effectiveExcludedRegions = isExcludedRegionsSupplierConfigured(excludedRegionsSupplier) ? @@ -236,12 +235,12 @@ public UnmodifiableList getApplicableWriteRegionRoutingC unavailableRegionsForPartition); } - public UnmodifiableList getApplicableReadRegionRoutingContexts(RxDocumentServiceRequest request) { + public List getApplicableReadRegionRoutingContexts(RxDocumentServiceRequest request) { return this.getApplicableReadRegionRoutingContexts(request, request.requestContext.getExcludeRegions(), request.requestContext.getUnavailableRegionsForPartition()); } - public UnmodifiableList getApplicableReadRegionRoutingContexts(List excludedRegionsOnRequest, List unavailableRegionsForPartition) { - UnmodifiableList readEndpoints = this.getReadEndpoints(); + public List getApplicableReadRegionRoutingContexts(List excludedRegionsOnRequest, List unavailableRegionsForPartition) { + List readEndpoints = this.getReadEndpoints(); Supplier excludedRegionsSupplier = this.connectionPolicy.getExcludedRegionsSupplier(); List effectiveExcludedRegions = isExcludedRegionsSupplierConfigured(excludedRegionsSupplier) ? @@ -268,11 +267,11 @@ public UnmodifiableList getApplicableReadRegionRoutingCo unavailableRegionsForPartition); } - private UnmodifiableList getApplicableReadRegionRoutingContexts( + private List getApplicableReadRegionRoutingContexts( RxDocumentServiceRequest request, List excludedRegionsOnRequest, List unavailableRegionsForPartition) { - UnmodifiableList readEndpoints = this.getReadEndpoints(); + List readEndpoints = this.getReadEndpoints(); Supplier excludedRegionsSupplier = this.connectionPolicy.getExcludedRegionsSupplier(); List effectiveExcludedRegions = isExcludedRegionsSupplierConfigured(excludedRegionsSupplier) ? @@ -299,12 +298,12 @@ private UnmodifiableList getApplicableReadRegionRoutingC unavailableRegionsForPartition); } - private UnmodifiableList getApplicableWriteRegionRoutingContexts( + private List getApplicableWriteRegionRoutingContexts( RxDocumentServiceRequest request, List excludedRegionsOnRequest, List unavailableRegionsForPartition) { - UnmodifiableList writeEndpoints = this.getWriteEndpoints(); + List writeEndpoints = this.getWriteEndpoints(); Supplier excludedRegionsSupplier = this.connectionPolicy.getExcludedRegionsSupplier(); List effectiveExcludedRegions = isExcludedRegionsSupplierConfigured(excludedRegionsSupplier) ? @@ -331,10 +330,10 @@ private UnmodifiableList getApplicableWriteRegionRouting unavailableRegionsForPartition); } - private UnmodifiableList getApplicableRegionRoutingContexts( + private List getApplicableRegionRoutingContexts( RxDocumentServiceRequest request, List effectivePreferredLocations, - UnmodifiableList regionalRoutingContexts, + List regionalRoutingContexts, RegionalRoutingContext hubRoutingContext, UnmodifiableMap regionNameByRegionalRoutingContext, UnmodifiableMap regionalRoutingContextByRegionName, @@ -389,7 +388,7 @@ private UnmodifiableList getApplicableRegionRoutingConte return this.reevaluate( request, effectivePreferredLocations, - new UnmodifiableList<>(applicableEndpoints), + Collections.unmodifiableList(applicableEndpoints), regionNameByRegionalRoutingContext, regionalRoutingContextByRegionName, userConfiguredExcludeRegions, @@ -400,11 +399,11 @@ private UnmodifiableList getApplicableRegionRoutingConte isFallbackEndpointUsed); } - private UnmodifiableList reevaluate( + private List reevaluate( RxDocumentServiceRequest request, // populated when global endpoint == default endpoint && preferred regions not populated by user List effectivePreferredLocations, - UnmodifiableList applicableRegionalRoutingContexts, + List applicableRegionalRoutingContexts, UnmodifiableMap regionNameByRegionalRoutingContexts, UnmodifiableMap regionalRoutingContextsByRegionName, // exclude regions from request options or client @@ -508,7 +507,7 @@ private UnmodifiableList reevaluate( } } - return new UnmodifiableList<>(modifiedRegionalRoutingContexts); + return Collections.unmodifiableList(modifiedRegionalRoutingContexts); } private boolean isExcludeRegionsConfigured(List excludedRegionsOnRequest, List excludedRegionsOnClient) { @@ -765,7 +764,7 @@ private void updateLocationCache( Iterable gatewayReadLocations, Iterable thinClientWriteLocations, Iterable thinClientReadLocations, - UnmodifiableList preferenceList, + List preferenceList, Boolean enableMultipleWriteLocations) { synchronized (this.lockObject) { DatabaseAccountLocationsInfo nextLocationInfo = new DatabaseAccountLocationsInfo(this.locationInfo); @@ -783,8 +782,8 @@ private void updateLocationCache( this.clearStaleEndpointUnavailabilityInfo(); if (gatewayReadLocations != null) { - Utils.ValueHolder> readLocationsValueHolderOut = Utils.ValueHolder.initialize(nextLocationInfo.availableReadLocations); - Utils.ValueHolder> availableReadEndpointsOut = Utils.ValueHolder.initialize(nextLocationInfo.availableReadRegionalRoutingContexts); + Utils.ValueHolder> readLocationsValueHolderOut = Utils.ValueHolder.initialize(nextLocationInfo.availableReadLocations); + Utils.ValueHolder> availableReadEndpointsOut = Utils.ValueHolder.initialize(nextLocationInfo.availableReadRegionalRoutingContexts); Utils.ValueHolder> readRegionMapValueHolderOut = Utils.ValueHolder.initialize(nextLocationInfo.regionNameByReadRegionalRoutingContexts); nextLocationInfo.availableReadRegionalRoutingContextsByRegionName = this.getEndpointsByLocation(gatewayReadLocations, thinClientReadLocations, readLocationsValueHolderOut, availableReadEndpointsOut, readRegionMapValueHolderOut); @@ -795,9 +794,9 @@ private void updateLocationCache( } if (gatewayWriteLocations != null) { - Utils.ValueHolder> writeLocationsValueHolderOut = Utils.ValueHolder.initialize(nextLocationInfo.availableWriteLocations); + Utils.ValueHolder> writeLocationsValueHolderOut = Utils.ValueHolder.initialize(nextLocationInfo.availableWriteLocations); Utils.ValueHolder> writeRegionMapOut = Utils.ValueHolder.initialize(nextLocationInfo.regionNameByWriteRegionalRoutingContexts); - Utils.ValueHolder> availableWriteEndpointsOut = Utils.ValueHolder.initialize(nextLocationInfo.availableWriteRegionalRoutingContexts); + Utils.ValueHolder> availableWriteEndpointsOut = Utils.ValueHolder.initialize(nextLocationInfo.availableWriteRegionalRoutingContexts); nextLocationInfo.availableWriteRegionalRoutingContextsByRegionName = this.getEndpointsByLocation(gatewayWriteLocations, thinClientWriteLocations, writeLocationsValueHolderOut, availableWriteEndpointsOut, writeRegionMapOut); nextLocationInfo.availableWriteLocations = writeLocationsValueHolderOut.v; @@ -827,8 +826,8 @@ private void updateLocationCache( } } - private UnmodifiableList getPreferredAvailableRoutingContexts(UnmodifiableMap endpointsByLocation, - UnmodifiableList orderedLocations, + private List getPreferredAvailableRoutingContexts(UnmodifiableMap endpointsByLocation, + List orderedLocations, OperationType expectedAvailableOperation, RegionalRoutingContext fallbackRegionalRoutingContext) { List endpoints = new ArrayList<>(); @@ -894,7 +893,7 @@ private UnmodifiableList getPreferredAvailableRoutingCon if (endpoints.isEmpty()) { endpoints.add(fallbackRegionalRoutingContext); } - return new UnmodifiableList<>(endpoints); + return Collections.unmodifiableList(endpoints); } private void addRoutingContexts( @@ -958,8 +957,8 @@ private void addRoutingContexts( private UnmodifiableMap getEndpointsByLocation(Iterable gatewayLocations, Iterable thinclientLocations, - Utils.ValueHolder> orderedLocations, - Utils.ValueHolder> orderedEndpointsHolder, + Utils.ValueHolder> orderedLocations, + Utils.ValueHolder> orderedEndpointsHolder, Utils.ValueHolder> regionMap) { Map endpointsByLocation = new CaseInsensitiveMap<>(); Map regionByEndpoint = new CaseInsensitiveMap<>(); @@ -968,8 +967,8 @@ private UnmodifiableMap getEndpointsByLocation(I addRoutingContexts(gatewayLocations, thinclientLocations, endpointsByLocation, regionByEndpoint, parsedLocations, orderedEndpoints); - orderedLocations.v = new UnmodifiableList<>(parsedLocations); - orderedEndpointsHolder.v = new UnmodifiableList<>(orderedEndpoints); + orderedLocations.v = Collections.unmodifiableList(parsedLocations); + orderedEndpointsHolder.v = Collections.unmodifiableList(orderedEndpoints); regionMap.v = (UnmodifiableMap) UnmodifiableMap.unmodifiableMap(regionByEndpoint); return (UnmodifiableMap) UnmodifiableMap.unmodifiableMap(endpointsByLocation); @@ -1048,26 +1047,26 @@ private static boolean isExcludedRegionsSupplierConfigured(Supplier writeRegionalRoutingContexts; - private UnmodifiableList readRegionalRoutingContexts; - private UnmodifiableList preferredLocations; - private UnmodifiableList effectivePreferredLocations; + private List writeRegionalRoutingContexts; + private List readRegionalRoutingContexts; + private List preferredLocations; + private List effectivePreferredLocations; // lower-case region - private UnmodifiableList availableWriteLocations; + private List availableWriteLocations; // lower-case region - private UnmodifiableList availableReadLocations; + private List availableReadLocations; private UnmodifiableMap availableWriteRegionalRoutingContextsByRegionName; private UnmodifiableMap availableReadRegionalRoutingContextsByRegionName; private UnmodifiableMap regionNameByWriteRegionalRoutingContexts; private UnmodifiableMap regionNameByReadRegionalRoutingContexts; - private UnmodifiableList availableWriteRegionalRoutingContexts; - private UnmodifiableList availableReadRegionalRoutingContexts; + private List availableWriteRegionalRoutingContexts; + private List availableReadRegionalRoutingContexts; private RegionalRoutingContext hubRoutingContext; public DatabaseAccountLocationsInfo(List preferredLocations, RegionalRoutingContext defaultRoutingContext) { - this.preferredLocations = new UnmodifiableList<>(preferredLocations.stream().map(loc -> loc.toLowerCase(Locale.ROOT)).collect(Collectors.toList())); - this.effectivePreferredLocations = new UnmodifiableList<>(Collections.emptyList()); + this.preferredLocations = Collections.unmodifiableList(preferredLocations.stream().map(loc -> loc.toLowerCase(Locale.ROOT)).collect(Collectors.toList())); + this.effectivePreferredLocations = Collections.emptyList(); this.availableWriteRegionalRoutingContextsByRegionName = (UnmodifiableMap) UnmodifiableMap.unmodifiableMap(new CaseInsensitiveMap<>()); this.availableReadRegionalRoutingContextsByRegionName @@ -1076,12 +1075,12 @@ public DatabaseAccountLocationsInfo(List preferredLocations, = (UnmodifiableMap) UnmodifiableMap.unmodifiableMap(new CaseInsensitiveMap<>()); this.regionNameByReadRegionalRoutingContexts = (UnmodifiableMap) UnmodifiableMap.unmodifiableMap(new CaseInsensitiveMap<>()); - this.availableReadLocations = new UnmodifiableList<>(Collections.emptyList()); - this.availableWriteLocations = new UnmodifiableList<>(Collections.emptyList()); - this.readRegionalRoutingContexts = new UnmodifiableList<>(Collections.singletonList(defaultRoutingContext)); - this.writeRegionalRoutingContexts = new UnmodifiableList<>(Collections.singletonList(defaultRoutingContext)); - this.availableReadRegionalRoutingContexts = new UnmodifiableList<>(Collections.singletonList(defaultRoutingContext)); - this.availableWriteRegionalRoutingContexts = new UnmodifiableList<>(Collections.singletonList(defaultRoutingContext)); + this.availableReadLocations = Collections.emptyList(); + this.availableWriteLocations = Collections.emptyList(); + this.readRegionalRoutingContexts = Collections.singletonList(defaultRoutingContext); + this.writeRegionalRoutingContexts = Collections.singletonList(defaultRoutingContext); + this.availableReadRegionalRoutingContexts = Collections.singletonList(defaultRoutingContext); + this.availableWriteRegionalRoutingContexts = Collections.singletonList(defaultRoutingContext); } public DatabaseAccountLocationsInfo(DatabaseAccountLocationsInfo other) {