@EventListener
  public void NotifySlackChannel(RepositoryPushEvent event) {
    // find out if notification is enabled for this repo
    Repository repository = event.getRepository();
    SlackSettings slackSettings = slackSettingsService.getSlackSettings(repository);
    String globalHookUrl = slackGlobalSettingsService.getWebHookUrl(KEY_GLOBAL_SETTING_HOOK_URL);

    SettingsSelector settingsSelector =
        new SettingsSelector(slackSettingsService, slackGlobalSettingsService, repository);
    SlackSettings resolvedSlackSettings = settingsSelector.getResolvedSlackSettings();

    if (resolvedSlackSettings.isSlackNotificationsEnabledForPush()) {
      String localHookUrl = slackSettings.getSlackWebHookUrl();
      WebHookSelector hookSelector = new WebHookSelector(globalHookUrl, localHookUrl);
      ChannelSelector channelSelector =
          new ChannelSelector(
              slackGlobalSettingsService.getChannelName(KEY_GLOBAL_SLACK_CHANNEL_NAME),
              slackSettings.getSlackChannelName());

      if (!hookSelector.isHookValid()) {
        log.error(
            "There is no valid configured Web hook url! Reason: " + hookSelector.getProblem());
        return;
      }

      if (repository.isFork() && !resolvedSlackSettings.isSlackNotificationsEnabledForPersonal()) {
        // simply return silently when we don't want forks to get notifications unless they're
        // explicitly enabled
        return;
      }

      String repoName = repository.getSlug();
      String projectName = repository.getProject().getKey();

      String repoPath = projectName + "/" + event.getRepository().getName();

      for (RefChange refChange : event.getRefChanges()) {
        String text;
        String ref = refChange.getRefId();
        NavBuilder.Repo repoUrlBuilder = navBuilder.project(projectName).repo(repoName);
        String url = repoUrlBuilder.commits().until(refChange.getRefId()).buildAbsolute();

        List<Changeset> myChanges = new LinkedList<Changeset>();
        boolean isNewRef =
            refChange.getFromHash().equalsIgnoreCase("0000000000000000000000000000000000000000");
        boolean isDeleted =
            refChange.getToHash().equalsIgnoreCase("0000000000000000000000000000000000000000")
                && refChange.getType() == RefChangeType.DELETE;
        if (isDeleted) {
          // issue#4: if type is "DELETE" and toHash is all zero then this is a branch delete
          if (ref.indexOf("refs/tags") >= 0) {
            text =
                String.format(
                    "Tag `%s` deleted from repository <%s|`%s`>.",
                    ref.replace("refs/tags/", ""), repoUrlBuilder.buildAbsolute(), repoPath);
          } else {
            text =
                String.format(
                    "Branch `%s` deleted from repository <%s|`%s`>.",
                    ref.replace("refs/heads/", ""), repoUrlBuilder.buildAbsolute(), repoPath);
          }
        } else if (isNewRef) {
          // issue#3 if fromHash is all zero (meaning the beginning of everything, probably), then
          // this push is probably
          // a new branch or tag, and we want only to display the latest commit, not the entire
          // history
          Changeset latestChangeSet = commitService.getChangeset(repository, refChange.getToHash());
          myChanges.add(latestChangeSet);
          if (ref.indexOf("refs/tags") >= 0) {
            text =
                String.format(
                    "Tag <%s|`%s`> pushed on <%s|`%s`>. See <%s|commit list>.",
                    url,
                    ref.replace("refs/tags/", ""),
                    repoUrlBuilder.buildAbsolute(),
                    repoPath,
                    url);
          } else {
            text =
                String.format(
                    "Branch <%s|`%s`> pushed on <%s|`%s`>. See <%s|commit list>.",
                    url,
                    ref.replace("refs/heads/", ""),
                    repoUrlBuilder.buildAbsolute(),
                    repoPath,
                    url);
          }
        } else {
          ChangesetsBetweenRequest request =
              new ChangesetsBetweenRequest.Builder(repository)
                  .exclude(refChange.getFromHash())
                  .include(refChange.getToHash())
                  .build();

          Page<Changeset> changeSets =
              commitService.getChangesetsBetween(
                  request, PageUtils.newRequest(0, PageRequest.MAX_PAGE_LIMIT));

          myChanges.addAll(Lists.newArrayList(changeSets.getValues()));

          int commitCount = myChanges.size();
          String commitStr = commitCount == 1 ? "commit" : "commits";

          String branch = ref.replace("refs/heads/", "");

          if (!branch.equals("master")) {
            continue;
          }

          text =
              String.format(
                  "Push on <%s|`%s`> branch <%s|`%s`> by `%s <%s>` (%d %s). See <%s|commit list>.",
                  repoUrlBuilder.buildAbsolute(),
                  repoPath,
                  url,
                  branch,
                  event.getUser() != null ? event.getUser().getDisplayName() : "unknown user",
                  event.getUser() != null ? event.getUser().getEmailAddress() : "unknown email",
                  commitCount,
                  commitStr,
                  url);
        }

        // Figure out what type of change this is:

        SlackPayload payload = new SlackPayload();

        payload.setText(text);
        payload.setMrkdwn(true);

        switch (resolvedSlackSettings.getNotificationLevel()) {
          case COMPACT:
            compactCommitLog(event, refChange, payload, repoUrlBuilder, myChanges);
            break;
          case VERBOSE:
            verboseCommitLog(event, refChange, payload, repoUrlBuilder, text, myChanges);
            break;
          case MINIMAL:
          default:
            break;
        }

        // slackSettings.getSlackChannelName might be:
        // - empty
        // - comma separated list of channel names, eg: #mych1, #mych2, #mych3

        if (channelSelector.getSelectedChannel().isEmpty()) {
          slackNotifier.SendSlackNotification(hookSelector.getSelectedHook(), gson.toJson(payload));
        } else {
          // send message to multiple channels
          List<String> channels =
              Arrays.asList(channelSelector.getSelectedChannel().split("\\s*,\\s*"));
          for (String channel : channels) {
            payload.setChannel(channel.trim());
            slackNotifier.SendSlackNotification(
                hookSelector.getSelectedHook(), gson.toJson(payload));
          }
        }
      }
    }
  }
Пример #2
0
 public void emit(T record) throws IOException, InterruptedException {
   for (int targetChannel : channelSelector.selectChannels(record, numChannels)) {
     sendToTarget(record, targetChannel);
   }
 }