Class DoppelgangerApiDetectorExtension

java.lang.Object
com.arc_e_tect.gradle.doppelganger.DoppelgangerApiDetectorExtension

public abstract class DoppelgangerApiDetectorExtension extends Object
DSL extension for the Doppelganger API Detector Gradle plugin.
 doppelgangerApiDetector {
     controllerDirs.from('src/main/java')                                    // default
     testDirs.from('src/testContract/java')                                  // default
     rootDocument   = file('src/main/resources/openapi/openapi.yaml')       // required
     // openApiDir  = rootDocument.get().asFile.parentFile                  // default
     // contractsDir = file('src/testContract/resources/contracts')        // required if useSpringCloudContract = true
     useRestDocs                 = true                                      // default
     useOpenApiRequestValidator  = false                                     // default
     useSpringCloudContract      = false                                     // default
     // propertyFiles.from('src/testCommon/resources/api-endpoints.properties') // default: empty
     // pathResolverHelperMethods.add('ApiEndpoints.get')                   // default: empty
     failOnDoppelganger = false                                              // default
     reportDir      = layout.buildDirectory.dir('reports/doppelganger-api-detector') // default
     reportFileName = 'doppelganger-apis.adoc'                               // default
     // systemUnderTestVersion = 'v1.0.0'          // optional; default: project.version
     trackContractHistory  = false                                           // default
     // contractHistoryFile = file('doppelganger-api-detector-contract-history.ndjson') // default
     updateContractHistory = trackContractHistory                            // default; see getUpdateContractHistory()

     // excludePaths.add('/actuator/health')                                 // default: empty
     // excludeFiles.from('doppelganger-exclusions.yaml')                    // default: empty
     // excludeWellKnown.add('spring-boot-actuator')                        // default: empty

     // Configuration for the separate `scanContracts` task - reuses controllerDirs, testDirs,
     // rootDocument, contractsDir, useRestDocs/useOpenApiRequestValidator/useSpringCloudContract,
     // and the exclude* properties above.
     includeResponseCoverage = false                                         // default
     // scanContractsReportFileName = 'contract-coverage.adoc'               // default
     trackResponseCoverageHistory = false                                    // default
     // responseCoverageHistoryFile = file('doppelganger-api-detector-response-coverage-history.ndjson') // default
     updateResponseCoverageHistory = trackResponseCoverageHistory            // default; see getUpdateResponseCoverageHistory()
 }
 

updateContractHistory can be overridden for the whole build from the command line, e.g. -PdoppelgangerApiDetector.updateContractHistory=true - see getUpdateContractHistory(). updateResponseCoverageHistory has its own, independent override - see getUpdateResponseCoverageHistory().

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    Default name of the persisted contract progress history file.
    static final String
    Suggested relative path of the directory searched for Spring Cloud Contract DSL files, shown in the DSL example above.
    static final String
    Default relative path of the directory searched for @RestController classes.
    static final String
    Default name of the generated AsciiDoc report file.
    static final String
    Default name of the persisted response coverage history file.
    static final String
    Default name of the scanContracts task's generated AsciiDoc report file.
    static final String
    Default relative path of the directory searched for test classes.
    static final String
    Extension DSL block name, i.e.
    static final String
    Name of the Gradle project property that overrides getUpdateContractHistory() from the command line for every project in the build, e.g.
    static final String
    Name of the Gradle project property that overrides getUpdateResponseCoverageHistory() from the command line for every project in the build, e.g.
  • Constructor Summary

    Constructors
    Constructor
    Description
    For use by the Gradle-generated concrete subclass.
  • Method Summary

    Modifier and Type
    Method
    Description
    abstract org.gradle.api.file.RegularFileProperty
    File that the persisted contract progress history is read from and, when getUpdateContractHistory() is true, written back to.
    abstract org.gradle.api.file.DirectoryProperty
    Directory searched for Spring Cloud Contract DSL files (*.groovy and *.yml), scanned recursively when getUseSpringCloudContract() is true.
    abstract org.gradle.api.file.ConfigurableFileCollection
    Directories to search recursively for @RestController classes.
    abstract org.gradle.api.file.ConfigurableFileCollection
    One or more YAML files of exclusion rules, in the same format bundled well-known sets use:
    abstract org.gradle.api.provider.ListProperty<String>
    Exclusion rule strings, parsed by ExclusionRule.parse(String) - e.g.
    abstract org.gradle.api.provider.ListProperty<String>
    Names of bundled, well-known exclusion sets to apply - e.g.
    abstract org.gradle.api.provider.Property<Boolean>
    Whether the build should fail when doppelganger APIs are found.
    abstract org.gradle.api.provider.Property<Boolean>
    Whether the scanContracts task additionally computes, for every declared response code, how many contract tests cover it.
    abstract org.gradle.api.file.DirectoryProperty
    Directory where OpenAPI descriptions are stored.
    abstract org.gradle.api.provider.ListProperty<String>
    Static helper-method conventions recognised when resolving a test's request-path argument, each given as "SimpleClassName.methodName" (e.g.
    abstract org.gradle.api.file.ConfigurableFileCollection
    Property files (.properties, .yml, or .yaml) merged into a single key/value map used to resolve a test's request-path argument when it is not a literal or a literal-initialized constant - specifically, a configured getPathResolverHelperMethods() call whose literal argument is a property key, or a field annotated @Value("${key}")/@Value("${key:default}").
    abstract org.gradle.api.file.DirectoryProperty
    Directory the AsciiDoc report is written to.
    abstract org.gradle.api.provider.Property<String>
    Name of the generated AsciiDoc report file (without path).
    abstract org.gradle.api.file.RegularFileProperty
    File that the persisted response coverage history is read from and, when getUpdateResponseCoverageHistory() is true, written back to.
    abstract org.gradle.api.file.RegularFileProperty
    The root OpenAPI document describing the API.
    abstract org.gradle.api.provider.Property<String>
    Name of the scanContracts task's generated AsciiDoc report file (without path), written to the same getReportDir().
    abstract org.gradle.api.provider.Property<String>
    Version of the system under test whose @RestController classes are scanned, printed in the generated report as e.g.
    abstract org.gradle.api.file.ConfigurableFileCollection
    Directories to search recursively for test classes, scanned by the Spring RestDocs and OpenAPI request validator verification sources when enabled.
    abstract org.gradle.api.provider.Property<Boolean>
    Whether to persist, across builds, a history of when each endpoint first reached each stage of its contract lifecycle - declared, implemented, verified - keyed by a fingerprint of its HTTP verb and path so the history is shared correctly with Shadow and Mirage API Detector when they're pointed at the same getContractHistoryFile().
    abstract org.gradle.api.provider.Property<Boolean>
    Whether to persist, across builds, a history of response code coverage - keyed by endpoint fingerprint and response code, tracking a live test-count gauge rather than milestone timestamps.
    abstract org.gradle.api.provider.Property<Boolean>
    Whether getContractHistoryFile() is written back to disk after being updated with the current run's endpoints.
    abstract org.gradle.api.provider.Property<Boolean>
    Whether getResponseCoverageHistoryFile() is written back to disk after being updated with the current run's coverage.
    abstract org.gradle.api.provider.Property<Boolean>
    Whether to treat Atlassian OpenAPI request validator usage as verification evidence.
    abstract org.gradle.api.provider.Property<Boolean>
    Whether to treat Spring RestDocs test methods as verification evidence: either a spring-restdocs-mockmvc mockMvc.perform(...) call paired with .andDo(document(...)), a spring-restdocs-webtestclient webTestClient.get()/post()/put()/delete()/patch().uri(...).exchange()... chain paired with .consumeWith(document(...)), or a spring-restdocs-restassured .filter(document(...)) paired with a when().get(...)/post(...)/... call.
    abstract org.gradle.api.provider.Property<Boolean>
    Whether to treat Spring Cloud Contract DSL files under getContractsDir() as verification evidence.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • NAME

      public static final String NAME
      Extension DSL block name, i.e. the name used to register the extension with the project.
      See Also:
    • DEFAULT_CONTROLLER_DIR

      public static final String DEFAULT_CONTROLLER_DIR
      Default relative path of the directory searched for @RestController classes.
      See Also:
    • DEFAULT_TEST_DIR

      public static final String DEFAULT_TEST_DIR
      Default relative path of the directory searched for test classes.
      See Also:
    • DEFAULT_CONTRACTS_DIR

      public static final String DEFAULT_CONTRACTS_DIR
      Suggested relative path of the directory searched for Spring Cloud Contract DSL files, shown in the DSL example above. Not applied as a convention default - see getContractsDir().
      See Also:
    • DEFAULT_REPORT_FILE_NAME

      public static final String DEFAULT_REPORT_FILE_NAME
      Default name of the generated AsciiDoc report file.
      See Also:
    • DEFAULT_CONTRACT_HISTORY_FILE_NAME

      public static final String DEFAULT_CONTRACT_HISTORY_FILE_NAME
      Default name of the persisted contract progress history file.
      See Also:
    • UPDATE_CONTRACT_HISTORY_OVERRIDE_PROPERTY

      public static final String UPDATE_CONTRACT_HISTORY_OVERRIDE_PROPERTY
      Name of the Gradle project property that overrides getUpdateContractHistory() from the command line for every project in the build, e.g. -PdoppelgangerApiDetector.updateContractHistory=true. Takes precedence over any project's own configured updateContractHistory value. The value is parsed as a boolean.
      See Also:
    • DEFAULT_SCAN_CONTRACTS_REPORT_FILE_NAME

      public static final String DEFAULT_SCAN_CONTRACTS_REPORT_FILE_NAME
      Default name of the scanContracts task's generated AsciiDoc report file.
      See Also:
    • DEFAULT_RESPONSE_COVERAGE_HISTORY_FILE_NAME

      public static final String DEFAULT_RESPONSE_COVERAGE_HISTORY_FILE_NAME
      Default name of the persisted response coverage history file.
      See Also:
    • UPDATE_RESPONSE_COVERAGE_HISTORY_OVERRIDE_PROPERTY

      public static final String UPDATE_RESPONSE_COVERAGE_HISTORY_OVERRIDE_PROPERTY
      Name of the Gradle project property that overrides getUpdateResponseCoverageHistory() from the command line for every project in the build, e.g. -PdoppelgangerApiDetector.updateResponseCoverageHistory=true. Takes precedence over any project's own configured updateResponseCoverageHistory value. The value is parsed as a boolean.
      See Also:
  • Constructor Details

    • DoppelgangerApiDetectorExtension

      public DoppelgangerApiDetectorExtension()
      For use by the Gradle-generated concrete subclass.
  • Method Details

    • getControllerDirs

      public abstract org.gradle.api.file.ConfigurableFileCollection getControllerDirs()
      Directories to search recursively for @RestController classes. One or more directories may be configured. Defaults to "src/main/java".
      Returns:
      mutable file collection of controller source directories
    • getTestDirs

      public abstract org.gradle.api.file.ConfigurableFileCollection getTestDirs()
      Directories to search recursively for test classes, scanned by the Spring RestDocs and OpenAPI request validator verification sources when enabled. One or more directories may be configured. Defaults to "src/testContract/java".
      Returns:
      mutable file collection of test source directories
    • getRootDocument

      public abstract org.gradle.api.file.RegularFileProperty getRootDocument()
      The root OpenAPI document describing the API. Required: every other OpenAPI document is expected to be reachable from this one via $ref links relative to it.
      Returns:
      mutable file property for the root OpenAPI document
    • getOpenApiDir

      public abstract org.gradle.api.file.DirectoryProperty getOpenApiDir()
      Directory where OpenAPI descriptions are stored. Used only to determine which files the task should track as inputs for up-to-date checks; every document actually consulted is discovered by following the $ref links reachable from getRootDocument(). Defaults to the root document's own parent directory.
      Returns:
      mutable directory property for the OpenAPI description directory
    • getContractsDir

      public abstract org.gradle.api.file.DirectoryProperty getContractsDir()
      Directory searched for Spring Cloud Contract DSL files (*.groovy and *.yml), scanned recursively when getUseSpringCloudContract() is true.

      Deliberately has no convention default, unlike this plugin's other directory properties: enabling getUseSpringCloudContract() without configuring this property is a DSL configuration error, not a bootstrapping gap - detectDoppelgangerApis fails eagerly in that case, rather than silently falling back to a guessed location. See DetectDoppelgangerApisTask.generate().

      Returns:
      mutable directory property for the Spring Cloud Contract directory
    • getPropertyFiles

      public abstract org.gradle.api.file.ConfigurableFileCollection getPropertyFiles()
      Property files (.properties, .yml, or .yaml) merged into a single key/value map used to resolve a test's request-path argument when it is not a literal or a literal-initialized constant - specifically, a configured getPathResolverHelperMethods() call whose literal argument is a property key, or a field annotated @Value("${key}")/@Value("${key:default}"). Keys from nested YAML mappings are flattened to dotted form (e.g. users: { by-username: /v1/users/{username} } becomes the key users.by-username), matching Spring's own property-resolution convention. Later files take precedence over earlier ones on key collision. Defaults to empty, in which case neither helper-method calls nor @Value fields are resolved (unchanged from previous plugin versions).
      Returns:
      mutable file collection of property files to merge for path resolution
    • getPathResolverHelperMethods

      public abstract org.gradle.api.provider.ListProperty<String> getPathResolverHelperMethods()
      Static helper-method conventions recognised when resolving a test's request-path argument, each given as "SimpleClassName.methodName" (e.g. "ApiEndpoints.get" for a shared ApiEndpoints.get("users.by-username") helper backed by a properties file). A call matching one of these conventions, with a single literal-string argument, has that literal looked up as a key in the merged map built from getPropertyFiles(); the resolved value is then treated exactly as a literal path would be. Matching is by simple name only - no classpath is consulted, consistent with every other scanner in this plugin. Defaults to empty, in which case no helper-method call is resolved (unchanged from previous plugin versions).
      Returns:
      mutable list property of "ClassName.methodName" helper-method conventions
    • getUseRestDocs

      public abstract org.gradle.api.provider.Property<Boolean> getUseRestDocs()
      Whether to treat Spring RestDocs test methods as verification evidence: either a spring-restdocs-mockmvc mockMvc.perform(...) call paired with .andDo(document(...)), a spring-restdocs-webtestclient webTestClient.get()/post()/put()/delete()/patch().uri(...).exchange()... chain paired with .consumeWith(document(...)), or a spring-restdocs-restassured .filter(document(...)) paired with a when().get(...)/post(...)/... call. Paths captured from a running-server style verification (REST Assured) have any leading segment matching getRootDocument()'s first servers[].url path stripped before comparison, since that path is typically a servlet context path neither the OpenAPI documentation nor the @RestController mapping itself declares. Defaults to true.
      Returns:
      mutable boolean property controlling whether the Spring RestDocs source is enabled
    • getUseOpenApiRequestValidator

      public abstract org.gradle.api.provider.Property<Boolean> getUseOpenApiRequestValidator()
      Whether to treat Atlassian OpenAPI request validator usage as verification evidence. Defaults to false.
      Returns:
      mutable boolean property controlling whether the OpenAPI request validator source is enabled
    • getUseSpringCloudContract

      public abstract org.gradle.api.provider.Property<Boolean> getUseSpringCloudContract()
      Whether to treat Spring Cloud Contract DSL files under getContractsDir() as verification evidence. Defaults to false.
      Returns:
      mutable boolean property controlling whether the Spring Cloud Contract source is enabled
    • getFailOnDoppelganger

      public abstract org.gradle.api.provider.Property<Boolean> getFailOnDoppelganger()
      Whether the build should fail when doppelganger APIs are found. The report is written either way. Defaults to false.
      Returns:
      mutable boolean property controlling whether the build fails on doppelganger APIs
    • getReportDir

      public abstract org.gradle.api.file.DirectoryProperty getReportDir()
      Directory the AsciiDoc report is written to. Defaults to build/reports/doppelganger-api-detector.
      Returns:
      mutable directory property for the report output directory
    • getReportFileName

      public abstract org.gradle.api.provider.Property<String> getReportFileName()
      Name of the generated AsciiDoc report file (without path). Defaults to "doppelganger-apis.adoc".
      Returns:
      mutable string property for the report file name
    • getSystemUnderTestVersion

      public abstract org.gradle.api.provider.Property<String> getSystemUnderTestVersion()
      Version of the system under test whose @RestController classes are scanned, printed in the generated report as e.g. System Under Test version: v1.0.0. Defaults to the project's own version (as set in the build file or a properties file); set this property to override that default, e.g. when the controllers scanned belong to a different artifact than the one being built.
      Returns:
      mutable string property for the system-under-test version
    • getTrackContractHistory

      public abstract org.gradle.api.provider.Property<Boolean> getTrackContractHistory()
      Whether to persist, across builds, a history of when each endpoint first reached each stage of its contract lifecycle - declared, implemented, verified - keyed by a fingerprint of its HTTP verb and path so the history is shared correctly with Shadow and Mirage API Detector when they're pointed at the same getContractHistoryFile(). Defaults to false.

      The history file configured via getContractHistoryFile() is always read when this property is true, regardless of getUpdateContractHistory().

      Returns:
      mutable boolean property controlling whether contract progress history is tracked
    • getContractHistoryFile

      public abstract org.gradle.api.file.RegularFileProperty getContractHistoryFile()
      File that the persisted contract progress history is read from and, when getUpdateContractHistory() is true, written back to. Defaults to "doppelganger-api-detector-contract-history.ndjson" directly in the project directory - deliberately not under build/, since this file is meant to be committed to version control so the history survives across checkouts. Only consulted when getTrackContractHistory() is true.
      Returns:
      mutable file property for the contract history file
    • getUpdateContractHistory

      public abstract org.gradle.api.provider.Property<Boolean> getUpdateContractHistory()
      Whether getContractHistoryFile() is written back to disk after being updated with the current run's endpoints. Defaults to the same value as getTrackContractHistory(). Only consulted when getTrackContractHistory() is true; the history file is always read regardless of this property's value, so a build with this set to false still reports against the up-to-date-in-memory history, it simply doesn't persist it.

      The "doppelgangerApiDetector.updateContractHistory" project property, when set (e.g. -PdoppelgangerApiDetector.updateContractHistory=true), overrides this property for every project in the build regardless of what any project configures here - typically driven from a Gradle property set differently per branch in the CI pipeline, since the plugin itself has no notion of which branch is currently checked out.

      Returns:
      mutable boolean property controlling whether the contract history file is written back
    • getExcludePaths

      public abstract org.gradle.api.provider.ListProperty<String> getExcludePaths()
      Exclusion rule strings, parsed by ExclusionRule.parse(String) - e.g. "/actuator/health" (any verb) or "GET /actuator/**" (verb-restricted, Ant-style */** wildcards). A declared-and-implemented, unverified endpoint matching any configured rule - from here, getExcludeFiles(), or getExcludeWellKnown() - is still a doppelganger API in fact, but is reported under == Excluded Doppelganger APIs instead of == Doppelganger APIs: it never fails getFailOnDoppelganger() and never reaches getContractHistoryFile(). Defaults to empty.
      Returns:
      mutable list property of exclusion rule strings
    • getExcludeFiles

      public abstract org.gradle.api.file.ConfigurableFileCollection getExcludeFiles()
      One or more YAML files of exclusion rules, in the same format bundled well-known sets use:
       exclusions:
         - "/actuator/health"
         - "GET /actuator/**"
       
      Rules from every configured file are combined with getExcludePaths() and getExcludeWellKnown(). Defaults to empty.
      Returns:
      mutable file collection of exclusion rule files
    • getExcludeWellKnown

      public abstract org.gradle.api.provider.ListProperty<String> getExcludeWellKnown()
      Names of bundled, well-known exclusion sets to apply - e.g. "spring-boot-actuator" for Spring Boot Actuator's management endpoints. Combined with getExcludePaths() and getExcludeFiles(). An unrecognised name fails the build. Defaults to empty.
      Returns:
      mutable list property of well-known exclusion set names
    • getIncludeResponseCoverage

      public abstract org.gradle.api.provider.Property<Boolean> getIncludeResponseCoverage()
      Whether the scanContracts task additionally computes, for every declared response code, how many contract tests cover it. Defaults to false: the breakdown is not merely hidden when disabled, it is never computed - this is the more expensive of the two statistics scanContracts can report, since it requires detecting the asserted status code of every matching contract test, not just whether one exists.

      For example, an endpoint GET /v1/foobars declaring response codes 200 and 404, with two contract tests asserting 200 and one asserting 404, reports 200 as covered by 2 test(s) and 404 as covered by 1 test(s) when this is true.

      Returns:
      mutable boolean property controlling whether response coverage is computed
    • getScanContractsReportFileName

      public abstract org.gradle.api.provider.Property<String> getScanContractsReportFileName()
      Name of the scanContracts task's generated AsciiDoc report file (without path), written to the same getReportDir(). Defaults to "contract-coverage.adoc".
      Returns:
      mutable string property for the scanContracts report file name
    • getTrackResponseCoverageHistory

      public abstract org.gradle.api.provider.Property<Boolean> getTrackResponseCoverageHistory()
      Whether to persist, across builds, a history of response code coverage - keyed by endpoint fingerprint and response code, tracking a live test-count gauge rather than milestone timestamps. Defaults to false. Only meaningful together with getIncludeResponseCoverage() - scanContracts fails eagerly if this is true while that is false, since there would be no per-response-code data to persist.
      Returns:
      mutable boolean property controlling whether response coverage history is tracked
    • getResponseCoverageHistoryFile

      public abstract org.gradle.api.file.RegularFileProperty getResponseCoverageHistoryFile()
      File that the persisted response coverage history is read from and, when getUpdateResponseCoverageHistory() is true, written back to. Defaults to "doppelganger-api-detector-response-coverage-history.ndjson" directly in the project directory - deliberately not under build/, for the same reason as getContractHistoryFile(). Only consulted when getTrackResponseCoverageHistory() is true. Deliberately a separate file from getContractHistoryFile(): response coverage is a Doppelganger-only concern with a different record schema, not shared with Shadow or Mirage API Detector.
      Returns:
      mutable file property for the response coverage history file
    • getUpdateResponseCoverageHistory

      public abstract org.gradle.api.provider.Property<Boolean> getUpdateResponseCoverageHistory()
      Whether getResponseCoverageHistoryFile() is written back to disk after being updated with the current run's coverage. Defaults to the same value as getTrackResponseCoverageHistory(). Only consulted when getTrackResponseCoverageHistory() is true; the history file is always read regardless of this property's value.

      The "doppelgangerApiDetector.updateResponseCoverageHistory" project property, when set, overrides this property for every project in the build - the same per-branch-CI-pipeline pattern getUpdateContractHistory() supports, independently of it.

      Returns:
      mutable boolean property controlling whether the response coverage history file is written back