in s3-artifact-storage-server/src/main/java/jetbrains/buildServer/artifacts/s3/orphans/S3OrphanedArtifactsScanner.java [289:348]
private BuildTypeEntry scanBuildTypePath(String projectId, String buildTypePath, String bucketName, Map<String, String> parameters) throws ConnectionCredentialsException {
List<ListObjectsV2Response> builds = getObjects(parameters, bucketName, projectId, buildTypePath);
List<String> paths = builds.stream()
.flatMap(res -> res.commonPrefixes().stream())
.map(CommonPrefix::prefix)
.collect(Collectors.toList());
if (paths.isEmpty()) {
LOG.debug("Found path that doesn't correlate to the expected storage structure: " + buildTypePath);
return new BuildTypeEntry(buildTypePath, Collections.emptySet(), true);
}
Set<BuildEntry> outdatedEntries = new HashSet<>();
Map<Long, BuildEntry> buildEntries = new HashMap<>();
for (String fullPath : paths) {
String path = fullPath;
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
String entryName = path.substring(path.lastIndexOf('/') + 1);
if (entryName.isEmpty()) {
continue;
}
BuildEntry buildEntry = new BuildEntry(path, entryName);
if (NUMERIC_BUILD_ID.matcher(entryName).matches()) {
long id = Long.parseLong(entryName);
buildEntries.put(id, buildEntry);
} else {
outdatedEntries.add(buildEntry);
}
}
LOG.debug("Found " + outdatedEntries + " of non-conforming build entries");
myServer.getRunningBuilds(null, build -> buildEntries.containsKey(build.getBuildId()))
.stream()
.map(Build::getBuildId)
.forEach(buildEntries::remove);
myBuildHistory.findEntries(buildEntries.keySet())
.forEach(build -> buildEntries.remove(build.getBuildId()));
scannedPaths.add(paths.size());
outdatedEntries.addAll(buildEntries.values());
LOG.debug("Found " + outdatedEntries + " of all entries in " + buildTypePath);
return new BuildTypeEntry(
buildTypePath,
outdatedEntries,
outdatedEntries.size() == paths.size()
);
}