in rest-api/src/jetbrains/buildServer/server/rest/request/BuildQueueRequest.java [168:234]
public Builds replaceBuilds(Builds builds, @QueryParam("fields") String fields, @Context UriInfo uriInfo, @Context HttpServletRequest request){
if (builds == null){
throw new BadRequestException("List of builds should be posted.");
}
if (builds.getSubmittedBuilds() == null){
throw new BadRequestException("Posted element should contain 'builds' sub-element.");
}
final jetbrains.buildServer.serverSide.BuildQueue buildQueue = myServiceLocator.getSingletonService(jetbrains.buildServer.serverSide.BuildQueue.class);
final List<BuildPromotion> queuedBuildPromotions = CollectionsUtil.convertCollection(buildQueue.getItems(), new Converter<BuildPromotion, SQueuedBuild>() {
public BuildPromotion createFrom(@NotNull final SQueuedBuild source) {
return source.getBuildPromotion();
}
});
final List<String> queuedBuildIds = CollectionsUtil.convertCollection(buildQueue.getItems(), new Converter<String, SQueuedBuild>() {
public String createFrom(@NotNull final SQueuedBuild source) {
return source.getItemId();
}
});
buildQueue.removeItems(queuedBuildIds, myServiceLocator.getSingletonService(UserFinder.class).getCurrentUser(), null); //todo: consider providing comment here
//TeamCity API issue: TW-34143
if (!buildQueue.isQueueEmpty()) {
throw new AuthorizationFailedException("Some builds were not canceled. Probably not sufficient permissions.");
}
//now delete the canceled builds
for (BuildPromotion queuedBuildPromotion : queuedBuildPromotions) {
final SBuild associatedBuild = queuedBuildPromotion.getAssociatedBuild();
if (associatedBuild == null){
throw new OperationException("After canceling a build with promotion id '" + queuedBuildPromotion.getId() + "' , no canceled build found to delete.");
}
DataProvider.deleteBuild(associatedBuild, myBeanContext.getSingletonService(BuildHistory.class));
}
// now queue
final SUser user = myServiceLocator.getSingletonService(UserFinder.class).getCurrentUser();
final Map<Long, Long> buildPromotionIdReplacements = new HashMap<Long, Long>();
List<Build> buildsToTrigger = builds.getSubmittedBuilds();
Map<Build, Exception> buildsWithErrors;
while (true) {
buildsWithErrors = triggerBuilds(buildsToTrigger, user, buildPromotionIdReplacements);
if (buildsWithErrors.isEmpty() || buildsToTrigger.size() <= buildsWithErrors.size()) {
//no errors or no builds triggered
break;
}
buildsToTrigger = new ArrayList<Build>(buildsWithErrors.keySet());
LOG.info("There was an error triggering " + buildsToTrigger.size() + " builds, will try again." + " Affected build ids: " + listBuildIds(buildsToTrigger));
//repeat (dependnecies order might be relevant)
}
if (buildsWithErrors.size() != 0) {
final StringBuilder buildListDetails = new StringBuilder();
for (Map.Entry<Build, Exception> buildExceptionEntry : buildsWithErrors.entrySet()) {
final Build build = buildExceptionEntry.getKey();
//noinspection ThrowableResultOfMethodCallIgnored
buildListDetails.append("Not able to add build").append(build.getPromotionIdOfSubmittedBuild() != null ? " with id '" + build.getPromotionIdOfSubmittedBuild() + "'" : "")
.append(" to the build queue due to error: ").append(buildExceptionEntry.getValue().toString());
buildListDetails.append("\n");
}
throw new BadRequestException("Error triggering " + buildsWithErrors.size() + " out of " + builds.getSubmittedBuilds().size() + " builds: \n" +
buildListDetails.substring(0, buildListDetails.length() - "\n".length()));
}
return getBuilds(null, fields, uriInfo, request);
}