Skip to content

Commit 950f7df

Browse files
committed
feat: [CI-5120]: Added support for triggerRepoFilterTask via manager
feat: [CI-5120]: Added support for triggerRepoFilterTask via manager
1 parent f0f5f2d commit 950f7df

2 files changed

Lines changed: 210 additions & 6 deletions

File tree

pipeline-service/modules/ng-triggers/src/main/java/io/harness/ngtriggers/utils/SCMDataObtainer.java

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
import static java.lang.String.format;
2222

2323
import io.harness.annotations.dev.OwnedBy;
24+
import io.harness.beans.DecryptableEntity;
2425
import io.harness.beans.DelegateTaskRequest;
2526
import io.harness.beans.IdentifierRef;
27+
import io.harness.connector.helper.GitApiAccessDecryptionHelper;
2628
import io.harness.delegate.beans.ci.pod.ConnectorDetails;
2729
import io.harness.delegate.beans.connector.scm.GitConnectionType;
2830
import io.harness.delegate.beans.connector.scm.ScmConnector;
@@ -34,6 +36,7 @@
3436
import io.harness.delegate.task.scm.GitRefType;
3537
import io.harness.delegate.task.scm.ScmGitRefTaskParams;
3638
import io.harness.delegate.task.scm.ScmGitRefTaskResponseData;
39+
import io.harness.exception.ConnectorNotFoundException;
3740
import io.harness.exception.InvalidArgumentsException;
3841
import io.harness.exception.TriggerException;
3942
import io.harness.exception.WingsException;
@@ -50,7 +53,11 @@
5053
import io.harness.product.ci.scm.proto.ParseWebhookResponse;
5154
import io.harness.product.ci.scm.proto.PullRequest;
5255
import io.harness.product.ci.scm.proto.PullRequestHook;
56+
import io.harness.product.ci.scm.proto.SCMGrpc;
57+
import io.harness.secrets.SecretDecryptor;
58+
import io.harness.security.encryption.EncryptedDataDetail;
5359
import io.harness.serializer.KryoSerializer;
60+
import io.harness.service.ScmServiceClient;
5461
import io.harness.tasks.BinaryResponseData;
5562
import io.harness.tasks.ErrorResponseData;
5663
import io.harness.tasks.ResponseData;
@@ -63,6 +70,8 @@
6370
import java.util.ArrayList;
6471
import java.util.List;
6572
import lombok.extern.slf4j.Slf4j;
73+
import net.jodah.failsafe.Failsafe;
74+
import net.jodah.failsafe.RetryPolicy;
6675
import org.apache.commons.lang3.StringUtils;
6776

6877
@Slf4j
@@ -75,6 +84,11 @@ public class SCMDataObtainer implements GitProviderBaseDataObtainer {
7584
public static final String GIT_URL_SUFFIX = ".git";
7685
public static final String PATH_SEPARATOR = "/";
7786
public static final String AZURE_REPO_BASE_URL = "azure.com";
87+
private static final Duration RETRY_SLEEP_DURATION = Duration.ofSeconds(2);
88+
private static final int MAX_ATTEMPTS = 3;
89+
@Inject private SCMGrpc.SCMBlockingStub scmBlockingStub;
90+
@Inject SecretDecryptor secretDecryptor;
91+
@Inject ScmServiceClient scmServiceClient;
7892

7993
@Inject
8094
public SCMDataObtainer(
@@ -187,6 +201,7 @@ private GitConnectionType retrieveGitConnectionType(ConnectorDetails gitConnecto
187201

188202
List<Commit> getCommitsInPr(ConnectorDetails connectorDetails, TriggerDetails triggerDetails, long number) {
189203
ScmConnector scmConnector = (ScmConnector) connectorDetails.getConnectorConfig();
204+
190205
try {
191206
WebhookTriggerConfigV2 webhookTriggerConfigV2 =
192207
(WebhookTriggerConfigV2) triggerDetails.getNgTriggerConfigV2().getSource().getSpec();
@@ -197,13 +212,59 @@ List<Commit> getCommitsInPr(ConnectorDetails connectorDetails, TriggerDetails tr
197212
} catch (Exception ex) {
198213
log.error("Failed to update url");
199214
}
215+
216+
ScmGitRefTaskParams scmGitRefTaskParams = ScmGitRefTaskParams.builder()
217+
.prNumber(number)
218+
.gitRefType(GitRefType.PULL_REQUEST_COMMITS)
219+
.encryptedDataDetails(connectorDetails.getEncryptedDataDetails())
220+
.scmConnector(scmConnector)
221+
.build();
222+
boolean executeOnDelegate =
223+
connectorDetails.getExecuteOnDelegate() == null || connectorDetails.getExecuteOnDelegate();
224+
225+
if (executeOnDelegate) {
226+
return fetchPrCommitsViaDelegate(connectorDetails, scmGitRefTaskParams, triggerDetails);
227+
} else {
228+
return fetchPrCommitsViaManager(connectorDetails, scmGitRefTaskParams, triggerDetails);
229+
}
230+
}
231+
232+
private List<Commit> fetchPrCommitsViaManager(
233+
ConnectorDetails connectorDetails, ScmGitRefTaskParams scmGitRefTaskParams, TriggerDetails triggerDetails) {
234+
RetryPolicy<Object> retryPolicy = getRetryPolicy(
235+
format("[Retrying failed call to fetch codebase metadata: [%s], attempt: {}", connectorDetails.getIdentifier()),
236+
format(
237+
"Failed call to fetch codebase metadata: [%s] after retrying {} times", connectorDetails.getIdentifier()));
238+
239+
decrypt(scmGitRefTaskParams.getScmConnector(), connectorDetails.getEncryptedDataDetails());
240+
ListCommitsInPRResponse listCommitsInPRResponse =
241+
Failsafe.with(retryPolicy)
242+
.get(()
243+
-> scmServiceClient.listCommitsInPR(
244+
scmGitRefTaskParams.getScmConnector(), scmGitRefTaskParams.getPrNumber(), scmBlockingStub));
245+
246+
return listCommitsInPRResponse.getCommitsList();
247+
}
248+
249+
private RetryPolicy<Object> getRetryPolicy(String failedAttemptMessage, String failureMessage) {
250+
return new RetryPolicy<>()
251+
.handle(Exception.class)
252+
.abortOn(ConnectorNotFoundException.class)
253+
.withDelay(RETRY_SLEEP_DURATION)
254+
.withMaxAttempts(MAX_ATTEMPTS)
255+
.onFailedAttempt(event -> log.info(failedAttemptMessage, event.getAttemptCount(), event.getLastFailure()))
256+
.onFailure(event -> log.error(failureMessage, event.getAttemptCount(), event.getFailure()));
257+
}
258+
259+
private void decrypt(ScmConnector connector, List<EncryptedDataDetail> encryptedDataDetails) {
260+
final DecryptableEntity decryptableEntity = secretDecryptor.decrypt(
261+
GitApiAccessDecryptionHelper.getAPIAccessDecryptableEntity(connector), encryptedDataDetails);
262+
GitApiAccessDecryptionHelper.setAPIAccessDecryptableEntity(connector, decryptableEntity);
263+
}
264+
265+
private List<Commit> fetchPrCommitsViaDelegate(
266+
ConnectorDetails connectorDetails, ScmGitRefTaskParams scmGitRefTaskParams, TriggerDetails triggerDetails) {
200267
if (ScmConnector.class.isAssignableFrom(connectorDetails.getConnectorConfig().getClass())) {
201-
ScmGitRefTaskParams scmGitRefTaskParams = ScmGitRefTaskParams.builder()
202-
.prNumber(number)
203-
.gitRefType(GitRefType.PULL_REQUEST_COMMITS)
204-
.encryptedDataDetails(connectorDetails.getEncryptedDataDetails())
205-
.scmConnector(scmConnector)
206-
.build();
207268
ResponseData responseData =
208269
taskExecutionUtils.executeSyncTask(DelegateTaskRequest.builder()
209270
.accountId(triggerDetails.getNgTriggerEntity().getAccountId())
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package io.harness.ngtriggers.utils;
2+
3+
import static io.harness.rule.OwnerRule.DEV_MITTAL;
4+
5+
import static org.assertj.core.api.Assertions.assertThat;
6+
import static org.mockito.ArgumentMatchers.anyLong;
7+
import static org.mockito.Matchers.any;
8+
import static org.mockito.Mockito.when;
9+
import static org.mockito.MockitoAnnotations.initMocks;
10+
11+
import io.harness.CategoryTest;
12+
import io.harness.beans.DelegateTaskRequest;
13+
import io.harness.category.element.UnitTests;
14+
import io.harness.delegate.beans.ci.pod.ConnectorDetails;
15+
import io.harness.delegate.beans.connector.ConnectorType;
16+
import io.harness.delegate.beans.connector.scm.GitConnectionType;
17+
import io.harness.delegate.beans.connector.scm.github.GithubApiAccessDTO;
18+
import io.harness.delegate.beans.connector.scm.github.GithubApiAccessType;
19+
import io.harness.delegate.beans.connector.scm.github.GithubConnectorDTO;
20+
import io.harness.delegate.beans.connector.scm.github.GithubTokenSpecDTO;
21+
import io.harness.delegate.task.scm.ScmGitRefTaskResponseData;
22+
import io.harness.encryption.SecretRefData;
23+
import io.harness.ngtriggers.beans.config.NGTriggerConfigV2;
24+
import io.harness.ngtriggers.beans.dto.TriggerDetails;
25+
import io.harness.ngtriggers.beans.entity.NGTriggerEntity;
26+
import io.harness.ngtriggers.beans.source.NGTriggerSourceV2;
27+
import io.harness.ngtriggers.beans.source.WebhookTriggerType;
28+
import io.harness.ngtriggers.beans.source.webhook.v2.WebhookTriggerConfigV2;
29+
import io.harness.product.ci.scm.proto.Commit;
30+
import io.harness.product.ci.scm.proto.ListCommitsInPRResponse;
31+
import io.harness.rule.Owner;
32+
import io.harness.secrets.SecretDecryptor;
33+
import io.harness.serializer.KryoSerializer;
34+
import io.harness.service.ScmServiceClient;
35+
import io.harness.tasks.BinaryResponseData;
36+
37+
import java.io.IOException;
38+
import java.util.List;
39+
import org.junit.Before;
40+
import org.junit.Test;
41+
import org.junit.experimental.categories.Category;
42+
import org.mockito.InjectMocks;
43+
import org.mockito.Mock;
44+
45+
public class SCMDataObtainerTest extends CategoryTest {
46+
@Mock SecretDecryptor secretDecryptor;
47+
@Mock ScmServiceClient scmServiceClient;
48+
@Mock TaskExecutionUtils taskExecutionUtils;
49+
@Mock KryoSerializer kryoSerializer;
50+
@InjectMocks SCMDataObtainer scmDataObtainer;
51+
52+
@Before
53+
public void setUp() throws IOException {
54+
initMocks(this);
55+
}
56+
57+
@Test
58+
@Owner(developers = DEV_MITTAL)
59+
@Category(UnitTests.class)
60+
public void testGetCommitsInPrViaDelegate() {
61+
TriggerDetails triggerDetails =
62+
TriggerDetails.builder()
63+
.ngTriggerConfigV2(
64+
NGTriggerConfigV2.builder()
65+
.source(NGTriggerSourceV2.builder()
66+
.spec(WebhookTriggerConfigV2.builder().type(WebhookTriggerType.GITHUB).build())
67+
.build())
68+
.build())
69+
.ngTriggerEntity(NGTriggerEntity.builder().accountId("account").build())
70+
.build();
71+
72+
ConnectorDetails connectorDetails =
73+
ConnectorDetails.builder()
74+
.connectorType(ConnectorType.GITHUB)
75+
.connectorConfig(GithubConnectorDTO.builder().connectionType(GitConnectionType.REPO).url("url").build())
76+
.executeOnDelegate(true)
77+
.build();
78+
79+
when(taskExecutionUtils.executeSyncTask(any(DelegateTaskRequest.class)))
80+
.thenReturn(BinaryResponseData.builder().build());
81+
82+
byte[] list = ListCommitsInPRResponse.newBuilder()
83+
.addCommits(Commit.newBuilder()
84+
.setSha("commitId")
85+
.setMessage("message")
86+
.setLink("http://github.com/octocat/hello-world/pull/1/commits/commitId")
87+
.build())
88+
.build()
89+
.toByteArray();
90+
when(kryoSerializer.asInflatedObject(any()))
91+
.thenReturn(ScmGitRefTaskResponseData.builder().listCommitsInPRResponse(list).build());
92+
93+
List<Commit> commits = scmDataObtainer.getCommitsInPr(connectorDetails, triggerDetails, 3);
94+
assertThat(commits.size()).isEqualTo(1);
95+
assertThat(commits.get(0).getSha()).isEqualTo("commitId");
96+
}
97+
98+
@Test
99+
@Owner(developers = DEV_MITTAL)
100+
@Category(UnitTests.class)
101+
public void testGetCommitsInPrViaManager() {
102+
TriggerDetails triggerDetails =
103+
TriggerDetails.builder()
104+
.ngTriggerConfigV2(
105+
NGTriggerConfigV2.builder()
106+
.source(NGTriggerSourceV2.builder()
107+
.spec(WebhookTriggerConfigV2.builder().type(WebhookTriggerType.GITHUB).build())
108+
.build())
109+
.build())
110+
.ngTriggerEntity(NGTriggerEntity.builder().accountId("account").build())
111+
.build();
112+
113+
ConnectorDetails connectorDetails =
114+
ConnectorDetails.builder()
115+
.connectorType(ConnectorType.GITHUB)
116+
.connectorConfig(GithubConnectorDTO.builder()
117+
.connectionType(GitConnectionType.REPO)
118+
.url("url")
119+
.apiAccess(GithubApiAccessDTO.builder()
120+
.type(GithubApiAccessType.TOKEN)
121+
.spec(GithubTokenSpecDTO.builder()
122+
.tokenRef(SecretRefData.builder().identifier("token").build())
123+
.build())
124+
.build())
125+
.build())
126+
.executeOnDelegate(false)
127+
.build();
128+
129+
ListCommitsInPRResponse list =
130+
ListCommitsInPRResponse.newBuilder()
131+
.addCommits(Commit.newBuilder()
132+
.setSha("commitId")
133+
.setMessage("message")
134+
.setLink("http://github.com/octocat/hello-world/pull/1/commits/commitId")
135+
.build())
136+
.build();
137+
when(scmServiceClient.listCommitsInPR(any(), anyLong(), any())).thenReturn(list);
138+
139+
List<Commit> commits = scmDataObtainer.getCommitsInPr(connectorDetails, triggerDetails, 3);
140+
assertThat(commits.size()).isEqualTo(1);
141+
assertThat(commits.get(0).getSha()).isEqualTo("commitId");
142+
}
143+
}

0 commit comments

Comments
 (0)