Skip to content

Commit 87f4d0d

Browse files
committed
add git settings controller
1 parent 5c0a848 commit 87f4d0d

File tree

11 files changed

+179
-53
lines changed

11 files changed

+179
-53
lines changed

core/src/main/java/com/flowci/core/flow/controller/GitController.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import com.flowci.core.flow.domain.FlowAction;
2222
import com.flowci.core.flow.domain.FlowGitTest;
2323
import com.flowci.core.flow.service.FlowService;
24-
import com.flowci.core.flow.service.GitService;
24+
import com.flowci.core.flow.service.GitConnService;
2525
import com.flowci.util.StringHelper;
2626
import java.util.List;
2727
import org.springframework.beans.factory.annotation.Autowired;
@@ -44,7 +44,7 @@ public class GitController {
4444
private FlowService flowService;
4545

4646
@Autowired
47-
private GitService gitService;
47+
private GitConnService gitConnService;
4848

4949
@PostMapping(value = "/{name}/git/test")
5050
@Action(FlowAction.GIT_TEST)
@@ -53,26 +53,26 @@ public void gitTest(@PathVariable String name, @Validated @RequestBody FlowGitTe
5353
String gitUrl = body.getGitUrl();
5454

5555
if (body.hasCredential()) {
56-
gitService.testConn(flow, gitUrl, body.getSecret());
56+
gitConnService.testConn(flow, gitUrl, body.getSecret());
5757
return;
5858
}
5959

6060
if (body.hasPrivateKey()) {
61-
gitService.testConn(flow, gitUrl, body.getRsa());
61+
gitConnService.testConn(flow, gitUrl, body.getRsa());
6262
return;
6363
}
6464

6565
if (body.hasUsernamePassword()) {
66-
gitService.testConn(flow, gitUrl, body.getAuth());
66+
gitConnService.testConn(flow, gitUrl, body.getAuth());
6767
}
6868

69-
gitService.testConn(flow, gitUrl, StringHelper.EMPTY);
69+
gitConnService.testConn(flow, gitUrl, StringHelper.EMPTY);
7070
}
7171

7272
@GetMapping(value = "/{name}/git/branches")
7373
@Action(FlowAction.LIST_BRANCH)
7474
public List<String> listGitBranches(@PathVariable String name) {
7575
Flow flow = flowService.get(name);
76-
return gitService.listGitBranch(flow);
76+
return gitConnService.listGitBranch(flow);
7777
}
7878
}

core/src/main/java/com/flowci/core/flow/service/GitService.java renamed to core/src/main/java/com/flowci/core/flow/service/GitConnService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
/**
2626
* @author yang
2727
*/
28-
public interface GitService {
28+
public interface GitConnService {
2929

3030
/**
3131
* Test git connection for http or ssh with credential

core/src/main/java/com/flowci/core/flow/service/GitServiceImpl.java renamed to core/src/main/java/com/flowci/core/flow/service/GitConnServiceImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
* @author yang
4646
*/
4747
@Log4j2
48-
@Service
49-
public class GitServiceImpl implements GitService {
48+
@Service("gitConnService")
49+
public class GitConnServiceImpl implements GitConnService {
5050

5151
@Autowired
5252
private TaskExecutor appTaskExecutor;
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package com.flowci.core.git.client;
22

33
import com.flowci.core.git.domain.GitCommitStatus;
4+
import com.flowci.core.secret.domain.Secret;
45

56
public interface GitAPIClient {
67

7-
void writeCommitStatus(GitCommitStatus commit);
8+
void writeCommitStatus(GitCommitStatus commit, Secret secret);
89
}

core/src/main/java/com/flowci/core/git/client/GithubAPIClient.java

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33
import com.fasterxml.jackson.annotation.JsonProperty;
44
import com.fasterxml.jackson.core.JsonProcessingException;
55
import com.fasterxml.jackson.databind.ObjectMapper;
6-
import com.flowci.core.git.dao.GitSettingsDao;
76
import com.flowci.core.git.domain.GitCommit;
87
import com.flowci.core.git.domain.GitCommitStatus;
98
import com.flowci.core.git.domain.GitRepo;
10-
import com.flowci.core.git.domain.GitSettings;
9+
import com.flowci.core.secret.domain.Secret;
10+
import com.flowci.core.secret.domain.TokenSecret;
11+
import com.flowci.exception.ArgumentException;
1112
import com.flowci.exception.CIException;
12-
import com.flowci.exception.NotFoundException;
1313
import com.flowci.exception.UnsupportedException;
1414
import lombok.extern.log4j.Log4j2;
15-
import org.springframework.stereotype.Component;
1615
import org.springframework.web.util.UriTemplate;
1716

1817
import java.net.URI;
@@ -23,7 +22,6 @@
2322
import java.util.Objects;
2423

2524
@Log4j2
26-
@Component("githubClient")
2725
public class GithubAPIClient implements GitAPIClient {
2826

2927
private final static UriTemplate HttpTemplate = new UriTemplate("https://github.com/{owner}/{repo}.git");
@@ -34,21 +32,23 @@ public class GithubAPIClient implements GitAPIClient {
3432

3533
private final static String CommitStatusAPI = "https://api.github.com/repos/%s/%s/statuses/%s";
3634

37-
private final GitSettingsDao gitSettingsDao;
38-
3935
private final HttpClient httpClient;
4036

4137
private final ObjectMapper objectMapper;
4238

43-
public GithubAPIClient(GitSettingsDao gitSettingsDao, HttpClient httpClient, ObjectMapper objectMapper) {
44-
this.gitSettingsDao = gitSettingsDao;
39+
public GithubAPIClient(HttpClient httpClient, ObjectMapper objectMapper) {
4540
this.httpClient = httpClient;
4641
this.objectMapper = objectMapper;
4742
}
4843

4944
@Override
50-
public void writeCommitStatus(GitCommitStatus commit) {
51-
GitRepo repo = getRepo(commit);
45+
public void writeCommitStatus(GitCommitStatus commit, Secret secret) {
46+
if (!(secret instanceof TokenSecret)) {
47+
throw new ArgumentException("Token secret is required");
48+
}
49+
50+
var tokenSecret = (TokenSecret) secret;
51+
var repo = getRepo(commit);
5252

5353
var body = new GitCommitPostBody();
5454
body.state = commit.getStatus();
@@ -57,7 +57,7 @@ public void writeCommitStatus(GitCommitStatus commit) {
5757

5858
try {
5959
var api = String.format(CommitStatusAPI, repo.getOwner(), repo.getOwner(), commit.getId());
60-
var request = getRequestBuilder(api)
60+
var request = getRequestBuilder(api, tokenSecret.getTokenData())
6161
.POST(HttpRequest.BodyPublishers.ofString(objectMapper.writeValueAsString(body)))
6262
.build();
6363

@@ -69,18 +69,10 @@ public void writeCommitStatus(GitCommitStatus commit) {
6969
}
7070
}
7171

72-
private HttpRequest.Builder getRequestBuilder(String url) {
73-
var optional = gitSettingsDao.findByKey(GitSettings.Key);
74-
if (optional.isEmpty()) {
75-
throw new NotFoundException("Git settings is missing");
76-
}
77-
78-
var tokenSecret = optional.get().getGitHubTokenSecret();
79-
Objects.requireNonNull(tokenSecret, "Github token secret is missing");
80-
72+
private HttpRequest.Builder getRequestBuilder(String url, String token) {
8173
return HttpRequest.newBuilder(URI.create(url))
8274
.setHeader("Accept", "application/vnd.github.v3+json")
83-
.setHeader("Authorization", "token " + tokenSecret);
75+
.setHeader("Authorization", "token " + token);
8476
}
8577

8678
private static class GitCommitPostBody {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.flowci.core.git.controller;
2+
3+
import com.flowci.core.common.domain.GitSource;
4+
import com.flowci.core.git.domain.GitSettings;
5+
import com.flowci.core.git.service.GitService;
6+
import com.flowci.exception.UnsupportedException;
7+
import lombok.extern.log4j.Log4j2;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.web.bind.annotation.PostMapping;
10+
import org.springframework.web.bind.annotation.RequestBody;
11+
import org.springframework.web.bind.annotation.RequestMapping;
12+
import org.springframework.web.bind.annotation.RestController;
13+
14+
@Log4j2
15+
@RestController
16+
@RequestMapping("/gitsettings")
17+
public class GitSettingsController {
18+
19+
@Autowired
20+
private GitService gitService;
21+
22+
@PostMapping("/save")
23+
public GitSettings save(@RequestBody Request.SaveOptions options) {
24+
if (options.getSource() == GitSource.GITHUB) {
25+
return gitService.saveGithubSecret(options.getSecret());
26+
}
27+
28+
throw new UnsupportedException("Unsupported git source");
29+
}
30+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.flowci.core.git.controller;
2+
3+
import com.flowci.core.common.domain.GitSource;
4+
import lombok.Getter;
5+
import lombok.Setter;
6+
7+
import javax.validation.constraints.NotEmpty;
8+
import javax.validation.constraints.NotNull;
9+
10+
public abstract class Request {
11+
12+
@Getter
13+
@Setter
14+
public static class SaveOptions {
15+
16+
@NotNull
17+
private GitSource source;
18+
19+
@NotEmpty
20+
private String secret;
21+
22+
}
23+
24+
}

core/src/main/java/com/flowci/core/git/domain/GitSettings.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class GitSettings {
1515
private String id;
1616

1717
@Indexed(unique = true)
18-
private String key;
18+
private String key = Key;
1919

2020
private String gitHubTokenSecret;
2121
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.flowci.core.git.service;
22

3+
import com.flowci.core.git.domain.GitSettings;
4+
35
public interface GitService {
46

7+
GitSettings saveGithubSecret(String secret);
58
}
Lines changed: 91 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,77 @@
11
package com.flowci.core.git.service;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
34
import com.flowci.core.common.domain.GitSource;
5+
import com.flowci.core.common.manager.SpringEventManager;
46
import com.flowci.core.git.client.GitAPIClient;
7+
import com.flowci.core.git.client.GithubAPIClient;
8+
import com.flowci.core.git.dao.GitSettingsDao;
59
import com.flowci.core.git.domain.GitCommitStatus;
10+
import com.flowci.core.git.domain.GitSettings;
611
import com.flowci.core.job.domain.Job;
712
import com.flowci.core.job.event.JobFinishedEvent;
813
import com.flowci.core.job.util.JobContextHelper;
14+
import com.flowci.core.secret.domain.Secret;
15+
import com.flowci.core.secret.domain.TokenSecret;
16+
import com.flowci.core.secret.event.GetSecretEvent;
17+
import com.flowci.exception.ArgumentException;
918
import com.flowci.util.StringHelper;
1019
import lombok.extern.log4j.Log4j2;
11-
import org.jvnet.hk2.annotations.Service;
1220
import org.springframework.beans.factory.annotation.Autowired;
1321
import org.springframework.context.event.EventListener;
22+
import org.springframework.dao.DuplicateKeyException;
23+
import org.springframework.stereotype.Service;
1424

1525
import javax.annotation.PostConstruct;
26+
import java.net.http.HttpClient;
1627
import java.util.HashMap;
1728
import java.util.Map;
1829

1930
@Log4j2
20-
@Service
31+
@Service("gitService")
2132
public class GitServiceImpl implements GitService {
2233

2334
@Autowired
24-
private GitAPIClient githubClient;
35+
private HttpClient httpClient;
2536

26-
private final Map<GitSource, GitAPIClient> clients = new HashMap<>(5);
37+
@Autowired
38+
private ObjectMapper objectMapper;
39+
40+
@Autowired
41+
private GitSettingsDao gitSettingsDao;
42+
43+
@Autowired
44+
private SpringEventManager eventManager;
45+
46+
private final Map<GitSource, ActionHandler> actions = new HashMap<>(5);
2747

2848
@PostConstruct
2949
public void init() {
30-
clients.put(GitSource.GITHUB, githubClient);
50+
actions.put(GitSource.GITHUB, new GitHubActionHandler());
51+
52+
var optional = gitSettingsDao.findByKey(GitSettings.Key);
53+
if (optional.isEmpty()) {
54+
try {
55+
gitSettingsDao.save(new GitSettings());
56+
} catch (DuplicateKeyException ignore) {
57+
// ignore the duplicate git settings key
58+
}
59+
}
60+
}
61+
62+
@Override
63+
public GitSettings saveGithubSecret(String secretName) {
64+
var event = eventManager.publish(new GetSecretEvent(this, secretName));
65+
var event1 = eventManager.publish(new GetSecretEvent(this, secretName));
66+
Secret secret = event1.getFetched();
67+
68+
if (!(secret instanceof TokenSecret)) {
69+
throw new ArgumentException("Token secret is required");
70+
}
71+
72+
var settings = loadGitSettings();
73+
settings.setGitHubTokenSecret(secretName);
74+
return gitSettingsDao.save(settings);
3175
}
3276

3377
@EventListener
@@ -40,22 +84,54 @@ public void onJobFinishEvent(JobFinishedEvent event) {
4084
return;
4185
}
4286

43-
var commit = new GitCommitStatus();
44-
commit.setId(JobContextHelper.getCommitId(job));
45-
commit.setUrl(JobContextHelper.getGitUrl(job));
46-
commit.setTargetUrl(JobContextHelper.getJobUrl(job));
47-
commit.setStatus(JobContextHelper.getStatus(job).name().toLowerCase());
48-
commit.setDesc(String.format("build %s from flow.ci", commit.getStatus()));
49-
5087
try {
5188
var source = GitSource.valueOf(gitSourceStr);
52-
var apiClient = clients.get(source);
89+
var handler = actions.get(source);
5390

54-
if (apiClient != null) {
55-
apiClient.writeCommitStatus(commit);
91+
if (handler == null) {
92+
return;
5693
}
94+
95+
var commit = new GitCommitStatus();
96+
commit.setId(JobContextHelper.getCommitId(job));
97+
commit.setUrl(JobContextHelper.getGitUrl(job));
98+
commit.setTargetUrl(JobContextHelper.getJobUrl(job));
99+
commit.setStatus(JobContextHelper.getStatus(job).name().toLowerCase());
100+
commit.setDesc(String.format("build %s from flow.ci", commit.getStatus()));
101+
102+
handler.write(commit);
57103
} catch (Throwable e) {
58104
log.warn(e.getMessage());
59105
}
60106
}
107+
108+
private GitSettings loadGitSettings() {
109+
return gitSettingsDao.findByKey(GitSettings.Key).get();
110+
}
111+
112+
private interface ActionHandler {
113+
void write(GitCommitStatus commit);
114+
}
115+
116+
private class GitHubActionHandler implements ActionHandler {
117+
118+
private final GitAPIClient client = new GithubAPIClient(httpClient, objectMapper);
119+
120+
@Override
121+
public void write(GitCommitStatus commit) {
122+
var settings = loadGitSettings();
123+
String secretName = settings.getGitHubTokenSecret();
124+
125+
var event = eventManager.publish(new GetSecretEvent(GitServiceImpl.this, secretName));
126+
Secret secret = event.getFetched();
127+
128+
if (!(secret instanceof TokenSecret)) {
129+
throw new ArgumentException("Token secret is required");
130+
}
131+
132+
TokenSecret tokenSecret = (TokenSecret) secret;
133+
client.writeCommitStatus(commit, tokenSecret);
134+
}
135+
}
136+
61137
}

0 commit comments

Comments
 (0)