diff --git a/THIRD-PARTY-LICENSES.properties b/THIRD-PARTY-LICENSES.properties index 5242c265..916cd02f 100644 --- a/THIRD-PARTY-LICENSES.properties +++ b/THIRD-PARTY-LICENSES.properties @@ -48,23 +48,23 @@ # Please fill the missing licenses for dependencies : # #Fri Apr 03 14:05:39 PDT 2020 -org.broadinstitute--wdl-draft2_2.13--84=WDL License https://github.com/openwdl/wdl/blob/master/LICENSE -org.broadinstitute--cromwell-wdl-model-draft2_2.13--84=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt -org.broadinstitute--cromwell-wdl-transforms-new-base_2.13--84=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt -org.broadinstitute--wdl-biscayne_2.13--84=WDL License https://github.com/openwdl/wdl/blob/master/LICENSE -org.broadinstitute--cromwell-wdl-model-draft3_2.13--84=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt -org.broadinstitute--cromwell-wdl-transforms-draft2_2.13--84=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt -org.broadinstitute--cromwell-wdl-transforms-shared_2.13--84=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt -org.broadinstitute--cromwell-wdl-model-core_2.13--84=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt -org.broadinstitute--cromwell-wdl-model-biscayne_2.13--84=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt +org.broadinstitute--wdl-draft2_2.13--85=WDL License https://github.com/openwdl/wdl/blob/master/LICENSE +org.broadinstitute--cromwell-wdl-model-draft2_2.13--85=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt +org.broadinstitute--cromwell-wdl-transforms-new-base_2.13--85=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt +org.broadinstitute--wdl-biscayne_2.13--85=WDL License https://github.com/openwdl/wdl/blob/master/LICENSE +org.broadinstitute--cromwell-wdl-model-draft3_2.13--85=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt +org.broadinstitute--cromwell-wdl-transforms-draft2_2.13--85=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt +org.broadinstitute--cromwell-wdl-transforms-shared_2.13--85=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt +org.broadinstitute--cromwell-wdl-model-core_2.13--85=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt +org.broadinstitute--cromwell-wdl-model-biscayne_2.13--85=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt com.readytalk--metrics3-statsd--4.2.0=The Apache Software License, Version 2.0 -org.broadinstitute--cromwell-common_2.13--84=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt -org.broadinstitute--cromwell-wdl-transforms-draft3_2.13--84=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt -org.broadinstitute--cromwell-wdl-transforms-biscayne_2.13--84=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt -org.broadinstitute--language-factory-core_2.13--84=WDL License https://github.com/openwdl/wdl/blob/master/LICENSE -org.broadinstitute--wdl-draft3_2.13--84=WDL License https://github.com/openwdl/wdl/blob/master/LICENSE -org.broadinstitute--cromwell-core_2.13--84=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt -org.broadinstitute--cromwell-wom_2.13--84=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt +org.broadinstitute--cromwell-common_2.13--85=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt +org.broadinstitute--cromwell-wdl-transforms-draft3_2.13--85=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt +org.broadinstitute--cromwell-wdl-transforms-biscayne_2.13--85=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt +org.broadinstitute--language-factory-core_2.13--85=WDL License https://github.com/openwdl/wdl/blob/master/LICENSE +org.broadinstitute--wdl-draft3_2.13--85=WDL License https://github.com/openwdl/wdl/blob/master/LICENSE +org.broadinstitute--cromwell-core_2.13--85=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt +org.broadinstitute--cromwell-wom_2.13--85=Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt com.readytalk--metrics-statsd-common--4.2.0=WDL License https://github.com/openwdl/wdl/blob/master/LICENSE org.antlr--antlr-runtime--3.4=The BSD License (https://www.antlr.org/license.html) dom4j--dom4j--1.6.1=https://github.com/dom4j/dom4j/blob/master/LICENSE diff --git a/THIRD-PARTY-LICENSES.txt b/THIRD-PARTY-LICENSES.txt index 91b54006..eefa08d2 100644 --- a/THIRD-PARTY-LICENSES.txt +++ b/THIRD-PARTY-LICENSES.txt @@ -1,5 +1,5 @@ -Lists of 413 third-party dependencies. +Lists of 417 third-party dependencies. (The Apache Software License, Version 2.0) Adapter: RxJava 2 (com.squareup.retrofit2:adapter-rxjava2:2.9.0 - https://github.com/square/retrofit) (Apache License, Version 2.0) akka-actor (com.typesafe.akka:akka-actor_2.13:2.5.32 - https://akka.io/) (Apache License, Version 2.0) akka-protobuf (com.typesafe.akka:akka-protobuf_2.13:2.5.32 - https://akka.io/) @@ -7,9 +7,9 @@ Lists of 413 third-party dependencies. (Apache License, Version 2.0) akka-stream (com.typesafe.akka:akka-stream_2.13:2.5.32 - https://akka.io/) (MIT) Alleycats core (org.typelevel:alleycats-core_2.13:2.7.0 - https://github.com/typelevel/cats) (Apache 2.0) annotation (org.typelevel:simulacrum-scalafix-annotations_2.13:0.5.4 - https://github.com/typelevel/simulacrum-scalafix) - (Apache License 2.0) Annotations for Metrics (io.dropwizard.metrics:metrics-annotation:4.2.18 - https://metrics.dropwizard.io/metrics-annotation) + (Apache License 2.0) Annotations for Metrics (io.dropwizard.metrics:metrics-annotation:4.2.19 - https://metrics.dropwizard.io/metrics-annotation) (The BSD License) ANTLR 4 Runtime (org.antlr:antlr4-runtime:4.10.1 - http://www.antlr.org/antlr4-runtime) - (EPL 2.0) (GPL2 w/ CPE) aopalliance version 1.0 repackaged as a module (org.glassfish.hk2.external:aopalliance-repackaged:3.0.3 - https://github.com/eclipse-ee4j/glassfish-hk2/external/aopalliance-repackaged) + (EPL 2.0) (GPL2 w/ CPE) aopalliance version 1.0 repackaged as a module (org.glassfish.hk2.external:aopalliance-repackaged:3.0.4 - https://github.com/eclipse-ee4j/glassfish-hk2/external/aopalliance-repackaged) (Apache License, Version 2.0) Apache Avro (org.apache.avro:avro:1.9.1 - https://avro.apache.org) (Apache License, Version 2.0) Apache Commons BeanUtils (commons-beanutils:commons-beanutils:1.9.4 - https://commons.apache.org/proper/commons-beanutils/) (Apache License, Version 2.0) Apache Commons Codec (commons-codec:commons-codec:1.15 - https://commons.apache.org/proper/commons-codec/) @@ -31,7 +31,7 @@ Lists of 413 third-party dependencies. (Apache License, Version 2.0) Apache HttpClient Fluent API (org.apache.httpcomponents:fluent-hc:4.5.2 - http://hc.apache.org/httpcomponents-client) (Apache License, Version 2.0) Apache HttpClient Mime (org.apache.httpcomponents:httpmime:4.5.2 - http://hc.apache.org/httpcomponents-client) (Apache License, Version 2.0) Apache HttpClient OSGi bundle (org.apache.httpcomponents:httpclient-osgi:4.5.2 - http://hc.apache.org/httpcomponents-client) - (Apache License, Version 2.0) Apache HttpComponents Core HTTP/1.1 (org.apache.httpcomponents.core5:httpcore5:5.2.1 - https://hc.apache.org/httpcomponents-core-5.2.x/5.2.1/httpcore5/) + (Apache License, Version 2.0) Apache HttpComponents Core HTTP/1.1 (org.apache.httpcomponents.core5:httpcore5:5.2.3 - https://hc.apache.org/httpcomponents-core-5.2.x/5.2.3/httpcore5/) (Apache License, Version 2.0) Apache HttpComponents Core HTTP/2 (org.apache.httpcomponents.core5:httpcore5-h2:5.2 - https://hc.apache.org/httpcomponents-core-5.2.x/5.2/httpcore5-h2/) (Apache License, Version 2.0) Apache HttpCore (org.apache.httpcomponents:httpcore:4.4.16 - http://hc.apache.org/httpcomponents-core-ga) (Apache License, Version 2.0) Apache HttpCore NIO (org.apache.httpcomponents:httpcore-nio:4.4.16 - http://hc.apache.org/httpcomponents-core-ga) @@ -79,16 +79,18 @@ Lists of 413 third-party dependencies. (Apache License, Version 2.0) AWS SDK for Java - Core (com.amazonaws:aws-java-sdk-core:1.11.83 - https://aws.amazon.com/sdkforjava) (Apache License 2.0) (The Apache Software License, Version 2.0) Bean Validation API (javax.validation:validation-api:2.0.1.Final - http://beanvalidation.org) (MIT) better-files (com.github.pathikrit:better-files_2.13:3.9.1 - https://github.com/pathikrit/better-files) - (Bouncy Castle Licence) Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs (org.bouncycastle:bcpkix-jdk15on:1.52 - http://www.bouncycastle.org/java.html) + (Bouncy Castle Licence) Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs (org.bouncycastle:bcpkix-jdk15on:1.60 - http://www.bouncycastle.org/java.html) (Bouncy Castle Licence) Bouncy Castle Provider (org.bouncycastle:bcprov-jdk15on:1.69 - https://www.bouncycastle.org/java.html) - (Apache License, Version 2.0) Byte Buddy (without dependencies) (net.bytebuddy:byte-buddy:1.14.3 - https://bytebuddy.net/byte-buddy) - (Apache License, Version 2.0) Byte Buddy agent (net.bytebuddy:byte-buddy-agent:1.14.3 - https://bytebuddy.net/byte-buddy-agent) - (Apache License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:3.1.5 - https://github.com/ben-manes/caffeine) + (Apache License, Version 2.0) Byte Buddy (without dependencies) (net.bytebuddy:byte-buddy:1.14.8 - https://bytebuddy.net/byte-buddy) + (Apache License, Version 2.0) Byte Buddy agent (net.bytebuddy:byte-buddy-agent:1.14.8 - https://bytebuddy.net/byte-buddy-agent) + (Apache License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:3.1.8 - https://github.com/ben-manes/caffeine) (Apache 2.0) cats (com.softwaremill.sttp:cats_2.13:1.7.2 - http://softwaremill.com/open-source) (MIT) Cats core (org.typelevel:cats-core_2.13:2.7.0 - https://github.com/typelevel/cats) + (MIT) Cats Free (org.typelevel:cats-free_2.13:2.1.1 - https://github.com/typelevel/cats) (MIT) Cats kernel (org.typelevel:cats-kernel_2.13:2.7.0 - https://github.com/typelevel/cats) + (MIT) Cats macros (org.typelevel:cats-macros_2.13:2.1.1 - https://github.com/typelevel/cats) (Apache-2.0) cats-effect (org.typelevel:cats-effect_2.13:2.5.3 - https://typelevel.org/cats-effect/) - (The MIT License) Checker Qual (org.checkerframework:checker-qual:3.32.0 - https://checkerframework.org/) + (The MIT License) Checker Qual (org.checkerframework:checker-qual:3.38.0 - https://checkerframework.org/) (Apache 2.0) Circe core (io.circe:circe-core_2.13:0.14.1 - https://github.com/circe/circe) (Apache 2.0) Circe generic (io.circe:circe-generic_2.13:0.14.1 - https://github.com/circe/circe) (Apache 2.0) Circe jawn (io.circe:circe-jawn_2.13:0.14.1 - https://github.com/circe/circe) @@ -105,61 +107,61 @@ Lists of 413 third-party dependencies. (The Apache License, Version 2.0) com.helger:profiler (com.helger:profiler:1.1.1 - https://github.com/phax/profiler) (The Apache Software License, Version 2.0) Commons Digester (commons-digester:commons-digester:2.1 - http://commons.apache.org/digester/) (The Apache Software License, Version 2.0) Commons Lang (commons-lang:commons-lang:2.6 - http://commons.apache.org/lang/) - (BSD-3-Clause) commons-compiler (org.codehaus.janino:commons-compiler:3.1.6 - http://janino-compiler.github.io/commons-compiler/) + (BSD-3-Clause) commons-compiler (org.codehaus.janino:commons-compiler:3.1.7 - http://janino-compiler.github.io/commons-compiler/) (Apache License 2.0) compiler (com.github.spullara.mustache.java:compiler:0.9.10 - http://github.com/spullara/mustache.java) - (Apache-2.0) config (com.typesafe:config:1.4.1 - https://github.com/lightbend/config) + (Apache-2.0) config (com.typesafe:config:1.4.2 - https://github.com/lightbend/config) (The Apache Software License, Version 2.0) Converter: Jackson (com.squareup.retrofit2:converter-jackson:2.9.0 - https://github.com/square/retrofit) - (Apache 2) (Apache 2.0) (Three-clause BSD-style) core (com.chuusai:shapeless_2.13:2.3.7 - https://github.com/milessabin/shapeless) - (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-common (org.broadinstitute:cromwell-common_2.13:84 - no url defined) - (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-core (org.broadinstitute:cromwell-core_2.13:84 - no url defined) - (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-model-biscayne (org.broadinstitute:cromwell-wdl-model-biscayne_2.13:84 - no url defined) - (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-model-core (org.broadinstitute:cromwell-wdl-model-core_2.13:84 - no url defined) - (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-model-draft2 (org.broadinstitute:cromwell-wdl-model-draft2_2.13:84 - no url defined) - (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-model-draft3 (org.broadinstitute:cromwell-wdl-model-draft3_2.13:84 - no url defined) - (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-transforms-biscayne (org.broadinstitute:cromwell-wdl-transforms-biscayne_2.13:84 - no url defined) - (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-transforms-draft2 (org.broadinstitute:cromwell-wdl-transforms-draft2_2.13:84 - no url defined) - (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-transforms-draft3 (org.broadinstitute:cromwell-wdl-transforms-draft3_2.13:84 - no url defined) - (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-transforms-new-base (org.broadinstitute:cromwell-wdl-transforms-new-base_2.13:84 - no url defined) - (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-transforms-shared (org.broadinstitute:cromwell-wdl-transforms-shared_2.13:84 - no url defined) - (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wom (org.broadinstitute:cromwell-wom_2.13:84 - no url defined) + (Apache 2) (Apache 2.0) (MIT) (Three-clause BSD-style) core (com.chuusai:shapeless_2.13:2.3.9 - https://github.com/milessabin/shapeless) + (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-common (org.broadinstitute:cromwell-common_2.13:85 - no url defined) + (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-core (org.broadinstitute:cromwell-core_2.13:85 - no url defined) + (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-model-biscayne (org.broadinstitute:cromwell-wdl-model-biscayne_2.13:85 - no url defined) + (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-model-core (org.broadinstitute:cromwell-wdl-model-core_2.13:85 - no url defined) + (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-model-draft2 (org.broadinstitute:cromwell-wdl-model-draft2_2.13:85 - no url defined) + (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-model-draft3 (org.broadinstitute:cromwell-wdl-model-draft3_2.13:85 - no url defined) + (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-transforms-biscayne (org.broadinstitute:cromwell-wdl-transforms-biscayne_2.13:85 - no url defined) + (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-transforms-draft2 (org.broadinstitute:cromwell-wdl-transforms-draft2_2.13:85 - no url defined) + (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-transforms-draft3 (org.broadinstitute:cromwell-wdl-transforms-draft3_2.13:85 - no url defined) + (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-transforms-new-base (org.broadinstitute:cromwell-wdl-transforms-new-base_2.13:85 - no url defined) + (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wdl-transforms-shared (org.broadinstitute:cromwell-wdl-transforms-shared_2.13:85 - no url defined) + (Cromwell License https://github.com/broadinstitute/cromwell/blob/develop/LICENSE.txt) cromwell-wom (org.broadinstitute:cromwell-wom_2.13:85 - no url defined) (Apache License, Version 2.0) cwlavro-generated (io.cwl:cwlavro-generated:2.0.4.8 - no url defined) (Apache License, Version 2.0) cwlavro-tools (io.cwl:cwlavro-tools:2.0.4.8 - no url defined) - (The Apache Software License, Version 2.0) docker-client (com.spotify:docker-client:7.0.2 - https://github.com/spotify/docker-client) + (The Apache Software License, Version 2.0) docker-client (com.spotify:docker-client:8.16.0 - https://github.com/spotify/docker-client) (The Apache Software License, Version 2.0) docker-java-api (com.github.docker-java:docker-java-api:3.3.0 - https://github.com/docker-java/docker-java) (The Apache Software License, Version 2.0) docker-java-core (com.github.docker-java:docker-java-core:3.3.0 - https://github.com/docker-java/docker-java) (The Apache Software License, Version 2.0) docker-java-transport (com.github.docker-java:docker-java-transport:3.3.0 - https://github.com/docker-java/docker-java) (The Apache Software License, Version 2.0) docker-java-transport-httpclient5 (com.github.docker-java:docker-java-transport-httpclient5:3.3.0 - https://github.com/docker-java/docker-java) - (Apache Software License, Version 2.0) dockstore-common (io.dockstore:dockstore-common:1.15.0-alpha.5 - no url defined) - (Apache Software License, Version 2.0) dockstore-integration-testing (io.dockstore:dockstore-integration-testing:1.15.0-alpha.5 - no url defined) - (Apache Software License, Version 2.0) dockstore-language-plugin-parent (io.dockstore:dockstore-language-plugin-parent:1.15.0-alpha.5 - no url defined) - (Apache Software License, Version 2.0) dockstore-webservice (io.dockstore:dockstore-webservice:1.15.0-alpha.5 - no url defined) - (Apache License 2.0) Dropwizard (io.dropwizard:dropwizard-core:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-core) - (Apache License 2.0) Dropwizard Asset Bundle (io.dropwizard:dropwizard-assets:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-assets) - (Apache License 2.0) Dropwizard Authentication (io.dropwizard:dropwizard-auth:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-auth) - (Apache License 2.0) Dropwizard Configuration Support (io.dropwizard:dropwizard-configuration:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-configuration) - (Apache License 2.0) Dropwizard Database Support (io.dropwizard:dropwizard-db:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-db) - (Apache License 2.0) Dropwizard Health Checking Support (io.dropwizard:dropwizard-health:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-health) - (Apache License 2.0) Dropwizard Hibernate Support (io.dropwizard:dropwizard-hibernate:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-hibernate) - (Apache License 2.0) Dropwizard HTTP Client (io.dropwizard:dropwizard-client:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-client) - (Apache License 2.0) Dropwizard Jackson Support (io.dropwizard:dropwizard-jackson:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-jackson) - (Apache License 2.0) Dropwizard JDBI3 Support (io.dropwizard:dropwizard-jdbi3:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-jdbi3) - (Apache License 2.0) Dropwizard Jersey Support (io.dropwizard:dropwizard-jersey:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-jersey) - (Apache License 2.0) Dropwizard Jetty Support (io.dropwizard:dropwizard-jetty:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-jetty) - (Apache License 2.0) Dropwizard Lifecycle Support (io.dropwizard:dropwizard-lifecycle:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-lifecycle) - (Apache License 2.0) Dropwizard Logging Support (io.dropwizard:dropwizard-logging:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-logging) - (Apache License 2.0) Dropwizard Metrics Support (io.dropwizard:dropwizard-metrics:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-metrics) - (Apache License 2.0) Dropwizard Migrations (io.dropwizard:dropwizard-migrations:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-migrations) - (Apache License 2.0) Dropwizard Multipart Form Support (io.dropwizard:dropwizard-forms:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-forms) - (Apache License 2.0) Dropwizard Request Logging Support (io.dropwizard:dropwizard-request-logging:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-request-logging) - (Apache License 2.0) Dropwizard Servlet Support (io.dropwizard:dropwizard-servlets:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-servlets) - (Apache License 2.0) Dropwizard Test Helpers (io.dropwizard:dropwizard-testing:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-testing) - (Apache License 2.0) Dropwizard Utility Classes (io.dropwizard:dropwizard-util:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-util) - (Apache License 2.0) Dropwizard Validation Support (io.dropwizard:dropwizard-validation:4.0.0 - http://www.dropwizard.io/4.0.0/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-validation) + (Apache Software License, Version 2.0) dockstore-common (io.dockstore:dockstore-common:1.15.0-alpha.13 - no url defined) + (Apache Software License, Version 2.0) dockstore-integration-testing (io.dockstore:dockstore-integration-testing:1.15.0-alpha.13 - no url defined) + (Apache Software License, Version 2.0) dockstore-language-plugin-parent (io.dockstore:dockstore-language-plugin-parent:1.15.0-alpha.13 - no url defined) + (Apache Software License, Version 2.0) dockstore-webservice (io.dockstore:dockstore-webservice:1.15.0-alpha.13 - no url defined) + (Apache License 2.0) Dropwizard (io.dropwizard:dropwizard-core:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-core) + (Apache License 2.0) Dropwizard Asset Bundle (io.dropwizard:dropwizard-assets:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-assets) + (Apache License 2.0) Dropwizard Authentication (io.dropwizard:dropwizard-auth:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-auth) + (Apache License 2.0) Dropwizard Configuration Support (io.dropwizard:dropwizard-configuration:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-configuration) + (Apache License 2.0) Dropwizard Database Support (io.dropwizard:dropwizard-db:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-db) + (Apache License 2.0) Dropwizard Health Checking Support (io.dropwizard:dropwizard-health:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-health) + (Apache License 2.0) Dropwizard Hibernate Support (io.dropwizard:dropwizard-hibernate:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-hibernate) + (Apache License 2.0) Dropwizard HTTP Client (io.dropwizard:dropwizard-client:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-client) + (Apache License 2.0) Dropwizard Jackson Support (io.dropwizard:dropwizard-jackson:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-jackson) + (Apache License 2.0) Dropwizard JDBI3 Support (io.dropwizard:dropwizard-jdbi3:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-jdbi3) + (Apache License 2.0) Dropwizard Jersey Support (io.dropwizard:dropwizard-jersey:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-jersey) + (Apache License 2.0) Dropwizard Jetty Support (io.dropwizard:dropwizard-jetty:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-jetty) + (Apache License 2.0) Dropwizard Lifecycle Support (io.dropwizard:dropwizard-lifecycle:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-lifecycle) + (Apache License 2.0) Dropwizard Logging Support (io.dropwizard:dropwizard-logging:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-logging) + (Apache License 2.0) Dropwizard Metrics Support (io.dropwizard:dropwizard-metrics:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-metrics) + (Apache License 2.0) Dropwizard Migrations (io.dropwizard:dropwizard-migrations:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-migrations) + (Apache License 2.0) Dropwizard Multipart Form Support (io.dropwizard:dropwizard-forms:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-forms) + (Apache License 2.0) Dropwizard Request Logging Support (io.dropwizard:dropwizard-request-logging:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-request-logging) + (Apache License 2.0) Dropwizard Servlet Support (io.dropwizard:dropwizard-servlets:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-servlets) + (Apache License 2.0) Dropwizard Test Helpers (io.dropwizard:dropwizard-testing:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-testing) + (Apache License 2.0) Dropwizard Utility Classes (io.dropwizard:dropwizard-util:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-util) + (Apache License 2.0) Dropwizard Validation Support (io.dropwizard:dropwizard-validation:4.0.2 - http://www.dropwizard.io/4.0.2/dropwizard-bom/dropwizard-dependencies/dropwizard-parent/dropwizard-validation) (The Apache Software License, Version 2.0) elasticsearch-core (org.elasticsearch:elasticsearch-core:7.10.2 - https://github.com/elastic/elasticsearch) (The Apache Software License, Version 2.0) elasticsearch-x-content (org.elasticsearch:elasticsearch-x-content:7.10.2 - https://github.com/elastic/elasticsearch) - (Apache 2.0) error-prone annotations (com.google.errorprone:error_prone_annotations:2.18.0 - https://errorprone.info/error_prone_annotations) - (MIT) fansi_2.13 (com.lihaoyi:fansi_2.13:0.3.0 - https://github.com/lihaoyi/Fansi) - (MIT) ficus (com.iheart:ficus_2.13:1.5.1 - http://iheartradio.github.io/ficus) + (Apache 2.0) error-prone annotations (com.google.errorprone:error_prone_annotations:2.22.0 - https://errorprone.info/error_prone_annotations) + (MIT) fansi_2.13 (com.lihaoyi:fansi_2.13:0.3.1 - https://github.com/lihaoyi/Fansi) + (MIT) ficus (com.iheart:ficus_2.13:1.5.2 - http://iheartradio.github.io/ficus) (The Apache Software License, Version 2.0) FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - http://findbugs.sourceforge.net/) (The Apache Software License, Version 2.0) GeantyRef (io.leangen.geantyref:geantyref:1.3.14 - https://github.com/leangen/geantyref) (Apache 2.0) genericExtras (io.circe:circe-generic-extras_2.13:0.14.1 - https://github.com/circe/circe-generic-extras) @@ -176,44 +178,44 @@ Lists of 413 third-party dependencies. (The Apache Software License, Version 2.0) GSON extensions to the Google HTTP Client Library for Java. (com.google.http-client:google-http-client-gson:1.41.8 - https://github.com/googleapis/google-http-java-client/google-http-client-gson) (The Apache Software License, Version 2.0) Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.1 - https://github.com/google/guava/failureaccess) (The Apache Software License, Version 2.0) Guava ListenableFuture only (com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava - https://github.com/google/guava/listenablefuture) - (Apache License, Version 2.0) Guava: Google Core Libraries for Java (com.google.guava:guava:31.1-jre - https://github.com/google/guava) + (Apache License, Version 2.0) Guava: Google Core Libraries for Java (com.google.guava:guava:32.1.2-jre - https://github.com/google/guava) (BSD License 3) Hamcrest (org.hamcrest:hamcrest:2.2 - http://hamcrest.org/JavaHamcrest/) (New BSD License) Hamcrest All (org.hamcrest:hamcrest-all:1.3 - https://github.com/hamcrest/JavaHamcrest/hamcrest-all) (New BSD License) Hamcrest Core (org.hamcrest:hamcrest-core:1.3 - https://github.com/hamcrest/JavaHamcrest/hamcrest-core) (GNU Library General Public License v2.1 or later) Hibernate Commons Annotations (org.hibernate.common:hibernate-commons-annotations:6.0.6.Final - http://hibernate.org) (GNU Library General Public License v2.1 or later) Hibernate ORM - hibernate-core (org.hibernate.orm:hibernate-core:6.1.7.Final - https://hibernate.org/orm) (Apache License 2.0) Hibernate Validator Engine (org.hibernate.validator:hibernate-validator:7.0.5.Final - http://hibernate.org/validator/hibernate-validator) - (EPL 2.0) (GPL2 w/ CPE) HK2 API module (org.glassfish.hk2:hk2-api:3.0.3 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-api) - (EPL 2.0) (GPL2 w/ CPE) HK2 Implementation Utilities (org.glassfish.hk2:hk2-utils:3.0.3 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-utils) + (EPL 2.0) (GPL2 w/ CPE) HK2 API module (org.glassfish.hk2:hk2-api:3.0.4 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-api) + (EPL 2.0) (GPL2 w/ CPE) HK2 Implementation Utilities (org.glassfish.hk2:hk2-utils:3.0.4 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-utils) (The Apache Software License, Version 2.0) HPPC Collections (com.carrotsearch:hppc:0.8.1 - http://labs.carrotsearch.com/hppc.html/hppc) (The Apache Software License, Version 2.0) IntelliJ IDEA Annotations (org.jetbrains:annotations:13.0 - http://www.jetbrains.org) (Apache 2.0) io.grpc:grpc-context (io.grpc:grpc-context:1.27.2 - https://github.com/grpc/grpc-java) (Eclipse Distribution License - v 1.0) istack common utility code runtime (com.sun.istack:istack-commons-runtime:4.0.1 - https://projects.eclipse.org/projects/ee4j/istack-commons/istack-commons-runtime) - (The Apache Software License, Version 2.0) J2ObjC Annotations (com.google.j2objc:j2objc-annotations:1.3 - https://github.com/google/j2objc/) + (Apache License, Version 2.0) J2ObjC Annotations (com.google.j2objc:j2objc-annotations:2.8 - https://github.com/google/j2objc/) (The Apache Software License, Version 2.0) Jackson (org.codehaus.jackson:jackson-core-asl:1.9.13 - http://jackson.codehaus.org) (The Apache Software License, Version 2.0) Jackson 2 extensions to the Google APIs Client Library for Java (com.google.api-client:google-api-client-jackson2:1.35.0 - https://github.com/googleapis/google-api-java-client/google-api-client-jackson2) - (The Apache Software License, Version 2.0) Jackson dataformat: CBOR (com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.14.2 - https://github.com/FasterXML/jackson-dataformats-binary) - (The Apache Software License, Version 2.0) Jackson datatype: Guava (com.fasterxml.jackson.datatype:jackson-datatype-guava:2.14.2 - https://github.com/FasterXML/jackson-datatypes-collections) - (The Apache Software License, Version 2.0) Jackson datatype: jdk8 (com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.14.2 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8) - (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310) + (The Apache Software License, Version 2.0) Jackson dataformat: CBOR (com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.15.2 - https://github.com/FasterXML/jackson-dataformats-binary) + (The Apache Software License, Version 2.0) Jackson datatype: Guava (com.fasterxml.jackson.datatype:jackson-datatype-guava:2.15.2 - https://github.com/FasterXML/jackson-datatypes-collections) + (The Apache Software License, Version 2.0) Jackson datatype: jdk8 (com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.15.2 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8) + (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310) (The Apache Software License, Version 2.0) Jackson extensions to the Google HTTP Client Library for Java. (com.google.http-client:google-http-client-jackson:1.29.2 - https://github.com/googleapis/google-http-java-client/google-http-client-jackson) - (Apache License 2.0) Jackson Integration for Metrics (io.dropwizard.metrics:metrics-json:4.2.18 - https://metrics.dropwizard.io/metrics-json) - (The Apache Software License, Version 2.0) Jackson Jakarta-RS: base (com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-base:2.14.2 - https://github.com/FasterXML/jackson-jakarta-rs-providers/jackson-jakarta-rs-base) - (The Apache Software License, Version 2.0) Jackson Jakarta-RS: JSON (com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-json-provider:2.14.2 - https://github.com/FasterXML/jackson-jakarta-rs-providers/jackson-jakarta-rs-json-provider) - (The Apache Software License, Version 2.0) Jackson module: Blackbird (com.fasterxml.jackson.module:jackson-module-blackbird:2.14.2 - https://github.com/FasterXML/jackson-modules-base) - (The Apache Software License, Version 2.0) Jackson module: Jakarta XML Bind Annotations (jakarta.xml.bind) (com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations:2.14.2 - https://github.com/FasterXML/jackson-modules-base) - (The Apache Software License, Version 2.0) Jackson module: Old JAXB Annotations (javax.xml.bind) (com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.14.2 - https://github.com/FasterXML/jackson-modules-base) - (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.14.2 - https://github.com/FasterXML/jackson) - (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.14.2 - https://github.com/FasterXML/jackson-core) - (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.14.2 - https://github.com/FasterXML/jackson) - (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.2 - https://github.com/FasterXML/jackson-dataformats-text) - (The Apache Software License, Version 2.0) Jackson-datatype-Hibernate5-jakarta (com.fasterxml.jackson.datatype:jackson-datatype-hibernate5-jakarta:2.14.2 - https://github.com/FasterXML/jackson-datatype-hibernate) - (The Apache Software License, Version 2.0) Jackson-JAXRS: base (com.fasterxml.jackson.jaxrs:jackson-jaxrs-base:2.14.2 - https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-base) - (The Apache Software License, Version 2.0) Jackson-JAXRS: JSON (com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.14.2 - https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-json-provider) - (The Apache Software License, Version 2.0) Jackson-module-parameter-names (com.fasterxml.jackson.module:jackson-module-parameter-names:2.14.2 - https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names) + (Apache License 2.0) Jackson Integration for Metrics (io.dropwizard.metrics:metrics-json:4.2.19 - https://metrics.dropwizard.io/metrics-json) + (The Apache Software License, Version 2.0) Jackson Jakarta-RS: base (com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-base:2.15.2 - https://github.com/FasterXML/jackson-jakarta-rs-providers/jackson-jakarta-rs-base) + (The Apache Software License, Version 2.0) Jackson Jakarta-RS: JSON (com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-json-provider:2.15.2 - https://github.com/FasterXML/jackson-jakarta-rs-providers/jackson-jakarta-rs-json-provider) + (The Apache Software License, Version 2.0) Jackson module: Blackbird (com.fasterxml.jackson.module:jackson-module-blackbird:2.15.2 - https://github.com/FasterXML/jackson-modules-base) + (The Apache Software License, Version 2.0) Jackson module: Jakarta XML Bind Annotations (jakarta.xml.bind) (com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations:2.15.2 - https://github.com/FasterXML/jackson-modules-base) + (The Apache Software License, Version 2.0) Jackson module: Old JAXB Annotations (javax.xml.bind) (com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.15.2 - https://github.com/FasterXML/jackson-modules-base) + (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.15.2 - https://github.com/FasterXML/jackson) + (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.15.2 - https://github.com/FasterXML/jackson-core) + (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.15.2 - https://github.com/FasterXML/jackson) + (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2 - https://github.com/FasterXML/jackson-dataformats-text) + (The Apache Software License, Version 2.0) Jackson-datatype-Hibernate5-jakarta (com.fasterxml.jackson.datatype:jackson-datatype-hibernate5-jakarta:2.15.2 - https://github.com/FasterXML/jackson-datatype-hibernate) + (The Apache Software License, Version 2.0) Jackson-JAXRS: base (com.fasterxml.jackson.jaxrs:jackson-jaxrs-base:2.15.2 - https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-base) + (The Apache Software License, Version 2.0) Jackson-JAXRS: JSON (com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.15.2 - https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-json-provider) + (The Apache Software License, Version 2.0) Jackson-module-parameter-names (com.fasterxml.jackson.module:jackson-module-parameter-names:2.15.2 - https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names) (EDL 1.0) Jakarta Activation (com.sun.activation:jakarta.activation:2.0.1 - https://github.com/eclipse-ee4j/jaf/jakarta.activation) (EDL 1.0) Jakarta Activation API (jakarta.activation:jakarta.activation-api:2.1.0 - https://github.com/eclipse-ee4j/jaf) - (EPL 2.0) (GPL2 w/ CPE) Jakarta Annotations API (jakarta.annotation:jakarta.annotation-api:2.0.0 - https://projects.eclipse.org/projects/ee4j.ca) + (EPL 2.0) (GPL2 w/ CPE) Jakarta Annotations API (jakarta.annotation:jakarta.annotation-api:2.1.1 - https://projects.eclipse.org/projects/ee4j.ca) (Apache License 2.0) Jakarta Bean Validation API (jakarta.validation:jakarta.validation-api:3.0.2 - https://beanvalidation.org) (The Apache Software License, Version 2.0) Jakarta Dependency Injection (jakarta.inject:jakarta.inject-api:2.0.1.MR - https://github.com/eclipse-ee4j/injection-api) (Eclipse Public License v. 2.0) (GNU General Public License, version 2 with the GNU Classpath Exception) Jakarta Expression Language API (jakarta.el:jakarta.el-api:4.0.0 - https://projects.eclipse.org/projects/ee4j.el) @@ -223,7 +225,7 @@ Lists of 413 third-party dependencies. (EPL 2.0) (GPL2 w/ CPE) Jakarta Servlet (jakarta.servlet:jakarta.servlet-api:5.0.0 - https://projects.eclipse.org/projects/ee4j.servlet) (Eclipse Distribution License - v 1.0) Jakarta XML Binding API (jakarta.xml.bind:jakarta.xml.bind-api:3.0.1 - https://github.com/eclipse-ee4j/jaxb-api/jakarta.xml.bind-api) (EPL 2.0) (GPL2 w/ CPE) jakarta.transaction API (jakarta.transaction:jakarta.transaction-api:2.0.0 - https://projects.eclipse.org/projects/ee4j.jta) - (BSD-3-Clause) janino (org.codehaus.janino:janino:3.1.6 - http://janino-compiler.github.io/janino/) + (BSD-3-Clause) janino (org.codehaus.janino:janino:3.1.7 - http://janino-compiler.github.io/janino/) (The Apache Software License, Version 2.0) Java 6 (and higher) Extensions to the Google API Client Library for Java. (com.google.api-client:google-api-client-java6:1.35.0 - https://github.com/googleapis/google-api-java-client/google-api-client-java6) (The Apache Software License, Version 2.0) Java 6 (and higher) extensions to the Google OAuth Client Library for Java. (com.google.oauth-client:google-oauth-client-java6:1.34.0 - https://github.com/googleapis/google-oauth-java-client/google-oauth-client-java6) (Apache License, Version 2.0) Java Annotation Indexer (org.jboss:jandex:2.4.2.Final - http://www.jboss.org/jandex) @@ -231,96 +233,98 @@ Lists of 413 third-party dependencies. (Apache-2.0) (LGPL-2.1-or-later) Java Native Access (net.java.dev.jna:jna:5.12.1 - https://github.com/java-native-access/jna) (The MIT License) Java SemVer (com.github.zafarkhaja:java-semver:0.9.0 - https://github.com/zafarkhaja/jsemver) (The Apache Software License, Version 2.0) java-diff-utils (io.github.java-diff-utils:java-diff-utils:4.12 - https://github.com/java-diff-utils/java-diff-utils/java-diff-utils) - (CDDL/GPLv2+CE) JavaBeans Activation Framework (com.sun.activation:javax.activation:1.2.0 - http://java.net/all/javax.activation/) + (Common Development and Distribution License (CDDL) v1.0) JavaBeans Activation Framework (JAF) (javax.activation:activation:1.1 - http://java.sun.com/products/javabeans/jaf/index.jsp) + (CDDL/GPLv2+CE) JavaBeans Activation Framework API jar (javax.activation:javax.activation-api:1.2.0 - http://java.net/all/javax.activation-api/) (Apache License 2.0) (LGPL 2.1) (MPL 1.1) Javassist (org.javassist:javassist:3.29.2-GA - http://www.javassist.org/) (CDDL + GPLv2 with classpath exception) javax.annotation API (javax.annotation:javax.annotation-api:1.3.2 - http://jcp.org/en/jsr/detail?id=250) (Eclipse Distribution License - v 1.0) JAXB Core (org.glassfish.jaxb:jaxb-core:3.0.2 - https://eclipse-ee4j.github.io/jaxb-ri/) (Eclipse Distribution License - v 1.0) JAXB Runtime (org.glassfish.jaxb:jaxb-runtime:3.0.2 - https://eclipse-ee4j.github.io/jaxb-ri/) + (CDDL 1.1) (GPL2 w/ CPE) jaxb-api (javax.xml.bind:jaxb-api:2.3.1 - https://github.com/javaee/jaxb-spec/jaxb-api) (Apache License, version 2.0) JBoss Logging 3 (org.jboss.logging:jboss-logging:3.4.3.Final - http://www.jboss.org) - (Apache License, Version 2.0) JCL 1.2 implemented over SLF4J (org.slf4j:jcl-over-slf4j:2.0.7 - http://www.slf4j.org) + (Apache License, Version 2.0) JCL 1.2 implemented over SLF4J (org.slf4j:jcl-over-slf4j:2.0.9 - http://www.slf4j.org) (Apache License, Version 2.0) jcommander (com.beust:jcommander:1.82 - https://jcommander.org) - (Apache License 2.0) jdbi3 core (org.jdbi:jdbi3-core:3.37.1 - https://jdbi.org/jdbi3-parent/jdbi3-core/) - (Apache License 2.0) jdbi3 guava (org.jdbi:jdbi3-guava:3.37.1 - https://jdbi.org/jdbi3-parent/jdbi3-guava/) - (Apache License 2.0) jdbi3 sqlobject (org.jdbi:jdbi3-sqlobject:3.37.1 - https://jdbi.org/jdbi3-parent/jdbi3-sqlobject/) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-connectors-apache (org.glassfish.jersey.connectors:jersey-apache-connector:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-apache-connector) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-connectors-apache5 (org.glassfish.jersey.connectors:jersey-apache5-connector:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-apache5-connector) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-container-servlet (org.glassfish.jersey.containers:jersey-container-servlet:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-container-servlet) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-container-servlet-core (org.glassfish.jersey.containers:jersey-container-servlet-core:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-container-servlet-core) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-core-client (org.glassfish.jersey.core:jersey-client:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client) - (Apache License, 2.0) (EPL 2.0) (Public Domain) (The GNU General Public License (GPL), Version 2, With Classpath Exception) jersey-core-common (org.glassfish.jersey.core:jersey-common:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-common) - (Apache License, 2.0) (EPL 2.0) (Modified BSD) (The GNU General Public License (GPL), Version 2, With Classpath Exception) jersey-core-server (org.glassfish.jersey.core:jersey-server:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-server) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-ext-bean-validation (org.glassfish.jersey.ext:jersey-bean-validation:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-bean-validation) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-ext-entity-filtering (org.glassfish.jersey.ext:jersey-entity-filtering:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-entity-filtering) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-ext-metainf-services (org.glassfish.jersey.ext:jersey-metainf-services:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-metainf-services) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-media-jaxb (org.glassfish.jersey.media:jersey-media-jaxb:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-jaxb) - (Apache License, 2.0) (EPL 2.0) (The GNU General Public License (GPL), Version 2, With Classpath Exception) jersey-media-json-jackson (org.glassfish.jersey.media:jersey-media-json-jackson:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-json-jackson) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-test-framework-core (org.glassfish.jersey.test-framework:jersey-test-framework-core:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-test-framework-core) - (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-test-framework-provider-inmemory (org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-inmemory:3.0.9 - https://projects.eclipse.org/projects/ee4j.jersey/project/project/jersey-test-framework-provider-inmemory) - (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: Http Utility (org.eclipse.jetty:jetty-http:11.0.14 - https://eclipse.org/jetty/jetty-http) - (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: IO Utility (org.eclipse.jetty:jetty-io:11.0.14 - https://eclipse.org/jetty/jetty-io) + (Apache License 2.0) jdbi3 core (org.jdbi:jdbi3-core:3.41.2 - https://jdbi.org/jdbi3-parent/jdbi3-core/) + (Apache License 2.0) jdbi3 guava (org.jdbi:jdbi3-guava:3.41.2 - https://jdbi.org/jdbi3-parent/jdbi3-guava/) + (Apache License 2.0) jdbi3 sqlobject (org.jdbi:jdbi3-sqlobject:3.41.2 - https://jdbi.org/jdbi3-parent/jdbi3-sqlobject/) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-connectors-apache (org.glassfish.jersey.connectors:jersey-apache-connector:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-apache-connector) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-connectors-apache5 (org.glassfish.jersey.connectors:jersey-apache5-connector:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-apache5-connector) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-container-servlet (org.glassfish.jersey.containers:jersey-container-servlet:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-container-servlet) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-container-servlet-core (org.glassfish.jersey.containers:jersey-container-servlet-core:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-container-servlet-core) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-core-client (org.glassfish.jersey.core:jersey-client:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-client) + (Apache License, 2.0) (EPL 2.0) (Public Domain) (The GNU General Public License (GPL), Version 2, With Classpath Exception) jersey-core-common (org.glassfish.jersey.core:jersey-common:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-common) + (Apache License, 2.0) (EPL 2.0) (Modified BSD) (The GNU General Public License (GPL), Version 2, With Classpath Exception) jersey-core-server (org.glassfish.jersey.core:jersey-server:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/jersey-server) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-ext-bean-validation (org.glassfish.jersey.ext:jersey-bean-validation:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-bean-validation) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-ext-entity-filtering (org.glassfish.jersey.ext:jersey-entity-filtering:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-entity-filtering) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-ext-metainf-services (org.glassfish.jersey.ext:jersey-metainf-services:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-metainf-services) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-inject-hk2 (org.glassfish.jersey.inject:jersey-hk2:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-hk2) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-media-jaxb (org.glassfish.jersey.media:jersey-media-jaxb:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-jaxb) + (Apache License, 2.0) (EPL 2.0) (The GNU General Public License (GPL), Version 2, With Classpath Exception) jersey-media-json-jackson (org.glassfish.jersey.media:jersey-media-json-jackson:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-json-jackson) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-media-multipart (org.glassfish.jersey.media:jersey-media-multipart:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-media-multipart) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-test-framework-core (org.glassfish.jersey.test-framework:jersey-test-framework-core:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/jersey-test-framework-core) + (Apache License, 2.0) (BSD 2-Clause) (EDL 1.0) (EPL 2.0) (GPL2 w/ CPE) (MIT license) (Modified BSD) (Public Domain) (W3C license) (jQuery license) jersey-test-framework-provider-inmemory (org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-inmemory:3.0.11 - https://projects.eclipse.org/projects/ee4j.jersey/project/project/jersey-test-framework-provider-inmemory) + (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: Http Utility (org.eclipse.jetty:jetty-http:11.0.16 - https://eclipse.dev/jetty/jetty-http) + (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: IO Utility (org.eclipse.jetty:jetty-io:11.0.16 - https://eclipse.dev/jetty/jetty-io) (Apache Software License - Version 2.0) (Eclipse Public License - Version 1.0) Jetty :: Jakarta Servlet API and Schemas for JPMS and OSGi (org.eclipse.jetty.toolchain:jetty-jakarta-servlet-api:5.0.2 - https://eclipse.org/jetty/jetty-jakarta-servlet-api) - (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: Security (org.eclipse.jetty:jetty-security:11.0.14 - https://eclipse.org/jetty/jetty-security) - (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: Server Core (org.eclipse.jetty:jetty-server:11.0.14 - https://eclipse.org/jetty/jetty-server) - (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:11.0.14 - https://eclipse.org/jetty/jetty-servlet) + (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: Security (org.eclipse.jetty:jetty-security:11.0.16 - https://eclipse.dev/jetty/jetty-security) + (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: Server Core (org.eclipse.jetty:jetty-server:11.0.16 - https://eclipse.dev/jetty/jetty-server) + (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:11.0.16 - https://eclipse.dev/jetty/jetty-servlet) (Apache Software License - Version 2.0) (Eclipse Public License - Version 1.0) Jetty :: SetUID Java (org.eclipse.jetty.toolchain.setuid:jetty-setuid-java:1.0.4 - https://eclipse.org/jetty/jetty-setuid-parent/jetty-setuid-java) - (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: Utilities (org.eclipse.jetty:jetty-util:11.0.14 - https://eclipse.org/jetty/jetty-util) - (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: Utility Servlets and Filters (org.eclipse.jetty:jetty-servlets:11.0.14 - https://eclipse.org/jetty/jetty-servlets) - (The Apache Software License, Version 2.0) jffi (com.github.jnr:jffi:1.2.9 - http://github.com/jnr/jffi) + (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: Utilities (org.eclipse.jetty:jetty-util:11.0.16 - https://eclipse.dev/jetty/jetty-util) + (Apache Software License - Version 2.0) (Eclipse Public License - Version 2.0) Jetty :: Utility Servlets and Filters (org.eclipse.jetty:jetty-servlets:11.0.16 - https://eclipse.dev/jetty/jetty-servlets) + (The Apache Software License, Version 2.0) jffi (com.github.jnr:jffi:1.2.15 - http://github.com/jnr/jffi) (Apache License, Version 2.0) JJWT :: API (io.jsonwebtoken:jjwt-api:0.11.5 - https://github.com/jwtk/jjwt/jjwt-api) (Apache License, Version 2.0) JJWT :: Extensions :: Jackson (io.jsonwebtoken:jjwt-jackson:0.11.5 - https://github.com/jwtk/jjwt/jjwt-jackson) (Apache License, Version 2.0) JJWT :: Impl (io.jsonwebtoken:jjwt-impl:0.11.5 - https://github.com/jwtk/jjwt/jjwt-impl) (The BSD License) JLine Bundle (org.jline:jline:3.21.0 - http://nexus.sonatype.org/oss-repository-hosting.html/jline-parent/jline) (Apache License, Version 2.0) JMES Path Query library (com.amazonaws:jmespath-java:1.11.83 - https://aws.amazon.com/sdkforjava) - (The Apache Software License, Version 2.0) jnr-constants (com.github.jnr:jnr-constants:0.8.7 - http://github.com/jnr/jnr-constants) - (The Apache Software License, Version 2.0) jnr-enxio (com.github.jnr:jnr-enxio:0.9 - http://github.com/jnr/jnr-enxio) - (The Apache Software License, Version 2.0) jnr-ffi (com.github.jnr:jnr-ffi:2.0.3 - http://github.com/jnr/jnr-ffi) - (Common Public License - v 1.0) (GNU General Public License Version 2) (GNU Lesser General Public License Version 2.1) jnr-posix (com.github.jnr:jnr-posix:3.0.12 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix) - (The Apache Software License, Version 2.0) jnr-unixsocket (com.github.jnr:jnr-unixsocket:0.8 - http://github.com/jnr/jnr-unixsocket) + (The Apache Software License, Version 2.0) jnr-constants (com.github.jnr:jnr-constants:0.9.8 - http://github.com/jnr/jnr-constants) + (The Apache Software License, Version 2.0) jnr-enxio (com.github.jnr:jnr-enxio:0.16 - http://github.com/jnr/jnr-enxio) + (The Apache Software License, Version 2.0) jnr-ffi (com.github.jnr:jnr-ffi:2.1.4 - http://github.com/jnr/jnr-ffi) + (Common Public License - v 1.0) (GNU General Public License Version 2) (GNU Lesser General Public License Version 2.1) jnr-posix (com.github.jnr:jnr-posix:3.0.35 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix) + (The Apache Software License, Version 2.0) jnr-unixsocket (com.github.jnr:jnr-unixsocket:0.18 - http://github.com/jnr/jnr-unixsocket) (MIT License) jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - http://github.com/jnr/jnr-x86asm) (Apache License, Version 2.0) Joda-Time (joda-time:joda-time:2.12.5 - https://www.joda.org/joda-time/) (The MIT License) JOpt Simple (net.sf.jopt-simple:jopt-simple:5.0.3 - http://pholser.github.io/jopt-simple) - (Public Domain) JSON in Java (org.json:json:20230227 - https://github.com/douglascrockford/JSON-java) + (Public Domain) JSON in Java (org.json:json:20231013 - https://github.com/douglascrockford/JSON-java) (Revised BSD License) JSONLD Java :: Core (com.github.jsonld-java:jsonld-java:0.8.3 - http://github.com/jsonld-java/jsonld-java/jsonld-java/) (The MIT License) jsoup Java HTML Parser (org.jsoup:jsoup:1.10.2 - https://jsoup.org/) (Apache License, Version 2.0) JSR 354 (Money and Currency API) (javax.money:money-api:1.1 - https://javamoney.github.io/) (MIT License) JTokkit (com.knuddels:jtokkit:0.6.1 - https://github.com/knuddelsgmbh/jtokkit) - (MIT License) JUL to SLF4J bridge (org.slf4j:jul-to-slf4j:2.0.7 - http://www.slf4j.org) + (MIT License) JUL to SLF4J bridge (org.slf4j:jul-to-slf4j:2.0.9 - http://www.slf4j.org) (Eclipse Public License 1.0) JUnit (junit:junit:4.13.2 - http://junit.org) - (Eclipse Public License v2.0) JUnit Jupiter (Aggregator) (org.junit.jupiter:junit-jupiter:5.9.2 - https://junit.org/junit5/) - (Eclipse Public License v2.0) JUnit Jupiter API (org.junit.jupiter:junit-jupiter-api:5.9.2 - https://junit.org/junit5/) - (Eclipse Public License v2.0) JUnit Jupiter Engine (org.junit.jupiter:junit-jupiter-engine:5.9.2 - https://junit.org/junit5/) - (Eclipse Public License v2.0) JUnit Jupiter Params (org.junit.jupiter:junit-jupiter-params:5.9.2 - https://junit.org/junit5/) - (Eclipse Public License v2.0) JUnit Platform Commons (org.junit.platform:junit-platform-commons:1.9.2 - https://junit.org/junit5/) - (Eclipse Public License v2.0) JUnit Platform Engine API (org.junit.platform:junit-platform-engine:1.9.2 - https://junit.org/junit5/) - (Apache License 2.0) JVM Integration for Metrics (io.dropwizard.metrics:metrics-jvm:4.2.18 - https://metrics.dropwizard.io/metrics-jvm) + (Eclipse Public License v2.0) JUnit Jupiter (Aggregator) (org.junit.jupiter:junit-jupiter:5.10.0 - https://junit.org/junit5/) + (Eclipse Public License v2.0) JUnit Jupiter API (org.junit.jupiter:junit-jupiter-api:5.10.0 - https://junit.org/junit5/) + (Eclipse Public License v2.0) JUnit Jupiter Engine (org.junit.jupiter:junit-jupiter-engine:5.10.0 - https://junit.org/junit5/) + (Eclipse Public License v2.0) JUnit Jupiter Params (org.junit.jupiter:junit-jupiter-params:5.10.0 - https://junit.org/junit5/) + (Eclipse Public License v2.0) JUnit Platform Commons (org.junit.platform:junit-platform-commons:1.10.0 - https://junit.org/junit5/) + (Eclipse Public License v2.0) JUnit Platform Engine API (org.junit.platform:junit-platform-engine:1.10.0 - https://junit.org/junit5/) + (Apache License 2.0) JVM Integration for Metrics (io.dropwizard.metrics:metrics-jvm:4.2.19 - https://metrics.dropwizard.io/metrics-jvm) (The Apache License, Version 2.0) Kotlin Stdlib (org.jetbrains.kotlin:kotlin-stdlib:1.6.20 - https://kotlinlang.org/) (The Apache License, Version 2.0) Kotlin Stdlib Common (org.jetbrains.kotlin:kotlin-stdlib-common:1.6.20 - https://kotlinlang.org/) (The Apache License, Version 2.0) Kotlin Stdlib Jdk7 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31 - https://kotlinlang.org/) (The Apache License, Version 2.0) Kotlin Stdlib Jdk8 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31 - https://kotlinlang.org/) (The Apache Software License, Version 2.0) lang-mustache (org.elasticsearch.plugin:lang-mustache-client:7.10.2 - https://github.com/elastic/elasticsearch) - (WDL License https://github.com/openwdl/wdl/blob/master/LICENSE) language-factory-core (org.broadinstitute:language-factory-core_2.13:84 - no url defined) - (Apache License, Version 2.0) Liquibase (org.liquibase:liquibase-core:4.19.0 - http://www.liquibase.org/liquibase-root/liquibase-dist) + (WDL License https://github.com/openwdl/wdl/blob/master/LICENSE) language-factory-core (org.broadinstitute:language-factory-core_2.13:85 - no url defined) + (Apache License, Version 2.0) Liquibase (org.liquibase:liquibase-core:4.23.0 - http://www.liquibase.com) (MIT License) liquibase-slf4j (com.mattbertolini:liquibase-slf4j:5.0.0 - https://github.com/mattbertolini/liquibase-slf4j) (Apache License 2.0) localstack-utils (cloud.localstack:localstack-utils:0.2.22 - http://localstack.cloud) - (Apache Software Licenses) Log4j Implemented Over SLF4J (org.slf4j:log4j-over-slf4j:2.0.7 - http://www.slf4j.org) - (Eclipse Public License - v 1.0) (GNU Lesser General Public License) Logback Access Module (ch.qos.logback:logback-access:1.4.6 - http://logback.qos.ch/logback-access) - (Eclipse Public License - v 1.0) (GNU Lesser General Public License) Logback Classic Module (ch.qos.logback:logback-classic:1.4.6 - http://logback.qos.ch/logback-classic) - (Eclipse Public License - v 1.0) (GNU Lesser General Public License) Logback Core Module (ch.qos.logback:logback-core:1.4.6 - http://logback.qos.ch/logback-core) + (Apache Software Licenses) Log4j Implemented Over SLF4J (org.slf4j:log4j-over-slf4j:2.0.9 - http://www.slf4j.org) + (Eclipse Public License - v 1.0) (GNU Lesser General Public License) Logback Access Module (ch.qos.logback:logback-access:1.4.11 - http://logback.qos.ch/logback-access) + (Eclipse Public License - v 1.0) (GNU Lesser General Public License) Logback Classic Module (ch.qos.logback:logback-classic:1.4.11 - http://logback.qos.ch/logback-classic) + (Eclipse Public License - v 1.0) (GNU Lesser General Public License) Logback Core Module (ch.qos.logback:logback-core:1.4.11 - http://logback.qos.ch/logback-core) (Apache License, Version 2.0) (MIT License) Logstash Logback Encoder (net.logstash.logback:logstash-logback-encoder:4.11 - https://github.com/logstash/logstash-logback-encoder) (Apache License, Version 2.0) Lucene Core (org.apache.lucene:lucene-core:8.7.0 - https://lucene.apache.org/lucene-parent/lucene-core) (MIT) mbknor-jackson-jsonSchema (com.kjetland:mbknor-jackson-jsonschema_2.12:1.0.34 - https://github.com/mbknor/mbknor-jackson-jsonSchema) - (Apache License 2.0) Metrics Core (io.dropwizard.metrics:metrics-core:4.2.18 - https://metrics.dropwizard.io/metrics-core) - (Apache License 2.0) Metrics Health Checks (io.dropwizard.metrics:metrics-healthchecks:4.2.18 - https://metrics.dropwizard.io/metrics-healthchecks) - (Apache License 2.0) Metrics Integration for Apache HttpClient 5.x (io.dropwizard.metrics:metrics-httpclient5:4.2.18 - https://metrics.dropwizard.io/metrics-httpclient5) - (Apache License 2.0) Metrics Integration for Caffeine 2.x (io.dropwizard.metrics:metrics-caffeine:4.2.18 - https://metrics.dropwizard.io/metrics-caffeine) - (Apache License 2.0) Metrics Integration for JDBI3 (io.dropwizard.metrics:metrics-jdbi3:4.2.18 - https://metrics.dropwizard.io/metrics-jdbi3) - (Apache License 2.0) Metrics Integration for Jersey 3.x (io.dropwizard.metrics:metrics-jersey3:4.2.18 - https://metrics.dropwizard.io/metrics-jersey3) - (Apache License 2.0) Metrics Integration for Jetty 11.x and higher (io.dropwizard.metrics:metrics-jetty11:4.2.18 - https://metrics.dropwizard.io/metrics-jetty11) - (Apache License 2.0) Metrics Integration for Logback (io.dropwizard.metrics:metrics-logback:4.2.18 - https://metrics.dropwizard.io/metrics-logback) - (Apache License 2.0) Metrics Integration with JMX (io.dropwizard.metrics:metrics-jmx:4.2.18 - https://metrics.dropwizard.io/metrics-jmx) - (Apache License 2.0) Metrics Utility Jakarta Servlets (io.dropwizard.metrics:metrics-jakarta-servlets:4.2.18 - https://metrics.dropwizard.io/metrics-jakarta-servlets) + (Apache License 2.0) Metrics Core (io.dropwizard.metrics:metrics-core:4.2.19 - https://metrics.dropwizard.io/metrics-core) + (Apache License 2.0) Metrics Health Checks (io.dropwizard.metrics:metrics-healthchecks:4.2.19 - https://metrics.dropwizard.io/metrics-healthchecks) + (Apache License 2.0) Metrics Integration for Apache HttpClient 5.x (io.dropwizard.metrics:metrics-httpclient5:4.2.19 - https://metrics.dropwizard.io/metrics-httpclient5) + (Apache License 2.0) Metrics Integration for Caffeine 2.x (io.dropwizard.metrics:metrics-caffeine:4.2.19 - https://metrics.dropwizard.io/metrics-caffeine) + (Apache License 2.0) Metrics Integration for JDBI3 (io.dropwizard.metrics:metrics-jdbi3:4.2.19 - https://metrics.dropwizard.io/metrics-jdbi3) + (Apache License 2.0) Metrics Integration for Jersey 3.x (io.dropwizard.metrics:metrics-jersey3:4.2.19 - https://metrics.dropwizard.io/metrics-jersey3) + (Apache License 2.0) Metrics Integration for Jetty 11.x and higher (io.dropwizard.metrics:metrics-jetty11:4.2.19 - https://metrics.dropwizard.io/metrics-jetty11) + (Apache License 2.0) Metrics Integration for Logback (io.dropwizard.metrics:metrics-logback:4.2.19 - https://metrics.dropwizard.io/metrics-logback) + (Apache License 2.0) Metrics Integration with JMX (io.dropwizard.metrics:metrics-jmx:4.2.19 - https://metrics.dropwizard.io/metrics-jmx) + (Apache License 2.0) Metrics Utility Jakarta Servlets (io.dropwizard.metrics:metrics-jakarta-servlets:4.2.19 - https://metrics.dropwizard.io/metrics-jakarta-servlets) (The Apache Software License, Version 2.0) metrics3-statsd (com.readytalk:metrics3-statsd:4.2.0 - no url defined) (Apache 2) metrics4-scala (nl.grons:metrics4-scala_2.13:4.2.8 - https://github.com/erikvanoosten/metrics-scala) (GNU General Public License (GPLv3)) metricsaggregator (io.dockstore:metricsaggregator:1.15.0-SNAPSHOT - https://github.com/dockstore/dockstore-support) @@ -328,7 +332,7 @@ Lists of 413 third-party dependencies. (The MIT License) mockito-core (org.mockito:mockito-core:3.12.4 - https://github.com/mockito/mockito) (The MIT License) mockito-inline (org.mockito:mockito-inline:3.12.4 - https://github.com/mockito/mockito) (Apache 2 License) Moneta Core (org.javamoney.moneta:moneta-core:1.4.2 - http://javamoney.org) - (MIT license) mouse (org.typelevel:mouse_2.13:1.0.10 - https://typelevel.org/mouse) + (MIT) mouse (org.typelevel:mouse_2.13:1.0.11 - https://typelevel.org/mouse) (Apache License, Version 2.0) Netty Reactive Streams HTTP support (com.typesafe.netty:netty-reactive-streams-http:2.0.5 - https://github.com/playframework/netty-reactive-streams/netty-reactive-streams-http) (Apache License, Version 2.0) Netty Reactive Streams Implementation (com.typesafe.netty:netty-reactive-streams:2.0.5 - https://github.com/playframework/netty-reactive-streams/netty-reactive-streams) (Apache License, Version 2.0) Netty/Buffer (io.netty:netty-buffer:4.1.72.Final - https://netty.io/netty-buffer/) @@ -350,19 +354,20 @@ Lists of 413 third-party dependencies. (Apache License, Version 2.0) Objenesis (org.objenesis:objenesis:3.2 - http://objenesis.org/objenesis) (The Apache Software License, Version 2.0) okhttp (com.squareup.okhttp3:okhttp:4.10.0 - https://square.github.io/okhttp/) (The Apache Software License, Version 2.0) okio (com.squareup.okio:okio-jvm:3.0.0 - https://github.com/square/okio/) - (Apache Software License, Version 2.0) openapi-java-client (io.dockstore:openapi-java-client:1.15.0-alpha.5 - no url defined) + (Apache Software License, Version 2.0) openapi-java-client (io.dockstore:openapi-java-client:1.15.0-alpha.13 - no url defined) (The Apache License, Version 2.0) OpenCensus (io.opencensus:opencensus-api:0.31.0 - https://github.com/census-instrumentation/opencensus-java) (Apache 2) opencsv (com.opencsv:opencsv:5.7.1 - http://opencsv.sf.net) + (Apache 2.0) optics (io.circe:circe-optics_2.13:0.14.1 - https://github.com/circe/circe-optics) (MIT License) ORCID - Model (org.orcid:orcid-model-jakarta:3.3.0 - https://github.com/ORCID/orcid-model) (The Apache License, Version 2.0) org.apiguardian:apiguardian-api (org.apiguardian:apiguardian-api:1.1.2 - https://github.com/apiguardian-team/apiguardian) - (The Apache License, Version 2.0) org.opentest4j:opentest4j (org.opentest4j:opentest4j:1.2.0 - https://github.com/ota4j-team/opentest4j) + (The Apache License, Version 2.0) org.opentest4j:opentest4j (org.opentest4j:opentest4j:1.3.0 - https://github.com/ota4j-team/opentest4j) (EPL 2.0) (GPL2 w/ CPE) OSGi resource locator (org.glassfish.hk2:osgi-resource-locator:1.0.3 - https://projects.eclipse.org/projects/ee4j/osgi-resource-locator) - (The Apache Software License, Version 2.0) PF4J (org.pf4j:pf4j:3.2.0 - http://nexus.sonatype.org/oss-repository-hosting.html/pf4j-parent/pf4j) + (The Apache Software License, Version 2.0) PF4J (org.pf4j:pf4j:3.10.0 - https://pf4j.org/pf4j) (BSD-2-Clause) PostgreSQL JDBC Driver (org.postgresql:postgresql:42.4.3 - https://jdbc.postgresql.org) - (MIT) pprint_2.13 (com.lihaoyi:pprint_2.13:0.7.1 - https://github.com/lihaoyi/PPrint) + (MIT) pprint_2.13 (com.lihaoyi:pprint_2.13:0.7.3 - https://github.com/lihaoyi/PPrint) (The Apache Software License, Version 2.0) rank-eval (org.elasticsearch.plugin:rank-eval-client:7.10.2 - https://github.com/elastic/elasticsearch) (CC0) reactive-streams (org.reactivestreams:reactive-streams:1.0.3 - http://www.reactive-streams.org/) - (MIT) refined (eu.timepit:refined_2.13:0.9.28 - https://github.com/fthomas/refined) + (MIT) refined (eu.timepit:refined_2.13:0.10.1 - https://github.com/fthomas/refined) (The Apache Software License, Version 2.0) rest (org.elasticsearch.client:elasticsearch-rest-client:7.10.2 - https://github.com/elastic/elasticsearch) (The Apache Software License, Version 2.0) rest-high-level (org.elasticsearch.client:elasticsearch-rest-high-level-client:7.10.2 - https://github.com/elastic/elasticsearch) (The Apache Software License, Version 2.0) Retrofit (com.squareup.retrofit2:retrofit:2.9.0 - https://github.com/square/retrofit) @@ -371,45 +376,44 @@ Lists of 413 third-party dependencies. (Apache-2.0) Scala Library (org.scala-lang:scala-library:2.13.9 - https://www.scala-lang.org/) (Apache-2.0) Scala Reflect (org.scala-lang:scala-reflect:2.13.9 - https://www.scala-lang.org/) (Apache-2.0) scala-java8-compat (org.scala-lang.modules:scala-java8-compat_2.13:0.9.0 - http://www.scala-lang.org/) - (Apache 2.0 License) scala-logging (com.typesafe.scala-logging:scala-logging_2.13:3.9.4 - https://github.com/lightbend/scala-logging) + (Apache 2.0 License) scala-logging (com.typesafe.scala-logging:scala-logging_2.13:3.9.5 - https://github.com/lightbend/scala-logging) (Apache-2.0) scala-parser-combinators (org.scala-lang.modules:scala-parser-combinators_2.13:1.1.2 - http://www.scala-lang.org/) - (Apache-2.0) scala-xml (org.scala-lang.modules:scala-xml_2.13:1.3.0 - http://www.scala-lang.org/) - (MIT) scopt (com.github.scopt:scopt_2.13:4.0.1 - https://github.com/scopt/scopt) - (MIT) Sentry SDK (io.sentry:sentry:5.2.4 - https://github.com/getsentry/sentry-java) + (MIT) scopt (com.github.scopt:scopt_2.13:4.1.0 - https://github.com/scopt/scopt) + (MIT) Sentry SDK (io.sentry:sentry:5.7.4 - https://github.com/getsentry/sentry-java) (The Apache Software License, Version 2.0) server (org.elasticsearch:elasticsearch:7.10.2 - https://github.com/elastic/elasticsearch) (The MIT License) service (com.theokanning.openai-gpt3-java:service:0.16.1 - https://github.com/theokanning/openai-java) - (EPL 2.0) (GPL2 w/ CPE) ServiceLocator Default Implementation (org.glassfish.hk2:hk2-locator:3.0.3 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-locator) - (MIT License) SLF4J API Module (org.slf4j:slf4j-api:2.0.7 - http://www.slf4j.org) + (EPL 2.0) (GPL2 w/ CPE) ServiceLocator Default Implementation (org.glassfish.hk2:hk2-locator:3.0.4 - https://github.com/eclipse-ee4j/glassfish-hk2/hk2-locator) + (MIT License) SLF4J API Module (org.slf4j:slf4j-api:2.0.9 - http://www.slf4j.org) (Apache License, Version 2.0) SnakeYAML (org.yaml:snakeyaml:2.0 - https://bitbucket.org/snakeyaml/snakeyaml) (The Apache License, Version 2.0) software.amazon.ion:ion-java (software.amazon.ion:ion-java:1.0.1 - https://github.com/amznlabs/ion-java/) - (MIT) sourcecode_2.13 (com.lihaoyi:sourcecode_2.13:0.2.7 - https://github.com/lihaoyi/sourcecode) + (MIT) sourcecode_2.13 (com.lihaoyi:sourcecode_2.13:0.2.8 - https://github.com/lihaoyi/sourcecode) (Apache 2) spray-json (io.spray:spray-json_2.13:1.3.6 - https://github.com/spray/spray-json) (Apache-2.0) ssl-config-core (com.typesafe:ssl-config-core_2.13:0.3.8 - https://github.com/lightbend/ssl-config) (Apache License 2.0) swagger-annotations (io.swagger:swagger-annotations:1.6.8 - https://github.com/swagger-api/swagger-core/modules/swagger-annotations) - (Apache License 2.0) swagger-annotations-jakarta (io.swagger.core.v3:swagger-annotations-jakarta:2.2.9 - https://github.com/swagger-api/swagger-core/modules/swagger-annotations-jakarta) + (Apache License 2.0) swagger-annotations-jakarta (io.swagger.core.v3:swagger-annotations-jakarta:2.2.15 - https://github.com/swagger-api/swagger-core/modules/swagger-annotations-jakarta) (Apache License 2.0) swagger-core (io.swagger:swagger-core:1.6.8 - https://github.com/swagger-api/swagger-core/modules/swagger-core) - (Apache License 2.0) swagger-core-jakarta (io.swagger.core.v3:swagger-core-jakarta:2.2.9 - https://github.com/swagger-api/swagger-core/modules/swagger-core-jakarta) - (Apache License 2.0) swagger-integration-jakarta (io.swagger.core.v3:swagger-integration-jakarta:2.2.9 - https://github.com/swagger-api/swagger-core/modules/swagger-integration-jakarta) + (Apache License 2.0) swagger-core-jakarta (io.swagger.core.v3:swagger-core-jakarta:2.2.15 - https://github.com/swagger-api/swagger-core/modules/swagger-core-jakarta) + (Apache License 2.0) swagger-integration-jakarta (io.swagger.core.v3:swagger-integration-jakarta:2.2.15 - https://github.com/swagger-api/swagger-core/modules/swagger-integration-jakarta) (Apache Software License, Version 2.0) swagger-java-bitbucket-client (io.dockstore:swagger-java-bitbucket-client:2.0.3 - no url defined) - (Apache Software License, Version 2.0) swagger-java-client (io.dockstore:swagger-java-client:1.15.0-alpha.5 - no url defined) + (Apache Software License, Version 2.0) swagger-java-client (io.dockstore:swagger-java-client:1.15.0-alpha.13 - no url defined) (Apache Software License, Version 2.0) swagger-java-discourse-client (io.dockstore:swagger-java-discourse-client:2.0.1 - no url defined) (Apache Software License, Version 2.0) swagger-java-quay-client (io.dockstore:swagger-java-quay-client:2.0.2 - no url defined) (Apache Software License, Version 2.0) swagger-java-sam-client (io.dockstore:swagger-java-sam-client:2.0.2 - no url defined) (Apache Software License, Version 2.0) swagger-java-zenodo-client (io.dockstore:swagger-java-zenodo-client:2.0.2 - no url defined) - (Apache License 2.0) swagger-jaxrs2-jakarta (io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.9 - https://github.com/swagger-api/swagger-core/modules/swagger-jaxrs2-jakarta) - (Apache License 2.0) swagger-jaxrs2-servlet-initializer-jakarta (io.swagger.core.v3:swagger-jaxrs2-servlet-initializer-jakarta:2.2.9 - https://github.com/swagger-api/swagger-core/modules/swagger-jaxrs2-servlet-initializer-jakarta) + (Apache License 2.0) swagger-jaxrs2-jakarta (io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.15 - https://github.com/swagger-api/swagger-core/modules/swagger-jaxrs2-jakarta) + (Apache License 2.0) swagger-jaxrs2-servlet-initializer-jakarta (io.swagger.core.v3:swagger-jaxrs2-servlet-initializer-jakarta:2.2.15 - https://github.com/swagger-api/swagger-core/modules/swagger-jaxrs2-servlet-initializer-jakarta) (Apache License 2.0) swagger-models (io.swagger:swagger-models:1.6.8 - https://github.com/swagger-api/swagger-core/modules/swagger-models) - (Apache License 2.0) swagger-models-jakarta (io.swagger.core.v3:swagger-models-jakarta:2.2.9 - https://github.com/swagger-api/swagger-core/modules/swagger-models-jakarta) + (Apache License 2.0) swagger-models-jakarta (io.swagger.core.v3:swagger-models-jakarta:2.2.15 - https://github.com/swagger-api/swagger-core/modules/swagger-models-jakarta) (Common Public License Version 1.0) System Rules (com.github.stefanbirkner:system-rules:1.16.1 - http://stefanbirkner.github.io/system-rules/) (MIT License) System Stubs Core (uk.org.webcompere:system-stubs-core:2.0.1 - https://github.com/webcompere/system-stubs/system-stubs-core/) (MIT License) System Stubs Jupiter (uk.org.webcompere:system-stubs-jupiter:2.0.1 - https://github.com/webcompere/system-stubs/system-stubs-jupiter/) - (Apache License 2.0) Throttling Appender (io.dropwizard.logback:logback-throttling-appender:1.1.9 - https://github.com/dropwizard/logback-throttling-appender/) - (Apache License, Version 2.0) tomcat-jdbc (org.apache.tomcat:tomcat-jdbc:10.1.7 - https://tomcat.apache.org/) - (Apache License, Version 2.0) tomcat-juli (org.apache.tomcat:tomcat-juli:10.1.7 - https://tomcat.apache.org/) + (Apache License 2.0) Throttling Appender (io.dropwizard.logback:logback-throttling-appender:1.4.0 - https://github.com/dropwizard/logback-throttling-appender/) + (Apache License, Version 2.0) tomcat-jdbc (org.apache.tomcat:tomcat-jdbc:10.1.13 - https://tomcat.apache.org/) + (Apache License, Version 2.0) tomcat-juli (org.apache.tomcat:tomcat-juli:10.1.13 - https://tomcat.apache.org/) (GNU General Public License (GPLv3)) toolbackup (io.dockstore:toolbackup:1.15.0-SNAPSHOT - https://github.com/dockstore/dockstore-support) (GNU General Public License (GPLv3)) tooltester (io.dockstore:tooltester:1.15.0-SNAPSHOT - https://github.com/dockstore/dockstore-support) (Eclipse Distribution License - v 1.0) TXW2 Runtime (org.glassfish.jaxb:txw2:3.0.2 - https://eclipse-ee4j.github.io/jaxb-ri/) (GNU General Public License (GPLv3)) utils (io.dockstore:utils:1.15.0-SNAPSHOT - https://github.com/dockstore/dockstore-support) - (WDL License https://github.com/openwdl/wdl/blob/master/LICENSE) wdl-biscayne (org.broadinstitute:wdl-biscayne_2.13:84 - no url defined) - (WDL License https://github.com/openwdl/wdl/blob/master/LICENSE) wdl-draft2 (org.broadinstitute:wdl-draft2_2.13:84 - no url defined) - (WDL License https://github.com/openwdl/wdl/blob/master/LICENSE) wdl-draft3 (org.broadinstitute:wdl-draft3_2.13:84 - no url defined) + (WDL License https://github.com/openwdl/wdl/blob/master/LICENSE) wdl-biscayne (org.broadinstitute:wdl-biscayne_2.13:85 - no url defined) + (WDL License https://github.com/openwdl/wdl/blob/master/LICENSE) wdl-draft2 (org.broadinstitute:wdl-draft2_2.13:85 - no url defined) + (WDL License https://github.com/openwdl/wdl/blob/master/LICENSE) wdl-draft3 (org.broadinstitute:wdl-draft3_2.13:85 - no url defined) diff --git a/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/MetricsAggregatorS3Client.java b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/MetricsAggregatorS3Client.java index 09239967..92c5b479 100644 --- a/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/MetricsAggregatorS3Client.java +++ b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/MetricsAggregatorS3Client.java @@ -29,6 +29,7 @@ import io.dockstore.openapi.client.model.ExecutionsRequestBody; import io.dockstore.openapi.client.model.Metrics; import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; import io.dockstore.openapi.client.model.ValidationExecution; import java.io.IOException; import java.net.URISyntaxException; @@ -132,6 +133,7 @@ public void aggregateMetrics(ExtendedGa4GhApi extendedGa4GhApi) { private ExecutionsRequestBody getExecutions(String toolId, String versionName, String platform) throws IOException, JsonSyntaxException { List metricsDataList = metricsDataS3Client.getMetricsData(toolId, versionName, Partner.valueOf(platform)); List runExecutionsFromAllSubmissions = new ArrayList<>(); + List taskExecutionsFromAllSubmissions = new ArrayList<>(); List validationExecutionsFromAllSubmissions = new ArrayList<>(); List aggregatedExecutionsFromAllSubmissions = new ArrayList<>(); @@ -140,12 +142,14 @@ private ExecutionsRequestBody getExecutions(String toolId, String versionName, S metricsData.platform(), metricsData.fileName()); ExecutionsRequestBody executionsFromOneSubmission = GSON.fromJson(fileContent, ExecutionsRequestBody.class); runExecutionsFromAllSubmissions.addAll(executionsFromOneSubmission.getRunExecutions()); + taskExecutionsFromAllSubmissions.addAll(executionsFromOneSubmission.getTaskExecutions()); validationExecutionsFromAllSubmissions.addAll(executionsFromOneSubmission.getValidationExecutions()); aggregatedExecutionsFromAllSubmissions.addAll(executionsFromOneSubmission.getAggregatedExecutions()); } return new ExecutionsRequestBody() .runExecutions(runExecutionsFromAllSubmissions) + .taskExecutions(taskExecutionsFromAllSubmissions) .validationExecutions(validationExecutionsFromAllSubmissions) .aggregatedExecutions(aggregatedExecutionsFromAllSubmissions); } diff --git a/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/MoneyStatistics.java b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/MoneyStatistics.java index 87102583..6b172ad5 100644 --- a/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/MoneyStatistics.java +++ b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/MoneyStatistics.java @@ -7,7 +7,7 @@ * Calculates money statistics in USD using the Java Money library to preserve accuracy. */ public class MoneyStatistics extends Statistics { - private static String currency = "USD"; + public static final String CURRENCY = "USD"; private MoneyStatistics() { super(); @@ -48,7 +48,7 @@ public static MoneyStatistics createFromStatistics(List statist public Money calculateMinimum(List dataPoints) { return dataPoints.stream() .min(Money::compareTo) - .orElse(Money.of(0, currency)); + .orElse(Money.of(0, CURRENCY)); } /** @@ -60,7 +60,7 @@ public Money calculateMinimum(List dataPoints) { public Money calculateMaximum(List dataPoints) { return dataPoints.stream() .max(Money::compareTo) - .orElse(Money.of(0, currency)); + .orElse(Money.of(0, CURRENCY)); } /** @@ -70,7 +70,7 @@ public Money calculateMaximum(List dataPoints) { */ @Override public Money calculateAverage(List dataPoints) { - Money sum = dataPoints.stream().reduce(Money.of(0, currency), Money::add); + Money sum = dataPoints.stream().reduce(Money.of(0, CURRENCY), Money::add); return sum.divide(dataPoints.size()); } @@ -85,6 +85,6 @@ public Money calculateWeightedAverage(List> statisti double weight = (double)stat.getNumberOfDataPoints() / (double)totalNumberOfDataPoints; return stat.getAverage().multiply(weight); }) - .reduce(Money.of(0, currency), Money::add); + .reduce(Money.of(0, CURRENCY), Money::add); } } diff --git a/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/AggregationHelper.java b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/AggregationHelper.java index 8041f441..0d2c9ac6 100644 --- a/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/AggregationHelper.java +++ b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/AggregationHelper.java @@ -1,28 +1,17 @@ package io.dockstore.metricsaggregator.helper; import static io.dockstore.common.metrics.FormatCheckHelper.checkExecutionDateISO8601Format; -import static io.dockstore.common.metrics.FormatCheckHelper.checkExecutionTimeISO8601Format; -import static io.dockstore.common.metrics.FormatCheckHelper.isValidCurrencyCode; import static java.util.stream.Collectors.groupingBy; import io.dockstore.metricsaggregator.DoubleStatistics; -import io.dockstore.metricsaggregator.MoneyStatistics; -import io.dockstore.openapi.client.model.Cost; -import io.dockstore.openapi.client.model.CostMetric; -import io.dockstore.openapi.client.model.CpuMetric; import io.dockstore.openapi.client.model.ExecutionStatusMetric; -import io.dockstore.openapi.client.model.ExecutionTimeMetric; import io.dockstore.openapi.client.model.ExecutionsRequestBody; -import io.dockstore.openapi.client.model.MemoryMetric; import io.dockstore.openapi.client.model.Metrics; -import io.dockstore.openapi.client.model.RunExecution; import io.dockstore.openapi.client.model.ValidationExecution; import io.dockstore.openapi.client.model.ValidationStatusMetric; import io.dockstore.openapi.client.model.ValidatorInfo; import io.dockstore.openapi.client.model.ValidatorVersionInfo; -import java.time.Duration; import java.util.ArrayList; -import java.util.Collection; import java.util.Comparator; import java.util.Date; import java.util.HashMap; @@ -30,11 +19,8 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.function.Function; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; -import org.javamoney.moneta.Money; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,14 +39,14 @@ private AggregationHelper() { public static Optional getAggregatedMetrics(ExecutionsRequestBody allSubmissions) { Metrics aggregatedMetrics = new Metrics(); // Set run metrics - Optional aggregatedExecutionStatus = getAggregatedExecutionStatus(allSubmissions); + Optional aggregatedExecutionStatus = new ExecutionStatusAggregator().getAggregatedMetricFromAllSubmissions(allSubmissions); boolean containsRunMetrics = aggregatedExecutionStatus.isPresent(); if (aggregatedExecutionStatus.isPresent()) { aggregatedMetrics.setExecutionStatusCount(aggregatedExecutionStatus.get()); - getAggregatedExecutionTime(allSubmissions).ifPresent(aggregatedMetrics::setExecutionTime); - getAggregatedCpu(allSubmissions).ifPresent(aggregatedMetrics::setCpu); - getAggregatedMemory(allSubmissions).ifPresent(aggregatedMetrics::setMemory); - getAggregatedCost(allSubmissions).ifPresent(aggregatedMetrics::setCost); + new ExecutionTimeAggregator().getAggregatedMetricFromAllSubmissions(allSubmissions).ifPresent(aggregatedMetrics::setExecutionTime); + new CpuAggregator().getAggregatedMetricFromAllSubmissions(allSubmissions).ifPresent(aggregatedMetrics::setCpu); + new MemoryAggregator().getAggregatedMetricFromAllSubmissions(allSubmissions).ifPresent(aggregatedMetrics::setMemory); + new CostAggregator().getAggregatedMetricFromAllSubmissions(allSubmissions).ifPresent(aggregatedMetrics::setCost); } // Set validation metrics @@ -76,257 +62,6 @@ public static Optional getAggregatedMetrics(ExecutionsRequestBody allSu return Optional.empty(); } - /** - * Aggregate Execution Status metrics from all submissions by summing up the count of each Execution Status encountered in the run executions and aggregated metrics. - * @param allSubmissions - * @return - */ - public static Optional getAggregatedExecutionStatus(ExecutionsRequestBody allSubmissions) { - // Calculate the status count from the run executions submitted - Map executionsStatusCount = allSubmissions.getRunExecutions().stream() - .map(execution -> execution.getExecutionStatus().toString()) - .collect(groupingBy(Function.identity(), Collectors.reducing(0, e -> 1, Integer::sum))); - - // Calculate the status count from the aggregated metrics submitted - Map metricsStatusCount = allSubmissions.getAggregatedExecutions().stream() - .map(Metrics::getExecutionStatusCount) - .filter(Objects::nonNull) - .map(executionStatusMetric -> executionStatusMetric.getCount().entrySet()) - .flatMap(Collection::stream) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Integer::sum)); - - // Get the combined status count - Map statusCount = Stream.of(metricsStatusCount, executionsStatusCount) - .map(Map::entrySet) - .flatMap(Collection::stream) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Integer::sum)); - - if (statusCount.isEmpty()) { - return Optional.empty(); - } - // Don't need to set the other fields because the setter for count will calculate and set the other fields - return Optional.of(new ExecutionStatusMetric().count(statusCount)); - } - - /** - * Aggregate Execution Time metrics from all submissions by calculating the minimum, maximum, and average. - * @param allSubmissions - * @return - */ - public static Optional getAggregatedExecutionTime(ExecutionsRequestBody allSubmissions) { - // Get aggregated Execution Time metrics that were submitted to Dockstore - List executionTimeMetrics = allSubmissions.getAggregatedExecutions().stream() - .map(Metrics::getExecutionTime) - .filter(Objects::nonNull) - .collect(Collectors.toCollection(ArrayList::new)); - getAggregatedExecutionTimeFromExecutions(allSubmissions.getRunExecutions()).ifPresent(executionTimeMetrics::add); - - if (!executionTimeMetrics.isEmpty()) { - List statistics = executionTimeMetrics.stream() - .map(metric -> new DoubleStatistics(metric.getMinimum(), metric.getMaximum(), metric.getAverage(), metric.getNumberOfDataPointsForAverage())) - .toList(); - - DoubleStatistics newStatistic = DoubleStatistics.createFromStatistics(statistics); - return Optional.of(new ExecutionTimeMetric() - .minimum(newStatistic.getMinimum()) - .maximum(newStatistic.getMaximum()) - .average(newStatistic.getAverage()) - .numberOfDataPointsForAverage(newStatistic.getNumberOfDataPoints())); - } - - return Optional.empty(); - } - - /** - * Calculate the aggregated Execution Time metric from individual run executions by calculating the minimum, maximum, and average - * @param runExecutions - * @return - */ - public static Optional getAggregatedExecutionTimeFromExecutions(List runExecutions) { - List executionTimes = runExecutions.stream() - .map(RunExecution::getExecutionTime) - .filter(Objects::nonNull) - .toList(); - - boolean containsMalformedExecutionTimes = executionTimes.stream().anyMatch(executionTime -> checkExecutionTimeISO8601Format(executionTime).isEmpty()); - // This really shouldn't happen because the webservice validates that the ExecutionTime is in the correct format - if (containsMalformedExecutionTimes) { - return Optional.empty(); // Don't aggregate if there's malformed data - } - - List executionTimesInSeconds = executionTimes.stream() - .map(executionTime -> { - // Convert executionTime in ISO 8601 duration format to seconds - Duration parsedISO8601ExecutionTime = checkExecutionTimeISO8601Format(executionTime).get(); - return Long.valueOf(parsedISO8601ExecutionTime.toSeconds()).doubleValue(); - }) - .toList(); - - if (!executionTimesInSeconds.isEmpty()) { - DoubleStatistics statistics = new DoubleStatistics(executionTimesInSeconds); - return Optional.of(new ExecutionTimeMetric() - .minimum(statistics.getMinimum()) - .maximum(statistics.getMaximum()) - .average(statistics.getAverage()) - .numberOfDataPointsForAverage(statistics.getNumberOfDataPoints())); - } - return Optional.empty(); - } - - /** - * Aggregate CPU metrics from all submissions by calculating the minimum, maximum, and average. - * @param allSubmissions - * @return - */ - public static Optional getAggregatedCpu(ExecutionsRequestBody allSubmissions) { - // Get aggregated Execution Time metrics that were submitted to Dockstore - List cpuMetrics = allSubmissions.getAggregatedExecutions().stream() - .map(Metrics::getCpu) - .filter(Objects::nonNull) - .collect(Collectors.toCollection(ArrayList::new)); - getAggregatedCpuFromExecutions(allSubmissions.getRunExecutions()).ifPresent(cpuMetrics::add); - - if (!cpuMetrics.isEmpty()) { - List statistics = cpuMetrics.stream() - .map(metric -> new DoubleStatistics(metric.getMinimum(), metric.getMaximum(), metric.getAverage(), metric.getNumberOfDataPointsForAverage())).toList(); - DoubleStatistics newStatistic = DoubleStatistics.createFromStatistics(statistics); - return Optional.of(new CpuMetric() - .minimum(newStatistic.getMinimum()) - .maximum(newStatistic.getMaximum()) - .average(newStatistic.getAverage()) - .numberOfDataPointsForAverage(newStatistic.getNumberOfDataPoints())); - } - return Optional.empty(); - } - - /** - * Aggregate CPU metrics from the list of run executions by calculating the minimum, maximum, and average. - * @param executions - * @return - */ - public static Optional getAggregatedCpuFromExecutions(List executions) { - List cpuRequirements = executions.stream() - .map(RunExecution::getCpuRequirements) - .filter(Objects::nonNull) - .map(Integer::doubleValue) - .toList(); - if (!cpuRequirements.isEmpty()) { - DoubleStatistics statistics = new DoubleStatistics(cpuRequirements); - return Optional.of(new CpuMetric() - .minimum(statistics.getMinimum()) - .maximum(statistics.getMaximum()) - .average(statistics.getAverage()) - .numberOfDataPointsForAverage(statistics.getNumberOfDataPoints())); - } - return Optional.empty(); - } - - /** - * Aggregate CPU metrics from all submissions by calculating the minimum, maximum, and average. - * @param allSubmissions - * @return - */ - public static Optional getAggregatedMemory(ExecutionsRequestBody allSubmissions) { - // Get aggregated Execution Time metrics that were submitted to Dockstore - List memoryMetrics = allSubmissions.getAggregatedExecutions().stream() - .map(Metrics::getMemory) - .filter(Objects::nonNull) - .collect(Collectors.toCollection(ArrayList::new)); - getAggregatedMemoryFromExecutions(allSubmissions.getRunExecutions()).ifPresent(memoryMetrics::add); - - if (!memoryMetrics.isEmpty()) { - List statistics = memoryMetrics.stream() - .map(metric -> new DoubleStatistics(metric.getMinimum(), metric.getMaximum(), metric.getAverage(), metric.getNumberOfDataPointsForAverage())).toList(); - DoubleStatistics newStatistic = DoubleStatistics.createFromStatistics(statistics); - return Optional.of(new MemoryMetric() - .minimum(newStatistic.getMinimum()) - .maximum(newStatistic.getMaximum()) - .average(newStatistic.getAverage()) - .numberOfDataPointsForAverage(newStatistic.getNumberOfDataPoints())); - } - return Optional.empty(); - } - - /** - * Aggregate Memory metrics from the list of run executions by calculating the minimum, maximum, and average. - * @param executions - * @return - */ - public static Optional getAggregatedMemoryFromExecutions(List executions) { - List memoryRequirements = executions.stream() - .map(RunExecution::getMemoryRequirementsGB) - .filter(Objects::nonNull) - .toList(); - if (!memoryRequirements.isEmpty()) { - DoubleStatistics statistics = new DoubleStatistics(memoryRequirements); - return Optional.of(new MemoryMetric() - .minimum(statistics.getMinimum()) - .maximum(statistics.getMaximum()) - .average(statistics.getAverage()) - .numberOfDataPointsForAverage(statistics.getNumberOfDataPoints())); - } - return Optional.empty(); - } - - /** - * Aggregate Cost metrics from all submissions by calculating the minimum, maximum, and average. - * @param allSubmissions - * @return - */ - public static Optional getAggregatedCost(ExecutionsRequestBody allSubmissions) { - // Get aggregated cost metrics that were submitted to Dockstore - List costMetrics = allSubmissions.getAggregatedExecutions().stream() - .map(Metrics::getCost) - .filter(Objects::nonNull) - .collect(Collectors.toCollection(ArrayList::new)); - getAggregatedCostFromExecutions(allSubmissions.getRunExecutions()).ifPresent(costMetrics::add); - - if (!costMetrics.isEmpty()) { - List statistics = costMetrics.stream() - .map(metric -> new MoneyStatistics(Money.of(metric.getMinimum(), metric.getUnit()), Money.of(metric.getMaximum(), metric.getUnit()), Money.of(metric.getAverage(), - metric.getUnit()), metric.getNumberOfDataPointsForAverage())) - .toList(); - MoneyStatistics moneyStatistics = MoneyStatistics.createFromStatistics(statistics); - return Optional.of(new CostMetric() - .minimum(moneyStatistics.getMinimum().getNumber().doubleValue()) - .maximum(moneyStatistics.getMaximum().getNumber().doubleValue()) - .average(moneyStatistics.getAverage().getNumber().doubleValue()) - .numberOfDataPointsForAverage(moneyStatistics.getNumberOfDataPoints())); - } - return Optional.empty(); - } - - /** - * Aggregate Cost metrics from the list of run executions by calculating the minimum, maximum, and average. - * @param executions - * @return - */ - public static Optional getAggregatedCostFromExecutions(List executions) { - List submittedCosts = executions.stream() - .map(RunExecution::getCost) - .filter(Objects::nonNull) - .toList(); - - boolean containsMalformedCurrencies = submittedCosts.stream().anyMatch(cost -> !isValidCurrencyCode(cost.getCurrency())); - // This shouldn't happen until we allow users to submit any currency they want - if (containsMalformedCurrencies) { - return Optional.empty(); // Don't aggregate if there's malformed data - } - - if (!submittedCosts.isEmpty()) { - List costs = submittedCosts.stream() - .map(cost -> Money.of(cost.getValue(), cost.getCurrency())) - .toList(); - MoneyStatistics statistics = new MoneyStatistics(costs); - return Optional.of(new CostMetric() - .minimum(statistics.getMinimum().getNumber().doubleValue()) - .maximum(statistics.getMaximum().getNumber().doubleValue()) - .average(statistics.getAverage().getNumber().doubleValue()) - .numberOfDataPointsForAverage(statistics.getNumberOfDataPoints())); - } - return Optional.empty(); - } - /** * Aggregate Validation metrics from the list of validation executions by retrieving the validation information for the most recent execution of * each validator tool version. diff --git a/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/CostAggregator.java b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/CostAggregator.java new file mode 100644 index 00000000..3b76a3be --- /dev/null +++ b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/CostAggregator.java @@ -0,0 +1,91 @@ +package io.dockstore.metricsaggregator.helper; + +import static io.dockstore.common.metrics.FormatCheckHelper.isValidCurrencyCode; +import static io.dockstore.metricsaggregator.MoneyStatistics.CURRENCY; + +import io.dockstore.metricsaggregator.MoneyStatistics; +import io.dockstore.openapi.client.model.Cost; +import io.dockstore.openapi.client.model.CostMetric; +import io.dockstore.openapi.client.model.Metrics; +import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.javamoney.moneta.Money; + +public class CostAggregator implements RunExecutionAggregator { + @Override + public CostMetric getMetricFromMetrics(Metrics metrics) { + return metrics.getCost(); + } + + @Override + public Cost getMetricFromRunExecution(RunExecution runExecution) { + return runExecution.getCost(); + } + + @Override + public Optional getWorkflowExecutionFromTaskExecutions(TaskExecutions taskExecutionsForOneWorkflowRun) { + final List taskExecutions = taskExecutionsForOneWorkflowRun.getTaskExecutions(); + if (taskExecutions != null && taskExecutions.stream().map(RunExecution::getCost).allMatch(Objects::nonNull)) { + // Get the overall cost by summing up the cost of each task + List taskCosts = taskExecutions.stream() + .map(RunExecution::getCost) + .toList(); + boolean containsMalformedCurrencies = taskCosts.stream().anyMatch(cost -> !isValidCurrencyCode(cost.getCurrency())); + // This shouldn't happen until we allow users to submit any currency they want + if (!containsMalformedCurrencies && !taskCosts.isEmpty()) { + Money totalCost = taskCosts.stream() + .map(cost -> Money.of(cost.getValue(), cost.getCurrency())) + .reduce(Money.of(0, CURRENCY), Money::add); + return Optional.of(new RunExecution().cost(new Cost().value(totalCost.getNumber().doubleValue()))); + } + } + return Optional.empty(); + } + + @Override + public Optional getAggregatedMetricFromWorkflowExecutions(List workflowExecutions) { + List submittedCosts = getNonNullMetricsFromRunExecutions(workflowExecutions); + + boolean containsMalformedCurrencies = submittedCosts.stream().anyMatch(cost -> !isValidCurrencyCode(cost.getCurrency())); + // This shouldn't happen until we allow users to submit any currency they want + if (containsMalformedCurrencies) { + return Optional.empty(); // Don't aggregate if there's malformed data + } + + if (!submittedCosts.isEmpty()) { + List costs = submittedCosts.stream() + .map(cost -> Money.of(cost.getValue(), cost.getCurrency())) + .toList(); + MoneyStatistics statistics = new MoneyStatistics(costs); + return Optional.of(new CostMetric() + .minimum(statistics.getMinimum().getNumber().doubleValue()) + .maximum(statistics.getMaximum().getNumber().doubleValue()) + .average(statistics.getAverage().getNumber().doubleValue()) + .numberOfDataPointsForAverage(statistics.getNumberOfDataPoints())); + } + return Optional.empty(); + } + + @Override + public Optional getAggregatedMetricsFromAggregatedMetrics(List aggregatedMetrics) { + if (!aggregatedMetrics.isEmpty()) { + List statistics = aggregatedMetrics.stream() + .map(metric -> new MoneyStatistics( + Money.of(metric.getMinimum(), metric.getUnit()), + Money.of(metric.getMaximum(), metric.getUnit()), + Money.of(metric.getAverage(), metric.getUnit()), + metric.getNumberOfDataPointsForAverage())) + .toList(); + MoneyStatistics moneyStatistics = MoneyStatistics.createFromStatistics(statistics); + return Optional.of(new CostMetric() + .minimum(moneyStatistics.getMinimum().getNumber().doubleValue()) + .maximum(moneyStatistics.getMaximum().getNumber().doubleValue()) + .average(moneyStatistics.getAverage().getNumber().doubleValue()) + .numberOfDataPointsForAverage(moneyStatistics.getNumberOfDataPoints())); + } + return Optional.empty(); + } +} diff --git a/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/CpuAggregator.java b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/CpuAggregator.java new file mode 100644 index 00000000..1254a788 --- /dev/null +++ b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/CpuAggregator.java @@ -0,0 +1,73 @@ +package io.dockstore.metricsaggregator.helper; + +import io.dockstore.metricsaggregator.DoubleStatistics; +import io.dockstore.openapi.client.model.CpuMetric; +import io.dockstore.openapi.client.model.Metrics; +import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +/** + * Aggregate CPU metrics by calculating the minimum, maximum, and average. + * @return + */ +public class CpuAggregator implements RunExecutionAggregator { + @Override + public CpuMetric getMetricFromMetrics(Metrics metrics) { + return metrics.getCpu(); + } + + @Override + public Integer getMetricFromRunExecution(RunExecution runExecution) { + return runExecution.getCpuRequirements(); + } + + @Override + public Optional getWorkflowExecutionFromTaskExecutions(TaskExecutions taskExecutionsForOneWorkflowRun) { + final List taskExecutions = taskExecutionsForOneWorkflowRun.getTaskExecutions(); + if (taskExecutions != null && taskExecutions.stream().map(RunExecution::getCpuRequirements).allMatch(Objects::nonNull)) { + // Get the overall CPU requirement by getting the maximum CPU value used + final Optional maxCpuRequirement = taskExecutions.stream() + .map(RunExecution::getCpuRequirements) + .filter(Objects::nonNull) + .max(Integer::compareTo); + if (maxCpuRequirement.isPresent()) { + return Optional.ofNullable(new RunExecution().cpuRequirements(maxCpuRequirement.get())); + } + } + return Optional.empty(); + } + + @Override + public Optional getAggregatedMetricFromWorkflowExecutions(List workflowExecutions) { + List cpuRequirements = getNonNullMetricsFromRunExecutions(workflowExecutions).stream() + .map(Integer::doubleValue) + .toList(); + if (!cpuRequirements.isEmpty()) { + DoubleStatistics statistics = new DoubleStatistics(cpuRequirements); + return Optional.of(new CpuMetric() + .minimum(statistics.getMinimum()) + .maximum(statistics.getMaximum()) + .average(statistics.getAverage()) + .numberOfDataPointsForAverage(statistics.getNumberOfDataPoints())); + } + return Optional.empty(); + } + + @Override + public Optional getAggregatedMetricsFromAggregatedMetrics(List aggregatedMetrics) { + if (!aggregatedMetrics.isEmpty()) { + List statistics = aggregatedMetrics.stream() + .map(metric -> new DoubleStatistics(metric.getMinimum(), metric.getMaximum(), metric.getAverage(), metric.getNumberOfDataPointsForAverage())).toList(); + DoubleStatistics newStatistic = DoubleStatistics.createFromStatistics(statistics); + return Optional.of(new CpuMetric() + .minimum(newStatistic.getMinimum()) + .maximum(newStatistic.getMaximum()) + .average(newStatistic.getAverage()) + .numberOfDataPointsForAverage(newStatistic.getNumberOfDataPoints())); + } + return Optional.empty(); + } +} diff --git a/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/ExecutionStatusAggregator.java b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/ExecutionStatusAggregator.java new file mode 100644 index 00000000..ec62f859 --- /dev/null +++ b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/ExecutionStatusAggregator.java @@ -0,0 +1,84 @@ +package io.dockstore.metricsaggregator.helper; + +import static java.util.stream.Collectors.groupingBy; + +import io.dockstore.openapi.client.model.ExecutionStatusMetric; +import io.dockstore.openapi.client.model.Metrics; +import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.RunExecution.ExecutionStatusEnum; +import io.dockstore.openapi.client.model.TaskExecutions; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * Aggregate Execution Status metrics by summing up the count of each Execution Status. + */ +public class ExecutionStatusAggregator implements RunExecutionAggregator { + + @Override + public ExecutionStatusMetric getMetricFromMetrics(Metrics metrics) { + return metrics.getExecutionStatusCount(); + } + + @Override + public ExecutionStatusEnum getMetricFromRunExecution(RunExecution runExecution) { + return runExecution.getExecutionStatus(); + } + + @Override + public Optional getWorkflowExecutionFromTaskExecutions(TaskExecutions taskExecutionsForOneWorkflowRun) { + final List taskExecutions = taskExecutionsForOneWorkflowRun.getTaskExecutions(); + if (taskExecutions != null && taskExecutions.stream().map(RunExecution::getExecutionStatus).allMatch(Objects::nonNull)) { + if (taskExecutions.stream().allMatch(taskRunExecution -> taskRunExecution.getExecutionStatus() == ExecutionStatusEnum.SUCCESSFUL)) { + // All executions were successful + return Optional.of(new RunExecution().executionStatus(ExecutionStatusEnum.SUCCESSFUL)); + } else { + // If there were failed executions, set the overall status to the most frequent failed status + Optional mostFrequentFailedStatus = taskExecutions.stream() + .map(RunExecution::getExecutionStatus) + .filter(taskExecutionStatus -> taskExecutionStatus != ExecutionStatusEnum.SUCCESSFUL) + .collect(groupingBy(Function.identity(), Collectors.reducing(0, e -> 1, Integer::sum))) + .entrySet() + .stream() + .max(Entry.comparingByValue()) + .map(Entry::getKey); + if (mostFrequentFailedStatus.isPresent()) { + return Optional.of(new RunExecution().executionStatus(mostFrequentFailedStatus.get())); + } + } + } + return Optional.empty(); + } + + @Override + public Optional getAggregatedMetricFromWorkflowExecutions(List workflowExecutions) { + if (!workflowExecutions.isEmpty()) { + // Calculate the status count from the workflow executions submitted + Map executionsStatusCount = workflowExecutions.stream() + .map(execution -> execution.getExecutionStatus().toString()) + .collect(groupingBy(Function.identity(), Collectors.reducing(0, e -> 1, Integer::sum))); + return Optional.of(new ExecutionStatusMetric().count(executionsStatusCount)); + } + return Optional.empty(); + } + + @Override + public Optional getAggregatedMetricsFromAggregatedMetrics(List aggregatedMetrics) { + if (!aggregatedMetrics.isEmpty()) { + Map statusCount = aggregatedMetrics.stream() + .filter(Objects::nonNull) + .map(executionStatusMetric -> executionStatusMetric.getCount().entrySet()) + .flatMap(Collection::stream) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Integer::sum)); + + return statusCount.isEmpty() ? Optional.empty() : Optional.of(new ExecutionStatusMetric().count(statusCount)); + } + return Optional.empty(); + } +} diff --git a/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/ExecutionTimeAggregator.java b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/ExecutionTimeAggregator.java new file mode 100644 index 00000000..0f05c4cd --- /dev/null +++ b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/ExecutionTimeAggregator.java @@ -0,0 +1,116 @@ +package io.dockstore.metricsaggregator.helper; + +import static io.dockstore.common.metrics.FormatCheckHelper.checkExecutionDateISO8601Format; +import static io.dockstore.common.metrics.FormatCheckHelper.checkExecutionTimeISO8601Format; + +import io.dockstore.metricsaggregator.DoubleStatistics; +import io.dockstore.openapi.client.model.ExecutionTimeMetric; +import io.dockstore.openapi.client.model.Metrics; +import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +/** + * Aggregate Execution Time metrics by calculating the minimum, maximum, and average. + */ +public final class ExecutionTimeAggregator implements RunExecutionAggregator { + @Override + public String getMetricFromRunExecution(RunExecution runExecution) { + return runExecution.getExecutionTime(); + } + + @Override + public ExecutionTimeMetric getMetricFromMetrics(Metrics metrics) { + return metrics.getExecutionTime(); + } + + @Override + public Optional getWorkflowExecutionFromTaskExecutions(TaskExecutions taskExecutionsForOneWorkflowRun) { + final List taskExecutions = taskExecutionsForOneWorkflowRun.getTaskExecutions(); + if (taskExecutions != null && taskExecutions.stream().map(RunExecution::getExecutionTime).allMatch(Objects::nonNull)) { + // We cannot calculate the overall total time from RunExecution's executionTime, which is in ISO 8601 duration format. + // Calculate a best guess using RunExecution's dateExecuted, which is in ISO 8601 date format + if (taskExecutions.size() == 1 && taskExecutions.get(0).getExecutionTime() != null) { + // If there's only one task, set the workflow-level execution time to be the execution time of the single task + return Optional.of(new RunExecution().executionTime(taskExecutions.get(0).getExecutionTime())); + + // Calculate a duration if all task executions have a valid dateExecuted + } else if (taskExecutions.stream().allMatch(execution -> checkExecutionDateISO8601Format(execution.getDateExecuted()).isPresent())) { + // Find the earliest date executed and latest date executed to calculate a duration estimate + final Optional earliestTaskExecutionDate = taskExecutions.stream() + .map(execution -> checkExecutionDateISO8601Format(execution.getDateExecuted()).get()) + .min(Date::compareTo); + final Optional latestTaskExecutionDate = taskExecutions.stream() + .map(execution -> checkExecutionDateISO8601Format(execution.getDateExecuted()).get()) + .max(Date::compareTo); + final Optional latestTaskExecuted = taskExecutions.stream() + .max(Comparator.comparing(execution -> checkExecutionDateISO8601Format(execution.getDateExecuted()).get(), Date::compareTo)); + + if (earliestTaskExecutionDate.isPresent() && latestTaskExecutionDate.isPresent() && latestTaskExecuted.isPresent()) { + // Execution dates are the start dates, calculate a rough duration from the execution dates of the earliest and latest tasks + long durationInMs = latestTaskExecutionDate.get().getTime() - earliestTaskExecutionDate.get().getTime(); + Duration duration = Duration.of(durationInMs, ChronoUnit.MILLIS); + // If the execution time of the latest task is present, add that to the duration to account for the amount of time the last task took to execute + Optional latestTaskExecutionTime = checkExecutionTimeISO8601Format(latestTaskExecuted.get().getExecutionTime()); + if (latestTaskExecutionTime.isPresent()) { + duration = duration.plus(latestTaskExecutionTime.get()); + } + return Optional.of(new RunExecution().executionTime(duration.toString())); + } + } + } + return Optional.empty(); + } + + @Override + public Optional getAggregatedMetricFromWorkflowExecutions(List workflowExecutions) { + List executionTimes = getNonNullMetricsFromRunExecutions(workflowExecutions); + + boolean containsMalformedExecutionTimes = executionTimes.stream().anyMatch(executionTime -> checkExecutionTimeISO8601Format(executionTime).isEmpty()); + // This really shouldn't happen because the webservice validates that the ExecutionTime is in the correct format + if (containsMalformedExecutionTimes) { + return Optional.empty(); // Don't aggregate if there's malformed data + } + + List executionTimesInSeconds = executionTimes.stream() + .map(executionTime -> { + // Convert executionTime in ISO 8601 duration format to seconds + Duration parsedISO8601ExecutionTime = checkExecutionTimeISO8601Format(executionTime).get(); + return (double) parsedISO8601ExecutionTime.toSeconds(); + }) + .toList(); + + if (!executionTimesInSeconds.isEmpty()) { + DoubleStatistics statistics = new DoubleStatistics(executionTimesInSeconds); + return Optional.of(new ExecutionTimeMetric() + .minimum(statistics.getMinimum()) + .maximum(statistics.getMaximum()) + .average(statistics.getAverage()) + .numberOfDataPointsForAverage(statistics.getNumberOfDataPoints())); + } + return Optional.empty(); + } + + @Override + public Optional getAggregatedMetricsFromAggregatedMetrics(List aggregatedMetrics) { + if (!aggregatedMetrics.isEmpty()) { + List statistics = aggregatedMetrics.stream() + .map(metric -> new DoubleStatistics(metric.getMinimum(), metric.getMaximum(), metric.getAverage(), metric.getNumberOfDataPointsForAverage())) + .toList(); + + DoubleStatistics newStatistic = DoubleStatistics.createFromStatistics(statistics); + return Optional.of(new ExecutionTimeMetric() + .minimum(newStatistic.getMinimum()) + .maximum(newStatistic.getMaximum()) + .average(newStatistic.getAverage()) + .numberOfDataPointsForAverage(newStatistic.getNumberOfDataPoints())); + } + return Optional.empty(); + } +} diff --git a/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/MemoryAggregator.java b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/MemoryAggregator.java new file mode 100644 index 00000000..07a34deb --- /dev/null +++ b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/MemoryAggregator.java @@ -0,0 +1,70 @@ +package io.dockstore.metricsaggregator.helper; + +import io.dockstore.metricsaggregator.DoubleStatistics; +import io.dockstore.openapi.client.model.MemoryMetric; +import io.dockstore.openapi.client.model.Metrics; +import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +/** + * Aggregate Memory metrics by calculating the minimum, maximum, and average. + */ +public class MemoryAggregator implements RunExecutionAggregator { + @Override + public MemoryMetric getMetricFromMetrics(Metrics metrics) { + return metrics.getMemory(); + } + + @Override + public Double getMetricFromRunExecution(RunExecution runExecution) { + return runExecution.getMemoryRequirementsGB(); + } + + @Override + public Optional getWorkflowExecutionFromTaskExecutions(TaskExecutions taskExecutionsForOneWorkflowRun) { + final List taskExecutions = taskExecutionsForOneWorkflowRun.getTaskExecutions(); + if (taskExecutions != null && taskExecutions.stream().map(RunExecution::getMemoryRequirementsGB).allMatch(Objects::nonNull)) { + // Get the overall memory requirement by getting the maximum memory value used + final Optional maxMemoryRequirement = taskExecutions.stream() + .map(RunExecution::getMemoryRequirementsGB) + .filter(Objects::nonNull) + .max(Double::compareTo); + if (maxMemoryRequirement.isPresent()) { + return Optional.of(new RunExecution().memoryRequirementsGB(maxMemoryRequirement.get())); + } + } + return Optional.empty(); + } + + @Override + public Optional getAggregatedMetricFromWorkflowExecutions(List workflowExecutions) { + List memoryRequirements = getNonNullMetricsFromRunExecutions(workflowExecutions); + if (!memoryRequirements.isEmpty()) { + DoubleStatistics statistics = new DoubleStatistics(memoryRequirements); + return Optional.of(new MemoryMetric() + .minimum(statistics.getMinimum()) + .maximum(statistics.getMaximum()) + .average(statistics.getAverage()) + .numberOfDataPointsForAverage(statistics.getNumberOfDataPoints())); + } + return Optional.empty(); + } + + @Override + public Optional getAggregatedMetricsFromAggregatedMetrics(List aggregatedMetrics) { + if (!aggregatedMetrics.isEmpty()) { + List statistics = aggregatedMetrics.stream() + .map(metric -> new DoubleStatistics(metric.getMinimum(), metric.getMaximum(), metric.getAverage(), metric.getNumberOfDataPointsForAverage())).toList(); + DoubleStatistics newStatistic = DoubleStatistics.createFromStatistics(statistics); + return Optional.of(new MemoryMetric() + .minimum(newStatistic.getMinimum()) + .maximum(newStatistic.getMaximum()) + .average(newStatistic.getAverage()) + .numberOfDataPointsForAverage(newStatistic.getNumberOfDataPoints())); + } + return Optional.empty(); + } +} diff --git a/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/RunExecutionAggregator.java b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/RunExecutionAggregator.java new file mode 100644 index 00000000..2d592eb2 --- /dev/null +++ b/metricsaggregator/src/main/java/io/dockstore/metricsaggregator/helper/RunExecutionAggregator.java @@ -0,0 +1,97 @@ +package io.dockstore.metricsaggregator.helper; + +import io.dockstore.openapi.client.model.ExecutionsRequestBody; +import io.dockstore.openapi.client.model.Metrics; +import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * An interface defining the methods needed to aggregate RunExecution's + * @param The aggregated metric from Metrics + * @param The execution metric from RunExecution + */ +public interface RunExecutionAggregator { + + M getMetricFromMetrics(Metrics metrics); + E getMetricFromRunExecution(RunExecution runExecution); + + /** + * Aggregates TaskExecutions that belong to a single workflow run into a workflow-level RunExecution + * @param taskExecutionsForOneWorkflowRun + * @return + */ + Optional getWorkflowExecutionFromTaskExecutions(TaskExecutions taskExecutionsForOneWorkflowRun); + + /** + * Aggregates workflow executions into an aggregated metric. + * @param workflowExecutions + * @return + */ + Optional getAggregatedMetricFromWorkflowExecutions(List workflowExecutions); + + /** + * Aggregates a list of aggregated metrics into one aggregated metric. + * @param aggregatedMetrics + * @return + */ + Optional getAggregatedMetricsFromAggregatedMetrics(List aggregatedMetrics); + + /** + * Returns a list of RunExecutions where the execution metric is not null. + * @param runExecutions + * @return + */ + default List getNonNullMetricsFromRunExecutions(List runExecutions) { + return runExecutions.stream() + .map(this::getMetricFromRunExecution) + .filter(Objects::nonNull) + .toList(); + } + + /** + * Aggregate metrics from all submissions in the ExecutionsRequestBody. + * This method uses the runExecutions, taskExecutions, and aggregatedExecutions from ExecutionRequestBody to create an aggregated metric. + * Metrics are aggregated by: + *
    + *
  1. Aggregating task executions, provided via ExecutionRequestBody.taskExecutions, into workflow executions.
  2. + *
  3. Aggregating workflow executions,submitted via ExecutionRequestBody.runExecutions and workflow executions that were aggregated from task executions, into an aggregated metric. + *
  4. Aggregating the list of aggregated metrics, submitted via ExecutionRequestBody.aggregatedExecutions and the aggregated metric that was aggregated from workflow executions, into one aggregated metric.
  5. + *
+ * @param allSubmissions + * @return + */ + default Optional getAggregatedMetricFromAllSubmissions(ExecutionsRequestBody allSubmissions) { + final List workflowExecutions = new ArrayList<>(allSubmissions.getRunExecutions()); + + // If task executions are present, calculate the workflow RunExecution containing the overall workflow-level execution time for each list of tasks + if (!allSubmissions.getTaskExecutions().isEmpty()) { + final List calculatedWorkflowExecutionsFromTasks = allSubmissions.getTaskExecutions().stream() + .map(this::getWorkflowExecutionFromTaskExecutions) + .filter(Optional::isPresent) + .map(Optional::get) + .toList(); + workflowExecutions.addAll(calculatedWorkflowExecutionsFromTasks); + } + + // Get aggregated metrics that were submitted to Dockstore + List aggregatedMetrics = allSubmissions.getAggregatedExecutions().stream() + .map(this::getMetricFromMetrics) + .filter(Objects::nonNull) + .collect(Collectors.toCollection(ArrayList::new)); + + // Aggregate workflow executions into one metric and add it to the list of aggregated metrics + Optional aggregatedMetricFromWorkflowExecutions = getAggregatedMetricFromWorkflowExecutions(workflowExecutions); + aggregatedMetricFromWorkflowExecutions.ifPresent(aggregatedMetrics::add); + + if (!aggregatedMetrics.isEmpty()) { + // Calculate the new aggregated metric from the list of aggregated metrics + return getAggregatedMetricsFromAggregatedMetrics(aggregatedMetrics); + } + return Optional.empty(); + } +} diff --git a/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/client/cli/MetricsAggregatorClientIT.java b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/client/cli/MetricsAggregatorClientIT.java index 85a9bd7a..5b3ee632 100644 --- a/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/client/cli/MetricsAggregatorClientIT.java +++ b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/client/cli/MetricsAggregatorClientIT.java @@ -54,6 +54,7 @@ import io.dockstore.openapi.client.model.ExecutionsRequestBody; import io.dockstore.openapi.client.model.Metrics; import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; import io.dockstore.openapi.client.model.ValidationExecution; import io.dockstore.openapi.client.model.ValidatorInfo; import io.dockstore.openapi.client.model.ValidatorVersionInfo; @@ -139,8 +140,8 @@ void testAggregateMetrics() { String id = "#workflow/" + workflow.getFullWorkflowPath(); String versionId = version.getName(); - // A successful run execution that ran for 5 minutes, requires 2 CPUs and 2 GBs of memory - List runExecutions = List.of(createRunExecution(SUCCESSFUL, "PT5M", 2, 2.0, new Cost().value(2.00), "us-central1")); + // A successful workflow run execution that ran for 5 minutes, requires 2 CPUs and 2 GBs of memory + List workflowExecutions = List.of(createRunExecution(SUCCESSFUL, "PT5M", 2, 2.0, new Cost().value(2.00), "us-central1")); // A successful miniwdl validation final String validatorToolVersion1 = "1.0"; ValidationExecution validationExecution1 = createValidationExecution(MINIWDL, validatorToolVersion1, true); @@ -148,8 +149,8 @@ void testAggregateMetrics() { ValidationExecution validationExecution2 = createValidationExecution(WOMTOOL, validatorToolVersion2, false); // Submit metrics for two platforms - extendedGa4GhApi.executionMetricsPost(new ExecutionsRequestBody().runExecutions(runExecutions).validationExecutions(List.of(validationExecution1)), platform1, id, versionId, ""); - extendedGa4GhApi.executionMetricsPost(new ExecutionsRequestBody().runExecutions(runExecutions).validationExecutions(List.of(validationExecution2)), platform2, id, versionId, ""); + extendedGa4GhApi.executionMetricsPost(new ExecutionsRequestBody().runExecutions(workflowExecutions).validationExecutions(List.of(validationExecution1)), platform1, id, versionId, ""); + extendedGa4GhApi.executionMetricsPost(new ExecutionsRequestBody().runExecutions(workflowExecutions).validationExecutions(List.of(validationExecution2)), platform2, id, versionId, ""); int expectedNumberOfPlatforms = 3; // 2 for platform1 and platform2, and 1 for ALL platforms // Aggregate metrics MetricsAggregatorClient.main(new String[] {"aggregate-metrics", "--config", CONFIG_FILE_PATH}); @@ -168,11 +169,11 @@ void testAggregateMetrics() { ValidatorInfo validationInfo; // A failed run execution that ran for 1 second, requires 2 CPUs and 4.5 GBs of memory - runExecutions = List.of(createRunExecution(FAILED_RUNTIME_INVALID, "PT1S", 4, 4.5, new Cost().value(2.00), "us-central1")); + workflowExecutions = List.of(createRunExecution(FAILED_RUNTIME_INVALID, "PT1S", 4, 4.5, new Cost().value(2.00), "us-central1")); // A failed miniwdl validation for the same validator version List validationExecutions = List.of(createValidationExecution(MINIWDL, "1.0", false)); - ExecutionsRequestBody executionsRequestBody = new ExecutionsRequestBody().runExecutions(runExecutions).validationExecutions(validationExecutions); - // Submit metrics for the same workflow version for platform 2 + ExecutionsRequestBody executionsRequestBody = new ExecutionsRequestBody().runExecutions(workflowExecutions).validationExecutions(validationExecutions); + // Submit metrics for the same workflow version for platform 1 extendedGa4GhApi.executionMetricsPost(executionsRequestBody, platform1, id, versionId, ""); // Aggregate metrics MetricsAggregatorClient.main(new String[] {"aggregate-metrics", "--config", CONFIG_FILE_PATH}); @@ -226,6 +227,52 @@ void testAggregateMetrics() { assertEquals(50d, validationInfo.getPassingRate()); assertEquals(2, validationInfo.getNumberOfRuns()); + // Submit two TaskExecutions, each one representing the task metrics for a single workflow execution + // A successful task execution that ran for 11 seconds, requires 6 CPUs and 5.5 GBs of memory. Signifies that this workflow execution only executed one task + TaskExecutions taskExecutions = new TaskExecutions().taskExecutions(List.of(createRunExecution(SUCCESSFUL, "PT11S", 6, 5.5, new Cost().value(2.00), "us-central1"))); + executionsRequestBody = new ExecutionsRequestBody().taskExecutions(List.of(taskExecutions)); + // Submit metrics for the same workflow version for platform 1 + extendedGa4GhApi.executionMetricsPost(executionsRequestBody, platform1, id, versionId, ""); + // Aggregate metrics + MetricsAggregatorClient.main(new String[] {"aggregate-metrics", "--config", CONFIG_FILE_PATH}); + // Get workflow version to verify aggregated metrics + workflow = workflowsApi.getPublishedWorkflow(32L, "metrics"); + version = workflow.getWorkflowVersions().stream().filter(v -> "master".equals(v.getName())).findFirst().orElse(null); + assertNotNull(version); + assertEquals(expectedNumberOfPlatforms, version.getMetricsByPlatform().size()); + platform1Metrics = version.getMetricsByPlatform().get(platform1); + + // This version now has three submissions of execution metrics data. Verify that the aggregated metrics are correct + assertEquals(2, platform1Metrics.getExecutionStatusCount().getNumberOfSuccessfulExecutions()); + assertEquals(1, platform1Metrics.getExecutionStatusCount().getNumberOfFailedExecutions()); + assertEquals(2, platform1Metrics.getExecutionStatusCount().getCount().get(SUCCESSFUL.name())); + assertEquals(1, platform1Metrics.getExecutionStatusCount().getCount().get(FAILED_RUNTIME_INVALID.name())); + assertFalse(platform1Metrics.getExecutionStatusCount().getCount().containsKey(FAILED_SEMANTIC_INVALID.name())); + + assertEquals(3, platform1Metrics.getCpu().getNumberOfDataPointsForAverage()); + assertEquals(2, platform1Metrics.getCpu().getMinimum()); + assertEquals(6, platform1Metrics.getCpu().getMaximum()); + assertEquals(4, platform1Metrics.getCpu().getAverage()); + assertNull(platform1Metrics.getCpu().getUnit()); + + assertEquals(3, platform1Metrics.getMemory().getNumberOfDataPointsForAverage()); + assertEquals(2, platform1Metrics.getMemory().getMinimum()); + assertEquals(5.5, platform1Metrics.getMemory().getMaximum()); + assertEquals(4, platform1Metrics.getMemory().getAverage()); + assertNotNull(platform1Metrics.getMemory().getUnit()); + + assertEquals(3, platform1Metrics.getCost().getNumberOfDataPointsForAverage()); + assertEquals(2, platform1Metrics.getCost().getMinimum()); + assertEquals(2, platform1Metrics.getCost().getMaximum()); + assertEquals(2, platform1Metrics.getCost().getAverage()); + assertNotNull(platform1Metrics.getCost().getUnit()); + + assertEquals(3, platform1Metrics.getExecutionTime().getNumberOfDataPointsForAverage()); + assertEquals(1, platform1Metrics.getExecutionTime().getMinimum()); + assertEquals(300, platform1Metrics.getExecutionTime().getMaximum()); + assertEquals(104, platform1Metrics.getExecutionTime().getAverage()); + assertNotNull(platform1Metrics.getExecutionTime().getUnit()); + testOverallAggregatedMetrics(version, validatorToolVersion1, validatorToolVersion2, platform1Metrics); } @@ -291,28 +338,31 @@ private static void testOverallAggregatedMetrics(WorkflowVersion version, String // Verify that the metrics aggregated across ALL platforms are correct Metrics overallMetrics = version.getMetricsByPlatform().get(Partner.ALL.name()); assertNotNull(overallMetrics); - assertEquals(2, overallMetrics.getExecutionStatusCount().getNumberOfSuccessfulExecutions()); + assertEquals(3, overallMetrics.getExecutionStatusCount().getNumberOfSuccessfulExecutions()); assertEquals(1, overallMetrics.getExecutionStatusCount().getNumberOfFailedExecutions()); - assertEquals(2, overallMetrics.getExecutionStatusCount().getCount().get(SUCCESSFUL.name())); + assertEquals(3, overallMetrics.getExecutionStatusCount().getCount().get(SUCCESSFUL.name())); assertEquals(1, platform1Metrics.getExecutionStatusCount().getCount().get(FAILED_RUNTIME_INVALID.name())); assertFalse(overallMetrics.getExecutionStatusCount().getCount().containsKey(FAILED_SEMANTIC_INVALID.name())); - assertEquals(3, overallMetrics.getCpu().getNumberOfDataPointsForAverage()); + // The CPU values submitted were 2, 2, 4, 6 + assertEquals(4, overallMetrics.getCpu().getNumberOfDataPointsForAverage()); assertEquals(2, overallMetrics.getCpu().getMinimum()); - assertEquals(4, overallMetrics.getCpu().getMaximum()); - assertEquals(2.6666666666666665, overallMetrics.getCpu().getAverage()); + assertEquals(6, overallMetrics.getCpu().getMaximum()); + assertEquals(3.5, overallMetrics.getCpu().getAverage()); assertNull(overallMetrics.getCpu().getUnit()); - assertEquals(3, overallMetrics.getMemory().getNumberOfDataPointsForAverage()); + // The memory values submitted were 2, 2, 4.5, 5.5 + assertEquals(4, overallMetrics.getMemory().getNumberOfDataPointsForAverage()); assertEquals(2, overallMetrics.getMemory().getMinimum()); - assertEquals(4.5, overallMetrics.getMemory().getMaximum()); - assertEquals(2.833333333333333, overallMetrics.getMemory().getAverage()); + assertEquals(5.5, overallMetrics.getMemory().getMaximum()); + assertEquals(3.5, overallMetrics.getMemory().getAverage()); assertNotNull(overallMetrics.getMemory().getUnit()); - assertEquals(3, overallMetrics.getExecutionTime().getNumberOfDataPointsForAverage()); + // The execution times submitted were PT5M, PT5M, PT1S, PT11S + assertEquals(4, overallMetrics.getExecutionTime().getNumberOfDataPointsForAverage()); assertEquals(1, overallMetrics.getExecutionTime().getMinimum()); assertEquals(300, overallMetrics.getExecutionTime().getMaximum()); - assertEquals(200.33333333333331, overallMetrics.getExecutionTime().getAverage()); + assertEquals(153, overallMetrics.getExecutionTime().getAverage()); assertNotNull(overallMetrics.getExecutionTime().getUnit()); assertEquals(2, overallMetrics.getValidationStatus().getValidatorTools().size()); diff --git a/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/AggregationHelperTest.java b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/AggregationHelperTest.java index ca255c2d..0f01f0f5 100644 --- a/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/AggregationHelperTest.java +++ b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/AggregationHelperTest.java @@ -19,6 +19,7 @@ import io.dockstore.openapi.client.model.MemoryMetric; import io.dockstore.openapi.client.model.Metrics; import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; import io.dockstore.openapi.client.model.ValidationExecution; import io.dockstore.openapi.client.model.ValidationStatusMetric; import io.dockstore.openapi.client.model.ValidatorInfo; @@ -34,13 +35,14 @@ class AggregationHelperTest { @Test void testGetAggregatedExecutionStatus() { + ExecutionStatusAggregator executionStatusAggregator = new ExecutionStatusAggregator(); ExecutionsRequestBody allSubmissions = new ExecutionsRequestBody(); - Optional executionStatusMetric = AggregationHelper.getAggregatedExecutionStatus(allSubmissions); + Optional executionStatusMetric = executionStatusAggregator.getAggregatedMetricFromAllSubmissions(allSubmissions); assertTrue(executionStatusMetric.isEmpty()); RunExecution submittedRunExecution = new RunExecution().executionStatus(SUCCESSFUL); allSubmissions = new ExecutionsRequestBody().runExecutions(List.of(submittedRunExecution)); - executionStatusMetric = AggregationHelper.getAggregatedExecutionStatus(allSubmissions); + executionStatusMetric = executionStatusAggregator.getAggregatedMetricFromAllSubmissions(allSubmissions); assertTrue(executionStatusMetric.isPresent()); assertEquals(1, executionStatusMetric.get().getCount().get(SUCCESSFUL.toString())); @@ -49,33 +51,70 @@ void testGetAggregatedExecutionStatus() { new ExecutionStatusMetric().count( Map.of(SUCCESSFUL.toString(), 10, FAILED_RUNTIME_INVALID.toString(), 1))); allSubmissions = new ExecutionsRequestBody().runExecutions(List.of(submittedRunExecution)).aggregatedExecutions(List.of(submittedAggregatedMetrics)); - executionStatusMetric = AggregationHelper.getAggregatedExecutionStatus(allSubmissions); + executionStatusMetric = executionStatusAggregator.getAggregatedMetricFromAllSubmissions(allSubmissions); assertTrue(executionStatusMetric.isPresent()); assertEquals(11, executionStatusMetric.get().getCount().get(SUCCESSFUL.toString())); assertEquals(1, executionStatusMetric.get().getCount().get(FAILED_RUNTIME_INVALID.toString())); assertNull(executionStatusMetric.get().getCount().get(FAILED_SEMANTIC_INVALID.toString()), "Should be null because the key doesn't exist in the count map"); + + // Aggregate submissions containing workflow run executions and task executions + submittedRunExecution = new RunExecution().executionStatus(SUCCESSFUL); + TaskExecutions taskExecutionsForOneWorkflowRun = new TaskExecutions().taskExecutions(List.of(submittedRunExecution)); + allSubmissions = new ExecutionsRequestBody().runExecutions(List.of(submittedRunExecution)).taskExecutions(List.of(taskExecutionsForOneWorkflowRun)); + executionStatusMetric = executionStatusAggregator.getAggregatedMetricFromAllSubmissions(allSubmissions); + assertTrue(executionStatusMetric.isPresent()); + assertEquals(2, executionStatusMetric.get().getCount().get(SUCCESSFUL.toString())); + // Submit one successful workflow execution and a list of task executions where the single task failed + taskExecutionsForOneWorkflowRun = new TaskExecutions().taskExecutions(List.of(new RunExecution().executionStatus(FAILED_RUNTIME_INVALID))); + allSubmissions = new ExecutionsRequestBody().runExecutions(List.of(submittedRunExecution)).taskExecutions(List.of(taskExecutionsForOneWorkflowRun)); + executionStatusMetric = executionStatusAggregator.getAggregatedMetricFromAllSubmissions(allSubmissions); + assertTrue(executionStatusMetric.isPresent()); + assertEquals(1, executionStatusMetric.get().getCount().get(SUCCESSFUL.toString())); + assertEquals(1, executionStatusMetric.get().getCount().get(FAILED_RUNTIME_INVALID.toString())); + // Submit one successful workflow execution and a list of task executions where there are two tasks that failed due to different reasons + taskExecutionsForOneWorkflowRun = new TaskExecutions().taskExecutions( + List.of(new RunExecution().executionStatus(FAILED_RUNTIME_INVALID), + new RunExecution().executionStatus(FAILED_SEMANTIC_INVALID))); + allSubmissions = new ExecutionsRequestBody().runExecutions(List.of(submittedRunExecution)).taskExecutions(List.of(taskExecutionsForOneWorkflowRun)); + executionStatusMetric = executionStatusAggregator.getAggregatedMetricFromAllSubmissions(allSubmissions); + assertTrue(executionStatusMetric.isPresent()); + assertEquals(1, executionStatusMetric.get().getCount().get(SUCCESSFUL.toString())); + // There should be 1 of either FAILED_RUNTIME_INVALID or FAILED_SEMANTIC_INVALID. + assertTrue(executionStatusMetric.get().getCount().containsKey(FAILED_RUNTIME_INVALID.toString()) || executionStatusMetric.get().getCount().containsKey(FAILED_SEMANTIC_INVALID.toString())); + // Submit one successful workflow execution and a list of task executions where there are 3 tasks that failed due to different reasons + taskExecutionsForOneWorkflowRun = new TaskExecutions().taskExecutions( + List.of(new RunExecution().executionStatus(FAILED_RUNTIME_INVALID), + new RunExecution().executionStatus(FAILED_RUNTIME_INVALID), + new RunExecution().executionStatus(FAILED_SEMANTIC_INVALID))); + allSubmissions = new ExecutionsRequestBody().runExecutions(List.of(submittedRunExecution)).taskExecutions(List.of(taskExecutionsForOneWorkflowRun)); + executionStatusMetric = executionStatusAggregator.getAggregatedMetricFromAllSubmissions(allSubmissions); + assertTrue(executionStatusMetric.isPresent()); + assertEquals(1, executionStatusMetric.get().getCount().get(SUCCESSFUL.toString())); + // There should be one count of FAILED_RUNTIME_INVALID because it's the most frequent failed status in the list of task executions + assertEquals(1, executionStatusMetric.get().getCount().get(FAILED_RUNTIME_INVALID.toString())); } @Test void testGetAggregatedExecutionTime() { + ExecutionTimeAggregator executionTimeAggregator = new ExecutionTimeAggregator(); List badExecutions = new ArrayList<>(); - Optional executionTimeMetric = AggregationHelper.getAggregatedExecutionTime(new ExecutionsRequestBody().runExecutions(badExecutions)); + Optional executionTimeMetric = executionTimeAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(badExecutions)); assertTrue(executionTimeMetric.isEmpty()); // Add an execution that doesn't have execution time data badExecutions.add(new RunExecution().executionStatus(SUCCESSFUL)); - executionTimeMetric = AggregationHelper.getAggregatedExecutionTime(new ExecutionsRequestBody().runExecutions(badExecutions)); + executionTimeMetric = executionTimeAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(badExecutions)); assertTrue(executionTimeMetric.isEmpty()); // Add an execution with malformed execution time data badExecutions.add(new RunExecution().executionStatus(SUCCESSFUL).executionTime("1 second")); - executionTimeMetric = AggregationHelper.getAggregatedExecutionTime(new ExecutionsRequestBody().runExecutions(badExecutions)); + executionTimeMetric = executionTimeAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(badExecutions)); assertTrue(executionTimeMetric.isEmpty()); // Add an execution with execution time final int timeInSeconds = 10; List executions = List.of(new RunExecution().executionStatus(SUCCESSFUL).executionTime(String.format("PT%dS", timeInSeconds))); - executionTimeMetric = AggregationHelper.getAggregatedExecutionTime(new ExecutionsRequestBody().runExecutions(executions)); + executionTimeMetric = executionTimeAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions)); assertTrue(executionTimeMetric.isPresent()); assertEquals(timeInSeconds, executionTimeMetric.get().getMinimum()); assertEquals(timeInSeconds, executionTimeMetric.get().getMaximum()); @@ -89,29 +128,52 @@ void testGetAggregatedExecutionTime() { .maximum(6.0) .average(4.0) .numberOfDataPointsForAverage(2)); - executionTimeMetric = AggregationHelper.getAggregatedExecutionTime(new ExecutionsRequestBody().runExecutions(executions).aggregatedExecutions(List.of(submittedAggregatedMetrics))); + executionTimeMetric = executionTimeAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions).aggregatedExecutions(List.of(submittedAggregatedMetrics))); assertTrue(executionTimeMetric.isPresent()); assertEquals(2.0, executionTimeMetric.get().getMinimum()); assertEquals(10.0, executionTimeMetric.get().getMaximum()); assertEquals(6, executionTimeMetric.get().getAverage()); assertEquals(3, executionTimeMetric.get().getNumberOfDataPointsForAverage()); + + // Aggregate submissions containing workflow run executions and task executions + // Submit a single workflow execution that took 10s and a single task that took 10s + executions = List.of(new RunExecution().executionStatus(SUCCESSFUL).executionTime(String.format("PT%dS", timeInSeconds))); + executionTimeMetric = executionTimeAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions).taskExecutions(List.of(new TaskExecutions().taskExecutions(executions)))); + assertTrue(executionTimeMetric.isPresent()); + assertEquals(timeInSeconds, executionTimeMetric.get().getMinimum()); + assertEquals(timeInSeconds, executionTimeMetric.get().getMaximum()); + assertEquals(timeInSeconds, executionTimeMetric.get().getAverage()); + assertEquals(2, executionTimeMetric.get().getNumberOfDataPointsForAverage()); // There should be 2 data points: 1 for the workflow execution and 1 for the list of tasks + // Submit a single workflow execution that took 10s and two tasks that took 10 seconds. This time, dateExecuted is provided + RunExecution task1 = new RunExecution().executionStatus(SUCCESSFUL).executionTime(String.format("PT%dS", timeInSeconds)); + RunExecution task2 = new RunExecution().executionStatus(SUCCESSFUL).executionTime(String.format("PT%dS", timeInSeconds)); + // The time difference between these two tasks is 10 seconds. When there is more than one task, the duration will be calculated from the dates executed, plus the duration of the last task, which is 10s + task1.setDateExecuted("2023-11-09T21:54:10.571285905Z"); + task2.setDateExecuted("2023-11-09T21:54:20.571285905Z"); + executionTimeMetric = executionTimeAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions).taskExecutions(List.of(new TaskExecutions().taskExecutions(List.of(task1, task2))))); + assertTrue(executionTimeMetric.isPresent()); + assertEquals(10, executionTimeMetric.get().getMinimum(), "The minimum is from the workflow execution"); + assertEquals(20, executionTimeMetric.get().getMaximum(), "The maximum is from the workflow execution calculated from the two tasks"); + assertEquals(15, executionTimeMetric.get().getAverage()); + assertEquals(2, executionTimeMetric.get().getNumberOfDataPointsForAverage()); // There should be 2 data points: 1 for the workflow execution and 1 for the list of tasks } @Test void testGetAggregatedCpu() { + CpuAggregator cpuAggregator = new CpuAggregator(); List executions = new ArrayList<>(); - Optional cpuMetric = AggregationHelper.getAggregatedCpu(new ExecutionsRequestBody().runExecutions(executions)); + Optional cpuMetric = cpuAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions)); assertTrue(cpuMetric.isEmpty()); // Add an execution that doesn't have cpu data executions.add(new RunExecution().executionStatus(SUCCESSFUL)); - cpuMetric = AggregationHelper.getAggregatedCpu(new ExecutionsRequestBody().runExecutions(executions)); + cpuMetric = cpuAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions)); assertTrue(cpuMetric.isEmpty()); // Add an execution with cpu data final int cpu = 1; executions.add(new RunExecution().executionStatus(SUCCESSFUL).cpuRequirements(cpu)); - cpuMetric = AggregationHelper.getAggregatedCpu(new ExecutionsRequestBody().runExecutions(executions)); + cpuMetric = cpuAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions)); assertTrue(cpuMetric.isPresent()); assertEquals(cpu, cpuMetric.get().getMinimum()); assertEquals(cpu, cpuMetric.get().getMaximum()); @@ -125,29 +187,43 @@ void testGetAggregatedCpu() { .maximum(6.0) .average(4.0) .numberOfDataPointsForAverage(2)); - cpuMetric = AggregationHelper.getAggregatedCpu(new ExecutionsRequestBody().runExecutions(executions).aggregatedExecutions(List.of(submittedAggregatedMetrics))); + cpuMetric = cpuAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions).aggregatedExecutions(List.of(submittedAggregatedMetrics))); assertTrue(cpuMetric.isPresent()); assertEquals(1.0, cpuMetric.get().getMinimum()); assertEquals(6.0, cpuMetric.get().getMaximum()); assertEquals(3, cpuMetric.get().getAverage()); assertEquals(3, cpuMetric.get().getNumberOfDataPointsForAverage()); + + // Aggregate submissions containing workflow run executions and task executions + executions = List.of(new RunExecution().executionStatus(SUCCESSFUL).cpuRequirements(cpu)); + // Two task executions with different CPU requirements. The workflow execution calculated from these tasks should take the highest cpuRequirement from the tasks + TaskExecutions taskExecutions = new TaskExecutions().taskExecutions(List.of( + new RunExecution().executionStatus(SUCCESSFUL).cpuRequirements(1), + new RunExecution().executionStatus(SUCCESSFUL).cpuRequirements(4))); + cpuMetric = cpuAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions).taskExecutions(List.of(taskExecutions))); + assertTrue(cpuMetric.isPresent()); + assertEquals(1.0, cpuMetric.get().getMinimum()); + assertEquals(4.0, cpuMetric.get().getMaximum()); + assertEquals(2.5, cpuMetric.get().getAverage()); + assertEquals(2, cpuMetric.get().getNumberOfDataPointsForAverage()); // Two data points: 1 from the workflow execution and 1 for the list of tasks } @Test void testGetAggregatedMemory() { + MemoryAggregator memoryAggregator = new MemoryAggregator(); List executions = new ArrayList<>(); - Optional memoryMetric = AggregationHelper.getAggregatedMemory(new ExecutionsRequestBody().runExecutions(executions)); + Optional memoryMetric = memoryAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions)); assertTrue(memoryMetric.isEmpty()); // Add an execution that doesn't have memory data executions.add(new RunExecution().executionStatus(SUCCESSFUL)); - memoryMetric = AggregationHelper.getAggregatedMemory(new ExecutionsRequestBody().runExecutions(executions)); + memoryMetric = memoryAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions)); assertTrue(memoryMetric.isEmpty()); // Add an execution with memory data Double memoryInGB = 2.0; executions.add(new RunExecution().executionStatus(SUCCESSFUL).memoryRequirementsGB(memoryInGB)); - memoryMetric = AggregationHelper.getAggregatedMemory(new ExecutionsRequestBody().runExecutions(executions)); + memoryMetric = memoryAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions)); assertTrue(memoryMetric.isPresent()); assertEquals(memoryInGB, memoryMetric.get().getMinimum()); assertEquals(memoryInGB, memoryMetric.get().getMaximum()); @@ -161,29 +237,44 @@ void testGetAggregatedMemory() { .maximum(6.0) .average(4.0) .numberOfDataPointsForAverage(2)); - memoryMetric = AggregationHelper.getAggregatedMemory(new ExecutionsRequestBody().runExecutions(executions).aggregatedExecutions(List.of(submittedAggregatedMetrics))); + memoryMetric = memoryAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions).aggregatedExecutions(List.of(submittedAggregatedMetrics))); assertTrue(memoryMetric.isPresent()); assertEquals(2.0, memoryMetric.get().getMinimum()); assertEquals(6.0, memoryMetric.get().getMaximum()); assertEquals(3.333333333333333, memoryMetric.get().getAverage()); assertEquals(3, memoryMetric.get().getNumberOfDataPointsForAverage()); + + // Aggregate submissions containing workflow run executions and task executions + executions = List.of(new RunExecution().executionStatus(SUCCESSFUL).memoryRequirementsGB(2.0)); + // Two task executions with different memory requirements. The workflow execution calculated from these tasks should take the highest memoryRequirementsGB from the tasks + TaskExecutions taskExecutions = new TaskExecutions().taskExecutions(List.of( + new RunExecution().executionStatus(SUCCESSFUL).memoryRequirementsGB(2.0), + new RunExecution().executionStatus(SUCCESSFUL).memoryRequirementsGB(4.0))); + memoryMetric = memoryAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions).taskExecutions(List.of(taskExecutions))); + assertTrue(memoryMetric.isPresent()); + assertEquals(2.0, memoryMetric.get().getMinimum()); + assertEquals(4.0, memoryMetric.get().getMaximum()); + assertEquals(3.0, memoryMetric.get().getAverage()); + assertEquals(2, memoryMetric.get().getNumberOfDataPointsForAverage()); // Two data points: 1 from the workflow execution and 1 for the list of tasks + } @Test void testGetAggregatedCost() { + CostAggregator costAggregator = new CostAggregator(); List executions = new ArrayList<>(); - Optional costMetric = AggregationHelper.getAggregatedCost(new ExecutionsRequestBody().runExecutions(executions)); + Optional costMetric = costAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions)); assertTrue(costMetric.isEmpty()); // Add an execution that doesn't have cost data executions.add(new RunExecution().executionStatus(SUCCESSFUL)); - costMetric = AggregationHelper.getAggregatedCost(new ExecutionsRequestBody().runExecutions(executions)); + costMetric = costAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions)); assertTrue(costMetric.isEmpty()); // Add an execution with cost data Double costInUSD = 2.00; executions.add(new RunExecution().executionStatus(SUCCESSFUL).cost(new Cost().value(costInUSD))); - costMetric = AggregationHelper.getAggregatedCost(new ExecutionsRequestBody().runExecutions(executions)); + costMetric = costAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions)); assertTrue(costMetric.isPresent()); assertEquals(costInUSD, costMetric.get().getMinimum()); assertEquals(costInUSD, costMetric.get().getMaximum()); @@ -197,12 +288,26 @@ void testGetAggregatedCost() { .maximum(6.00) .average(4.00) .numberOfDataPointsForAverage(2)); - costMetric = AggregationHelper.getAggregatedCost(new ExecutionsRequestBody().runExecutions(executions).aggregatedExecutions(List.of(submittedAggregatedMetrics))); + costMetric = costAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions).aggregatedExecutions(List.of(submittedAggregatedMetrics))); assertTrue(costMetric.isPresent()); assertEquals(2.0, costMetric.get().getMinimum()); assertEquals(6.0, costMetric.get().getMaximum()); assertEquals(3.333333333333333, costMetric.get().getAverage()); assertEquals(3, costMetric.get().getNumberOfDataPointsForAverage()); + + // Aggregate submissions containing workflow run executions and task executions + executions = List.of(new RunExecution().executionStatus(SUCCESSFUL).cost(new Cost().value(2.00))); + // Two task executions with different memory requirements. The workflow execution calculated from these tasks should have the sum of the cost of all tasks + TaskExecutions taskExecutions = new TaskExecutions().taskExecutions(List.of( + new RunExecution().executionStatus(SUCCESSFUL).cost(new Cost().value(2.00)), + new RunExecution().executionStatus(SUCCESSFUL).cost(new Cost().value(4.00)) + )); + costMetric = costAggregator.getAggregatedMetricFromAllSubmissions(new ExecutionsRequestBody().runExecutions(executions).taskExecutions(List.of(taskExecutions))); + assertTrue(costMetric.isPresent()); + assertEquals(2.0, costMetric.get().getMinimum()); + assertEquals(6.0, costMetric.get().getMaximum()); // The max is the cost of the two tasks summed together + assertEquals(4.0, costMetric.get().getAverage()); + assertEquals(2, costMetric.get().getNumberOfDataPointsForAverage()); // Two data points: 1 from the workflow execution and 1 for the list of tasks } @Test diff --git a/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/CostAggregatorTest.java b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/CostAggregatorTest.java new file mode 100644 index 00000000..d3dc047c --- /dev/null +++ b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/CostAggregatorTest.java @@ -0,0 +1,74 @@ +package io.dockstore.metricsaggregator.helper; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.dockstore.openapi.client.model.Cost; +import io.dockstore.openapi.client.model.CostMetric; +import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Test; + +class CostAggregatorTest { + private static final CostAggregator COST_AGGREGATOR = new CostAggregator(); + + /** + * Tests that the aggregator calculates the correct workflow RunExecution from a list of task RunExecutions. + */ + @Test + void testGetWorkflowExecutionFromTaskExecutions() { + // Empty TaskExecutions should return Optional.empty() + Optional workflowExecution = COST_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(new TaskExecutions()); + assertTrue(workflowExecution.isEmpty()); + + // The workflow execution generated from a single task should have the same cost as the one task + TaskExecutions taskExecutions = new TaskExecutions().taskExecutions(List.of(new RunExecution().cost(new Cost().value(1.0)))); + workflowExecution = COST_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(taskExecutions); + assertTrue(workflowExecution.isPresent()); + assertEquals(1.0, workflowExecution.get().getCost().getValue()); + + // The workflow execution generated from multiple tasks should have the sum of costs from the list of tasks + taskExecutions.setTaskExecutions(List.of( + new RunExecution().cost(new Cost().value(1.0)), + new RunExecution().cost(new Cost().value(2.0)), + new RunExecution().cost(new Cost().value(3.0)) + )); + workflowExecution = COST_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(taskExecutions); + assertTrue(workflowExecution.isPresent()); + assertEquals(6.0, workflowExecution.get().getCost().getValue()); + } + + /** + * Tests that the aggregator calculates the correct aggregated metric from a list of workflow RunExecutions + */ + @Test + void testGetAggregatedMetricFromWorkflowExecutions() { + // Empty list should return Optional.empty() + Optional costMetric = COST_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(List.of()); + assertTrue(costMetric.isEmpty()); + + // Test the metric calculated from a single workflow execution. The min, max, and average should be the same value as the single execution + List workflowExecutions = List.of(new RunExecution().cost(new Cost().value(1.0))); + costMetric = COST_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(workflowExecutions); + assertTrue(costMetric.isPresent()); + assertEquals(1.0, costMetric.get().getMinimum()); + assertEquals(1.0, costMetric.get().getMaximum()); + assertEquals(1.0, costMetric.get().getAverage()); + assertEquals(1, costMetric.get().getNumberOfDataPointsForAverage()); + + // Test the metric calculated from multiple workflow executions. + workflowExecutions = List.of( + new RunExecution().cost(new Cost().value(2.0)), + new RunExecution().cost(new Cost().value(4.0)), + new RunExecution().cost(new Cost().value(6.0)) + ); + costMetric = COST_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(workflowExecutions); + assertTrue(costMetric.isPresent()); + assertEquals(2.0, costMetric.get().getMinimum()); + assertEquals(6.0, costMetric.get().getMaximum()); + assertEquals(4.0, costMetric.get().getAverage()); + assertEquals(3, costMetric.get().getNumberOfDataPointsForAverage()); + } +} diff --git a/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/CpuAggregatorTest.java b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/CpuAggregatorTest.java new file mode 100644 index 00000000..f551a52e --- /dev/null +++ b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/CpuAggregatorTest.java @@ -0,0 +1,73 @@ +package io.dockstore.metricsaggregator.helper; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.dockstore.openapi.client.model.CpuMetric; +import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Test; + +class CpuAggregatorTest { + private static final CpuAggregator CPU_AGGREGATOR = new CpuAggregator(); + + /** + * Tests that the aggregator calculates the correct workflow RunExecution from a list of task RunExecutions. + */ + @Test + void testGetWorkflowExecutionFromTaskExecutions() { + // Empty TaskExecutions should return Optional.empty() + Optional workflowExecution = CPU_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(new TaskExecutions()); + assertTrue(workflowExecution.isEmpty()); + + // The workflow execution generated from a single task should have the same cpuRequirements as the one task + TaskExecutions taskExecutions = new TaskExecutions().taskExecutions(List.of(new RunExecution().cpuRequirements(1))); + workflowExecution = CPU_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(taskExecutions); + assertTrue(workflowExecution.isPresent()); + assertEquals(1, workflowExecution.get().getCpuRequirements()); + + // The workflow execution generated from multiple tasks should have the cpuRequirements from the highest cpuRequirements from the list of tasks + taskExecutions.setTaskExecutions(List.of( + new RunExecution().cpuRequirements(1), + new RunExecution().cpuRequirements(2), + new RunExecution().cpuRequirements(3) + )); + workflowExecution = CPU_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(taskExecutions); + assertTrue(workflowExecution.isPresent()); + assertEquals(3, workflowExecution.get().getCpuRequirements()); + } + + /** + * Tests that the aggregator calculates the correct aggregated metric from a list of workflow RunExecutions + */ + @Test + void testGetAggregatedMetricFromWorkflowExecutions() { + // Empty list should return Optional.empty() + Optional cpuMetric = CPU_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(List.of()); + assertTrue(cpuMetric.isEmpty()); + + // Test the metric calculated from a single workflow execution. The min, max, and average should be the same value as the single execution + List workflowExecutions = List.of(new RunExecution().cpuRequirements(1)); + cpuMetric = CPU_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(workflowExecutions); + assertTrue(cpuMetric.isPresent()); + assertEquals(1.0, cpuMetric.get().getMinimum()); + assertEquals(1.0, cpuMetric.get().getMaximum()); + assertEquals(1.0, cpuMetric.get().getAverage()); + assertEquals(1, cpuMetric.get().getNumberOfDataPointsForAverage()); + + // Test the metric calculated from multiple workflow executions. + workflowExecutions = List.of( + new RunExecution().cpuRequirements(2), + new RunExecution().cpuRequirements(4), + new RunExecution().cpuRequirements(6) + ); + cpuMetric = CPU_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(workflowExecutions); + assertTrue(cpuMetric.isPresent()); + assertEquals(2.0, cpuMetric.get().getMinimum()); + assertEquals(6.0, cpuMetric.get().getMaximum()); + assertEquals(4.0, cpuMetric.get().getAverage()); + assertEquals(3, cpuMetric.get().getNumberOfDataPointsForAverage()); + } +} diff --git a/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/ExecutionStatusAggregatorTest.java b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/ExecutionStatusAggregatorTest.java new file mode 100644 index 00000000..f6f3695c --- /dev/null +++ b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/ExecutionStatusAggregatorTest.java @@ -0,0 +1,97 @@ +package io.dockstore.metricsaggregator.helper; + +import static io.dockstore.openapi.client.model.RunExecution.ExecutionStatusEnum.FAILED_RUNTIME_INVALID; +import static io.dockstore.openapi.client.model.RunExecution.ExecutionStatusEnum.FAILED_SEMANTIC_INVALID; +import static io.dockstore.openapi.client.model.RunExecution.ExecutionStatusEnum.SUCCESSFUL; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.dockstore.openapi.client.model.ExecutionStatusMetric; +import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Test; + +class ExecutionStatusAggregatorTest { + private static final ExecutionStatusAggregator EXECUTION_STATUS_AGGREGATOR = new ExecutionStatusAggregator(); + + /** + * Tests that the aggregator calculates the correct workflow RunExecution from a list of task RunExecutions. + */ + @Test + void testGetWorkflowExecutionFromTaskExecutions() { + // Empty TaskExecutions should return Optional.empty() + Optional workflowExecution = EXECUTION_STATUS_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(new TaskExecutions()); + assertTrue(workflowExecution.isEmpty()); + + // The workflow execution generated from a single task should have the same status as the one task + TaskExecutions taskExecutions = new TaskExecutions().taskExecutions(List.of(new RunExecution().executionStatus(SUCCESSFUL))); + workflowExecution = EXECUTION_STATUS_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(taskExecutions); + assertTrue(workflowExecution.isPresent()); + assertEquals(SUCCESSFUL, workflowExecution.get().getExecutionStatus()); + + // The workflow execution generated from tasks that were all successful should have a successful status + taskExecutions.setTaskExecutions(List.of( + new RunExecution().executionStatus(SUCCESSFUL), + new RunExecution().executionStatus(SUCCESSFUL), + new RunExecution().executionStatus(SUCCESSFUL) + )); + workflowExecution = EXECUTION_STATUS_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(taskExecutions); + assertTrue(workflowExecution.isPresent()); + assertEquals(SUCCESSFUL, workflowExecution.get().getExecutionStatus()); + + // The workflow execution generated from tasks that where there are failures should have the most frequent failed status + taskExecutions.setTaskExecutions(List.of( + new RunExecution().executionStatus(SUCCESSFUL), + new RunExecution().executionStatus(FAILED_SEMANTIC_INVALID), + new RunExecution().executionStatus(FAILED_RUNTIME_INVALID), + new RunExecution().executionStatus(FAILED_RUNTIME_INVALID) + )); + workflowExecution = EXECUTION_STATUS_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(taskExecutions); + assertTrue(workflowExecution.isPresent()); + // Should be FAILED_RUNTIME_INVALID because it's the most frequent failed status + assertEquals(FAILED_RUNTIME_INVALID, workflowExecution.get().getExecutionStatus()); + // When there are equal counts of all failed statuses, the workflow execution status should be one of them + taskExecutions.setTaskExecutions(List.of( + new RunExecution().executionStatus(SUCCESSFUL), + new RunExecution().executionStatus(FAILED_SEMANTIC_INVALID), + new RunExecution().executionStatus(FAILED_RUNTIME_INVALID) + )); + workflowExecution = EXECUTION_STATUS_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(taskExecutions); + assertTrue(workflowExecution.isPresent()); + assertTrue(workflowExecution.get().getExecutionStatus() == FAILED_RUNTIME_INVALID + || workflowExecution.get().getExecutionStatus() == FAILED_SEMANTIC_INVALID); + } + + /** + * Tests that the aggregator calculates the correct aggregated metric from a list of workflow RunExecutions + */ + @Test + void testGetAggregatedMetricFromWorkflowExecutions() { + // Empty list should return Optional.empty() + Optional executionStatusMetric = EXECUTION_STATUS_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(List.of()); + assertTrue(executionStatusMetric.isEmpty()); + + // Test the metric calculated from a single workflow execution. + List workflowExecutions = List.of(new RunExecution().executionStatus(SUCCESSFUL)); + executionStatusMetric = EXECUTION_STATUS_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(workflowExecutions); + assertTrue(executionStatusMetric.isPresent()); + assertEquals(1, executionStatusMetric.get().getCount().get(SUCCESSFUL.toString())); + assertFalse(executionStatusMetric.get().getCount().containsKey(FAILED_SEMANTIC_INVALID.toString())); + assertFalse(executionStatusMetric.get().getCount().containsKey(FAILED_RUNTIME_INVALID.toString())); + + // Test the metric calculated from multiple workflow executions. + workflowExecutions = List.of( + new RunExecution().executionStatus(SUCCESSFUL), + new RunExecution().executionStatus(FAILED_SEMANTIC_INVALID), + new RunExecution().executionStatus(FAILED_RUNTIME_INVALID) + ); + executionStatusMetric = EXECUTION_STATUS_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(workflowExecutions); + assertTrue(executionStatusMetric.isPresent()); + assertEquals(1, executionStatusMetric.get().getCount().get(SUCCESSFUL.toString())); + assertEquals(1, executionStatusMetric.get().getCount().get(FAILED_SEMANTIC_INVALID.toString())); + assertEquals(1, executionStatusMetric.get().getCount().get(FAILED_RUNTIME_INVALID.toString())); + } +} diff --git a/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/ExecutionTimeAggregatorTest.java b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/ExecutionTimeAggregatorTest.java new file mode 100644 index 00000000..9e799247 --- /dev/null +++ b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/ExecutionTimeAggregatorTest.java @@ -0,0 +1,81 @@ +package io.dockstore.metricsaggregator.helper; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.dockstore.openapi.client.model.ExecutionTimeMetric; +import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Test; + +class ExecutionTimeAggregatorTest { + private static final ExecutionTimeAggregator EXECUTION_TIME_AGGREGATOR = new ExecutionTimeAggregator(); + + /** + * Tests that the aggregator calculates the correct workflow RunExecution from a list of task RunExecutions. + */ + @Test + void testGetWorkflowExecutionFromTaskExecutions() { + // Empty TaskExecutions should return Optional.empty() + Optional workflowExecution = EXECUTION_TIME_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(new TaskExecutions()); + assertTrue(workflowExecution.isEmpty()); + + // The workflow execution generated from a single task should have the executionTime as the one task + String tenSecondsExecutionTime = "PT10S"; + TaskExecutions taskExecutions = new TaskExecutions().taskExecutions(List.of(new RunExecution().executionTime(tenSecondsExecutionTime))); + workflowExecution = EXECUTION_TIME_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(taskExecutions); + assertTrue(workflowExecution.isPresent()); + assertEquals(tenSecondsExecutionTime, workflowExecution.get().getExecutionTime()); + + // The workflow execution generated from multiple tasks should calculate the executionTime from the earliest and latest dateExecuted fields from the tasks + List iso8601Dates = List.of("2023-11-09T21:54:00.571285905Z", "2023-11-09T21:54:10.571285905Z", "2023-11-09T21:54:20.571285905Z"); // 10 second increments + // Create 3 tasks where the difference between each dateExecuted is 10 seconds + taskExecutions.setTaskExecutions(iso8601Dates.stream() + .map(dateExecuted -> { + // Setting the execution time, but this isn't used to calculate the workflow RunExecution execution time + RunExecution taskExecution = new RunExecution().executionTime(tenSecondsExecutionTime); + taskExecution.setDateExecuted(dateExecuted); + return taskExecution; + }) + .toList() + ); + workflowExecution = EXECUTION_TIME_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(taskExecutions); + assertTrue(workflowExecution.isPresent()); + // Should be 30 seconds because the difference between the earliest and latest date executed is 20 seconds and the duration of the last task is 10s + assertEquals("PT30S", workflowExecution.get().getExecutionTime()); + } + + /** + * Tests that the aggregator calculates the correct aggregated metric from a list of workflow RunExecutions + */ + @Test + void testGetAggregatedMetricFromWorkflowExecutions() { + // Empty list should return Optional.empty() + Optional executionTimeMetric = EXECUTION_TIME_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(List.of()); + assertTrue(executionTimeMetric.isEmpty()); + + // Test the metric calculated from a single workflow execution. The min, max, and average should be the same value as the single execution + List workflowExecutions = List.of(new RunExecution().executionTime("PT10S")); // 10 seconds + executionTimeMetric = EXECUTION_TIME_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(workflowExecutions); + assertTrue(executionTimeMetric.isPresent()); + assertEquals(10.0, executionTimeMetric.get().getMinimum()); + assertEquals(10.0, executionTimeMetric.get().getMaximum()); + assertEquals(10.0, executionTimeMetric.get().getAverage()); + assertEquals(1, executionTimeMetric.get().getNumberOfDataPointsForAverage()); + + // Test the metric calculated from multiple workflow executions. + workflowExecutions = List.of( + new RunExecution().executionTime("PT10S"), // 10 seconds + new RunExecution().executionTime("PT20S"), // 20 seconds + new RunExecution().executionTime("PT30S") // 30 seconds + ); + executionTimeMetric = EXECUTION_TIME_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(workflowExecutions); + assertTrue(executionTimeMetric.isPresent()); + assertEquals(10.0, executionTimeMetric.get().getMinimum()); + assertEquals(30.0, executionTimeMetric.get().getMaximum()); + assertEquals(20.0, executionTimeMetric.get().getAverage()); + assertEquals(3, executionTimeMetric.get().getNumberOfDataPointsForAverage()); + } +} diff --git a/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/MemoryAggregatorTest.java b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/MemoryAggregatorTest.java new file mode 100644 index 00000000..a897ae11 --- /dev/null +++ b/metricsaggregator/src/test/java/io/dockstore/metricsaggregator/helper/MemoryAggregatorTest.java @@ -0,0 +1,73 @@ +package io.dockstore.metricsaggregator.helper; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.dockstore.openapi.client.model.MemoryMetric; +import io.dockstore.openapi.client.model.RunExecution; +import io.dockstore.openapi.client.model.TaskExecutions; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Test; + +class MemoryAggregatorTest { + private static final MemoryAggregator MEMORY_AGGREGATOR = new MemoryAggregator(); + + /** + * Tests that the aggregator calculates the correct workflow RunExecution from a TaskExecutions that represents a list of task RunExecutions that were executed during a single workflow execution. + */ + @Test + void testGetWorkflowExecutionFromTaskExecutions() { + // Empty TaskExecutions should return Optional.empty() + Optional workflowExecution = MEMORY_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(new TaskExecutions()); + assertTrue(workflowExecution.isEmpty()); + + // The workflow execution generated from a single task should have the same memoryRequirementsGB as the one task + TaskExecutions taskExecutions = new TaskExecutions().taskExecutions(List.of(new RunExecution().memoryRequirementsGB(1.0))); + workflowExecution = MEMORY_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(taskExecutions); + assertTrue(workflowExecution.isPresent()); + assertEquals(1.0, workflowExecution.get().getMemoryRequirementsGB()); + + // The workflow execution generated from multiple tasks should have the memoryRequirementsGB from the highest memoryRequirementsGB from the list of tasks + taskExecutions.setTaskExecutions(List.of( + new RunExecution().memoryRequirementsGB(1.0), + new RunExecution().memoryRequirementsGB(2.0), + new RunExecution().memoryRequirementsGB(3.0) + )); + workflowExecution = MEMORY_AGGREGATOR.getWorkflowExecutionFromTaskExecutions(taskExecutions); + assertTrue(workflowExecution.isPresent()); + assertEquals(3.0, workflowExecution.get().getMemoryRequirementsGB()); + } + + /** + * Tests that the aggregator calculates the correct aggregated metric from a list of workflow RunExecutions + */ + @Test + void testGetAggregatedMetricFromWorkflowExecutions() { + // Empty list should return Optional.empty() + Optional memoryMetric = MEMORY_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(List.of()); + assertTrue(memoryMetric.isEmpty()); + + // Test the memory metric calculated from a single workflow execution. The min, max, and average should be the same value as the single execution + List workflowExecutions = List.of(new RunExecution().memoryRequirementsGB(1.0)); + memoryMetric = MEMORY_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(workflowExecutions); + assertTrue(memoryMetric.isPresent()); + assertEquals(1.0, memoryMetric.get().getMinimum()); + assertEquals(1.0, memoryMetric.get().getMaximum()); + assertEquals(1.0, memoryMetric.get().getAverage()); + assertEquals(1, memoryMetric.get().getNumberOfDataPointsForAverage()); + + // Test the memory metric calculated from multiple workflow executions. + workflowExecutions = List.of( + new RunExecution().memoryRequirementsGB(2.0), + new RunExecution().memoryRequirementsGB(4.0), + new RunExecution().memoryRequirementsGB(6.0) + ); + memoryMetric = MEMORY_AGGREGATOR.getAggregatedMetricFromWorkflowExecutions(workflowExecutions); + assertTrue(memoryMetric.isPresent()); + assertEquals(2.0, memoryMetric.get().getMinimum()); + assertEquals(6.0, memoryMetric.get().getMaximum()); + assertEquals(4.0, memoryMetric.get().getAverage()); + assertEquals(3, memoryMetric.get().getNumberOfDataPointsForAverage()); + } +} diff --git a/pom.xml b/pom.xml index 821308b4..4538516f 100644 --- a/pom.xml +++ b/pom.xml @@ -38,7 +38,7 @@ scm:git:git@github.com:dockstore/dockstore-support.git UTF-8 - 1.15.0-alpha.5 + 1.15.0-alpha.13 3.0.0-M5 2.22.2 false @@ -160,7 +160,7 @@ org.glassfish.jersey.inject jersey-hk2 - 3.0.9 + 3.0.11 @@ -525,7 +525,7 @@ javax.servlet:javax.servlet-api javax.validation:validation-api - + diff --git a/toolbackup/pom.xml b/toolbackup/pom.xml index 2cac274f..4a6f6767 100644 --- a/toolbackup/pom.xml +++ b/toolbackup/pom.xml @@ -186,7 +186,8 @@ com.spotify docker-client - 7.0.2 + 8.16.0 + shaded @@ -199,7 +200,7 @@ commons-io commons-io - 2.7 + 2.11.0