diff --git a/src/main/java/com/redhat/exhort/integration/providers/osv/OsvIntegration.java b/src/main/java/com/redhat/exhort/integration/providers/osv/OsvIntegration.java index d31b0968..b572af8f 100644 --- a/src/main/java/com/redhat/exhort/integration/providers/osv/OsvIntegration.java +++ b/src/main/java/com/redhat/exhort/integration/providers/osv/OsvIntegration.java @@ -19,6 +19,7 @@ package com.redhat.exhort.integration.providers.osv; import org.apache.camel.Exchange; +import org.apache.camel.builder.AggregationStrategies; import org.apache.camel.builder.endpoint.EndpointRouteBuilder; import org.eclipse.microprofile.config.inject.ConfigProperty; @@ -34,7 +35,7 @@ @ApplicationScoped public class OsvIntegration extends EndpointRouteBuilder { - @ConfigProperty(name = "api.onguard.timeout", defaultValue = "30s") + @ConfigProperty(name = "api.onguard.timeout", defaultValue = "60s") String timeout; @Inject VulnerabilityProvider vulnerabilityProvider; @@ -45,17 +46,31 @@ public void configure() throws Exception { // fmt:off from(direct("osvScan")) .routeId("osvScan") - .circuitBreaker() - .faultToleranceConfiguration() - .timeoutEnabled(true) - .timeoutDuration(timeout) - .end() - .transform(method(OsvRequestBuilder.class, "buildRequest")) - .to(direct("osvRequest")) - .onFallback() - .process(responseHandler::processResponseError) - .end() - .transform().method(responseHandler, "buildReport"); + .choice() + .when(method(OsvRequestBuilder.class, "isEmpty")) + .setBody(method(responseHandler, "emptyResponse")) + .transform().method(responseHandler, "buildReport") + .endChoice() + .otherwise() + .to(direct("osvSplitRequest")) + .transform().method(responseHandler, "buildReport"); + + from(direct("osvSplitRequest")) + .routeId("osvSplitRequest") + .transform(method(OsvRequestBuilder.class, "split")) + .split(body(), AggregationStrategies.beanAllowNull(responseHandler, "aggregateSplit")) + .parallelProcessing() + .transform().method(OsvRequestBuilder.class, "buildRequest") + .process(this::processRequest) + .circuitBreaker() + .faultToleranceConfiguration() + .timeoutEnabled(true) + .timeoutDuration(timeout) + .end() + .to(vertxHttp("{{api.onguard.host}}")) + .transform(method(responseHandler, "responseToIssues")) + .onFallback() + .process(responseHandler::processResponseError); from(direct("osvRequest")) .routeId("osvRequest") diff --git a/src/main/java/com/redhat/exhort/integration/providers/osv/OsvRequestBuilder.java b/src/main/java/com/redhat/exhort/integration/providers/osv/OsvRequestBuilder.java index 54835f4c..dc1f0412 100644 --- a/src/main/java/com/redhat/exhort/integration/providers/osv/OsvRequestBuilder.java +++ b/src/main/java/com/redhat/exhort/integration/providers/osv/OsvRequestBuilder.java @@ -18,6 +18,9 @@ package com.redhat.exhort.integration.providers.osv; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.redhat.exhort.config.ObjectMapperProducer; @@ -28,13 +31,35 @@ @RegisterForReflection public class OsvRequestBuilder { - private ObjectMapper mapper = ObjectMapperProducer.newInstance(); + private static final int BULK_SIZE = 128; + + private final ObjectMapper mapper = ObjectMapperProducer.newInstance(); - public String buildRequest(DependencyTree tree) throws JsonProcessingException { + public String buildRequest(List refs) throws JsonProcessingException { var request = mapper.createObjectNode(); var purls = mapper.createArrayNode(); - tree.getAll().forEach(dep -> purls.add(dep.ref())); + refs.forEach(dep -> purls.add(dep)); request.set("purls", purls); return mapper.writeValueAsString(request); } + + public List> split(DependencyTree tree) { + List> bulks = new ArrayList<>(); + List bulk = new ArrayList<>(); + for (var pkg : tree.getAll()) { + if (bulk.size() == BULK_SIZE) { + bulks.add(bulk); + bulk = new ArrayList<>(); + } + bulk.add(pkg.ref()); + } + if (!bulk.isEmpty()) { + bulks.add(bulk); + } + return bulks; + } + + public boolean isEmpty(DependencyTree tree) { + return tree.dependencies().isEmpty(); + } } diff --git a/src/main/java/com/redhat/exhort/integration/providers/tpa/TpaIntegration.java b/src/main/java/com/redhat/exhort/integration/providers/tpa/TpaIntegration.java index 8ccdcca8..7b5e4238 100644 --- a/src/main/java/com/redhat/exhort/integration/providers/tpa/TpaIntegration.java +++ b/src/main/java/com/redhat/exhort/integration/providers/tpa/TpaIntegration.java @@ -43,7 +43,7 @@ public class TpaIntegration extends EndpointRouteBuilder { private static final String TPA_CLIENT_TENANT = "tpa"; private static final int TPA_CLIENT_TIMEOUT = 10; - @ConfigProperty(name = "api.tpa.timeout", defaultValue = "30s") + @ConfigProperty(name = "api.tpa.timeout", defaultValue = "60s") String timeout; @ConfigProperty(name = "quarkus.oidc-client.tpa.enabled", defaultValue = "true")