Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,12 @@ private boolean hasAnyHash(Optional<String> sha256, Optional<String> sha1, Optio
}

protected void processBrewBuild(Component component, Artifact artifact) {
KojiBuild brewBuild = kojiService.findBuild(artifact);
KojiBuild brewBuild = null;
try {
brewBuild = kojiService.findBuild(artifact);
} catch (Throwable e) {
log.error("Lookup in Brew failed due to {}", e.getMessage() == null ? e.toString() : e.getMessage(), e);
}
if (brewBuild != null) {

log.debug(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,20 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;

import org.apache.commons.collections4.MultiValuedMap;
import org.eclipse.microprofile.context.ManagedExecutor;
import org.eclipse.microprofile.faulttolerance.Retry;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.jboss.pnc.build.finder.core.BuildConfig;
import org.jboss.pnc.build.finder.core.BuildFinder;
Expand Down Expand Up @@ -69,14 +73,17 @@
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import static org.jboss.sbomer.core.rest.faulttolerance.Constants.KOJI_SERVICE_DELAY;
import static org.jboss.sbomer.core.rest.faulttolerance.Constants.KOJI_SERVICE_MAX_RETRIES;

/**
* A service to interact with the Koji (Brew) build system.
*/
@Slf4j
@ApplicationScoped
public class KojiService {

private static final Long MAX_BREW_WAIT_5_MIN = 5 * 60 * 1000L;
private static final int MAX_BREW_WAIT_MIN = 5;
private static final KojiObjectMapper MAPPER = new KojiObjectMapper();
public static final String REMOTE_SOURCE_PREFIX = "remote-source";
public static final String REMOTE_SOURCE_DELIMITER = "-";
Expand Down Expand Up @@ -109,7 +116,7 @@ public class KojiService {
* @return Results of the analysis if the whole operation was successful.
* @throws Throwable Thrown in case of any errors during the analysis
*/
public List<KojiBuild> find(
private List<KojiBuild> find(
String url,
DistributionAnalyzerListener distributionAnalyzerListener,
BuildFinderListener buildFinderListener) throws Throwable {
Expand All @@ -122,12 +129,7 @@ public List<KojiBuild> find(
}
});

try {
return awaitResults(finderTask);
} catch (InterruptedException | ExecutionException e) { // NOSONAR We are rethrowing it.
log.debug("Analysis failed due to {}", e.getMessage(), e);
throw e.getCause();
}
return awaitResults(finderTask);
}

/**
Expand Down Expand Up @@ -177,56 +179,48 @@ private List<KojiBuild> find(
return brewBuilds;
}

private List<KojiBuild> awaitResults(Future<List<KojiBuild>> finderTask)
throws InterruptedException, ExecutionException {

int retry = 1;
while (!finderTask.isDone() && (retry * 500L) < MAX_BREW_WAIT_5_MIN) {
try {
retry++;
// FIXME: Call to 'Thread.sleep()' in a loop, probably busy-waiting
Thread.sleep(500);
} catch (InterruptedException e) {
log.warn("Sleeping while awaiting results was interrupted", e);
Thread.currentThread().interrupt();
}
}
if (finderTask.isDone()) {
return finderTask.get();
private List<KojiBuild> awaitResults(Future<List<KojiBuild>> finderTask) throws Throwable {
try {
return finderTask.get(MAX_BREW_WAIT_MIN, TimeUnit.MINUTES);
} catch (TimeoutException e) {
log.debug("Timeout waiting for build results");
return Collections.emptyList();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return Collections.emptyList();
} catch (ExecutionException e) { // NOSONAR We are rethrowing it.
log.debug("Analysis failed due to {}", e.getMessage(), e);
throw e.getCause();
}
return Collections.emptyList();
}

public KojiBuild findBuild(Artifact artifact) {

@Retry(maxRetries = KOJI_SERVICE_MAX_RETRIES, delay = KOJI_SERVICE_DELAY, delayUnit = ChronoUnit.SECONDS)
public KojiBuild findBuild(Artifact artifact) throws Throwable {
if (artifact.getPublicUrl() == null) {
return null;
}

try {
FinderStatus status = new FinderStatus();
log.trace("Searching for artifact '{}' in Brew...", artifact.getPublicUrl());
List<KojiBuild> brewBuilds = find(artifact.getPublicUrl(), status, status);
if (brewBuilds.size() == 1) {
log.trace(
"Found Brew build with id {} of artifact: '{}'",
brewBuilds.get(0).getId(),
artifact.getPublicUrl());
return brewBuilds.get(0);
} else if (brewBuilds.size() > 1) {
String brewBuildIds = brewBuilds.stream().map(KojiBuild::getId).collect(Collectors.joining(", "));
log.warn(
"Multiple builds (with ids: {}) where found in Brew of the artifact '{}', picking the first one!",
brewBuildIds,
artifact.getPublicUrl());
return brewBuilds.get(0);
}
} catch (Throwable e) {
log.error("Lookup in Brew failed due to {}", e.getMessage() == null ? e.toString() : e.getMessage(), e);
FinderStatus status = new FinderStatus();
log.trace("Searching for artifact '{}' in Brew...", artifact.getPublicUrl());
List<KojiBuild> brewBuilds = find(artifact.getPublicUrl(), status, status);
if (brewBuilds.size() == 1) {
log.trace(
"Found Brew build with id {} of artifact: '{}'",
brewBuilds.get(0).getId(),
artifact.getPublicUrl());
return brewBuilds.get(0);
} else if (brewBuilds.size() > 1) {
String brewBuildIds = brewBuilds.stream().map(KojiBuild::getId).collect(Collectors.joining(", "));
log.warn(
"Multiple builds (with ids: {}) where found in Brew of the artifact '{}', picking the first one!",
brewBuildIds,
artifact.getPublicUrl());
return brewBuilds.get(0);
}
return null;
}

@Retry(maxRetries = KOJI_SERVICE_MAX_RETRIES, delay = KOJI_SERVICE_DELAY, delayUnit = ChronoUnit.SECONDS)
public KojiBuildInfo findBuildByRPM(String nvra) throws KojiClientException {
if (nvra == null) {
return null;
Expand Down Expand Up @@ -267,6 +261,7 @@ public KojiBuildInfo findBuildByRPM(String nvra) throws KojiClientException {
return buildInfo;
}

@Retry(maxRetries = KOJI_SERVICE_MAX_RETRIES, delay = KOJI_SERVICE_DELAY, delayUnit = ChronoUnit.SECONDS)
public KojiBuildInfo findBuild(int id) throws KojiClientException {
log.debug("Retrieving Brew build with id '{}'...", id);

Expand All @@ -280,6 +275,7 @@ public KojiBuildInfo findBuild(int id) throws KojiClientException {
return build;
}

@Retry(maxRetries = KOJI_SERVICE_MAX_RETRIES, delay = KOJI_SERVICE_DELAY, delayUnit = ChronoUnit.SECONDS)
public KojiBuildInfo findBuild(String nvr) throws KojiClientException {
if (nvr == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ public class Constants {
public static final int ERRATA_CLIENT_MAX_RETRIES = 15;
public static final int PYXIS_CLIENT_MAX_RETRIES = 15;
public static final int ATLAS_CLIENT_MAX_RETRIES = 15;
public static final int KOJI_SERVICE_MAX_RETRIES = 15;
public static final int KOJI_DOWNLOAD_CLIENT_MAX_RETRIES = 15;
public static final int SBOMER_CLIENT_MAX_RETRIES = 15;

public static final long PNC_CLIENT_DELAY = 1;
public static final long ERRATA_CLIENT_DELAY = 1;
public static final long PYXIS_CLIENT_DELAY = 1;
public static final long ATLAS_CLIENT_DELAY = 1;
public static final long KOJI_SERVICE_DELAY = 1;
public static final long KOJI_DOWNLOAD_CLIENT_DELAY = 1;
public static final long SBOMER_CLIENT_DELAY = 1;

Expand Down
Loading