generated from CDCgov/template
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add retry mechanism to call RS history API (#747)
* Changed OrderSender.sendOrder to return the sent submissionId (as optional) * Added sentSubmissionId to PartnerMetadata record, and renamed uniqueId to receivedSubmissionId. Also, overloaded record constructor to only take receivedSubmissionId * Updated tests * Added missed import and fixed more tests * Fixed test * Fixed e2e test * Refactored to split RS endpoint logic to its own ReportStreamEndpointClient class * Added custom exception for ReportStreamEndpointClient * Refactored for separation of concerns and clarity * Further refactoring in preparation to call the history API * Added implementation for http get method * Added call to history API to update receiver metadata * Added missing application context registration for ReportStreamEndpointClient * Removed unused line * Import missing class * Added some comments * Added methods to partially update PartnerMetadata and making sure to read existing metadata before updating * Added tests for PartnerMetadataOrchestrator * Some code cleaning * Fixed test * Added tests for PartnerMetadata changes * Added tests for requestHistoryEndpoint + some cleanup * Cleaned up naming and add logging * Implemented updateMetadataForReceivedOrder and getMetadata * Refactored PartnerMetadata.withSentSubmissionFields to split into separate methods for each parameter * Changed logic to make sure to save sentSubmissionId into metadata file even if not able to retrieve receiver * Fixed tests * Added tests for updateMetadataForReceivedOrder + validation logic * Added test to cover logic for missing receiver in getMetadata * Added todo comment * Added logging * Added RetryTask class to help add retry mechanism when calling the history API to get receiver * Added tests * Missed import * Refactored string comparison * Made improvements based on Jeff's feedback * Simplified logic by using try/catch instead of checking for expected format * Added null check * Simplified logic by catching exception instead of checking for expected format * Return if sentSubmissionId is null given we can't update the metadata * Fixed wrong commit * Fixed failing tests * Update etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/metadata/PartnerMetadataOrchestrator.java Co-authored-by: halprin <[email protected]> * Fixed exception * test case for single param constructor * single param contructor for PartnerMetadataException * super with sigle param * Added missing mock return value for requestHistoryEndpoint * Fixed failing test * Cleanup * Refactored RetryTask to be synchronous * Added test assertions * Added error logging if not able to save metadata after retries * Refactored happy path test to get more coverage * Added a test and refactored to simplify * Added test for exception use case * Added javadocs * Cleanup based on feedback * Refactored retry implementation to return T and throw an exception in case of too many failed retries * Fixed call, still need to fix test * Fixed and added tests * Committed by mistake * Added test and javadocs for RetryFailedException --------- Co-authored-by: halprin <[email protected]> Co-authored-by: jorge Lopez <[email protected]>
- Loading branch information
1 parent
7ba993b
commit fd9c8d4
Showing
7 changed files
with
213 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
shared/src/main/java/gov/hhs/cdc/trustedintermediary/utils/RetryFailedException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package gov.hhs.cdc.trustedintermediary.utils; | ||
|
||
/** | ||
* Custom exception that wraps the last exception thrown after the maximum number of retries has | ||
* been reached. It could also be thrown in the case of a InterruptedException. | ||
*/ | ||
public class RetryFailedException extends Exception { | ||
|
||
public RetryFailedException(String message, Throwable cause) { | ||
super(message, cause); | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
shared/src/main/java/gov/hhs/cdc/trustedintermediary/utils/SyncRetryTask.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package gov.hhs.cdc.trustedintermediary.utils; | ||
|
||
import gov.hhs.cdc.trustedintermediary.wrappers.Logger; | ||
import java.util.concurrent.Callable; | ||
import javax.inject.Inject; | ||
|
||
/** | ||
* Provides a reusable utility for retrying a task with a specified number of retries and wait time | ||
* between retries. | ||
*/ | ||
public class SyncRetryTask { | ||
private static final SyncRetryTask INSTANCE = new SyncRetryTask(); | ||
@Inject Logger logger; | ||
|
||
public static SyncRetryTask getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
private SyncRetryTask() {} | ||
|
||
public <T> T retry(Callable<T> task, int maxRetries, long waitTime) | ||
throws RetryFailedException { | ||
Exception lastException = null; | ||
int attempt = 0; | ||
|
||
while (attempt < maxRetries) { | ||
try { | ||
return task.call(); | ||
} catch (Exception e) { | ||
lastException = e; | ||
attempt++; | ||
|
||
logger.logWarning("Attempt {}: Retrying in {}s", attempt, waitTime * 2 / 1000); | ||
|
||
try { | ||
Thread.sleep(waitTime); | ||
} catch (InterruptedException ie) { | ||
Thread.currentThread().interrupt(); // Restore interrupted status | ||
throw new RetryFailedException("Thread interrupted during retries", ie); | ||
} | ||
|
||
waitTime *= 2; | ||
} | ||
} | ||
|
||
throw new RetryFailedException("Failed after " + maxRetries + " retries", lastException); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/utils/RetryFailedExceptionTest.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package gov.hhs.cdc.trustedintermediary.utils | ||
|
||
import spock.lang.Specification | ||
|
||
class RetryFailedExceptionTest extends Specification { | ||
def "test constructor"() { | ||
given: | ||
def message = "DogCow" | ||
|
||
when: | ||
def innerException = new IOException() | ||
def exception = new RetryFailedException(message, innerException) | ||
|
||
then: | ||
exception.getMessage() == message | ||
exception.getCause() == innerException | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/utils/SyncRetryTaskTest.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package gov.hhs.cdc.trustedintermediary.utils | ||
|
||
import gov.hhs.cdc.trustedintermediary.context.TestApplicationContext | ||
import spock.lang.Specification | ||
|
||
import java.util.concurrent.Callable | ||
|
||
class SyncRetryTaskTest extends Specification { | ||
|
||
def setup() { | ||
TestApplicationContext.reset() | ||
TestApplicationContext.init() | ||
TestApplicationContext.register(SyncRetryTask, SyncRetryTask.getInstance()) | ||
TestApplicationContext.injectRegisteredImplementations() | ||
} | ||
|
||
def "scheduleRetry should retry the task until it succeeds"() { | ||
given: | ||
def maxRetries = 3 | ||
def waitTime = 10 | ||
Callable<Void> mockTask = Mock(Callable) | ||
|
||
when: | ||
def result = SyncRetryTask.getInstance().retry(mockTask, maxRetries, waitTime) | ||
|
||
then: | ||
(1..maxRetries - 1) * mockTask.call() >> { throw new Exception("Fail") } | ||
1 * mockTask.call() >> null // Succeeds on the last attempt | ||
result == null | ||
} | ||
|
||
def "scheduleRetry should give up after max retries and throw RetryFailedException"() { | ||
given: | ||
def maxRetries = 3 | ||
def waitTime = 10 | ||
Callable<Void> mockTask = Mock(Callable) | ||
|
||
when: | ||
SyncRetryTask.getInstance().retry(mockTask, maxRetries, waitTime) | ||
|
||
then: | ||
maxRetries * mockTask.call() >> { throw new Exception("Fail") } | ||
def exception = thrown(RetryFailedException) | ||
exception.getCause().getClass() == Exception | ||
} | ||
} |