Skip to content

Commit

Permalink
Merge pull request #5 from danshan/feature/sonarqube
Browse files Browse the repository at this point in the history
Feature/sonarqube
  • Loading branch information
danshan authored Mar 22, 2017
2 parents 73fc15a + 6e17edd commit 2357e43
Show file tree
Hide file tree
Showing 17 changed files with 299 additions and 2 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@

![MicroBadger](docs/microbadger.png)

* [Docker](https://docker.io)

![Docker](docs/docker.png)

* [SonarQube](https://www.sonarqube.org/)

![SonarQube](docs/sonar.png)

## Create Webhook

[Slack Apps](https://api.slack.com/apps) 中创建一个 App, 以 DaoCloud 为例:
Expand Down
6 changes: 6 additions & 0 deletions bin/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
#!/bin/bash

mvn sonar:sonar \
-Dsonar.host.url=https://sonarqube.com \
-Dsonar.organization=$SONAR_ORG \
-Dsonar.login=$SONAR_TOKEN

java -jar \
-Dslack.daocloud="$SLACK_DAOCLOUD" \
-Dslack.microbadger="$SLACK_MICROBADGER" \
-Dslack.docker="$SLACK_DOCKER" \
-Dslack.sonar="$SLACK_SONAR" \
$DATA_DIR/$APP_NAME/target/$APP_NAME.jar
Binary file added docs/docker.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/sonar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/main/java/com/shanhh/webhook/config/SlackConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ public class SlackConfig {

@Value("${slack.docker}")
private String slackForDocker;

@Value("${slack.sonar}")
private String sonarForDocker;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import com.shanhh.webhook.slack.beans.Hook;
import com.shanhh.webhook.slack.beans.SlackPayload;
import com.shanhh.webhook.slack.service.SlackService;
import com.shanhh.webhook.sonarqube.beans.SonarPayload;
import com.shanhh.webhook.sonarqube.service.SonarService;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
Expand All @@ -27,14 +29,17 @@
@RequestMapping("/webhook")
public class WebhookController {

@Resource
private SlackService slackService;

@Resource
private DaocloudService daocloudService;
@Resource
private MicrobadgerService microbadgerService;
@Resource
private DockerService dockerService;
@Resource
private SlackService slackService;
private SonarService sonarService;

@RequestMapping(value = "daocloud", method = RequestMethod.POST)
public String daocloud(@RequestBody DaocloudPayload payload) throws IOException {
Expand All @@ -54,4 +59,9 @@ public String daocloud(@RequestBody DockerPayload payload) throws IOException {
return slackService.send(Hook.DOCKER, slackPayload);
}

@RequestMapping(value = "sonar", method = RequestMethod.POST)
public String sonar(@RequestBody SonarPayload payload) throws IOException {
SlackPayload slackPayload = sonarService.exec(payload);
return slackService.send(Hook.SONAR, slackPayload);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.shanhh.webhook.daocloud.beans;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Data;
Expand Down Expand Up @@ -28,6 +29,7 @@
*/
@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class DaocloudPayload implements Serializable {
/*
@formatter:on
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.shanhh.webhook.docker.beans;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Data;
Expand All @@ -16,6 +17,7 @@
*/
@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class DockerPayload implements Serializable {
/*
@formatter:on
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.shanhh.webhook.microbadger.beans;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.AllArgsConstructor;
Expand All @@ -16,6 +17,7 @@
*/
@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class MicrobadgerPayload implements Serializable {
/*
@formatter:on
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/shanhh/webhook/slack/beans/Hook.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
* @since 2017-03-03 22:45
*/
public enum Hook {
MICROBADGER, DAOCLOUD, DOCKER
MICROBADGER, DAOCLOUD, DOCKER, SONAR
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ public class SlackAttaPayload implements SlackPayload {
@formatter:off
*/

private String text;
private List<Attachment> attachments;
@JsonProperty("mrkdwn_in")
private List<String> mrkdwnIn;

@Data
@Builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ private String getHookUrl(Hook hook) {
return slackConfig.getSlackForMicrobadger();
case DOCKER:
return slackConfig.getSlackForDocker();
case SONAR:
return slackConfig.getSonarForDocker();
default:
throw new IllegalArgumentException("unsupported webhook");
}
Expand Down
103 changes: 103 additions & 0 deletions src/main/java/com/shanhh/webhook/sonarqube/beans/SonarPayload.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.shanhh.webhook.sonarqube.beans;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
* @author dan
* @since 2017-03-21 17:30
*/
@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class SonarPayload implements Serializable {
/*
@formatter:on
{
"analysedAt": "2016-11-18T10:46:28+0100",
"project": {
"key": "org.sonarqube:example",
"name": "Example"
},
"properties": {
},
"qualityGate": {
"conditions": [
{
"errorThreshold": "1",
"metric": "new_security_rating",
"onLeakPeriod": true,
"operator": "GREATER_THAN",
"status": "OK",
"value": "1"
},
{
"errorThreshold": "1",
"metric": "new_reliability_rating",
"onLeakPeriod": true,
"operator": "GREATER_THAN",
"status": "OK",
"value": "1"
},
{
"errorThreshold": "1",
"metric": "new_maintainability_rating",
"onLeakPeriod": true,
"operator": "GREATER_THAN",
"status": "OK",
"value": "1"
},
{
"errorThreshold": "80",
"metric": "new_coverage",
"onLeakPeriod": true,
"operator": "LESS_THAN",
"status": "NO_VALUE"
}
],
"name": "SonarQube way",
"status": "OK"
},
"status": "SUCCESS",
"taskId": "AVh21JS2JepAEhwQ-b3u"
}
@formatter:off
*/

private String analysedAt;
private Project project;
private QualityGate qualityGate;
private String status;
private String taskId;

@Data
@NoArgsConstructor
public static class Project implements Serializable {
private String key;
private String name;
}

@Data
@NoArgsConstructor
public static class QualityGate implements Serializable {
private List<Condition> conditions;
private String name;
private String status;
}

@Data
@NoArgsConstructor
public static class Condition implements Serializable {
private String errorThreshold;
private String metric;
private boolean onLeakPeriod;
private String operator;
private String status;
private String value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.shanhh.webhook.sonarqube.service;

import com.shanhh.webhook.slack.beans.SlackPayload;
import com.shanhh.webhook.sonarqube.beans.SonarPayload;

/**
* @author dan
* @since 2017-03-21 17:37
*/
public interface SonarService {
SlackPayload exec(SonarPayload payload);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.shanhh.webhook.sonarqube.service;

import com.google.common.collect.Lists;
import com.shanhh.webhook.slack.beans.SlackAttaColor;
import com.shanhh.webhook.slack.beans.SlackAttaPayload;
import com.shanhh.webhook.slack.beans.SlackPayload;
import com.shanhh.webhook.sonarqube.beans.SonarPayload;

import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;

/**
* @author dan
* @since 2017-03-21 17:38
*/
@Slf4j
@Service
public class SonarServiceImpl implements SonarService {

@Override
public SlackPayload exec(SonarPayload payload) {
if (checkSkip(payload)) {
return null;
}

SlackAttaPayload slack = new SlackAttaPayload();

List<SlackAttaPayload.Attachment> attachments = Lists.newLinkedList();
if (payload.getQualityGate() != null && !CollectionUtils.isEmpty(payload.getQualityGate().getConditions())) {
payload.getQualityGate().getConditions().stream()
// .filter(condition -> !"OK".equals(condition.getStatus()))
.forEach(condition -> {
SlackAttaPayload.Attachment attachment = SlackAttaPayload.Attachment.builder()
.color(SlackAttaColor.danger.name())
.title(condition.getMetric())
.text(String.format("*%s*: `%s` %s `%s`", condition.getStatus(), condition.getValue(), condition.getOperator(), condition.getErrorThreshold()))
.mrkdwnIn(Arrays.asList("text"))
.build();
attachments.add(attachment);
});
}
while (attachments.size() > 30) {
attachments.remove(attachments.size() - 1);
}

slack.setText(String.format("%s: `%s`", payload.getProject().getName(), payload.getStatus()));
slack.setAttachments(attachments);
slack.setMrkdwnIn(Arrays.asList("text"));
return slack;
}

private boolean checkSkip(SonarPayload payload) {
return false;
}
}
1 change: 1 addition & 0 deletions src/main/resources/application.sample.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ slack:
daocloud:
microbadger:
docker:
sonar:
Loading

0 comments on commit 2357e43

Please sign in to comment.