大概的流程是用Jenkins调用Maven,在Maven里面用Jacoco测试覆盖率。Jacoco的报告文件是本地的CSV文件。但是这样不太好看,还要去Jeknins Server上把CSV拉下来。
后来测试了下,可以把CSV直接发布到Confluence里面,这样就方便了。
在Confluence里面直接写CSV很简单,就是通过CSV宏
{CSV}
HEAD1,HEAD2
1,2
3,4
{CSV}
要实现代码自动创建这个CSV,需要知道下面的东西:
1. Confluence的用户名密码;
2. 相应的Space ID;
3. Confluence CSV的XML描述语言。
最后写成了一个Java小程序,直接在Jenkins里面通过sh来调用。
import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
/**
* @author Feifei Liu
* @datetime 2018-03-29 11:11
*/
public class PostCSVToConfluence {
static {
// Disable SSL check, for Confluence Server has a self-signed SSL Certificate
Security.setProperty("ssl.SocketFactory.provider", "com.ibm.jsse2.SSLSocketFactoryImpl");
Security.setProperty("ssl.ServerSocketFactory.provider", "com.ibm.jsse2.SSLServerSocketFactoryImpl");
disableSSLCertificateChecking();
}
public static void main(String[] argu) throws IOException {
String username = "USER";
String password = "PASSWORD";
String file = argu[0];
System.out.println("Reading " + file);
Map headers = new HashMap<>();
headers.put("Content-Type", "application/json");
// Basic Authentication.
String encoded = Base64.getEncoder().encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8)); //Java 8
headers.put("Authorization", "Basic "+encoded);
String cdata = getCData(file);
String title = "Java Coverage Report for " + new Date().toString();
// Build JSON to be posted to confluence server
// 修改 key 到 要发布结果的SPACE
String body = "{\n" +
" \"type\": \"page\",\n" +
" \"title\": \"" + title +"\",\n" +
" \"space\": {\n" +
" \"key\": \"ACD\"\n" + // <==== SPACE Name
" },\n" +
" \"body\" :{ \n" +
" \"storage\": {\n" +
" \"value\": \"INLINE " + cdata + " \" "+
" ,\n\"representation\": \"storage\"\n" +
" }} \n" +
"}";
System.out.println(body);
try {
// Confluence 的 API
post("https://192.168.88.12:8443/confluence/rest/api/content", headers, body );
} catch (IOException e) {
e.printStackTrace();
}
}
// 读本地文件,拼装成一个CDATA; 注意这里因为没有中文的需求就没处理编码
private static String getCData(String file) throws IOException {
String r = "
StringBuffer s = new StringBuffer(r);
BufferedReader br = new BufferedReader(new FileReader(file));
String line = br.readLine();
boolean first = true;
while (line != null) {
if (!first) {
s.append("\\n");
}
s.append(line);
first = false;
line = br.readLine();
}
s.append("]]>");
return s.toString();
}
/**
* POST request to url.
* @param header headers
* @param body body
* @return response body, if successful
*/
public static String post(String httpurl, Map headers, String body) throws IOException {
HttpURLConnection conn = null;
try {
URL url = new URL(httpurl);
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setUseCaches(false);
//Set headers
for (String key : headers.keySet()) {
String v = headers.get(key);
if (v != null) {
conn.setRequestProperty(key, headers.get(key));
}
}
conn.connect();
if (body != null) {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
bw.write(body);
bw.flush();
bw.close();
}
// Request not successful
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
// Read response
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
StringBuffer response = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
br.close();
throw new IOException("Request Failed. HTTP Error Code: " + conn.getResponseCode() + " \n " + response.toString());
}
Map> map = conn.getHeaderFields();
// Read response
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer response = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
br.close();
return response.toString();
} catch (IOException e) {
throw e;
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
/**
* Disables the SSL certificate checking for new instances of {@link HttpsURLConnection} This has been created to
* aid testing on a local box, not for use on production.
*/
private static void disableSSLCertificateChecking() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// Not implemented
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// Not implemented
}
} };
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
}