Drop the Grails 3 sample as it is incompatible with Framework 5
Closes gh-637
This commit is contained in:
@@ -180,10 +180,6 @@ samples {
|
||||
dependOn 'spring-restdocs-webtestclient:install'
|
||||
dependOn 'spring-restdocs-asciidoctor:install'
|
||||
|
||||
restNotesGrails {
|
||||
workingDir "$projectDir/samples/rest-notes-grails"
|
||||
}
|
||||
|
||||
restNotesSpringHateoas {
|
||||
workingDir "$projectDir/samples/rest-notes-spring-hateoas"
|
||||
}
|
||||
|
||||
@@ -44,11 +44,6 @@ If you want to jump straight in, a number of sample applications are available:
|
||||
|===
|
||||
| Sample | Build system | Description
|
||||
|
||||
| {samples}/rest-notes-grails[Grails]
|
||||
| Gradle
|
||||
| Demonstrates the use of Spring REST docs with https://grails.org[Grails] and
|
||||
https://github.com/spockframework/spock[Spock].
|
||||
|
||||
| {samples}/rest-assured[REST Assured]
|
||||
| Gradle
|
||||
| Demonstrates the use of Spring REST Docs with http://rest-assured.io[REST Assured].
|
||||
|
||||
10
samples/rest-notes-grails/.gitignore
vendored
10
samples/rest-notes-grails/.gitignore
vendored
@@ -1,10 +0,0 @@
|
||||
.gradle
|
||||
build/
|
||||
classes/
|
||||
.idea
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.project
|
||||
.settings
|
||||
.classpath
|
||||
@@ -1,93 +0,0 @@
|
||||
# rest-notes-grails
|
||||
|
||||
## Overview
|
||||
|
||||
This is a sample project using Grails 3, Spock, and Spring REST docs. For more
|
||||
information about the Grails framework please see [grails.org](https://grails.org).
|
||||
|
||||
Grails is built on top of Spring Boot and Gradle so there are a few different ways to
|
||||
run this project including:
|
||||
|
||||
### Gradle Wrapper (recommended)
|
||||
|
||||
The gradle wrapper allows a project to build without having Gradle installed locally. The
|
||||
executable file will acquire the version of Gradle and other dependencies recommended for
|
||||
this project. This is especially important since some versions of Gradle may cause
|
||||
conflicts with this project.
|
||||
|
||||
On Unix-like platforms, such as Linux and Mac OS X:
|
||||
|
||||
```
|
||||
$ ./gradlew run
|
||||
```
|
||||
|
||||
On Windows:
|
||||
|
||||
```
|
||||
$ gradlew run
|
||||
```
|
||||
|
||||
*Please note*, if you are including integration tests in Grails, they will not run as
|
||||
part of the `gradle test` task. Run them via the build task or individually as
|
||||
`gradle integrationTest`
|
||||
|
||||
### Gradle Command Line
|
||||
|
||||
Clean the project:
|
||||
|
||||
```
|
||||
$ gradle clean
|
||||
```
|
||||
|
||||
Build the project:
|
||||
|
||||
```
|
||||
$ gradle build
|
||||
```
|
||||
|
||||
Run the project:
|
||||
|
||||
```
|
||||
$ gradle run
|
||||
```
|
||||
|
||||
### Grails Command Line
|
||||
|
||||
Grails applications also have a command line feature useful for code generation and
|
||||
running projects locally. The command line is accessible by typing `grails` in the
|
||||
terminal at the root of the project. Please ensure you are running the correct version
|
||||
of Grails as specified in [gradle.properties](gradle.properties)
|
||||
|
||||
Similar to `gradle clean`, this task destroys the `build` directory and cached assets.
|
||||
|
||||
```
|
||||
grails> clean
|
||||
```
|
||||
|
||||
The 'test-app' task runs all of the tests for the project.
|
||||
|
||||
```
|
||||
grails> test-app
|
||||
```
|
||||
|
||||
The `run-app` task is used to run the application locally. By default, the project is
|
||||
run in development mode including automatic reloading and not caching static assets. It
|
||||
is not suggested to use this in production.
|
||||
|
||||
```
|
||||
grails> run-app
|
||||
```
|
||||
|
||||
### Building and Viewing the Docs
|
||||
|
||||
This is an example of the Grails API profile. Therefore, there is no view layer to
|
||||
return the docs as static assets. The result of running `asciidoctor` or `build` is that
|
||||
the docs are sent to `/build/asciidoc/`. You can then publish them to a destination of
|
||||
your choosing using the [gradle github-pages](https://github.com/ajoberstar/gradle-git)
|
||||
plugin or similar.
|
||||
|
||||
To just generate documentation and not run the application use:
|
||||
|
||||
```
|
||||
$ ./gradlew asciidoctor
|
||||
```
|
||||
@@ -1,101 +0,0 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "https://repo.grails.org/grails/core" }
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
|
||||
classpath "org.grails.plugins:hibernate5:6.0.7"
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'org.asciidoctor.convert' version '1.5.3'
|
||||
}
|
||||
|
||||
version "0.1"
|
||||
group "com.example"
|
||||
|
||||
apply plugin: "war"
|
||||
apply plugin: "eclipse"
|
||||
apply plugin: "idea"
|
||||
apply plugin: "org.grails.grails-web"
|
||||
|
||||
ext {
|
||||
restDocsVersion = "2.0.4.BUILD-SNAPSHOT"
|
||||
snippetsDir = file('src/docs/generated-snippets')
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven { url 'https://repo.spring.io/libs-snapshot' }
|
||||
maven { url "https://repo.grails.org/grails/core" }
|
||||
}
|
||||
|
||||
dependencyManagement {
|
||||
dependencies {
|
||||
dependency "org.springframework.restdocs:spring-restdocs-core:$restDocsVersion"
|
||||
dependency "org.springframework.restdocs:spring-restdocs-restassured:$restDocsVersion"
|
||||
dependency "org.springframework.restdocs:spring-restdocs-asciidoctor:$restDocsVersion"
|
||||
}
|
||||
imports {
|
||||
mavenBom "org.grails:grails-bom:$grailsVersion"
|
||||
}
|
||||
applyMavenExclusions false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
asciidoctor "org.springframework.restdocs:spring-restdocs-asciidoctor"
|
||||
|
||||
compile "org.springframework.boot:spring-boot-starter-logging"
|
||||
compile "org.springframework.boot:spring-boot-autoconfigure"
|
||||
compile "org.springframework.boot:spring-boot-starter-actuator"
|
||||
compile "org.springframework.boot:spring-boot-starter-tomcat"
|
||||
compile "org.grails:grails-core"
|
||||
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.plugins: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.2.Final"
|
||||
compile "org.hibernate:hibernate-ehcache:5.1.2.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"
|
||||
runtime 'org.apache.tomcat:tomcat-jdbc'
|
||||
|
||||
testCompile "io.rest-assured:rest-assured:3.0.2"
|
||||
testCompile "org.grails:grails-test-mixins:3.3.0"
|
||||
testCompile "org.grails.plugins:geb"
|
||||
testCompile "org.grails:grails-datastore-rest-client"
|
||||
testCompile "org.springframework.restdocs:spring-restdocs-restassured"
|
||||
|
||||
testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1"
|
||||
testRuntime "net.sourceforge.htmlunit:htmlunit:2.18"
|
||||
}
|
||||
|
||||
ext {
|
||||
snippetsDir = file('build/generated-snippets')
|
||||
}
|
||||
|
||||
test {
|
||||
outputs.dir snippetsDir
|
||||
}
|
||||
|
||||
asciidoctor {
|
||||
dependsOn integrationTest
|
||||
inputs.dir snippetsDir
|
||||
}
|
||||
|
||||
build.dependsOn asciidoctor
|
||||
@@ -1 +0,0 @@
|
||||
grailsVersion=3.3.9
|
||||
Binary file not shown.
@@ -1,5 +0,0 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
|
||||
172
samples/rest-notes-grails/gradlew
vendored
172
samples/rest-notes-grails/gradlew
vendored
@@ -1,172 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# 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
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# 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
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
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" -a "$nonstop" = "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
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
84
samples/rest-notes-grails/gradlew.bat
vendored
84
samples/rest-notes-grails/gradlew.bat
vendored
@@ -1,84 +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
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@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=
|
||||
|
||||
@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 Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_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=%*
|
||||
|
||||
: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
|
||||
@@ -1,100 +0,0 @@
|
||||
---
|
||||
grails:
|
||||
profile: rest-api
|
||||
codegen:
|
||||
defaultPackage: com.example
|
||||
info:
|
||||
app:
|
||||
name: '@info.app.name@'
|
||||
version: '@info.app.version@'
|
||||
grailsVersion: '@info.app.grailsVersion@'
|
||||
spring:
|
||||
groovy:
|
||||
template:
|
||||
check-template-location: false
|
||||
|
||||
---
|
||||
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
|
||||
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
|
||||
hibernate:
|
||||
cache:
|
||||
queries: false
|
||||
|
||||
---
|
||||
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
|
||||
server:
|
||||
port: 0
|
||||
production:
|
||||
dataSource:
|
||||
dbCreate: update
|
||||
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
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import grails.util.BuildSettings
|
||||
import grails.util.Environment
|
||||
|
||||
// See https://logback.qos.ch/manual/groovy.html for details on configuration
|
||||
appender('STDOUT', ConsoleAppender) {
|
||||
encoder(PatternLayoutEncoder) {
|
||||
pattern = "%level %logger - %msg%n"
|
||||
}
|
||||
}
|
||||
|
||||
root(ERROR, ['STDOUT'])
|
||||
|
||||
def targetDir = BuildSettings.TARGET_DIR
|
||||
if (Environment.isDevelopmentMode() && targetDir) {
|
||||
appender("FULL_STACKTRACE", FileAppender) {
|
||||
file = "${targetDir}/stacktrace.log"
|
||||
append = true
|
||||
encoder(PatternLayoutEncoder) {
|
||||
pattern = "%level %logger - %msg%n"
|
||||
}
|
||||
}
|
||||
logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false)
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
// Place your Spring DSL code here
|
||||
beans = {}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example
|
||||
|
||||
class UrlMappings {
|
||||
|
||||
static mappings = {
|
||||
'/notes'(resources: 'note')
|
||||
|
||||
"500"(view: '/error')
|
||||
"404"(view: '/notFound')
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example
|
||||
|
||||
import grails.rest.Resource
|
||||
|
||||
@Resource(uri='/notes')
|
||||
class Note {
|
||||
|
||||
Long id
|
||||
|
||||
String title
|
||||
|
||||
String body
|
||||
|
||||
static hasMany = [tags: Tag]
|
||||
|
||||
static mapping = {
|
||||
tags joinTable: [name: "mm_notes_tags", key: 'mm_note_id' ]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example
|
||||
|
||||
import grails.rest.Resource
|
||||
|
||||
@Resource(uri='/tags')
|
||||
class Tag {
|
||||
|
||||
Long id
|
||||
|
||||
String name
|
||||
|
||||
static hasMany = [notes: Note]
|
||||
|
||||
static belongsTo = Note
|
||||
|
||||
static mapping = {
|
||||
notes joinTable: [name: "mm_notes_tags", key: 'mm_tag_id']
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
default.doesnt.match.message=Property [{0}] of class [{1}] with value [{2}] does not match the required pattern [{3}]
|
||||
default.invalid.url.message=Property [{0}] of class [{1}] with value [{2}] is not a valid URL
|
||||
default.invalid.creditCard.message=Property [{0}] of class [{1}] with value [{2}] is not a valid credit card number
|
||||
default.invalid.email.message=Property [{0}] of class [{1}] with value [{2}] is not a valid e-mail address
|
||||
default.invalid.range.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid range from [{3}] to [{4}]
|
||||
default.invalid.size.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid size range from [{3}] to [{4}]
|
||||
default.invalid.max.message=Property [{0}] of class [{1}] with value [{2}] exceeds maximum value [{3}]
|
||||
default.invalid.min.message=Property [{0}] of class [{1}] with value [{2}] is less than minimum value [{3}]
|
||||
default.invalid.max.size.message=Property [{0}] of class [{1}] with value [{2}] exceeds the maximum size of [{3}]
|
||||
default.invalid.min.size.message=Property [{0}] of class [{1}] with value [{2}] is less than the minimum size of [{3}]
|
||||
default.invalid.validator.message=Property [{0}] of class [{1}] with value [{2}] does not pass custom validation
|
||||
default.not.inlist.message=Property [{0}] of class [{1}] with value [{2}] is not contained within the list [{3}]
|
||||
default.blank.message=Property [{0}] of class [{1}] cannot be blank
|
||||
default.not.equal.message=Property [{0}] of class [{1}] with value [{2}] cannot equal [{3}]
|
||||
default.null.message=Property [{0}] of class [{1}] cannot be null
|
||||
default.not.unique.message=Property [{0}] of class [{1}] with value [{2}] must be unique
|
||||
|
||||
default.paginate.prev=Previous
|
||||
default.paginate.next=Next
|
||||
default.boolean.true=True
|
||||
default.boolean.false=False
|
||||
default.date.format=yyyy-MM-dd HH:mm:ss z
|
||||
default.number.format=0
|
||||
|
||||
default.created.message={0} {1} created
|
||||
default.updated.message={0} {1} updated
|
||||
default.deleted.message={0} {1} deleted
|
||||
default.not.deleted.message={0} {1} could not be deleted
|
||||
default.not.found.message={0} not found with id {1}
|
||||
default.optimistic.locking.failure=Another user has updated this {0} while you were editing
|
||||
|
||||
default.home.label=Home
|
||||
default.list.label={0} List
|
||||
default.add.label=Add {0}
|
||||
default.new.label=New {0}
|
||||
default.create.label=Create {0}
|
||||
default.show.label=Show {0}
|
||||
default.edit.label=Edit {0}
|
||||
|
||||
default.button.create.label=Create
|
||||
default.button.edit.label=Edit
|
||||
default.button.update.label=Update
|
||||
default.button.delete.label=Delete
|
||||
default.button.delete.confirm.message=Are you sure?
|
||||
|
||||
# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author)
|
||||
typeMismatch.java.net.URL=Property {0} must be a valid URL
|
||||
typeMismatch.java.net.URI=Property {0} must be a valid URI
|
||||
typeMismatch.java.util.Date=Property {0} must be a valid Date
|
||||
typeMismatch.java.lang.Double=Property {0} must be a valid number
|
||||
typeMismatch.java.lang.Integer=Property {0} must be a valid number
|
||||
typeMismatch.java.lang.Long=Property {0} must be a valid number
|
||||
typeMismatch.java.lang.Short=Property {0} must be a valid number
|
||||
typeMismatch.java.math.BigDecimal=Property {0} must be a valid number
|
||||
typeMismatch.java.math.BigInteger=Property {0} must be a valid number
|
||||
typeMismatch=Property {0} is type-mismatched
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example
|
||||
|
||||
import grails.boot.GrailsApp
|
||||
import grails.boot.config.GrailsAutoConfiguration
|
||||
|
||||
class Application extends GrailsAutoConfiguration {
|
||||
|
||||
static void main(String[] args) {
|
||||
GrailsApp.run(Application, args)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example
|
||||
|
||||
class BootStrap {
|
||||
|
||||
def init = { servletContext ->
|
||||
environments {
|
||||
test {
|
||||
new Note(title: 'Hello, World!', body: 'Hello from the Integration Test').save()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def destroy = {}
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
response.status 500
|
||||
|
||||
json {
|
||||
message "Internal server error"
|
||||
error 500
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
response.status 404
|
||||
|
||||
json {
|
||||
message "Not Found"
|
||||
error 404
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
= Grails RESTful Notes API Guide
|
||||
Andy Wilkinson; Jenn Strater
|
||||
:doctype: book
|
||||
:icons: font
|
||||
:source-highlighter: highlightjs
|
||||
:toc: left
|
||||
:toclevels: 4
|
||||
:sectlinks:
|
||||
:operation-curl-request-title: Example request
|
||||
:operation-http-response-title: Example response
|
||||
|
||||
[[overview]]
|
||||
= Overview
|
||||
|
||||
[[overview-http-verbs]]
|
||||
== HTTP verbs
|
||||
|
||||
Grails RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its
|
||||
use of HTTP verbs.
|
||||
|
||||
|===
|
||||
| Verb | Usage
|
||||
|
||||
| `GET`
|
||||
| Used to retrieve a resource
|
||||
|
||||
| `POST`
|
||||
| Used to create a new resource
|
||||
|
||||
| `PATCH`
|
||||
| Used to update an existing resource, including partial updates
|
||||
|
||||
| `DELETE`
|
||||
| Used to delete an existing resource
|
||||
|===
|
||||
|
||||
[[overview-http-status-codes]]
|
||||
== HTTP status codes
|
||||
|
||||
Grails RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its
|
||||
use of HTTP status codes.
|
||||
|
||||
|===
|
||||
| Status code | Usage
|
||||
|
||||
| `200 OK`
|
||||
| The request completed successfully
|
||||
|
||||
| `201 Created`
|
||||
| A new resource has been created successfully. The resource's URI is available from the response's
|
||||
`Location` header
|
||||
|
||||
| `204 No Content`
|
||||
| An update to an existing resource has been applied successfully
|
||||
|
||||
| `400 Bad Request`
|
||||
| The request was malformed. The response body will include an error providing further information
|
||||
|
||||
| `404 Not Found`
|
||||
| The requested resource did not exist
|
||||
|===
|
||||
|
||||
[[resources]]
|
||||
= Resources
|
||||
|
||||
|
||||
|
||||
[[resources-notes]]
|
||||
== Notes
|
||||
|
||||
The Notes resources is used to create and list notes
|
||||
|
||||
|
||||
|
||||
[[resources-notes-list]]
|
||||
=== Listing notes
|
||||
|
||||
A `GET` request will list all of the service's notes.
|
||||
|
||||
operation::notes-list-example[snippets='response-fields,curl-request,http-response']
|
||||
|
||||
|
||||
|
||||
[[resources-notes-create]]
|
||||
=== Creating a note
|
||||
|
||||
A `POST` request is used to create a note
|
||||
|
||||
operation::notes-create-example[snippets='request-fields,curl-request,http-response']
|
||||
|
||||
|
||||
|
||||
[[resources-note-retrieve]]
|
||||
=== Retrieve a note
|
||||
|
||||
A `GET` request will retrieve the details of a note
|
||||
|
||||
operation::note-get-example[snippets='response-fields,curl-request,http-response']
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example
|
||||
|
||||
import org.springframework.restdocs.payload.JsonFieldType
|
||||
|
||||
import static io.restassured.RestAssured.given
|
||||
import static org.hamcrest.CoreMatchers.is
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath
|
||||
import static org.springframework.restdocs.restassured3.operation.preprocess.RestAssuredPreprocessors.modifyUris
|
||||
import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document
|
||||
import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.documentationConfiguration
|
||||
|
||||
import io.restassured.builder.RequestSpecBuilder
|
||||
import io.restassured.specification.RequestSpecification
|
||||
import grails.test.mixin.integration.Integration
|
||||
import grails.transaction.Rollback
|
||||
import org.junit.Rule
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.restdocs.JUnitRestDocumentation
|
||||
import spock.lang.Specification
|
||||
|
||||
@Integration
|
||||
@Rollback
|
||||
class ApiDocumentationSpec extends Specification {
|
||||
|
||||
@Rule
|
||||
JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation()
|
||||
|
||||
@Value('${local.server.port}')
|
||||
Integer serverPort
|
||||
|
||||
protected RequestSpecification documentationSpec
|
||||
|
||||
void setup() {
|
||||
this.documentationSpec = new RequestSpecBuilder()
|
||||
.addFilter(documentationConfiguration(restDocumentation))
|
||||
.build()
|
||||
}
|
||||
|
||||
void 'test and document notes list request'() {
|
||||
expect:
|
||||
given(this.documentationSpec)
|
||||
.accept(MediaType.APPLICATION_JSON.toString())
|
||||
.filter(document('notes-list-example',
|
||||
preprocessRequest(modifyUris()
|
||||
.host('api.example.com')
|
||||
.removePort()),
|
||||
preprocessResponse(prettyPrint()),
|
||||
responseFields(
|
||||
fieldWithPath('[].id').description('the id of the note'),
|
||||
fieldWithPath('[].title').description('the title of the note'),
|
||||
fieldWithPath('[].body').description('the body of the note'),
|
||||
fieldWithPath('[].tags').type(JsonFieldType.ARRAY).description('the list of tags associated with the note'),
|
||||
)))
|
||||
.when()
|
||||
.port(this.serverPort)
|
||||
.get('/notes')
|
||||
.then()
|
||||
.assertThat()
|
||||
.statusCode(is(200))
|
||||
}
|
||||
|
||||
void 'test and document create new note'() {
|
||||
expect:
|
||||
given(this.documentationSpec)
|
||||
.accept(MediaType.APPLICATION_JSON.toString())
|
||||
.contentType(MediaType.APPLICATION_JSON.toString())
|
||||
.filter(document('notes-create-example',
|
||||
preprocessRequest(modifyUris()
|
||||
.host('api.example.com')
|
||||
.removePort()),
|
||||
preprocessResponse(prettyPrint()),
|
||||
requestFields(
|
||||
fieldWithPath('title').description('the title of the note'),
|
||||
fieldWithPath('body').description('the body of the note'),
|
||||
subsectionWithPath('tags').type(JsonFieldType.ARRAY).description('a list of tags associated to the note')
|
||||
),
|
||||
responseFields(
|
||||
fieldWithPath('id').description('the id of the note'),
|
||||
fieldWithPath('title').description('the title of the note'),
|
||||
fieldWithPath('body').description('the body of the note'),
|
||||
subsectionWithPath('tags').type(JsonFieldType.ARRAY).description('the list of tags associated with the note')
|
||||
)))
|
||||
.body('{ "body": "My test example", "title": "Eureka!", "tags": [{"name": "testing123"}] }')
|
||||
.when()
|
||||
.port(this.serverPort)
|
||||
.post('/notes')
|
||||
.then()
|
||||
.assertThat()
|
||||
.statusCode(is(201))
|
||||
}
|
||||
|
||||
void 'test and document getting specific note'() {
|
||||
expect:
|
||||
given(this.documentationSpec)
|
||||
.accept(MediaType.APPLICATION_JSON.toString())
|
||||
.filter(document('note-get-example',
|
||||
preprocessRequest(modifyUris()
|
||||
.host('api.example.com')
|
||||
.removePort()),
|
||||
preprocessResponse(prettyPrint()),
|
||||
responseFields(
|
||||
fieldWithPath('id').description('the id of the note'),
|
||||
fieldWithPath('title').description('the title of the note'),
|
||||
fieldWithPath('body').description('the body of the note'),
|
||||
fieldWithPath('tags').type(JsonFieldType.ARRAY).description('the list of tags associated with the note'),
|
||||
)))
|
||||
.when()
|
||||
.port(this.serverPort)
|
||||
.get('/notes/1')
|
||||
.then()
|
||||
.assertThat()
|
||||
.statusCode(is(200))
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user