Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify metrics aggregator to use AggregatedExecution #479

Merged
merged 9 commits into from
Jan 18, 2024

Conversation

kathy-t
Copy link
Contributor

@kathy-t kathy-t commented Jan 8, 2024

Description
Corresponding PRs:

This PR modifies the metrics aggregator to use AggregatedExecution instead of Metrics as a result of the webservice changes in dockstore/dockstore#5778.

Also did some slight re-organizing to create a ValidationStatusAggregator, similar to the aggregators for the other metrics. There are no functional code changes there.

Note that builds will fail until I update the Dockstore webservice version to a tag containing the corresponding webservice changes.

Review Instructions
Build should pass.

Issue
SEAB-5943

Security
If there are any concerns that require extra attention from the security team, highlight them here.

Please make sure that you've checked the following before submitting your pull request. Thanks!

  • Check that you pass the basic style checks and unit tests by running mvn clean install in the project that you have modified (until https://ucsc-cgl.atlassian.net/browse/SEAB-5300 adds multi-module support properly)
  • Ensure that the PR targets the correct branch. Check the milestone or fix version of the ticket.
  • If you are changing dependencies, check with dependabot to ensure you are not introducing new high/critical vulnerabilities
  • If this PR is for a user-facing feature, create and link a documentation ticket for this feature (usually in the same milestone as the linked issue). Style points if you create a documentation PR directly and link that instead.

@kathy-t kathy-t self-assigned this Jan 8, 2024
@kathy-t kathy-t marked this pull request as ready for review January 8, 2024 15:59
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file can be skimmed. There are no functional code changes, I copied code from AggregationHelper into this new class for organization

pom.xml Outdated Show resolved Hide resolved
Copy link
Member

@denis-yuen denis-yuen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comments, but curious about updates

THIRD-PARTY-LICENSES.txt Outdated Show resolved Hide resolved
@@ -184,6 +186,7 @@ private void submitValidationData(MetricsAggregatorConfig config, ValidatorToolE
.validatorToolVersion(validatorVersion)
.isValid(isValid);
validationExecution.setDateExecuted(dateExecuted);
validationExecution.setExecutionId(UUID.randomUUID().toString()); // No execution ID was provided by DNAstack, generate a random one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be a parameter? (i.e. to keep the execution id consistent between qa, staging, prod even if it is fake/arbitrary)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, a random execution id is also used for the tests below, but that is ok

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this command only uploads to one environment, so it's currently not possible to keep the execution ID consisten between QA, staging, and prod for this command

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant, would it make sense to provide it as a parameter like java -jar target/metricsaggregator-*-SNAPSHOT.jar submit-validation-data --config my-custom-config --data <path-to-my-data-file> --validator MINIWDL --validatorVersion 1.0 --platform DNA_STACK --execution-id first-run-after-ai-omics-release for example

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see, hmm yes I think that would work assuming that the file DNAstack provided us contains no duplicate combo of TRS ID and version, otherwise the duplicates will fail because the execution ID already exists for the TRS ID and version (and platform).

I think it's a safe assumption to make given that they provided us with a list of TRS IDs and versions that validated correctly with miniwdl (there's no point in duplicate TRS ID and version entries because it conveys the same info). I'll make the change so it's consistent between environments

Copy link
Member

@denis-yuen denis-yuen Jan 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may be getting turned around, could you refresh my memory as to how the execution id enters the system and is there a difference between validations and normal executions in light of

In order to efficiently find the execution to update, the S3 key must contain the execution ID. The file name in S3 > was previously the current time in ms, but it's now the user-provided execution ID. This means that each file in the > metrics S3 bucket contains only 1 execution, whereas it previously could contain multiple.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you refresh my memory as to how the execution id enters the system

In dockstore/dockstore#5778, the execution ID enters the system through the POST /api/ga4gh/v2/extended/{id}/versions/{version_id}/executions endpoint. In that endpoint's request body, users specify the executions that they want to submit, whether it's a list of workflow executions, a list of validation executions, and/or a list of taskExecutions sets. Each execution in each list of executions requires a user-provided ID that will become the file name in S3.

is there a difference between validations and normal executions in light of
In order to efficiently find the execution to update, the S3 key must contain the execution ID. The file name in S3 was previously the current time in ms, but it's now the user-provided execution ID. This means that each file in the metrics S3 bucket contains only 1 execution, whereas it previously could contain multiple.

There is no difference between validations and normal executions - validations are a type of execution and are included in the italicized comment, i.e. they need a user-provided execution ID and they can be updated. There's 3 types of executions: workflow executions, validation executions, and task executions

return Optional.of(new ValidationStatusMetric().validatorTools(newValidatorToolToValidatorInfo));
}

static Optional<ValidationExecution> getLatestValidationExecution(List<ValidationExecution> executions) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these two methods look the same, can ValidationExecution and ValidatorVersionInfo share an interface that has getDateExecuted

* @param executions
* @return
*/
@SuppressWarnings("checkstyle:magicnumber")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I'd add a const for 100 and get rid of this suppression.

@kathy-t
Copy link
Contributor Author

kathy-t commented Jan 12, 2024

Re-requesting reviews due to the new changes in dockstore/dockstore#5778.

The new change is that the metrics aggregator now takes the newest execution if there are multiple executions with the same ID.

Comment on lines 162 to 163
// Note: executions that were submitted to S3 prior to the existence of execution IDs don't have an execution ID.
// For the purposes of aggregation, generate one so that the execution is considered unique.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important note: we have executions in S3 that were submitted prior to the existence of executions IDs thus they don't have one. The metrics aggregator generates a random one in this case because the executions are assumed to be unique. The aggregator does not send back the object with a randomly generated execution ID to S3.

Should I create a ticket to migrate previous executions in S3 to have an execution ID or do we just live with this work-around?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also wipe the old executions and submit anew with execution IDs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, true, everything in the metrics S3 bucket is submitted by us and it would allow us to get rid of this special case. If we're okay with that, sounds like we can do the following steps:

  1. Wipe the entire metrics bucket (everything in it was submitted by us)
  2. Re-submit the DNAstack validation metrics using the submit-validation-data command
  3. Re-upload the tool tester AGC executions using the upload-results command, which uploads the executions in this directory. There's not many so a quick fix is to manually modify those files to include execution IDs.
  4. Ingest Terra metrics
  5. Aggregate metrics

@denis-yuen if we're okay with that, I'll take out that PR change that I commented on and add release notes steps to do the above. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the PR so that we can wipe the metrics bucket and re-ingest the DNAstack validation metrics and tool tester AGC executions.

  • For the DNAstack validation metrics, I modified the metricsaggregator/scripts/format-dnastack-validation-data.sh script so that it takes a dateExecuted argument that is used by the executions submitted to Dockstore. This way, we can set the dateExecuted to the date of the first time we submitted the metrics
  • For the tooltester AGC executions, I added a unique UUID as the execution ID for each execution, and I had to add a dateExecuted field because that's required by our schema now. Luckily, the date executed is the file name, so I just converted those epoch milliseconds to ISO date format

I will add the steps mentioned in my previous comment to the release checklist. @denis-yuen re-requesting your review

Copy link

codecov bot commented Jan 16, 2024

Codecov Report

Attention: 23 lines in your changes are missing coverage. Please review.

Comparison is base (2936d16) 52.79% compared to head (be583c1) 54.31%.

Files Patch % Lines
...saggregator/helper/ValidationStatusAggregator.java 85.71% 6 Missing and 7 partials ⚠️
...e/metricsaggregator/MetricsAggregatorS3Client.java 86.66% 6 Missing ⚠️
...re/metricsaggregator/helper/AggregationHelper.java 81.25% 1 Missing and 2 partials ⚠️
...csaggregator/helper/ExecutionStatusAggregator.java 80.00% 1 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             develop     #479      +/-   ##
=============================================
+ Coverage      52.79%   54.31%   +1.52%     
- Complexity       248      267      +19     
=============================================
  Files             30       31       +1     
  Lines           1665     1725      +60     
  Branches         141      143       +2     
=============================================
+ Hits             879      937      +58     
- Misses           721      725       +4     
+ Partials          65       63       -2     
Flag Coverage Δ
metricsaggregator 45.27% <87.76%> (+1.85%) ⬆️
toolbackup 41.27% <52.12%> (-1.49%) ⬇️
tooltester 32.23% <52.12%> (-1.17%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@kathy-t kathy-t mentioned this pull request Jan 16, 2024
4 tasks
Comment on lines 162 to 163
// Note: executions that were submitted to S3 prior to the existence of execution IDs don't have an execution ID.
// For the purposes of aggregation, generate one so that the execution is considered unique.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also wipe the old executions and submit anew with execution IDs.

validatorToolToValidations.forEach((validatorTool, validatorToolExecutions) -> {
Optional<ValidationExecution> latestValidationExecution = getLatestValidationExecution(validatorToolExecutions);

if (latestValidationExecution.isPresent()) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, no need to change this, but the ifPresent/get in this block (and elsewhere) has the same risk as a check and subsequent use of a nullable: if we try to use an Optional with no value, an exception gets thrown, and it's easy for someone to later get rid of the check and break the code. To eliminate that possibility, there's an ifPresent that accepts a consumer:
https://docs.oracle.com/en/java/javase/21/docs//api/java.base/java/util/Optional.html#ifPresent(java.util.function.Consumer)

With it, you can do something like:

getLatestValidationExecution(validatorToolExecutions).ifPresent(latestValidationExecution -> {
  // some stuff
});

There's also an ifPresentOrElse to implement both sides of a conditional.
https://docs.oracle.com/en/java/javase/21/docs//api/java.base/java/util/Optional.html#ifPresentOrElse(java.util.function.Consumer,java.lang.Runnable)

// Set run metrics
Optional<ExecutionStatusMetric> aggregatedExecutionStatus = new ExecutionStatusAggregator().getAggregatedMetricFromMetricsList(aggregatedMetrics);
boolean containsRunMetrics = aggregatedExecutionStatus.isPresent();
if (aggregatedExecutionStatus.isPresent()) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The data is such that if we can't aggregate an ExecutionStatusMetric, we can't aggregate these other things, either?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it was previously like this. The idea is that execution status is a metric that we require from all run executions thus ExecutionStatusMetric is an aggregated metric that the webservice requires

* @param <M> The aggregated metric from Metrics
* @param <E> The execution metric from RunExecution
*/
public interface RunExecutionAggregator<M, E> {
public interface ExecutionAggregator<T, M, E> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would there be a benefit to bounding any of the generic types, here or elsewhere? (I don't know the answer.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I bound T because it has to be a type of Execution, but the others are not boundable because they don't share a common type

Copy link

sonarcloud bot commented Jan 17, 2024

Quality Gate Failed Quality Gate failed

Failed conditions

0.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarCloud

@kathy-t kathy-t merged commit 81eb362 into develop Jan 18, 2024
9 of 10 checks passed
@kathy-t kathy-t deleted the feature/seab-5943/update-executions branch January 18, 2024 14:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants