Handler getHandler()

in commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/github/ChangeStatusUpdater.java [143:293]


  Handler getHandler(@NotNull VcsRoot root,
                     @NotNull Map<String, String> params,
                     @NotNull final GitHubPublisher publisher) {

    return new Handler() {

      public void changeStarted(@NotNull BuildRevision revision, @NotNull SBuild build, @NotNull String viewUrl) throws PublisherException {
        doChangeUpdate(revision, build, DefaultStatusMessages.BUILD_STARTED, GitHubChangeState.Pending, viewUrl);
      }

      public void changeCompleted(@NotNull BuildRevision revision, @NotNull SBuild build, @NotNull String viewUrl) throws PublisherException {
        LOG.debug("Status :" + build.getStatusDescriptor().getStatus().getText());
        LOG.debug("Status Priority:" + build.getStatusDescriptor().getStatus().getPriority());

        final GitHubChangeState status = getGitHubChangeState(build);
        final String text = getGitHubChangeText(build);
        doChangeUpdate(revision, build, text, status, viewUrl);
      }

      @Override
      public boolean changeQueued(@NotNull BuildRevision revision, @NotNull BuildPromotion buildPromotion,
                                  @NotNull AdditionalTaskInfo additionalTaskInfo, @NotNull String viewUrl) throws PublisherException {
        return doQueuedChangeUpdate(revision, buildPromotion, additionalTaskInfo, viewUrl, false);
      }

      @Override
      public boolean changeRemovedFromQueue(@NotNull BuildRevision revision, @NotNull BuildPromotion buildPromotion,
                                            @NotNull AdditionalTaskInfo additionalTaskInfo, @NotNull String viewUrl) throws PublisherException {
        return doQueuedChangeUpdate(revision, buildPromotion, additionalTaskInfo, viewUrl, true);
      }

      @NotNull
      private String getGitHubChangeText(@NotNull SBuild build) {
        if (build.getBuildStatus().isSuccessful()) {
          return DefaultStatusMessages.BUILD_FINISHED;
        } else {
          return DefaultStatusMessages.BUILD_FAILED;
        }
      }

      @NotNull
      private GitHubChangeState getGitHubChangeState(@NotNull final SBuild build) {
        final Status status = build.getStatusDescriptor().getStatus();
        final byte priority = status.getPriority();

        if (priority == Status.NORMAL.getPriority()) {
          return GitHubChangeState.Success;
        } else if (priority == Status.FAILURE.getPriority()) {
          return GitHubChangeState.Failure;
        } else {
          return GitHubChangeState.Error;
        }
      }

      @Override
      public CommitStatus getStatus(@NotNull BuildRevision revision) throws PublisherException {
        RepositoryVersion version = revision.getRepositoryVersion();
        String buildContext = params.get(Constants.GITHUB_CONTEXT);
        LOG.debug("Requesting statuses for " +
                  "hash: " + version.getVersion() + ", " +
                  "branch: " + version.getVcsBranch() + ", " +
                  "build: " + buildContext);

        Repository repo = parseRepository(root);
        GitHubStatusClient statusClient = new GitHubStatusClient(params, publisher, root);
        try {
          return statusClient.getStatus(revision, repo);
        } catch (IOException e) {
          publisher.getProblems().reportProblem(String.format("Commit Status Publisher error. Can not receive status for revision: %s", revision.getRevision()), publisher,
                                                buildContext, publisher.getServerUrl(), e, LOG);
        }
        return null;
      }

      @Override
      public Collection<CommitStatus> getStatuses(@NotNull BuildRevision revision) throws PublisherException {
        RepositoryVersion version = revision.getRepositoryVersion();
        String buildContext = params.get(Constants.GITHUB_CONTEXT);
        LOG.debug("Requesting statuses for " +
                  "hash: " + version.getVersion() + ", " +
                  "branch: " + version.getVcsBranch() + ", " +
                  "build: " + buildContext);

        Repository repo = parseRepository(root);
        GitHubStatusClient statusClient = new GitHubStatusClient(params, publisher, root);

        final int perPage = 25;
        int page = 1;
        Collection<CommitStatus> result = new ArrayList<>();
        boolean keepLoading;
        final int statusesThreshold = TeamCityProperties.getInteger(Constants.STATUSES_TO_LOAD_THRESHOLD_PROPERTY, Constants.STATUSES_TO_LOAD_THRESHOLD_DEFAULT_VAL);

        do {
          Collection<CommitStatus> statuses;
          try {
            statuses = statusClient.getStatuses(revision, repo, perPage, page);
          } catch (IOException | PublisherException e) {
            publisher.getProblems().reportProblem(String.format("Commit Status Publisher error. Can not receive status for revision: %s", revision.getRevision()), publisher,
                                                  buildContext, publisher.getServerUrl(), e, LOG);
            if (e instanceof PublisherException) {
              throw (PublisherException)e;
            }
            return Collections.emptyList();
          }
          if (statuses == null) return result;
          result.addAll(statuses);
          keepLoading = !statuses.isEmpty() &&
                        result.size() < statusesThreshold &&
                        statuses.stream().noneMatch(status -> buildContext.equals(status.context));
        } while (keepLoading);
        return result;
      }

      private void doChangeUpdate(@NotNull final BuildRevision revision,
                                  @NotNull final SBuild build,
                                  @NotNull final String message,
                                  @NotNull final GitHubChangeState targetStatus,
                                  @NotNull String viewUrl) throws PublisherException {
        final RepositoryVersion version = revision.getRepositoryVersion();
        LOG.debug("Scheduling GitHub status update for " +
                 "hash: " + version.getVersion() + ", " +
                 "branch: " + version.getVcsBranch() + ", " +
                 "buildId: " + build.getBuildId() + ", " +
                 "status: " + targetStatus);

        Repository repo = parseRepository(root);

        GitHubStatusClient statusClient = new GitHubStatusClient(params, publisher, root);
        statusClient.update(revision, build, message, targetStatus, repo, viewUrl);
      }

      private boolean doQueuedChangeUpdate(@NotNull BuildRevision revision,
                                           @NotNull BuildPromotion buildPromotion,
                                           @NotNull AdditionalTaskInfo additionalTaskInfo,
                                           @NotNull String viewUrl,
                                           boolean deletedFromQueue) throws PublisherException {
        final RepositoryVersion version = revision.getRepositoryVersion();
        final GitHubChangeState targetStatus = deletedFromQueue ? GitHubChangeState.Failure : GitHubChangeState.Pending;
        LOG.debug("Scheduling GitHub status update for " +
                 "hash: " + version.getVersion() + ", " +
                 "branch: " + version.getVcsBranch() + ", " +
                 "buildId: " + buildPromotion.getId() + ", " +
                 "status: " + targetStatus);

        Repository repo = parseRepository(root);

        GitHubQueuedStatusClient statusClient = new GitHubQueuedStatusClient(params, publisher, root);
        return statusClient.update(revision, buildPromotion, targetStatus, repo, additionalTaskInfo, viewUrl);
      }
    };
  }