diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml new file mode 100644 index 0000000..c7f57d3 --- /dev/null +++ b/.github/workflows/gradle.yml @@ -0,0 +1,95 @@ +name: "Java CI" +on: + push: + branches: + - '[5-9].[0-9].x' + pull_request: + branches: + - '[5-9].[0-9].x' + workflow_dispatch: +env: + GIT_USER_NAME: 'grails-build' + GIT_USER_EMAIL: 'grails-build@users.noreply.github.com' +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + java: ['17', '21'] + steps: + - name: "📥 Checkout the repository" + uses: actions/checkout@v4 + - name: "☕️ Setup JDK" + uses: actions/setup-java@v4 + with: + distribution: 'liberica' + java-version: ${{ matrix.java }} + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + - name: "🔨 Run Base Tests" + env: + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + DEVELOCITY_BUILD_CACHE_NODE_USER: ${{ secrets.DEVELOCITY_BUILD_CACHE_NODE_USER }} + DEVELOCITY_BUILD_CACHE_NODE_KEY: ${{ secrets.DEVELOCITY_BUILD_CACHE_NODE_KEY }} + run: ./gradlew check --continue + - name: "☄️ Upload Base Tests Results - cache-headers" + if: ${{ always() }} + uses: actions/upload-artifact@v4 + with: + name: testreport-cache-headers-${{ matrix.java }} + path: examples/plugin/build/reports/tests + - name: "☄️ Upload Base Tests Results - standalone app for plugin" + if: ${{ always() }} + uses: actions/upload-artifact@v4 + with: + name: testreport-plugin-test-app-${{ matrix.java }} + path: examples/plugin-test-app/build/reports/tests + - name: "☄️ Upload Base Tests Results - functional app for plugin" + if: ${{ always() }} + uses: actions/upload-artifact@v4 + with: + name: testreport-functional-test-app-${{ matrix.java }} + path: examples/functional-test-app/build/reports/tests + publish: + if: github.event_name == 'push' + needs: build + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: "📥 Checkout the repository" + uses: actions/checkout@v4 + - name: "☕️ Setup JDK" + uses: actions/setup-java@v4 + with: + distribution: 'liberica' + java-version: '17' + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + - name: "📤 Publish to Snapshot (repo.grails.org)" + env: + GRAILS_PUBLISH_RELEASE: 'false' + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + MAVEN_PUBLISH_USERNAME: ${{ secrets.MAVEN_PUBLISH_USERNAME }} + MAVEN_PUBLISH_PASSWORD: ${{ secrets.MAVEN_PUBLISH_PASSWORD }} + MAVEN_PUBLISH_URL: ${{ secrets.MAVEN_PUBLISH_SNAPSHOT_URL }} + working-directory: ./plugin + run: ../gradlew publish + - name: "📜 Generate Documentation" + if: success() + env: + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + working-directory: ./plugin + run: ../gradlew docs + - name: "🚀 Publish to Github Pages" + if: success() + uses: grails/github-pages-deploy-action@grails + env: + SKIP_SNAPSHOT: ${{ contains(needs.publish.outputs.release_version, 'M') }} + TARGET_REPOSITORY: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GH_TOKEN }} + BRANCH: gh-pages + FOLDER: plugin/build/docs + DOC_FOLDER: gh-pages + COMMIT_EMAIL: ${{ env.GIT_USER_EMAIL }} + COMMIT_NAME: ${{ env.GIT_USER_NAME }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8a8bc1f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,163 @@ +name: "Release" +on: + release: + types: [published] +env: + GIT_USER_NAME: 'grails-build' + GIT_USER_EMAIL: 'grails-build@users.noreply.github.com' +jobs: + publish: + permissions: + contents: write # to create release + issues: write # to modify milestones + runs-on: ubuntu-latest + outputs: + release_version: ${{ steps.release_version.outputs.value }} + target_branch: ${{ steps.extract_branch.outputs.value }} + extract_repository_name: ${{ steps.extract_repository_name.outputs.repository_name }} + env: + GIT_USER_NAME: 'grails-build' + GIT_USER_EMAIL: 'grails-build@users.noreply.github.com' + steps: + - name: "📥 Checkout the repository" + uses: actions/checkout@v4 + with: + token: ${{ secrets.GH_TOKEN }} + - name: "Extract repository name" + id: extract_repository_name + run: | + echo "repository_name=${GITHUB_REPOSITORY##*/}" >> $GITHUB_OUTPUT + - name: "☕️ Setup JDK" + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + - name: "📝 Store the target branch" + id: extract_branch + run: | + echo "Determining Target Branch" + TARGET_BRANCH=${GITHUB_REF#refs/heads/} + echo $TARGET_BRANCH + echo "value=${TARGET_BRANCH}" >> $GITHUB_OUTPUT + - name: "📝Set the current release version" + id: release_version + run: echo "value=${GITHUB_REF:11}" >> $GITHUB_OUTPUT + - name: "⚙️ Run pre-release" + uses: grails/github-actions/pre-release@main + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: "🔐 Generate key file for artifact signing" + env: + SECRING_FILE: ${{ secrets.SECRING_FILE }} + run: | + printf "%s" "$SECRING_FILE" | base64 -d > "${{ github.workspace }}/secring.gpg" + - name: "🧩 Run Assemble" + if: success() + id: assemble + env: + DEVELOCITY_BUILD_CACHE_NODE_USER: ${{ secrets.DEVELOCITY_BUILD_CACHE_NODE_USER }} + DEVELOCITY_BUILD_CACHE_NODE_KEY: ${{ secrets.DEVELOCITY_BUILD_CACHE_NODE_KEY }} + run: ./gradlew -U assemble -Psigning.secretKeyRingFile=${{ github.workspace }}/secring.gpg -Psigning.keyId=${{ secrets.SIGNING_KEY }} + - name: "🚀 Publish to Maven Central" + id: publish + env: + GRAILS_PUBLISH_RELEASE: 'true' + NEXUS_PUBLISH_USERNAME: ${{ secrets.NEXUS_PUBLISH_USERNAME }} + NEXUS_PUBLISH_PASSWORD: ${{ secrets.NEXUS_PUBLISH_PASSWORD }} + NEXUS_PUBLISH_URL: ${{ secrets.NEXUS_PUBLISH_RELEASE_URL }} + NEXUS_PUBLISH_STAGING_PROFILE_ID: ${{ secrets.NEXUS_PUBLISH_STAGING_PROFILE_ID }} + NEXUS_PUBLISH_DESCRIPTION: '${{ steps.extract_repository_name.outputs.repository_name }}:${{ steps.release_version.outputs.value }}' + SIGNING_KEY: ${{ secrets.SIGNING_KEY }} + SIGNING_PASSPHRASE: ${{ secrets.SIGNING_PASSPHRASE }} + DEVELOCITY_BUILD_CACHE_NODE_USER: ${{ secrets.DEVELOCITY_BUILD_CACHE_NODE_USER }} + DEVELOCITY_BUILD_CACHE_NODE_KEY: ${{ secrets.DEVELOCITY_BUILD_CACHE_NODE_KEY }} + run: > + ./gradlew + -Psigning.keyId=${{ secrets.SIGNING_KEY }} + -Psigning.secretKeyRingFile=${{ github.workspace }}/secring.gpg + publishToSonatype + closeSonatypeStagingRepository + release: + needs: publish + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: "📥 Checkout repository" + uses: actions/checkout@v4 + - name: "☕️ Setup JDK" + uses: actions/setup-java@v4 + with: + distribution: liberica + java-version: 17 + - name: "📥 Checkout repository" + uses: actions/checkout@v4 + with: + token: ${{ secrets.GH_TOKEN }} + ref: v${{ needs.publish.outputs.release_version }} + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + with: + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + - name: "🏆 Release staging repository" + env: + GRAILS_PUBLISH_RELEASE: 'true' + DEVELOCITY_BUILD_CACHE_NODE_USER: ${{ secrets.DEVELOCITY_BUILD_CACHE_NODE_USER }} + DEVELOCITY_BUILD_CACHE_NODE_KEY: ${{ secrets.DEVELOCITY_BUILD_CACHE_NODE_KEY }} + NEXUS_PUBLISH_USERNAME: ${{ secrets.NEXUS_PUBLISH_USERNAME }} + NEXUS_PUBLISH_PASSWORD: ${{ secrets.NEXUS_PUBLISH_PASSWORD }} + NEXUS_PUBLISH_URL: ${{ secrets.NEXUS_PUBLISH_RELEASE_URL }} + NEXUS_PUBLISH_STAGING_PROFILE_ID: ${{ secrets.NEXUS_PUBLISH_STAGING_PROFILE_ID }} + NEXUS_PUBLISH_DESCRIPTION: '${{ needs.publish.outputs.extract_repository_name }}:${{ needs.publish.outputs.release_version }}' + run: > + ./gradlew + findSonatypeStagingRepository + releaseSonatypeStagingRepository + - name: "⚙️Run post-release" + if: success() + uses: grails/github-actions/post-release@main + with: + token: ${{ secrets.GITHUB_TOKEN }} + env: + SNAPSHOT_SUFFIX: -SNAPSHOT + docs: + needs: publish + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: "📥 Checkout the repository" + uses: actions/checkout@v4 + with: + token: ${{ secrets.GH_TOKEN }} + ref: v${{ needs.publish.outputs.release_version }} + - name: "☕️ Setup JDK" + uses: actions/setup-java@v4 + with: + distribution: 'liberica' + java-version: '17' + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + - name: "📜 Generate Documentation" + env: + DEVELOCITY_BUILD_CACHE_NODE_USER: ${{ secrets.DEVELOCITY_BUILD_CACHE_NODE_USER }} + DEVELOCITY_BUILD_CACHE_NODE_KEY: ${{ secrets.DEVELOCITY_BUILD_CACHE_NODE_KEY }} + working-directory: ./plugin + run: ../gradlew docs + - name: "🚀 Publish to Github Pages" + if: success() + uses: grails/github-pages-deploy-action@v2 + env: + SKIP_SNAPSHOT: ${{ contains(needs.publish.outputs.release_version, 'M') }} + # if multiple releases are being done, this is the last branch - 1 version + #SKIP_LATEST: ${{ !startsWith(needs.publish.outputs.target_branch, '6.2') }} + TARGET_REPOSITORY: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GH_TOKEN }} + BRANCH: gh-pages + FOLDER: plugin/build/docs + DOC_FOLDER: gh-pages + COMMIT_EMAIL: ${{ env.GIT_USER_EMAIL }} + COMMIT_NAME: ${{ env.GIT_USER_NAME }} + VERSION: ${{ needs.publish.outputs.release_version }} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 6b05bf8..5c64a13 100644 --- a/build.gradle +++ b/build.gradle @@ -1,94 +1,62 @@ buildscript { repositories { - mavenLocal() - maven { url "https://repo.grails.org/grails/core" } + maven { + url = 'https://repository.apache.org/content/groups/snapshots' + content { + includeVersionByRegex 'org[.]apache[.]((grails)|(groovy)).*', '.*', '.*-SNAPSHOT' + } + } + maven { url = 'https://repo.grails.org/grails/restricted' } } dependencies { - classpath "org.grails:grails-gradle-plugin:$grailsVersion" - classpath "org.asciidoctor:asciidoctor-gradle-plugin:$asciidoctorGradlePluginVersion" - classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.4.0" - + classpath platform("org.apache.grails:grails-bom:$grailsVersion") + classpath "org.apache.grails:grails-gradle-plugins" + classpath 'org.apache.grails.gradle:grails-publish' } } -def versionTxt = file('version.txt') -version versionTxt.exists() ? versionTxt.text.trim() : '0.1' -group "org.grails.plugins" - -apply plugin:"eclipse" -apply plugin:"idea" -apply plugin:"org.grails.grails-plugin" -apply plugin:"org.grails.grails-plugin-publish" -apply from: "${rootProject.projectDir}/gradle/docs.gradle" -apply plugin: 'org.asciidoctor.convert' -apply plugin: "com.jfrog.artifactory" -repositories { - mavenLocal() - maven { url "https://repo.grails.org/grails/core" } +allprojects { + repositories { + mavenCentral() + maven { + url = 'https://repository.apache.org/content/groups/snapshots' + content { + includeVersionByRegex 'org[.]apache[.]((grails)|(groovy)).*', '.*', '.*-SNAPSHOT' + } + } + maven { url = 'https://repo.grails.org/grails/restricted' } +// mavenLocal() // for local testing, do not commit uncommented + } } -dependencies { - provided "org.springframework.boot:spring-boot-starter-logging" - provided "org.springframework.boot:spring-boot-starter-actuator" - provided "org.springframework.boot:spring-boot-autoconfigure" - provided "org.springframework.boot:spring-boot-starter-tomcat" - - provided "org.grails:grails-web-boot" - provided "org.grails:grails-dependencies" - - testCompile "org.grails:grails-plugin-testing" +version projectVersion +group "org.apache.grails" - console "org.grails:grails-console" - - profile "org.grails.profiles:web-plugin" -} +subprojects { subproject -> + subproject.version = rootProject.version + subproject.group = rootProject.group -bootRun { - jvmArgs('-Dspring.output.ansi.enabled=always') - addResources = true -} -// enable if you wish to package this plugin as a standalone application -bootRepackage.enabled = false -grailsPublish { - user = System.getenv('BINTRAY_USER') ?: project.bintrayUser - key = System.getenv('BINTRAY_KEY') ?: project.bintrayKey - portalUser = System.getenv('GRAILS_PORTAL_USER') ?: project.grailsPortalUser - portalPassword = System.getenv('GRAILS_PORTAL_PASSWORD') ?: project.grailsPortalPassword - repo = 'plugins' - userOrg = "grails" - githubSlug = 'grails-plugins/cache-headers' - license { - name = 'Apache-2.0' + tasks.withType(Test).configureEach { + useJUnitPlatform() } - title = 'Grails Cache Headers Plugin' - desc = 'Improve your application performance with browser caching, with easy ways to set caching headers\n' + - 'in controller responses' - developers = [sdelamo: 'Sergio del Amo'] -} + tasks.matching { it.name == "integrationTest" && it instanceof Test }.configureEach { + shouldRunAfter tasks.test + useJUnitPlatform() + } -artifactory { - contextUrl = 'http://oss.jfrog.org' - publish { - repository { - repoKey = 'oss-snapshot-local' - username = System.getenv("BINTRAY_USER") ?: project.bintrayUser - password = System.getenv("BINTRAY_KEY") ?: project.bintrayKey - } - defaults { - publications('maven') + if (subproject.name == 'cache-headers') { + apply plugin: "org.apache.grails.gradle.grails-publish" + grailsPublish { + githubSlug = 'grails-plugins/cache-headers' + license { + name = 'Apache-2.0' + } + title = 'Grails Cache Headers Plugin' + desc = 'Improve your application performance with browser caching, with easy ways to set caching headers\n' + + 'in controller responses' + developers = [sdelamo: 'Sergio del Amo', rahulshishodia: 'Rahul Shishodia'] } } } -task docs { - dependsOn 'asciidoctor' -} - -jar { - exclude "*TestController**" -} - - -apply from: "${rootProject.projectDir}/gradle/integrationTestVerbose.gradle" -apply from: "${rootProject.projectDir}/gradle/testVerbose.gradle" \ No newline at end of file diff --git a/examples/functional-test-app/build.gradle b/examples/functional-test-app/build.gradle new file mode 100644 index 0000000..b44c8da --- /dev/null +++ b/examples/functional-test-app/build.gradle @@ -0,0 +1,76 @@ +buildscript { + repositories { + mavenLocal() + maven { url "https://repo.grails.org/grails/restricted" } + } + dependencies { + classpath platform("org.apache.grails:grails-bom:$grailsVersion") + classpath "org.apache.grails:grails-gradle-plugins" + classpath "org.apache.grails:grails-data-hibernate5" + } +} + +plugins { + id 'eclipse' + id 'idea' + id 'war' +} + +apply plugin: "org.apache.grails.gradle.grails-web" +apply plugin: "org.apache.grails.gradle.grails-gson" + +repositories { + mavenLocal() + maven { url "https://repo.grails.org/grails/core" } +} + +grails { + plugins { + implementation project(':cache-headers') + } +} + +dependencies { + implementation platform("org.apache.grails:grails-bom:$grailsVersion") + + implementation "org.springframework.boot:spring-boot-starter-logging" + implementation "org.springframework.boot:spring-boot-autoconfigure" + implementation "org.springframework.boot:spring-boot-starter-actuator" + implementation "org.springframework.boot:spring-boot-starter-tomcat" + + implementation "org.apache.grails:grails-core" + implementation "org.apache.grails:grails-url-mappings" + implementation "org.apache.grails:grails-codecs" + implementation "org.apache.grails:grails-rest-transforms" + implementation "org.apache.grails:grails-interceptors" + implementation "org.apache.grails:grails-services" + implementation "org.apache.grails:grails-datasource" + implementation "org.apache.grails:grails-databinding" + implementation "org.apache.grails:grails-async" + implementation "org.apache.grails:grails-web-boot" + implementation "org.apache.grails:grails-logging" + implementation "org.apache.grails:grails-views-gson" + implementation "org.apache.grails:grails-data-mongodb-gson-templates" + implementation "org.apache.grails:grails-cache" + implementation "org.apache.grails:grails-data-hibernate5" + implementation 'org.hibernate:hibernate-ehcache:5.6.15.Final' + + console "org.grails:grails-console" + + profile "org.grails.profiles:rest-api" + runtimeOnly "com.h2database:h2" + + testImplementation "org.apache.grails:grails-testing-support-web" + testImplementation "org.apache.grails:grails-testing-support-views-gson" + testImplementation "org.apache.grails:grails-geb" + testImplementation "org.seleniumhq.selenium:htmlunit-driver:4.13.0" + testImplementation 'org.htmlunit:htmlunit:4.21.0' +} + +apply from: "${rootDir}/gradle/integrationTestVerbose.gradle" +apply from: "${rootDir}/gradle/testVerbose.gradle" + +bootRun { + jvmArgs('-Dspring.output.ansi.enabled=always') + sourceResources sourceSets.main +} diff --git a/examples/functional-test-app/grails-app/conf/application.yml b/examples/functional-test-app/grails-app/conf/application.yml new file mode 100644 index 0000000..cdcb4bd --- /dev/null +++ b/examples/functional-test-app/grails-app/conf/application.yml @@ -0,0 +1,119 @@ +--- +grails: + profile: rest-api + codegen: + defaultPackage: test + spring: + transactionManagement: + proxies: false + gorm: + # Whether to autowire entities. + # Disabled by default for performance reasons. + autowire: false + reactor: + # Whether to translate GORM events into Reactor events + # Disabled by default for performance reasons + events: false +info: + app: + name: '@info.app.name@' + version: '@info.app.version@' + grailsVersion: '@info.app.grailsVersion@' +spring: + main: + banner-mode: "off" + groovy: + template: + check-template-location: false + +# Spring Actuator Endpoints are Disabled by Default +management: + endpoints: + enabled-by-default: false + jmx: + exposure: + include: "*" + +--- +grails: + mime: + disable: + accept: + header: + userAgents: + - Gecko + - WebKit + - Presto + - Trident + types: + json: + - application/json + - text/json + hal: + - application/hal+json + - application/hal+xml + xml: + - text/xml + - application/xml + atom: application/atom+xml + css: text/css + csv: text/csv + js: text/javascript + rss: application/rss+xml + text: text/plain + all: '*/*' + urlmapping: + cache: + maxsize: 1000 + controllers: + defaultScope: singleton + converters: + encoding: UTF-8 + +--- +hibernate: + cache: + queries: false + use_second_level_cache: true + use_query_cache: false + region.factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory + +dataSource: + pooled: true + jmxExport: true + driverClassName: org.h2.Driver + dialect: org.hibernate.dialect.H2Dialect + username: sa + password: '' + +environments: + development: + dataSource: + dbCreate: create-drop + url: jdbc:h2:mem:testDb;DB_CLOSE_DELAY=-1;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + test: + dataSource: + dbCreate: update + url: jdbc:h2:mem:testDb;DB_CLOSE_DELAY=-1;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + production: + dataSource: + dbCreate: none + url: jdbc:h2:./prodDb;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + properties: + jmxEnabled: true + initialSize: 5 + maxActive: 50 + minIdle: 5 + maxIdle: 25 + maxWait: 10000 + maxAge: 600000 + timeBetweenEvictionRunsMillis: 5000 + minEvictableIdleTimeMillis: 60000 + validationQuery: SELECT 1 + validationQueryTimeout: 3 + validationInterval: 15000 + testOnBorrow: true + testWhileIdle: true + testOnReturn: false + jdbcInterceptors: ConnectionState + defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED diff --git a/examples/functional-test-app/grails-app/conf/logback-spring.xml b/examples/functional-test-app/grails-app/conf/logback-spring.xml new file mode 100644 index 0000000..5913114 --- /dev/null +++ b/examples/functional-test-app/grails-app/conf/logback-spring.xml @@ -0,0 +1,37 @@ + + + + + + + + + + UTF-8 + + %clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(---){faint} [%15.15t] %clr(%-40.40logger{39}){cyan} : %m%n%wex + + + + + + + ${LOG_DIR:-build}/stacktrace.log + true + + %level %logger - %msg%n + + + + + + + + + + + + + diff --git a/examples/functional-test-app/grails-app/conf/spring/resources.groovy b/examples/functional-test-app/grails-app/conf/spring/resources.groovy new file mode 100644 index 0000000..2a54949 --- /dev/null +++ b/examples/functional-test-app/grails-app/conf/spring/resources.groovy @@ -0,0 +1,8 @@ +package spring + +import grails.plugin.json.view.mvc.JsonViewResolver + +// Place your Spring DSL code here +beans = { + jsonSmartViewResolver(JsonViewResolver) +} diff --git a/functional-test-app/grails-app/controllers/test/ApplicationController.groovy b/examples/functional-test-app/grails-app/controllers/test/ApplicationController.groovy similarity index 100% rename from functional-test-app/grails-app/controllers/test/ApplicationController.groovy rename to examples/functional-test-app/grails-app/controllers/test/ApplicationController.groovy diff --git a/functional-test-app/grails-app/controllers/test/BookController.groovy b/examples/functional-test-app/grails-app/controllers/test/BookController.groovy similarity index 100% rename from functional-test-app/grails-app/controllers/test/BookController.groovy rename to examples/functional-test-app/grails-app/controllers/test/BookController.groovy diff --git a/functional-test-app/grails-app/controllers/test/UrlMappings.groovy b/examples/functional-test-app/grails-app/controllers/test/UrlMappings.groovy similarity index 100% rename from functional-test-app/grails-app/controllers/test/UrlMappings.groovy rename to examples/functional-test-app/grails-app/controllers/test/UrlMappings.groovy diff --git a/functional-test-app/grails-app/domain/test/Book.groovy b/examples/functional-test-app/grails-app/domain/test/Book.groovy similarity index 62% rename from functional-test-app/grails-app/domain/test/Book.groovy rename to examples/functional-test-app/grails-app/domain/test/Book.groovy index 70fa871..af533c1 100644 --- a/functional-test-app/grails-app/domain/test/Book.groovy +++ b/examples/functional-test-app/grails-app/domain/test/Book.groovy @@ -4,4 +4,8 @@ class Book { String name Date dateCreated Date lastUpdated + + static mapping = { + table 'books' + } } \ No newline at end of file diff --git a/functional-test-app/grails-app/i18n/messages.properties b/examples/functional-test-app/grails-app/i18n/messages.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages.properties rename to examples/functional-test-app/grails-app/i18n/messages.properties diff --git a/functional-test-app/grails-app/i18n/messages_cs_CZ.properties b/examples/functional-test-app/grails-app/i18n/messages_cs_CZ.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_cs_CZ.properties rename to examples/functional-test-app/grails-app/i18n/messages_cs_CZ.properties diff --git a/functional-test-app/grails-app/i18n/messages_da.properties b/examples/functional-test-app/grails-app/i18n/messages_da.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_da.properties rename to examples/functional-test-app/grails-app/i18n/messages_da.properties diff --git a/functional-test-app/grails-app/i18n/messages_de.properties b/examples/functional-test-app/grails-app/i18n/messages_de.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_de.properties rename to examples/functional-test-app/grails-app/i18n/messages_de.properties diff --git a/functional-test-app/grails-app/i18n/messages_es.properties b/examples/functional-test-app/grails-app/i18n/messages_es.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_es.properties rename to examples/functional-test-app/grails-app/i18n/messages_es.properties diff --git a/functional-test-app/grails-app/i18n/messages_fr.properties b/examples/functional-test-app/grails-app/i18n/messages_fr.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_fr.properties rename to examples/functional-test-app/grails-app/i18n/messages_fr.properties diff --git a/functional-test-app/grails-app/i18n/messages_it.properties b/examples/functional-test-app/grails-app/i18n/messages_it.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_it.properties rename to examples/functional-test-app/grails-app/i18n/messages_it.properties diff --git a/functional-test-app/grails-app/i18n/messages_ja.properties b/examples/functional-test-app/grails-app/i18n/messages_ja.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_ja.properties rename to examples/functional-test-app/grails-app/i18n/messages_ja.properties diff --git a/functional-test-app/grails-app/i18n/messages_nb.properties b/examples/functional-test-app/grails-app/i18n/messages_nb.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_nb.properties rename to examples/functional-test-app/grails-app/i18n/messages_nb.properties diff --git a/functional-test-app/grails-app/i18n/messages_nl.properties b/examples/functional-test-app/grails-app/i18n/messages_nl.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_nl.properties rename to examples/functional-test-app/grails-app/i18n/messages_nl.properties diff --git a/functional-test-app/grails-app/i18n/messages_pl.properties b/examples/functional-test-app/grails-app/i18n/messages_pl.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_pl.properties rename to examples/functional-test-app/grails-app/i18n/messages_pl.properties diff --git a/functional-test-app/grails-app/i18n/messages_pt_BR.properties b/examples/functional-test-app/grails-app/i18n/messages_pt_BR.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_pt_BR.properties rename to examples/functional-test-app/grails-app/i18n/messages_pt_BR.properties diff --git a/functional-test-app/grails-app/i18n/messages_pt_PT.properties b/examples/functional-test-app/grails-app/i18n/messages_pt_PT.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_pt_PT.properties rename to examples/functional-test-app/grails-app/i18n/messages_pt_PT.properties diff --git a/functional-test-app/grails-app/i18n/messages_ru.properties b/examples/functional-test-app/grails-app/i18n/messages_ru.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_ru.properties rename to examples/functional-test-app/grails-app/i18n/messages_ru.properties diff --git a/functional-test-app/grails-app/i18n/messages_sv.properties b/examples/functional-test-app/grails-app/i18n/messages_sv.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_sv.properties rename to examples/functional-test-app/grails-app/i18n/messages_sv.properties diff --git a/functional-test-app/grails-app/i18n/messages_th.properties b/examples/functional-test-app/grails-app/i18n/messages_th.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_th.properties rename to examples/functional-test-app/grails-app/i18n/messages_th.properties diff --git a/functional-test-app/grails-app/i18n/messages_zh_CN.properties b/examples/functional-test-app/grails-app/i18n/messages_zh_CN.properties similarity index 100% rename from functional-test-app/grails-app/i18n/messages_zh_CN.properties rename to examples/functional-test-app/grails-app/i18n/messages_zh_CN.properties diff --git a/functional-test-app/grails-app/init/test/Application.groovy b/examples/functional-test-app/grails-app/init/test/Application.groovy similarity index 100% rename from functional-test-app/grails-app/init/test/Application.groovy rename to examples/functional-test-app/grails-app/init/test/Application.groovy diff --git a/functional-test-app/grails-app/init/test/BootStrap.groovy b/examples/functional-test-app/grails-app/init/test/BootStrap.groovy similarity index 100% rename from functional-test-app/grails-app/init/test/BootStrap.groovy rename to examples/functional-test-app/grails-app/init/test/BootStrap.groovy diff --git a/functional-test-app/grails-app/views/application/index.gson b/examples/functional-test-app/grails-app/views/application/index.gson similarity index 100% rename from functional-test-app/grails-app/views/application/index.gson rename to examples/functional-test-app/grails-app/views/application/index.gson diff --git a/functional-test-app/grails-app/views/book/bookDisplay.gson b/examples/functional-test-app/grails-app/views/book/bookDisplay.gson similarity index 100% rename from functional-test-app/grails-app/views/book/bookDisplay.gson rename to examples/functional-test-app/grails-app/views/book/bookDisplay.gson diff --git a/functional-test-app/grails-app/views/error.gson b/examples/functional-test-app/grails-app/views/error.gson similarity index 100% rename from functional-test-app/grails-app/views/error.gson rename to examples/functional-test-app/grails-app/views/error.gson diff --git a/functional-test-app/grails-app/views/errors/_errors.gson b/examples/functional-test-app/grails-app/views/errors/_errors.gson similarity index 100% rename from functional-test-app/grails-app/views/errors/_errors.gson rename to examples/functional-test-app/grails-app/views/errors/_errors.gson diff --git a/functional-test-app/grails-app/views/notFound.gson b/examples/functional-test-app/grails-app/views/notFound.gson similarity index 100% rename from functional-test-app/grails-app/views/notFound.gson rename to examples/functional-test-app/grails-app/views/notFound.gson diff --git a/functional-test-app/grails-app/views/object/_object.gson b/examples/functional-test-app/grails-app/views/object/_object.gson similarity index 100% rename from functional-test-app/grails-app/views/object/_object.gson rename to examples/functional-test-app/grails-app/views/object/_object.gson diff --git a/functional-test-app/src/integration-test/groovy/test/BookControllerSpec.groovy b/examples/functional-test-app/src/integration-test/groovy/test/BookControllerSpec.groovy similarity index 71% rename from functional-test-app/src/integration-test/groovy/test/BookControllerSpec.groovy rename to examples/functional-test-app/src/integration-test/groovy/test/BookControllerSpec.groovy index 5c21a66..e682920 100644 --- a/functional-test-app/src/integration-test/groovy/test/BookControllerSpec.groovy +++ b/examples/functional-test-app/src/integration-test/groovy/test/BookControllerSpec.groovy @@ -1,8 +1,8 @@ package test -import grails.plugins.rest.client.RestBuilder -import grails.test.mixin.integration.Integration -import grails.transaction.Rollback +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration +import org.springframework.web.client.RestTemplate import spock.lang.Specification @Rollback @@ -19,14 +19,13 @@ class BookControllerSpec extends Specification { def "book show"() { given: - RestBuilder rest = new RestBuilder() + RestTemplate rest = new RestTemplate() expect: Book.read(1) when: - - def resp = rest.get("http://localhost:${serverPort}/book/1") + def resp = rest.getForEntity("http://localhost:${serverPort}/book/1", String) then: resp.statusCode.value() == 200 diff --git a/functional-test-app/src/test/groovy/test/BookControllerAllowedMethodsSpec.groovy b/examples/functional-test-app/src/test/groovy/test/BookControllerAllowedMethodsSpec.groovy similarity index 68% rename from functional-test-app/src/test/groovy/test/BookControllerAllowedMethodsSpec.groovy rename to examples/functional-test-app/src/test/groovy/test/BookControllerAllowedMethodsSpec.groovy index 65d0801..7acd832 100644 --- a/functional-test-app/src/test/groovy/test/BookControllerAllowedMethodsSpec.groovy +++ b/examples/functional-test-app/src/test/groovy/test/BookControllerAllowedMethodsSpec.groovy @@ -1,13 +1,11 @@ package test -import grails.test.mixin.TestFor +import grails.testing.web.controllers.ControllerUnitTest import spock.lang.Specification import spock.lang.Unroll -import static javax.servlet.http.HttpServletResponse.SC_METHOD_NOT_ALLOWED -import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND +import static jakarta.servlet.http.HttpServletResponse.SC_METHOD_NOT_ALLOWED -@TestFor(BookController) -class BookControllerAllowedMethodsSpec extends Specification { +class BookControllerAllowedMethodsSpec extends Specification implements ControllerUnitTest { @Unroll def "test TestController.show does not accept #method requests"(String method) { diff --git a/examples/plugin-test-app/build.gradle b/examples/plugin-test-app/build.gradle new file mode 100644 index 0000000..e56a038 --- /dev/null +++ b/examples/plugin-test-app/build.gradle @@ -0,0 +1,46 @@ +plugins { + id 'eclipse' + id 'idea' +} + +apply plugin:"org.apache.grails.gradle.grails-web" + +grails { + plugins { + implementation project(':cache-headers') + } +} + +dependencies { + implementation platform("org.apache.grails:grails-bom:$grailsVersion") + + implementation "org.apache.grails:grails-dependencies-starter-web" + + implementation "org.apache.grails:grails-web-boot" + implementation "org.springframework.boot:spring-boot-autoconfigure" + implementation "org.springframework.boot:spring-boot-starter" + implementation "org.springframework.boot:spring-boot-starter-actuator" + implementation "org.springframework.boot:spring-boot-starter-logging" + implementation "org.springframework.boot:spring-boot-starter-tomcat" + + implementation("org.apache.groovy:groovy-dateutil:5.0.3") + + implementation "io.methvin:directory-watcher:0.3.0" + implementation "net.java.dev.jna:jna:5.18.1" + + testImplementation "org.apache.grails:grails-testing-support-web" + testImplementation "org.spockframework:spock-core" + + console "org.apache.grails:grails-console" + + profile "org.apache.grails.profiles:web-plugin" +} + +bootRun { + jvmArgs('-Dspring.output.ansi.enabled=always') + sourceResources sourceSets.main +} + +bootJar.enabled = true + +apply from: "${rootProject.projectDir}/gradle/integrationTestVerbose.gradle" diff --git a/examples/plugin-test-app/grails-app/conf/application.yml b/examples/plugin-test-app/grails-app/conf/application.yml new file mode 100644 index 0000000..34283e8 --- /dev/null +++ b/examples/plugin-test-app/grails-app/conf/application.yml @@ -0,0 +1,91 @@ +--- +grails: + profile: web-plugin + codegen: + defaultPackage: grails.plugins.cacheheaders + spring: + transactionManagement: + proxies: false + gorm: + # Whether to autowire entities. + # Disabled by default for performance reasons. + autowire: false + reactor: + # Whether to translate GORM events into Reactor events + # Disabled by default for performance reasons + events: false +info: + app: + name: '@info.app.name@' + version: '@info.app.version@' + grailsVersion: '@info.app.grailsVersion@' +spring: + main: + banner-mode: "off" + groovy: + template: + check-template-location: false + +# Spring Actuator Endpoints are Disabled by Default +management: + endpoints: + enabled-by-default: false + jmx: + exposure: + include: "*" + +--- +grails: + mime: + disable: + accept: + header: + userAgents: + - Gecko + - WebKit + - Presto + - Trident + types: + all: '*/*' + atom: application/atom+xml + css: text/css + csv: text/csv + form: application/x-www-form-urlencoded + html: + - text/html + - application/xhtml+xml + js: text/javascript + json: + - application/json + - text/json + multipartForm: multipart/form-data + pdf: application/pdf + rss: application/rss+xml + text: text/plain + hal: + - application/hal+json + - application/hal+xml + xml: + - text/xml + - application/xml + urlmapping: + cache: + maxsize: 1000 + controllers: + defaultScope: singleton + converters: + encoding: UTF-8 + views: + default: + codec: html + gsp: + encoding: UTF-8 + htmlcodec: xml + codecs: + expression: html + scriptlets: html + taglib: none + staticparts: none +spring: + jmx: + unique-names: true diff --git a/examples/plugin-test-app/grails-app/conf/logback-spring.xml b/examples/plugin-test-app/grails-app/conf/logback-spring.xml new file mode 100644 index 0000000..cc7c9e0 --- /dev/null +++ b/examples/plugin-test-app/grails-app/conf/logback-spring.xml @@ -0,0 +1,19 @@ + + + + + + true + + ${CONSOLE_LOG_THRESHOLD} + + + ${CONSOLE_LOG_PATTERN} + ${CONSOLE_LOG_CHARSET} + + + + + + + diff --git a/examples/plugin-test-app/grails-app/conf/spring/resources.groovy b/examples/plugin-test-app/grails-app/conf/spring/resources.groovy new file mode 100644 index 0000000..302e501 --- /dev/null +++ b/examples/plugin-test-app/grails-app/conf/spring/resources.groovy @@ -0,0 +1,3 @@ +beans = { + +} diff --git a/grails-app/controllers/com/grailsrocks/cacheheaders/TestController.groovy b/examples/plugin-test-app/grails-app/controllers/grails/plugins/cacheheaders/TestController.groovy similarity index 94% rename from grails-app/controllers/com/grailsrocks/cacheheaders/TestController.groovy rename to examples/plugin-test-app/grails-app/controllers/grails/plugins/cacheheaders/TestController.groovy index 75cea6a..cd404eb 100644 --- a/grails-app/controllers/com/grailsrocks/cacheheaders/TestController.groovy +++ b/examples/plugin-test-app/grails-app/controllers/grails/plugins/cacheheaders/TestController.groovy @@ -1,4 +1,4 @@ -package com.grailsrocks.cacheheaders +package grails.plugins.cacheheaders import grails.plugins.cacheheaders.CacheHeadersTrait diff --git a/grails-app/init/grails/plugins/cacheheaders/Application.groovy b/examples/plugin-test-app/grails-app/init/grails/plugins/cacheheaders/Application.groovy similarity index 84% rename from grails-app/init/grails/plugins/cacheheaders/Application.groovy rename to examples/plugin-test-app/grails-app/init/grails/plugins/cacheheaders/Application.groovy index f9416c9..bbd4d40 100644 --- a/grails-app/init/grails/plugins/cacheheaders/Application.groovy +++ b/examples/plugin-test-app/grails-app/init/grails/plugins/cacheheaders/Application.groovy @@ -2,11 +2,9 @@ package grails.plugins.cacheheaders import grails.boot.GrailsApp import grails.boot.config.GrailsAutoConfiguration -import grails.plugins.metadata.PluginSource import groovy.transform.CompileStatic @CompileStatic -@PluginSource class Application extends GrailsAutoConfiguration { static void main(String[] args) { GrailsApp.run(Application, args) diff --git a/examples/plugin-test-app/grails-app/init/grails/plugins/cacheheaders/BootStrap.groovy b/examples/plugin-test-app/grails-app/init/grails/plugins/cacheheaders/BootStrap.groovy new file mode 100644 index 0000000..71d445d --- /dev/null +++ b/examples/plugin-test-app/grails-app/init/grails/plugins/cacheheaders/BootStrap.groovy @@ -0,0 +1,17 @@ +package grails.plugins.cacheheaders + +import groovy.transform.CompileStatic + +@CompileStatic +class BootStrap { + + def init = { + + } + + + def destroy = { + + } + +} diff --git a/src/integration-test/groovy/cacheheaders/CacheMethodsSpec.groovy b/examples/plugin-test-app/src/integration-test/groovy/grails/plugins/cacheheaders/CacheMethodsSpec.groovy similarity index 92% rename from src/integration-test/groovy/cacheheaders/CacheMethodsSpec.groovy rename to examples/plugin-test-app/src/integration-test/groovy/grails/plugins/cacheheaders/CacheMethodsSpec.groovy index 08ae2ea..3f5a454 100644 --- a/src/integration-test/groovy/cacheheaders/CacheMethodsSpec.groovy +++ b/examples/plugin-test-app/src/integration-test/groovy/grails/plugins/cacheheaders/CacheMethodsSpec.groovy @@ -1,12 +1,11 @@ -package cacheheaders +package grails.plugins.cacheheaders -import com.grailsrocks.cacheheaders.TestController -import grails.plugins.cacheheaders.CacheHeadersService +import grails.testing.mixin.integration.Integration +import grails.util.Holders import spock.lang.Specification import grails.util.GrailsWebMockUtil import org.springframework.beans.factory.annotation.Autowired import spock.lang.Shared -import grails.test.mixin.integration.Integration import spock.lang.Subject import java.text.SimpleDateFormat @@ -28,7 +27,7 @@ class CacheMethodsSpec extends Specification { def "preset can turn caching off"() { given: - grails.util.Holders.config.cache.headers.presets.presetDeny = false + Holders.config.cache.headers.presets.presetDeny = false when: testController.presetTest1() diff --git a/src/test/groovy/grails/plugins/cacheheaders/CacheHeadersServiceSpec.groovy b/examples/plugin-test-app/src/test/groovy/grails/plugins/cacheheaders/CacheHeadersServiceSpec.groovy similarity index 96% rename from src/test/groovy/grails/plugins/cacheheaders/CacheHeadersServiceSpec.groovy rename to examples/plugin-test-app/src/test/groovy/grails/plugins/cacheheaders/CacheHeadersServiceSpec.groovy index ac01de0..1413efe 100644 --- a/src/test/groovy/grails/plugins/cacheheaders/CacheHeadersServiceSpec.groovy +++ b/examples/plugin-test-app/src/test/groovy/grails/plugins/cacheheaders/CacheHeadersServiceSpec.groovy @@ -1,14 +1,14 @@ package grails.plugins.cacheheaders -import grails.test.mixin.TestFor +import grails.plugins.cacheheaders.CacheHeadersService +import grails.testing.services.ServiceUnitTest import org.springframework.mock.web.MockHttpServletRequest import org.springframework.mock.web.MockHttpServletResponse import spock.lang.Specification import java.text.SimpleDateFormat -@TestFor(CacheHeadersService) -class CacheHeadersServiceSpec extends Specification { +class CacheHeadersServiceSpec extends Specification implements ServiceUnitTest { MockHttpServletRequest req MockHttpServletResponse resp diff --git a/functional-test-app/build.gradle b/functional-test-app/build.gradle deleted file mode 100644 index c2647bf..0000000 --- a/functional-test-app/build.gradle +++ /dev/null @@ -1,66 +0,0 @@ -buildscript { - repositories { - mavenLocal() - maven { url "https://repo.grails.org/grails/core" } - } - dependencies { - classpath "org.grails:grails-gradle-plugin:$grailsVersion" - classpath "org.grails.plugins:hibernate5:${gormVersion-".RELEASE"}" - classpath "org.grails.plugins:views-gradle:1.1.6" - } -} - -version "0.1" -group "test" - -apply plugin:"eclipse" -apply plugin:"idea" -apply plugin:"war" -apply plugin:"org.grails.grails-web" -apply plugin:"org.grails.plugins.views-json" - -repositories { - mavenLocal() - maven { url "https://repo.grails.org/grails/core" } -} - -dependencies { - compile "org.springframework.boot:spring-boot-starter-logging" - compile "org.springframework.boot:spring-boot-autoconfigure" - compile "org.grails:grails-core" - compile "org.springframework.boot:spring-boot-starter-actuator" - compile "org.springframework.boot:spring-boot-starter-tomcat" - compile "org.grails:grails-plugin-url-mappings" - compile "org.grails:grails-plugin-rest" - compile "org.grails:grails-plugin-codecs" - compile "org.grails:grails-plugin-interceptors" - compile "org.grails:grails-plugin-services" - compile "org.grails:grails-plugin-datasource" - compile "org.grails:grails-plugin-databinding" - compile "org.grails:grails-plugin-async" - compile "org.grails:grails-web-boot" - compile "org.grails:grails-logging" - compile "org.grails.plugins:cache" - compile "org.grails.plugins:hibernate5" - compile "org.hibernate:hibernate-core:5.1.3.Final" - compile "org.hibernate:hibernate-ehcache:5.1.3.Final" - compile "org.grails.plugins:views-json" - compile "org.grails.plugins:views-json-templates" - console "org.grails:grails-console" - profile "org.grails.profiles:rest-api" - runtime "com.h2database:h2" - testCompile "org.grails:grails-plugin-testing" - testCompile "org.grails.plugins:geb" - testCompile "org.grails:grails-datastore-rest-client" - testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1" - testRuntime "net.sourceforge.htmlunit:htmlunit:2.18" -} - -apply from: "../gradle/cache-headers.gradle" -apply from: "../gradle/integrationTestVerbose.gradle" -apply from: "../gradle/testVerbose.gradle" - -bootRun { - jvmArgs('-Dspring.output.ansi.enabled=always') - addResources = true -} diff --git a/functional-test-app/gradle.properties b/functional-test-app/gradle.properties deleted file mode 100644 index 2ec2ead..0000000 --- a/functional-test-app/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -grailsVersion=3.2.11 -gormVersion=6.0.12.RELEASE -gradleWrapperVersion=3.4.1 diff --git a/functional-test-app/gradle/wrapper/gradle-wrapper.jar b/functional-test-app/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index deedc7f..0000000 Binary files a/functional-test-app/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/functional-test-app/gradle/wrapper/gradle-wrapper.properties b/functional-test-app/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index cc2cec1..0000000 --- a/functional-test-app/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Nov 27 23:09:32 CET 2015 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-bin.zip diff --git a/functional-test-app/gradlew b/functional-test-app/gradlew deleted file mode 100755 index 9d82f78..0000000 --- a/functional-test-app/gradlew +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/functional-test-app/gradlew.bat b/functional-test-app/gradlew.bat deleted file mode 100755 index aec9973..0000000 --- a/functional-test-app/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/functional-test-app/grails-app/conf/application.yml b/functional-test-app/grails-app/conf/application.yml deleted file mode 100644 index 9ce20b0..0000000 --- a/functional-test-app/grails-app/conf/application.yml +++ /dev/null @@ -1,116 +0,0 @@ ---- -grails: - profile: rest-api - codegen: - defaultPackage: test - spring: - transactionManagement: - proxies: false - gorm: - # Whether to autowire entities. - # Disabled by default for performance reasons. - autowire: false - reactor: - # Whether to translate GORM events into Reactor events - # Disabled by default for performance reasons - events: false -info: - app: - name: '@info.app.name@' - version: '@info.app.version@' - grailsVersion: '@info.app.grailsVersion@' -spring: - main: - banner-mode: "off" - groovy: - template: - check-template-location: false - -# Spring Actuator Endpoints are Disabled by Default -endpoints: - enabled: false - jmx: - enabled: true - ---- -grails: - mime: - disable: - accept: - header: - userAgents: - - Gecko - - WebKit - - Presto - - Trident - types: - json: - - application/json - - text/json - hal: - - application/hal+json - - application/hal+xml - xml: - - text/xml - - application/xml - atom: application/atom+xml - css: text/css - csv: text/csv - js: text/javascript - rss: application/rss+xml - text: text/plain - all: '*/*' - urlmapping: - cache: - maxsize: 1000 - controllers: - defaultScope: singleton - converters: - encoding: UTF-8 - ---- -hibernate: - cache: - queries: false - use_second_level_cache: true - use_query_cache: false - region.factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory - -dataSource: - pooled: true - jmxExport: true - driverClassName: org.h2.Driver - username: sa - password: - -environments: - development: - dataSource: - dbCreate: create-drop - url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE - test: - dataSource: - dbCreate: update - url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE - production: - dataSource: - dbCreate: none - url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE - properties: - jmxEnabled: true - initialSize: 5 - maxActive: 50 - minIdle: 5 - maxIdle: 25 - maxWait: 10000 - maxAge: 600000 - timeBetweenEvictionRunsMillis: 5000 - minEvictableIdleTimeMillis: 60000 - validationQuery: SELECT 1 - validationQueryTimeout: 3 - validationInterval: 15000 - testOnBorrow: true - testWhileIdle: true - testOnReturn: false - jdbcInterceptors: ConnectionState - defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED diff --git a/functional-test-app/grails-app/conf/logback.groovy b/functional-test-app/grails-app/conf/logback.groovy deleted file mode 100644 index 20f85e1..0000000 --- a/functional-test-app/grails-app/conf/logback.groovy +++ /dev/null @@ -1,36 +0,0 @@ -import grails.util.BuildSettings -import grails.util.Environment -import org.springframework.boot.logging.logback.ColorConverter -import org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter - -import java.nio.charset.Charset - -conversionRule 'clr', ColorConverter -conversionRule 'wex', WhitespaceThrowableProxyConverter - -// See http://logback.qos.ch/manual/groovy.html for details on configuration -appender('STDOUT', ConsoleAppender) { - encoder(PatternLayoutEncoder) { - charset = Charset.forName('UTF-8') - - pattern = - '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} ' + // Date - '%clr(%5p) ' + // Log level - '%clr(---){faint} %clr([%15.15t]){faint} ' + // Thread - '%clr(%-40.40logger{39}){cyan} %clr(:){faint} ' + // Logger - '%m%n%wex' // Message - } -} - -def targetDir = BuildSettings.TARGET_DIR -if (Environment.isDevelopmentMode() && targetDir != null) { - appender("FULL_STACKTRACE", FileAppender) { - file = "${targetDir}/stacktrace.log" - append = true - encoder(PatternLayoutEncoder) { - pattern = "%level %logger - %msg%n" - } - } - logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false) -} -root(ERROR, ['STDOUT']) diff --git a/functional-test-app/grails-app/conf/spring/resources.groovy b/functional-test-app/grails-app/conf/spring/resources.groovy deleted file mode 100644 index fa95006..0000000 --- a/functional-test-app/grails-app/conf/spring/resources.groovy +++ /dev/null @@ -1,3 +0,0 @@ -// Place your Spring DSL code here -beans = { -} diff --git a/functional-test-app/grails-wrapper.jar b/functional-test-app/grails-wrapper.jar deleted file mode 100644 index bc85146..0000000 Binary files a/functional-test-app/grails-wrapper.jar and /dev/null differ diff --git a/functional-test-app/grailsw b/functional-test-app/grailsw deleted file mode 100755 index c2c921c..0000000 --- a/functional-test-app/grailsw +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Grails start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRAILS_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-XX:+TieredCompilation" "-XX:TieredStopAtLevel=1" "-XX:CICompilerCount=3"' - - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -JAR_PATH=$APP_HOME/grails-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRAILS_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRAILS_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRAILS_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRAILS_OPTS - -exec "$JAVACMD" -jar "${JVM_OPTS[@]}" "$JAR_PATH" "$@" diff --git a/functional-test-app/grailsw.bat b/functional-test-app/grailsw.bat deleted file mode 100755 index c48c384..0000000 --- a/functional-test-app/grailsw.bat +++ /dev/null @@ -1,89 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Grails startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRAILS_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-XX:+TieredCompilation" "-XX:TieredStopAtLevel=1" "-XX:CICompilerCount=3" - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line -set JAR_PATH=%APP_HOME%/grails-wrapper.jar - -@rem Execute Grails -"%JAVA_EXE%" -jar %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRAILS_OPTS% %JAR_PATH% %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRAILS_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRAILS_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/functional-test-app/settings.gradle b/functional-test-app/settings.gradle deleted file mode 100644 index 98c0a46..0000000 --- a/functional-test-app/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name='test' diff --git a/gradle.properties b/gradle.properties index de953dc..4f3e74a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,10 +1,15 @@ -grailsVersion=3.2.10 -gradleWrapperVersion=3.4.1 -asciidoctorGradlePluginVersion=1.5.3 +projectVersion=3.0.0 +grailsVersion=7.0.5 +gradleWrapperVersion=8.14.2 +asciidoctorJvmVersion=4.0.4 +artifactoryVersion=5.2.5 +customUserDataVersion=2.2.1 +develocityVersion=4.0 websiteUrl=http://grails-plugins.github.io/cache-headers issueTrackerUrl=https://github.com/grails-plugins/cache-headers/issues vcsUrl=https://github.com/grails-plugins/cache-headers bintrayUser= bintrayKey= grailsPortalUser= -grailsPortalPassword= \ No newline at end of file +grailsPortalPassword= +GRAILS_PUBLISH_RELEASE=false diff --git a/gradle/cache-headers.gradle b/gradle/cache-headers.gradle deleted file mode 100644 index ea33932..0000000 --- a/gradle/cache-headers.gradle +++ /dev/null @@ -1,16 +0,0 @@ -File pluginDir = file('.').parentFile -File versionTxt -while (true) { - versionTxt = new File(pluginDir, 'version.txt') - if (versionTxt.exists()) { - break - } - pluginDir = pluginDir.parentFile -} -project.ext.pluginName = pluginDir.name - 'grails-' - -project.ext.pluginVersion = versionTxt.text.trim() - -dependencies { - compile "org.grails.plugins:$pluginName:$pluginVersion" -} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b395c81..018086e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-all.zip diff --git a/grails-app/conf/application.yml b/grails-app/conf/application.yml deleted file mode 100644 index cfe636e..0000000 --- a/grails-app/conf/application.yml +++ /dev/null @@ -1,89 +0,0 @@ ---- -grails: - profile: web-plugin - codegen: - defaultPackage: grails.plugins.cacheheaders - spring: - transactionManagement: - proxies: false - gorm: - # Whether to autowire entities. - # Disabled by default for performance reasons. - autowire: false - reactor: - # Whether to translate GORM events into Reactor events - # Disabled by default for performance reasons - events: false -info: - app: - name: '@info.app.name@' - version: '@info.app.version@' - grailsVersion: '@info.app.grailsVersion@' -spring: - main: - banner-mode: "off" - groovy: - template: - check-template-location: false - -# Spring Actuator Endpoints are Disabled by Default -endpoints: - enabled: false - jmx: - enabled: true - ---- -grails: - mime: - disable: - accept: - header: - userAgents: - - Gecko - - WebKit - - Presto - - Trident - types: - all: '*/*' - atom: application/atom+xml - css: text/css - csv: text/csv - form: application/x-www-form-urlencoded - html: - - text/html - - application/xhtml+xml - js: text/javascript - json: - - application/json - - text/json - multipartForm: multipart/form-data - pdf: application/pdf - rss: application/rss+xml - text: text/plain - hal: - - application/hal+json - - application/hal+xml - xml: - - text/xml - - application/xml - urlmapping: - cache: - maxsize: 1000 - controllers: - defaultScope: singleton - converters: - encoding: UTF-8 - views: - default: - codec: html - gsp: - encoding: UTF-8 - htmlcodec: xml - codecs: - expression: html - scriptlets: html - taglib: none - staticparts: none -endpoints: - jmx: - unique-names: true diff --git a/plugin/build.gradle b/plugin/build.gradle new file mode 100644 index 0000000..94c4103 --- /dev/null +++ b/plugin/build.gradle @@ -0,0 +1,51 @@ +plugins { + id 'eclipse' + id 'idea' + id 'java-library' + id 'maven-publish' + id 'org.asciidoctor.jvm.convert' version "$asciidoctorJvmVersion" + id 'com.jfrog.artifactory' version "$artifactoryVersion" +} + +version project.version + +apply plugin:"org.apache.grails.gradle.grails-plugin" +apply plugin: 'org.apache.grails.gradle.grails-exploded' +apply from: "${rootProject.projectDir}/gradle/docs.gradle" + +compileJava.options.release = 17 + +dependencies { + implementation platform("org.apache.grails:grails-bom:$grailsVersion") + compileOnly "org.apache.grails:grails-dependencies-starter-web" + + implementation("org.apache.groovy:groovy-dateutil:4.0.29") + + testImplementation "org.apache.grails:grails-testing-support-web" +} + +grails { + springDependencyManagement = false +} + +bootJar.enabled = false + +artifactory { + contextUrl = 'http://oss.jfrog.org' + publish { + repository { + repoKey = 'oss-snapshot-local' + username = System.getenv("BINTRAY_USER") ?: project.bintrayUser + password = System.getenv("BINTRAY_KEY") ?: project.bintrayKey + } + defaults { + publications('maven') + } + } +} + +tasks.register('docs') { + dependsOn 'asciidoctor' +} + +apply from: "${rootProject.projectDir}/gradle/testVerbose.gradle" diff --git a/grails-app/services/grails/plugins/cacheheaders/CacheHeadersService.groovy b/plugin/grails-app/services/grails/plugins/cacheheaders/CacheHeadersService.groovy similarity index 99% rename from grails-app/services/grails/plugins/cacheheaders/CacheHeadersService.groovy rename to plugin/grails-app/services/grails/plugins/cacheheaders/CacheHeadersService.groovy index 88aaa0e..2a5bdc3 100644 --- a/grails-app/services/grails/plugins/cacheheaders/CacheHeadersService.groovy +++ b/plugin/grails-app/services/grails/plugins/cacheheaders/CacheHeadersService.groovy @@ -1,5 +1,8 @@ package grails.plugins.cacheheaders +import groovy.util.logging.Slf4j + +@Slf4j class CacheHeadersService { boolean enabled = true diff --git a/src/docs/asciidoc/index.adoc b/plugin/src/docs/asciidoc/index.adoc similarity index 99% rename from src/docs/asciidoc/index.adoc rename to plugin/src/docs/asciidoc/index.adoc index 55542a5..d445fb8 100644 --- a/src/docs/asciidoc/index.adoc +++ b/plugin/src/docs/asciidoc/index.adoc @@ -11,7 +11,7 @@ Install the plugin by adding a dependency in `build.gradle` [source, groovy] ---- -compile 'or.grails.plugins:cache-headers:2.0.1' +compile 'org.apache.grails:cache-headers:3.0.0' ---- == Description diff --git a/src/main/groovy/grails/plugins/cacheheaders/CacheHeadersGrailsPlugin.groovy b/plugin/src/main/groovy/grails/plugins/cacheheaders/CacheHeadersGrailsPlugin.groovy similarity index 77% rename from src/main/groovy/grails/plugins/cacheheaders/CacheHeadersGrailsPlugin.groovy rename to plugin/src/main/groovy/grails/plugins/cacheheaders/CacheHeadersGrailsPlugin.groovy index bbf537b..45d492a 100644 --- a/src/main/groovy/grails/plugins/cacheheaders/CacheHeadersGrailsPlugin.groovy +++ b/plugin/src/main/groovy/grails/plugins/cacheheaders/CacheHeadersGrailsPlugin.groovy @@ -10,10 +10,9 @@ import groovy.util.logging.Slf4j class CacheHeadersGrailsPlugin extends Plugin { // the version or versions of Grails the plugin is designed for - def grailsVersion = "3.2.10 > *" + def grailsVersion = "7.0.0 > *" // resources that are excluded from plugin packaging def pluginExcludes = [ - "**/TestController**", "src/docs/**", ] @@ -22,9 +21,14 @@ class CacheHeadersGrailsPlugin extends Plugin { def authorEmail = 'graeme.rocher@gmail.com' def title = 'Caching Headers Plugin' def description = 'Improve your application performance with browser caching, with easy ways to set caching headers in controller responses' - def developers = [[name: "Marc Palmer", email: "marc@grailsrocks.com"], [name: "Graeme Rocher", email: "graeme.rocher@gmail.com"], [name: 'Sergio del Amo', email: 'sergio.delamo@softamo.com']] - def issueManagement = [system: "Github", url: "http://github.com/grails-plugins/grails-cache-headers/issues"] - def scm = [url: 'http://github.com/grails-plugins/grails-cache-headers'] + def developers = [ + [name: "Marc Palmer", email: "marc@grailsrocks.com"], + [name: "Graeme Rocher", email: "graeme.rocher@gmail.com"], + [name: 'Sergio del Amo', email: 'sergio.delamo@softamo.com'], + [name: 'Rahul Shishodia', email: 'rahul.shishodia.10@gmail.com'] + ] + def issueManagement = [system: "Github", url: "http://github.com/grails-plugins/ cache-headers/issues"] + def scm = [url: 'http://github.com/grails-plugins/cache-headers'] def license = "APACHE" def documentation = "http://grails.org/plugin/cache-headers" @@ -45,4 +49,4 @@ class CacheHeadersGrailsPlugin extends Plugin { // Config change might mean that the caching has been turned on/off doWithApplicationContext() } -} \ No newline at end of file +} diff --git a/src/main/groovy/grails/plugins/cacheheaders/CacheHeadersTrait.groovy b/plugin/src/main/groovy/grails/plugins/cacheheaders/CacheHeadersTrait.groovy similarity index 100% rename from src/main/groovy/grails/plugins/cacheheaders/CacheHeadersTrait.groovy rename to plugin/src/main/groovy/grails/plugins/cacheheaders/CacheHeadersTrait.groovy diff --git a/src/main/groovy/grails/plugins/cacheheaders/WithCacheHeadersDelegate.groovy b/plugin/src/main/groovy/grails/plugins/cacheheaders/WithCacheHeadersDelegate.groovy similarity index 100% rename from src/main/groovy/grails/plugins/cacheheaders/WithCacheHeadersDelegate.groovy rename to plugin/src/main/groovy/grails/plugins/cacheheaders/WithCacheHeadersDelegate.groovy diff --git a/plugin/src/test/groovy/grails/plugins/cacheheaders/CacheHeadersServiceSpec.groovy b/plugin/src/test/groovy/grails/plugins/cacheheaders/CacheHeadersServiceSpec.groovy new file mode 100644 index 0000000..1413efe --- /dev/null +++ b/plugin/src/test/groovy/grails/plugins/cacheheaders/CacheHeadersServiceSpec.groovy @@ -0,0 +1,246 @@ +package grails.plugins.cacheheaders + +import grails.plugins.cacheheaders.CacheHeadersService +import grails.testing.services.ServiceUnitTest +import org.springframework.mock.web.MockHttpServletRequest +import org.springframework.mock.web.MockHttpServletResponse +import spock.lang.Specification + +import java.text.SimpleDateFormat + +class CacheHeadersServiceSpec extends Specification implements ServiceUnitTest { + + MockHttpServletRequest req + MockHttpServletResponse resp + Expando context + + private static final String RFC1123_DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz" // Always GMT + + void setup() { + req = new MockHttpServletRequest() + resp = new MockHttpServletResponse() + context = new Expando( + request: req, + response: resp, + render: { String s -> resp.outputStream << s.bytes }) + } + + def "withCacheHeaders does not set Last-Modified or ETag if caching is disabled"() { + given: + service.enabled = false + + when: + req.addHeader('If-None-Match', "1234567Z") + + def res = service.withCacheHeaders(context) { + etag { + "1234567Z" + } + generate { + render "Hello!" + } + } + + then: + resp.status == 200 + resp.contentAsString == 'Hello!' + resp.getHeader('Last-Modified') == null + resp.getHeader('ETag') == null + } + + def "request where Header If-None-Match matches ETag"() { + when: + req.addHeader('If-None-Match', "1234567Z") + + def res = service.withCacheHeaders(context) { + etag { + "1234567Z" + } + } + + then: + resp.status == 304 // Not Modified + resp.getHeader('Last-Modified') == null + resp.getHeader('ETag') == null + } + + def "withCacheHeaders ETag does not match last modfied unchanged"() { + + given: + def lastMod = new Date() - 100 + + when: + req.addHeader('If-None-Match', "dsfdsfdsfdsfsd") + // This is an AWFUL hack because spring mock http request/response does not do string <-> date coercion + req.addHeader('If-Modified-Since', lastMod) + + def res = service.withCacheHeaders(context) { + etag { + "1234567Z" + } + + lastModified { + lastMod + } + + generate { + render "Derelict Herds" + } + } + + then: + resp.status == 200 + resp.contentAsString == 'Derelict Herds' + resp.getHeader('ETag') == '1234567Z' + resp.getHeader('Last-Modified') == dateToHTTPDate(lastMod) + + } + + void "withCacheHeaders ETag match Last Modified Changed"() { + given: + def lastMod = new Date() - 100 + + when: + req.addHeader('If-None-Match', "bingo") + // This is an AWFUL hack because spring mock http request/response does not do string <-> date coercion + req.addHeader('If-Modified-Since', lastMod-1) + + def res = service.withCacheHeaders(context) { + etag { + "bingo" + } + + lastModified { + lastMod + } + + generate { + render "Derelict Herds" + } + } + + then: + resp.status == 200 + resp.contentAsString == 'Derelict Herds' + resp.getHeader('ETag') == 'bingo' + resp.getHeader('Last-Modified') == dateToHTTPDate(lastMod) + } + + void "withCacheHeaders ETag match, last Modified unchanged"() { + given: + def lastMod = new Date() - 100 + + when: + req.addHeader('If-None-Match', "bingo") + // This is an AWFUL hack because spring mock http request/response does not do string <-> date coercion + req.addHeader('If-Modified-Since', lastMod) + + def res = service.withCacheHeaders(context) { + etag { + "bingo" + } + + lastModified { + lastMod + } + + generate { + render "Derelict Herds" + } + } + + then: + resp.status == 304 // Not Modified + } + + + def "withCacheHeaders ETag No Match, LastModChanged"() { + given: + def lastMod = new Date() - 100 + + when: + req.addHeader('If-None-Match', "dsfdsfdsfdsfsd") + // This is an AWFUL hack because spring mock http request/response does not do string <-> date coercion + req.addHeader('If-Modified-Since', lastMod-1) + + def res = service.withCacheHeaders(context) { + etag { + "1234567Z" + } + + lastModified { + lastMod + } + + generate { + render "Derelict Herds" + } + } + + then: + resp.status == 200 + resp.contentAsString == 'Derelict Herds' + resp.getHeader('ETag') == '1234567Z' + resp.getHeader('Last-Modified') == dateToHTTPDate(lastMod) + } + + def "testWithCacheHeadersLastModChanged"() { + when: + // This is an AWFUL hack because spring mock http request/response does not do string <-> date coercion + req.addHeader('If-Modified-Since', new Date() - 102) + + def lastMod = new Date() - 100 + + def res = service.withCacheHeaders(context) { + etag { + "OU812" + } + lastModified { + lastMod + } + + generate { + render "Porcelain Heart" + } + } + + then: + resp.status == 200 + resp.contentAsString == 'Porcelain Heart' + resp.getHeader('ETag') == 'OU812' + resp.getHeader('Last-Modified') == dateToHTTPDate(lastMod) + } + + def "testWithCacheHeadersLastModNotNewer"() { + given: + def d = new Date() - 100 + + when: + // This is an AWFUL hack because spring mock http request/response does not do string <-> date coercion + req.addHeader('If-Modified-Since', d) + def lastMod = d + def res = service.withCacheHeaders(context) { + etag { + "5150" + } + lastModified { + lastMod + } + + generate { + render "Hessian Peel" + } + } + + then: + resp.status == 304 // Not Modified + resp.getHeader('Last-Modified') == null + resp.getHeader('ETag') == null + } + + private static String dateToHTTPDate(date) { + def v = new SimpleDateFormat(RFC1123_DATE_FORMAT, Locale.ENGLISH) + v.timeZone = TimeZone.getTimeZone('GMT') + return v.format(date) + } +} diff --git a/settings.gradle b/settings.gradle index 1097938..90fd525 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,33 @@ -rootProject.name='cache-headers' +plugins { + id "com.gradle.develocity" version "$develocityVersion" + id "com.gradle.common-custom-user-data-gradle-plugin" version "$customUserDataVersion" +} + +def isCI = System.getenv().containsKey('CI') +def isLocal = !isCI + +develocity { + server = 'https://ge.grails.org' + buildScan { + tag('grails') + tag('grails-forge') + publishing.onlyIf { it.authenticated } + uploadInBackground = isLocal + } +} + +buildCache { + local { enabled = isLocal } + remote(develocity.buildCache) { + push = isCI + enabled = true + } +} + +rootProject.name='grails-cache-headers' + +include 'plugin' +include 'examples:plugin-test-app' +include 'examples:functional-test-app' + +findProject(":plugin").name = "cache-headers" diff --git a/version.txt b/version.txt deleted file mode 100644 index e9307ca..0000000 --- a/version.txt +++ /dev/null @@ -1 +0,0 @@ -2.0.2