com.capitalone.dashboard.collector.DefaultGitHubClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of github-scm-collector Show documentation
Show all versions of github-scm-collector Show documentation
Github Collector Microservice collecting stats from Github
package com.capitalone.dashboard.collector;
import com.capitalone.dashboard.model.Commit;
import com.capitalone.dashboard.model.CommitType;
import com.capitalone.dashboard.model.GitHubRepo;
import com.capitalone.dashboard.util.Encryption;
import com.capitalone.dashboard.util.EncryptionException;
import com.capitalone.dashboard.util.Supplier;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestOperations;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
/**
* GitHubClient implementation that uses SVNKit to fetch information about
* Subversion repositories.
*/
@Component
public class DefaultGitHubClient implements GitHubClient {
private static final Log LOG = LogFactory.getLog(DefaultGitHubClient.class);
private final GitHubSettings settings;
private final RestOperations restOperations;
private static final String SEGMENT_API = "/api/v3/repos/";
private static final String PUBLIC_GITHUB_REPO_HOST = "api.github.com/repos/";
private static final String PUBLIC_GITHUB_HOST_NAME = "github.com";
private static final int FIRST_RUN_HISTORY_DEFAULT = 14;
@Autowired
public DefaultGitHubClient(GitHubSettings settings,
Supplier restOperationsSupplier) {
this.settings = settings;
this.restOperations = restOperationsSupplier.get();
}
@Override
@SuppressWarnings({"PMD.NPathComplexity","PMD.ExcessiveMethodLength"}) // agreed, fixme
public List getCommits(GitHubRepo repo, boolean firstRun) {
List commits = new ArrayList<>();
// format URL
String repoUrl = (String) repo.getOptions().get("url");
if (repoUrl.endsWith(".git")) {
repoUrl = repoUrl.substring(0, repoUrl.lastIndexOf(".git"));
}
URL url;
String hostName = "";
String protocol = "";
try {
url = new URL(repoUrl);
hostName = url.getHost();
protocol = url.getProtocol();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
LOG.error(e.getMessage());
}
String hostUrl = protocol + "://" + hostName + "/";
String repoName = repoUrl.substring(hostUrl.length(), repoUrl.length());
String apiUrl;
if (hostName.startsWith(PUBLIC_GITHUB_HOST_NAME)) {
apiUrl = protocol + "://" + PUBLIC_GITHUB_REPO_HOST + repoName;
} else {
apiUrl = protocol + "://" + hostName + SEGMENT_API + repoName;
LOG.debug("API URL IS:"+apiUrl);
}
Date dt;
if (firstRun) {
int firstRunDaysHistory = settings.getFirstRunHistoryDays();
if (firstRunDaysHistory > 0) {
dt = getDate(new Date(), -firstRunDaysHistory, 0);
} else {
dt = getDate(new Date(), -FIRST_RUN_HISTORY_DEFAULT, 0);
}
} else {
dt = getDate(new Date(repo.getLastUpdated()), 0, -10);
}
Calendar calendar = new GregorianCalendar();
TimeZone timeZone = calendar.getTimeZone();
Calendar cal = Calendar.getInstance(timeZone);
cal.setTime(dt);
String thisMoment = String.format("%tFT% response = makeRestCall(queryUrlPage, repo.getUserId(), decryptedPassword);
JSONArray jsonArray = paresAsArray(response);
for (Object item : jsonArray) {
JSONObject jsonObject = (JSONObject) item;
String sha = str(jsonObject, "sha");
JSONObject commitObject = (JSONObject) jsonObject.get("commit");
JSONObject authorObject = (JSONObject) commitObject.get("author");
String message = str(commitObject, "message");
String author = str(authorObject, "name");
long timestamp = new DateTime(str(authorObject, "date"))
.getMillis();
JSONArray parents = (JSONArray) jsonObject.get("parents");
Commit commit = new Commit();
commit.setTimestamp(System.currentTimeMillis());
commit.setScmUrl(repo.getRepoUrl());
commit.setScmBranch(repo.getBranch());
commit.setScmRevisionNumber(sha);
commit.setScmAuthor(author);
commit.setScmCommitLog(message);
commit.setScmCommitTimestamp(timestamp);
commit.setNumberOfChanges(1);
commit.setType(getCommitType(CollectionUtils.size(parents), message));
commits.add(commit);
}
if (CollectionUtils.isEmpty(jsonArray)) {
lastPage = true;
} else {
lastPage = isThisLastPage(response);
pageNumber++;
queryUrlPage = queryUrl + "&page=" + pageNumber;
}
} catch (RestClientException re) {
LOG.error(re.getMessage() + ":" + queryUrl);
lastPage = true;
}
}
return commits;
}
private CommitType getCommitType (int parentSize, String commitMessage ) {
if (parentSize > 1) return CommitType.Merge;
if (settings.getNotBuiltCommits() == null) return CommitType.New;
for (String s : settings.getNotBuiltCommits()) {
if (commitMessage.contains(s)) {
return CommitType.NotBuilt;
}
}
return CommitType.New;
}
private Date getDate(Date dateInstance, int offsetDays, int offsetMinutes) {
Calendar cal = Calendar.getInstance();
cal.setTime(dateInstance);
cal.add(Calendar.DATE, offsetDays);
cal.add(Calendar.MINUTE, offsetMinutes);
return cal.getTime();
}
private boolean isThisLastPage(ResponseEntity response) {
HttpHeaders header = response.getHeaders();
List link = header.get("Link");
if (link == null || link.isEmpty()) {
return true;
} else {
for (String l : link) {
if (l.contains("rel=\"next\"")) {
return false;
}
}
}
return true;
}
private ResponseEntity makeRestCall(String url, String userId,
String password) {
// Basic Auth only.
if (!"".equals(userId) && !"".equals(password)) {
return restOperations.exchange(url, HttpMethod.GET,
new HttpEntity<>(createHeaders(userId, password)),
String.class);
} else {
return restOperations.exchange(url, HttpMethod.GET, null,
String.class);
}
}
private HttpHeaders createHeaders(final String userId, final String password) {
String auth = userId + ":" + password;
byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.US_ASCII));
String authHeader = "Basic " + new String(encodedAuth);
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", authHeader);
return headers;
}
private JSONArray paresAsArray(ResponseEntity response) {
try {
return (JSONArray) new JSONParser().parse(response.getBody());
} catch (ParseException pe) {
LOG.error(pe.getMessage());
}
return new JSONArray();
}
private String str(JSONObject json, String key) {
Object value = json.get(key);
return value == null ? null : value.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy