2121import static java .lang .String .format ;
2222
2323import io .harness .annotations .dev .OwnedBy ;
24+ import io .harness .beans .DecryptableEntity ;
2425import io .harness .beans .DelegateTaskRequest ;
2526import io .harness .beans .IdentifierRef ;
27+ import io .harness .connector .helper .GitApiAccessDecryptionHelper ;
2628import io .harness .delegate .beans .ci .pod .ConnectorDetails ;
2729import io .harness .delegate .beans .connector .scm .GitConnectionType ;
2830import io .harness .delegate .beans .connector .scm .ScmConnector ;
3436import io .harness .delegate .task .scm .GitRefType ;
3537import io .harness .delegate .task .scm .ScmGitRefTaskParams ;
3638import io .harness .delegate .task .scm .ScmGitRefTaskResponseData ;
39+ import io .harness .exception .ConnectorNotFoundException ;
3740import io .harness .exception .InvalidArgumentsException ;
3841import io .harness .exception .TriggerException ;
3942import io .harness .exception .WingsException ;
5053import io .harness .product .ci .scm .proto .ParseWebhookResponse ;
5154import io .harness .product .ci .scm .proto .PullRequest ;
5255import 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 ;
5359import io .harness .serializer .KryoSerializer ;
60+ import io .harness .service .ScmServiceClient ;
5461import io .harness .tasks .BinaryResponseData ;
5562import io .harness .tasks .ErrorResponseData ;
5663import io .harness .tasks .ResponseData ;
6370import java .util .ArrayList ;
6471import java .util .List ;
6572import lombok .extern .slf4j .Slf4j ;
73+ import net .jodah .failsafe .Failsafe ;
74+ import net .jodah .failsafe .RetryPolicy ;
6675import 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 ())
0 commit comments