Skip to content

Commit e0861d7

Browse files
Fix #1222: Chunk request with large number of matched resources (#1223)
* Fix #1222: Chunk request with large number of matched resources * CAPI, with v3 API, is limited to returning responses with max 5000 max matched resources; so we chunk them into request with max 5000 matched resources * first try * Fix #1222: Chunk request with large number of matched resources * CAPI, with v3 API, is limited to returning responses with max 5000 max matched resources; so we chunk them into request with max 5000 matched resources * update code that calls the request instead of the request code itself
1 parent 6c5652e commit e0861d7

File tree

4 files changed

+64
-3
lines changed

4 files changed

+64
-3
lines changed

cloudfoundry-util/src/main/java/org/cloudfoundry/util/ResourceMatchingUtilsV3.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Collection;
2525
import java.util.Enumeration;
2626
import java.util.List;
27+
import java.util.stream.Collectors;
2728
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
2829
import org.apache.commons.compress.archivers.zip.ZipFile;
2930
import org.cloudfoundry.client.CloudFoundryClient;
@@ -46,6 +47,7 @@ public final class ResourceMatchingUtilsV3 {
4647

4748
private static final Logger LOGGER =
4849
LoggerFactory.getLogger("cloudfoundry-client.resource-matching-v3");
50+
public static final int MAX_RESOURCES_SIZE = 5000;
4951

5052
private ResourceMatchingUtilsV3() {}
5153

@@ -55,9 +57,9 @@ public static Mono<List<MatchedResource>> getMatchedResources(
5557
? getArtifactMetadataFromDirectory(application)
5658
: getArtifactMetadataFromZip(application))
5759
.collectList()
58-
.flatMap(
59-
(List<ArtifactMetadata> artifactMetadatas) ->
60-
requestListMatchingResources(cloudFoundryClient, artifactMetadatas))
60+
.flatMapMany(Flux::fromIterable)
61+
.buffer(MAX_RESOURCES_SIZE)
62+
.flatMap(chunk -> requestListMatchingResources(cloudFoundryClient, chunk))
6163
.map(ListMatchingResourcesResponse::getResources)
6264
.doOnNext(
6365
matched ->
@@ -68,6 +70,8 @@ public static Mono<List<MatchedResource>> getMatchedResources(
6870
matched.stream()
6971
.mapToInt(MatchedResource::getSize)
7072
.sum())))
73+
.collectList()
74+
.map(lists -> lists.stream().flatMap(List::stream).collect(Collectors.toList()))
7175
.subscribeOn(Schedulers.boundedElastic());
7276
}
7377

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package org.cloudfoundry.util;
2+
3+
import static org.cloudfoundry.util.ResourceMatchingUtilsV3.getMatchedResources;
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertNotNull;
6+
import static org.mockito.Mockito.mock;
7+
import static org.mockito.Mockito.when;
8+
9+
import java.io.IOException;
10+
import java.nio.file.Path;
11+
import java.util.List;
12+
import org.cloudfoundry.client.CloudFoundryClient;
13+
import org.cloudfoundry.client.v3.resourcematch.ListMatchingResourcesResponse;
14+
import org.cloudfoundry.client.v3.resourcematch.MatchedResource;
15+
import org.junit.jupiter.api.Test;
16+
import org.springframework.core.io.ClassPathResource;
17+
import reactor.core.publisher.Mono;
18+
19+
class ResourceMatchingUtilsV3Test {
20+
21+
@Test
22+
void requestListMatchingResources2() throws IOException {
23+
CloudFoundryClient cloudFoundryClient = mock(CloudFoundryClient.class);
24+
when(cloudFoundryClient.resourceMatchV3())
25+
.thenReturn(
26+
request ->
27+
Mono.just(
28+
ListMatchingResourcesResponse.builder()
29+
.addAllResources(request.getResources())
30+
.build()));
31+
32+
Path testApplication = new ClassPathResource("test-application.zip").getFile().toPath();
33+
34+
List<MatchedResource> result =
35+
getMatchedResources(cloudFoundryClient, testApplication).block();
36+
assertNotNull(result);
37+
assertEquals(2, result.size());
38+
}
39+
40+
@Test
41+
void requestListMatchingResources15001() throws IOException {
42+
CloudFoundryClient cloudFoundryClient = mock(CloudFoundryClient.class);
43+
when(cloudFoundryClient.resourceMatchV3())
44+
.thenReturn(
45+
request ->
46+
Mono.just(
47+
ListMatchingResourcesResponse.builder()
48+
.addAllResources(request.getResources())
49+
.build()));
50+
Path testApplication = new ClassPathResource("15001_files.zip").getFile().toPath();
51+
52+
List<MatchedResource> result =
53+
getMatchedResources(cloudFoundryClient, testApplication).block();
54+
assertNotNull(result);
55+
assertEquals(15001, result.size());
56+
}
57+
}
1.94 MB
Binary file not shown.
450 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)