├── .gitignore ├── LICENSE ├── README.md ├── api-deploy.sh ├── api ├── .classpath ├── .gitignore ├── .gradle │ └── 2.7 │ │ └── taskArtifacts │ │ ├── cache.properties │ │ ├── cache.properties.lock │ │ ├── fileHashes.bin │ │ ├── fileSnapshots.bin │ │ ├── outputFileStates.bin │ │ └── taskArtifacts.bin ├── .project ├── .settings │ ├── gradle │ │ ├── org.springsource.ide.eclipse.gradle.core.import.prefs │ │ ├── org.springsource.ide.eclipse.gradle.core.prefs │ │ └── org.springsource.ide.eclipse.gradle.refresh.prefs │ └── org.eclipse.jdt.core.prefs ├── bin │ └── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src │ ├── main │ ├── java │ │ └── br │ │ │ └── com │ │ │ └── rcoli │ │ │ ├── Application.java │ │ │ ├── controller │ │ │ └── MainController.java │ │ │ └── model │ │ │ └── Response.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── br │ └── com │ └── rcoli │ └── ApplicationTests.java └── resources └── application-localhost.yml /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | 118 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # spring-boot-jenkins 2 | Example of the deployment of a Spring Boot App with Jenkins in a Unix System 3 | 4 | One thing that I found very hard to do was to integrate a spring boot project into a CI environment using jenkins. As a default behavior, the Jenkins process tree killer always kills the process started by a job which stops the execution of a Spring Boot App after the jenkins job finishes. In addition of that, I wanted to see the server log on the jenkyns windows until it finishes loading. This article will try to help us solving this problems. 5 | 6 | But first I would like to discuss what I consider a good practice to a Spring Boot App CI environment. I find very useful to first copy the artifacts to a specified area on the server to keep track of the artifacts deployed and deploy the artifact from that location. Also, I create a server log file there and start to listening on the jenkins window until the server started. 7 | 8 | So the script below does that. With some minor improvements self explained on the comments, but in summary it does this: 9 | 10 | - stop whatever process running on the deployed port. 11 | - delete the files of the previous deploy 12 | - copy the files to deploy location 13 | - start application with nohup command, java - jar 14 | - start listening to the server log until it reaches a specific instruction. 15 | 16 | 17 | Finally you have to do some adjustments to your job on Jenkins to avoid the default tree killing process. Just add this instruction before calling the sh: BUILD_ID=dontKillMe /path/to/my/script.sh (FIGURE 3) 18 | 19 | You can see the jenkins job configuration window on FIGURES 1, 2, and 3 and the log result window on FIGURES 4 and 5. 20 | 21 | Go to my github repo to check the project, but it recommend to extract the shell script to another repo to keep it lifecycle independent of your app. 22 | 23 | https://github.com/rcoli/spring-boot-jenkins 24 | 25 | 26 | This is my deploy folder structure (FIGURE 6): 27 | ``` 28 | -- spring-boot 29 | 30 | ---- dev 31 | ------ resources 32 | -------- application.yml 33 | ------ initServer.log 34 | ------ my-app-jar 35 | 36 | ---- sit 37 | ------ resources 38 | -------- application.yml 39 | ------ initServer.log 40 | ------ my-app-jar 41 | 42 | ---- uat 43 | ------ resources 44 | -------- application.yml 45 | ------ initServer.log 46 | ------ my-app-jar 47 | ``` 48 | * dev - develop, sit - system integration testing, uat - user acceptance testing, application.yml - external app configuration file 49 | 50 | 51 | This my project folder structure (FIGURE 7 and 8): 52 | ``` 53 | -- my-project 54 | ---- resources 55 | ------ application.yml 56 | ---- api 57 | ------ src 58 | ------ (other project file) 59 | ------ build.gradle 60 | ``` 61 | 62 | The script example. 63 | 64 | ```bash 65 | 66 | #!/bin/bash 67 | 68 | # COMMAND LINE VARIABLES 69 | #enviroment FIRST ARGUMENT 70 | # Ex: dev | sit | uat 71 | env=$1 72 | # deploy port SECOND ARGUMENT 73 | # Ex: 8090 | 8091 | 8092 74 | serverPort=$2 75 | # THIRD ARGUMENT project name, deploy folder name and jar name 76 | projectName=$3 #spring-boot 77 | # FOURTH ARGUMENT external config file name 78 | # Ex: application-localhost.yml 79 | configFile=$4 80 | 81 | 82 | #### CONFIGURABLE VARIABLES ###### 83 | #destination absolute path. It must be pre created or you can 84 | # improve this script to create if not exists 85 | destAbsPath=/home/rcoli/Desktop/$projectName/$env 86 | configFolder=resources 87 | ############################################################## 88 | 89 | ##### 90 | ##### DONT CHANGE HERE ############## 91 | #jar file 92 | # $WORKSPACE is a jenkins var 93 | sourFile=$WORKSPACE/api/build/libs/$projectName*.jar 94 | destFile=$destAbsPath/$projectName.jar 95 | 96 | #config files folder 97 | sourConfigFolder=$WORKSPACE/$configFolder* 98 | destConfigFolder=$destAbsPath/$configFolder 99 | 100 | properties=--spring.config.location=$destAbsPath/$configFolder/$configFile 101 | 102 | #CONSTANTS 103 | logFile=initServer.log 104 | dstLogFile=$destAbsPath/$logFile 105 | #whatToFind="Started Application in" 106 | whatToFind="Started " 107 | msgLogFileCreated="$logFile created" 108 | msgBuffer="Buffering: " 109 | msgAppStarted="Application Started... exiting buffer!" 110 | 111 | ### FUNCTIONS 112 | ############## 113 | function stopServer(){ 114 | echo " " 115 | echo "Stoping process on port: $serverPort" 116 | fuser -n tcp -k $serverPort > redirection & 117 | echo " " 118 | } 119 | 120 | function deleteFiles(){ 121 | echo "Deleting $destFile" 122 | rm -rf $destFile 123 | 124 | echo "Deleting $destConfigFolder" 125 | rm -rf $destConfigFolder 126 | 127 | echo "Deleting $dstLogFile" 128 | rm -rf $dstLogFile 129 | 130 | echo " " 131 | } 132 | 133 | function copyFiles(){ 134 | echo "Copying files from $sourFile" 135 | cp $sourFile $destFile 136 | 137 | echo "Copying files from $sourConfigFolder" 138 | cp -r $sourConfigFolder $destConfigFolder 139 | 140 | echo " " 141 | } 142 | 143 | function run(){ 144 | 145 | #echo "java -jar $destFile --server.port=$serverPort $properties" | at now + 1 minutes 146 | 147 | nohup nice java -jar $destFile --server.port=$serverPort $properties $> $dstLogFile 2>&1 & 148 | 149 | echo "COMMAND: nohup nice java -jar $destFile --server.port=$serverPort $properties $> $dstLogFile 2>&1 &" 150 | 151 | echo " " 152 | } 153 | function changeFilePermission(){ 154 | 155 | echo "Changing File Permission: chmod 777 $destFile" 156 | 157 | chmod 777 $destFile 158 | 159 | echo " " 160 | } 161 | 162 | function watch(){ 163 | 164 | tail -f $dstLogFile | 165 | 166 | while IFS= read line 167 | do 168 | echo "$msgBuffer" "$line" 169 | 170 | if [[ "$line" == *"$whatToFind"* ]]; then 171 | echo $msgAppStarted 172 | pkill tail 173 | fi 174 | done 175 | } 176 | 177 | ### FUNCTIONS CALLS 178 | ##################### 179 | # Use Example of this file. Args: enviroment | port | project name | external resourcce 180 | # BUILD_ID=dontKillMe /path/to/this/file/api-deploy.sh dev 8082 spring-boot application-localhost.yml 181 | 182 | # 1 - stop server on port ... 183 | stopServer 184 | 185 | # 2 - delete destinations folder content 186 | deleteFiles 187 | 188 | # 3 - copy files to deploy dir 189 | copyFiles 190 | 191 | changeFilePermission 192 | # 4 - start server 193 | run 194 | 195 | # 5 - watch loading messages until ($whatToFind) message is found 196 | watch 197 | ``` 198 | 199 | --- Jenkins Job Configuration (Git) FIGURE 1 200 | ![alt tag](https://cloud.githubusercontent.com/assets/1146514/10940518/ed6d4062-82ed-11e5-88e8-6529970d2831.png) 201 | 202 | --- Jenkins Job Configuration (Gradle) FIGURE 2 203 | ![alt tag](https://cloud.githubusercontent.com/assets/1146514/10940527/fc1a0078-82ed-11e5-9dd7-aa75924b1d3f.png) 204 | 205 | --- Jenkins Job Configuration (Deploy) FIGURE 3 206 | ![alt tag](https://cloud.githubusercontent.com/assets/1146514/10940534/0678e232-82ee-11e5-84dd-6ca751e66903.png) 207 | 208 | 209 | 210 | --- Jenkins Summary Beginning FIGURE 4 211 | ![alt tag](https://cloud.githubusercontent.com/assets/1146514/10939540/74ed1058-82e9-11e5-9ca8-fcdfa9138647.png) 212 | 213 | --- Jenkins Summary Finnished (Job Complete) FIGURE 5 214 | ![alt tag](https://cloud.githubusercontent.com/assets/1146514/10939547/7a37dc6e-82e9-11e5-9b1e-bda47592ed6d.png) 215 | 216 | 217 | --- Deploy Structure Folder FIGURE 6 218 | ![alt tag](https://cloud.githubusercontent.com/assets/1146514/10939616/0aefad86-82ea-11e5-8d6b-40ca67df04f2.png) 219 | 220 | 221 | --- Project structure folder FIGURE 7 222 | ![alt tag](https://cloud.githubusercontent.com/assets/1146514/10939537/708ed014-82e9-11e5-85e1-c53ac1d219eb.png) 223 | 224 | --- External Resources Folder FIGURE 8 225 | ![alt tag](https://cloud.githubusercontent.com/assets/1146514/10939548/7e91ed90-82e9-11e5-8a61-31e6f6f9c42a.png) 226 | -------------------------------------------------------------------------------- /api-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # COMMAND LINE VARIABLES 4 | #enviroment FIRST ARGUMENT 5 | # Ex: dev | sit | uat 6 | env=$1 7 | # deploy port SECOND ARGUMENT 8 | # Ex: 8090 | 8091 | 8092 9 | serverPort=$2 10 | # THIRD ARGUMENT project name, deploy folder name and jar name 11 | projectName=$3 #spring-boot 12 | # FOURTH ARGUMENT external config file name 13 | # Ex: application-localhost.yml 14 | configFile=$4 15 | 16 | 17 | #### CONFIGURABLE VARIABLES ###### 18 | #destination absolute path. It must be pre created or you can 19 | # improve this script to create if not exists 20 | destAbsPath=/home/rcoli/Desktop/$projectName/$env 21 | configFolder=resources 22 | ############################################################## 23 | 24 | ##### 25 | ##### DONT CHANGE HERE ############## 26 | #jar file 27 | # $WORKSPACE is a jenkins var 28 | sourFile=$WORKSPACE/api/build/libs/$projectName*.jar 29 | destFile=$destAbsPath/$projectName.jar 30 | 31 | #config files folder 32 | sourConfigFolder=$WORKSPACE/$configFolder* 33 | destConfigFolder=$destAbsPath/$configFolder 34 | 35 | properties=--spring.config.location=$destAbsPath/$configFolder/$configFile 36 | 37 | #CONSTANTS 38 | logFile=initServer.log 39 | dstLogFile=$destAbsPath/$logFile 40 | #whatToFind="Started Application in" 41 | whatToFind="Started " 42 | msgLogFileCreated="$logFile created" 43 | msgBuffer="Buffering: " 44 | msgAppStarted="Application Started... exiting buffer!" 45 | 46 | ### FUNCTIONS 47 | ############## 48 | function stopServer(){ 49 | echo " " 50 | echo "Stoping process on port: $serverPort" 51 | fuser -n tcp -k $serverPort > redirection & 52 | echo " " 53 | } 54 | 55 | function deleteFiles(){ 56 | echo "Deleting $destFile" 57 | rm -rf $destFile 58 | 59 | echo "Deleting $destConfigFolder" 60 | rm -rf $destConfigFolder 61 | 62 | echo "Deleting $dstLogFile" 63 | rm -rf $dstLogFile 64 | 65 | echo " " 66 | } 67 | 68 | function copyFiles(){ 69 | echo "Copying files from $sourFile" 70 | cp $sourFile $destFile 71 | 72 | echo "Copying files from $sourConfigFolder" 73 | cp -r $sourConfigFolder $destConfigFolder 74 | 75 | echo " " 76 | } 77 | 78 | function run(){ 79 | 80 | #echo "java -jar $destFile --server.port=$serverPort $properties" | at now + 1 minutes 81 | 82 | nohup nice java -jar $destFile --server.port=$serverPort $properties $> $dstLogFile 2>&1 & 83 | 84 | echo "COMMAND: nohup nice java -jar $destFile --server.port=$serverPort $properties $> $dstLogFile 2>&1 &" 85 | 86 | echo " " 87 | } 88 | function changeFilePermission(){ 89 | 90 | echo "Changing File Permission: chmod 777 $destFile" 91 | 92 | chmod 777 $destFile 93 | 94 | echo " " 95 | } 96 | 97 | function watch(){ 98 | 99 | tail -f $dstLogFile | 100 | 101 | while IFS= read line 102 | do 103 | echo "$msgBuffer" "$line" 104 | 105 | if [[ "$line" == *"$whatToFind"* ]]; then 106 | echo $msgAppStarted 107 | pkill tail 108 | exit 109 | fi 110 | done 111 | } 112 | 113 | ### FUNCTIONS CALLS 114 | ##################### 115 | # Use Example of this file. Args: enviroment | port | project name | external resourcce 116 | # BUILD_ID=dontKillMe /path/to/this/file/api-deploy.sh dev 8082 spring-boot application-localhost.yml 117 | 118 | # 1 - stop server on port ... 119 | stopServer 120 | 121 | # 2 - delete destinations folder content 122 | deleteFiles 123 | 124 | # 3 - copy files to deploy dir 125 | copyFiles 126 | 127 | changeFilePermission 128 | # 4 - start server 129 | run 130 | 131 | # 5 - watch loading messages until ($whatToFind) message is found 132 | watch 133 | -------------------------------------------------------------------------------- /api/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /api/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | -------------------------------------------------------------------------------- /api/.gradle/2.7/taskArtifacts/cache.properties: -------------------------------------------------------------------------------- 1 | #Tue Nov 03 12:10:25 BRST 2015 2 | -------------------------------------------------------------------------------- /api/.gradle/2.7/taskArtifacts/cache.properties.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcoli/spring-boot-jenkins/7d5add771fc3ab1b9c924927373c91e72a004e53/api/.gradle/2.7/taskArtifacts/cache.properties.lock -------------------------------------------------------------------------------- /api/.gradle/2.7/taskArtifacts/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcoli/spring-boot-jenkins/7d5add771fc3ab1b9c924927373c91e72a004e53/api/.gradle/2.7/taskArtifacts/fileHashes.bin -------------------------------------------------------------------------------- /api/.gradle/2.7/taskArtifacts/fileSnapshots.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcoli/spring-boot-jenkins/7d5add771fc3ab1b9c924927373c91e72a004e53/api/.gradle/2.7/taskArtifacts/fileSnapshots.bin -------------------------------------------------------------------------------- /api/.gradle/2.7/taskArtifacts/outputFileStates.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcoli/spring-boot-jenkins/7d5add771fc3ab1b9c924927373c91e72a004e53/api/.gradle/2.7/taskArtifacts/outputFileStates.bin -------------------------------------------------------------------------------- /api/.gradle/2.7/taskArtifacts/taskArtifacts.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcoli/spring-boot-jenkins/7d5add771fc3ab1b9c924927373c91e72a004e53/api/.gradle/2.7/taskArtifacts/taskArtifacts.bin -------------------------------------------------------------------------------- /api/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | api 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.springsource.ide.eclipse.gradle.core.nature 16 | org.eclipse.jdt.core.javanature 17 | 18 | 19 | -------------------------------------------------------------------------------- /api/.settings/gradle/org.springsource.ide.eclipse.gradle.core.import.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleImportPreferences 2 | #Tue Nov 03 12:09:55 BRST 2015 3 | addResourceFilters=true 4 | afterTasks=afterEclipseImport; 5 | beforeTasks=cleanEclipse;eclipse; 6 | enableAfterTasks=true 7 | enableBeforeTasks=true 8 | enableDependendencyManagement=true 9 | projects=; 10 | -------------------------------------------------------------------------------- /api/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences 2 | #Tue Nov 03 12:10:27 BRST 2015 3 | build.family.org.gradle.tooling.model.eclipse.HierarchicalEclipseProject=; 4 | org.springsource.ide.eclipse.gradle.linkedresources= 5 | org.springsource.ide.eclipse.gradle.rootprojectloc= 6 | -------------------------------------------------------------------------------- /api/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences 2 | #Tue Nov 03 12:10:26 BRST 2015 3 | addResourceFilters=true 4 | afterTasks=afterEclipseImport; 5 | beforeTasks=cleanEclipse;eclipse; 6 | enableAfterTasks=true 7 | enableBeforeTasks=true 8 | useHierarchicalNames=false 9 | -------------------------------------------------------------------------------- /api/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | # 2 | #Wed Nov 04 10:24:52 BRST 2015 3 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 4 | org.eclipse.jdt.core.compiler.compliance=1.7 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 7 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 8 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 9 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 10 | eclipse.preferences.version=1 11 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 12 | org.eclipse.jdt.core.compiler.source=1.7 13 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 14 | -------------------------------------------------------------------------------- /api/bin/.gitignore: -------------------------------------------------------------------------------- 1 | /application.properties 2 | /br/ 3 | /templates/ 4 | /application.yml 5 | -------------------------------------------------------------------------------- /api/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | springBootVersion = '1.2.7.RELEASE' 4 | } 5 | repositories { 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 10 | classpath('io.spring.gradle:dependency-management-plugin:0.5.2.RELEASE') 11 | } 12 | } 13 | 14 | apply plugin: 'java' 15 | apply plugin: 'eclipse' 16 | apply plugin: 'idea' 17 | apply plugin: 'spring-boot' 18 | apply plugin: 'io.spring.dependency-management' 19 | 20 | jar { 21 | baseName = 'spring-boot' 22 | version = '0.0.1-SNAPSHOT' 23 | } 24 | sourceCompatibility = 1.7 25 | targetCompatibility = 1.7 26 | 27 | repositories { 28 | mavenCentral() 29 | } 30 | 31 | 32 | dependencies { 33 | compile('org.springframework.boot:spring-boot-starter-data-rest') 34 | compile('org.springframework.boot:spring-boot-starter-web') 35 | testCompile('org.springframework.boot:spring-boot-starter-test') 36 | } 37 | 38 | 39 | eclipse { 40 | classpath { 41 | containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER') 42 | containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7' 43 | } 44 | } 45 | 46 | task wrapper(type: Wrapper) { 47 | gradleVersion = '2.7' 48 | } 49 | -------------------------------------------------------------------------------- /api/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-bin.zip 6 | -------------------------------------------------------------------------------- /api/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >&- 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >&- 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /api/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /api/src/main/java/br/com/rcoli/Application.java: -------------------------------------------------------------------------------- 1 | package br.com.rcoli; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(Application.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /api/src/main/java/br/com/rcoli/controller/MainController.java: -------------------------------------------------------------------------------- 1 | package br.com.rcoli.controller; 2 | 3 | import java.util.Date; 4 | 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import br.com.rcoli.model.Response; 10 | 11 | @RestController 12 | public class MainController { 13 | 14 | @Value("${my.property}") 15 | private String property; 16 | 17 | 18 | @RequestMapping("/") 19 | public Response index() { 20 | 21 | Response response = new Response(); 22 | 23 | 24 | response.setMyString(property); 25 | response.setMyDate(new Date()); 26 | response.setMyInteger(123); 27 | response.setMyBoolean(true); 28 | 29 | 30 | 31 | return response; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /api/src/main/java/br/com/rcoli/model/Response.java: -------------------------------------------------------------------------------- 1 | package br.com.rcoli.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | import com.fasterxml.jackson.annotation.JsonFormat; 7 | 8 | public class Response implements Serializable { 9 | 10 | private static final long serialVersionUID = -6669438424821208880L; 11 | 12 | private String myString; 13 | 14 | @JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ssZ") 15 | private Date myDate; 16 | 17 | private Boolean myBoolean; 18 | 19 | private Integer myInteger; 20 | 21 | public Response() { 22 | } 23 | 24 | public String getMyString() { 25 | return myString; 26 | } 27 | 28 | public void setMyString(String myString) { 29 | this.myString = myString; 30 | } 31 | 32 | public Date getMyDate() { 33 | return myDate; 34 | } 35 | 36 | public void setMyDate(Date myDate) { 37 | this.myDate = myDate; 38 | } 39 | 40 | public Boolean getMyBoolean() { 41 | return myBoolean; 42 | } 43 | 44 | public void setMyBoolean(Boolean myBoolean) { 45 | this.myBoolean = myBoolean; 46 | } 47 | 48 | public Integer getMyInteger() { 49 | return myInteger; 50 | } 51 | 52 | public void setMyInteger(Integer myInteger) { 53 | this.myInteger = myInteger; 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | return "Response [myString=" + myString + ", myDate=" + myDate + ", myBoolean=" + myBoolean + ", myInteger=" + myInteger + "]"; 59 | } 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /api/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | my: 2 | property: This is my INTERNAL property. 3 | 4 | server: 5 | port: 8090 6 | -------------------------------------------------------------------------------- /api/src/test/java/br/com/rcoli/ApplicationTests.java: -------------------------------------------------------------------------------- 1 | package br.com.rcoli; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.test.context.web.WebAppConfiguration; 6 | import org.springframework.boot.test.SpringApplicationConfiguration; 7 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 8 | 9 | @RunWith(SpringJUnit4ClassRunner.class) 10 | @SpringApplicationConfiguration(classes = Application.class) 11 | @WebAppConfiguration 12 | public class ApplicationTests { 13 | 14 | @Test 15 | public void contextLoads() { 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /resources/application-localhost.yml: -------------------------------------------------------------------------------- 1 | my: 2 | property: This is my EXTERNAL property. --------------------------------------------------------------------------------