├── 9781484244753.jpg ├── Contributing.md ├── LICENSE.txt ├── README.md ├── ch10 └── serverless-example-ch10 │ ├── build.gradle │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ └── main │ └── java │ └── com │ └── example │ └── App.java ├── ch11 └── messaging-examples-ch11 │ ├── .gradle │ ├── 5.4 │ │ ├── executionHistory │ │ │ ├── executionHistory.bin │ │ │ └── executionHistory.lock │ │ ├── fileChanges │ │ │ └── last-build.bin │ │ ├── fileContent │ │ │ └── fileContent.lock │ │ ├── fileHashes │ │ │ ├── fileHashes.bin │ │ │ └── fileHashes.lock │ │ ├── gc.properties │ │ └── javaCompile │ │ │ └── javaCompile.lock │ ├── buildOutputCleanup │ │ ├── buildOutputCleanup.lock │ │ ├── cache.properties │ │ └── outputFiles.bin │ └── vcs-1 │ │ └── gc.properties │ ├── build.gradle │ ├── build │ └── classes │ │ └── java │ │ └── main │ │ └── com │ │ └── example │ │ ├── Application.class │ │ └── rabbitmq │ │ └── RabbitMQConfig.class │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── src │ └── main │ ├── java │ └── com │ │ └── example │ │ ├── Application.java │ │ ├── kafka │ │ ├── KafkaConsumer.java │ │ └── KafkaProducer.java │ │ └── rabbitmq │ │ ├── Consumer.java │ │ ├── Producer.java │ │ └── RabbitMQConfig.java │ └── resources │ ├── application.properties │ └── application.yml ├── ch2 ├── hello-dropwizard │ ├── application.yml │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── example │ │ └── blogs │ │ ├── BlogApplication.java │ │ ├── api │ │ └── PostResource.java │ │ ├── config │ │ └── BlogAppConfig.java │ │ └── model │ │ └── Post.java ├── hello-spark │ ├── .classpath │ ├── .project │ ├── .settings │ │ ├── org.eclipse.buildship.core.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.eclipse.wst.common.project.facet.core.xml │ ├── .springBeans │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── hello.iml │ ├── settings.gradle │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── example │ │ └── hello │ │ └── HelloWorld.java └── hello-spring │ ├── build.gradle │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── hello │ │ │ └── HelloApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── example │ └── hello │ └── HelloApplicationTests.java ├── ch3 └── blog-app-jpa-ch3 │ ├── build.gradle │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── blog_app │ │ │ ├── BlogJpaApp.java │ │ │ ├── constants │ │ │ ├── PgArrayType.java │ │ │ └── PgEnumType.java │ │ │ ├── helper │ │ │ └── DataGenerator.java │ │ │ ├── model │ │ │ └── jpa │ │ │ │ ├── Address.java │ │ │ │ ├── Blog.java │ │ │ │ ├── Comment.java │ │ │ │ ├── CommentLike.java │ │ │ │ ├── File.java │ │ │ │ ├── Post.java │ │ │ │ ├── PostFileJoinTable.java │ │ │ │ ├── PostStatus.java │ │ │ │ └── User.java │ │ │ ├── repository │ │ │ ├── BlogRepository.java │ │ │ ├── CommentRepository.java │ │ │ ├── FileRepository.java │ │ │ ├── PostRepository.java │ │ │ ├── UserRepository.java │ │ │ └── base │ │ │ │ ├── BaseRepository.java │ │ │ │ └── BaseRepositoryImpl.java │ │ │ ├── service │ │ │ └── UserCRUDService.java │ │ │ └── web │ │ │ └── IndexController.java │ └── resources │ │ ├── application.yml │ │ └── schema.sql │ └── test │ ├── java │ └── com │ │ └── example │ │ └── blog_app │ │ ├── BlogJpaAppTests.java │ │ └── BlogTestBase.java │ └── resources │ └── application-test.yml ├── ch4 └── eshop-ch4 │ ├── build.gradle │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── src │ └── main │ ├── java │ └── com │ │ └── example │ │ └── eshop │ │ ├── Application.java │ │ ├── config │ │ ├── DbConfigPrimary.java │ │ └── DbConfigSecondary.java │ │ ├── converter │ │ └── CustomerAddressConverter.java │ │ ├── model │ │ ├── dto │ │ │ └── CustomerDto.java │ │ ├── history │ │ │ └── PurchaseHistory.java │ │ ├── orders │ │ │ ├── Customer.java │ │ │ ├── Order.java │ │ │ └── Product.java │ │ ├── projection │ │ │ └── CustomerProjection.java │ │ └── type │ │ │ └── CustomerAddress.java │ │ ├── repository │ │ ├── history │ │ │ └── PurchaseHistoryRepository.java │ │ └── orders │ │ │ ├── CustomerRepository.java │ │ │ ├── OrderRepository.java │ │ │ └── ProductRepository.java │ │ └── service │ │ └── impl │ │ ├── CustomerService.java │ │ └── ProductService.java │ └── resources │ ├── application.properties │ └── application.yml ├── ch5 ├── blog-spring-data-mongodb-ch5 │ ├── build.gradle │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── blog_app │ │ │ ├── BlogApp.java │ │ │ ├── model │ │ │ └── mongo │ │ │ │ ├── Comment.java │ │ │ │ ├── Post.java │ │ │ │ └── PostStatus.java │ │ │ └── repository │ │ │ └── PostMongoRepository.java │ │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── blog_app │ │ └── BlogTests.java ├── eblog-spring-data-jdbc-ch5 │ ├── build.gradle │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── eblog │ │ │ ├── App.java │ │ │ ├── model │ │ │ ├── Author.java │ │ │ └── Post.java │ │ │ ├── repository │ │ │ ├── AuthorRepository.java │ │ │ └── PostRepository.java │ │ │ └── web │ │ │ └── TestController.java │ │ └── resources │ │ └── application.properties └── eshop-jdbc-template-ch5 │ ├── .sts4-cache │ └── classpath-data.json │ ├── build.gradle │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── eshop │ │ │ ├── Application.java │ │ │ └── model │ │ │ └── dto │ │ │ └── CustomerOrder.java │ └── resources │ │ └── application.properties │ └── test │ ├── java │ └── com │ │ └── example │ │ └── eshop │ │ └── EshopAppTests.java │ └── resources │ └── schema.sql ├── ch6 └── spring-cloud-ch6 │ ├── admin-service │ ├── .classpath │ ├── .project │ ├── .settings │ │ ├── org.eclipse.buildship.core.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.springframework.ide.eclipse.prefs │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── admin │ │ │ └── AdminApp.java │ │ └── resources │ │ └── application.yml │ ├── config-service │ ├── .classpath │ ├── .project │ ├── .settings │ │ ├── org.eclipse.buildship.core.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.springframework.ide.eclipse.prefs │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── config │ │ │ └── ConfigApp.java │ │ └── resources │ │ ├── application.yml │ │ └── bootstrap.yml │ ├── discovery-service │ ├── .classpath │ ├── .project │ ├── .settings │ │ ├── org.eclipse.buildship.core.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.springframework.ide.eclipse.prefs │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── eshop │ │ │ └── discovery │ │ │ └── DiscoveryApp.java │ │ └── resources │ │ └── application.yml │ ├── eshop │ ├── .classpath │ ├── .project │ ├── .settings │ │ ├── org.eclipse.buildship.core.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.springframework.ide.eclipse.prefs │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── eshop │ │ │ ├── EshopApp.java │ │ │ ├── config │ │ │ ├── SwaggerConfig.java │ │ │ └── WebConfig.java │ │ │ ├── dto │ │ │ └── LoginRequest.java │ │ │ ├── http │ │ │ └── InventoryClient.java │ │ │ ├── model │ │ │ ├── Customer.java │ │ │ ├── Order.java │ │ │ └── Product.java │ │ │ ├── repository │ │ │ ├── CustomerRepository.java │ │ │ ├── OrderRepository.java │ │ │ └── ProductRepository.java │ │ │ ├── service │ │ │ └── impl │ │ │ │ ├── CustomerService.java │ │ │ │ ├── OrderService.java │ │ │ │ ├── OrderServiceWithFiegn.java │ │ │ │ └── ProductService.java │ │ │ └── web │ │ │ ├── LoginController.java │ │ │ └── TestController.java │ │ └── resources │ │ ├── application.properties │ │ └── application.yml │ ├── gateway-service │ ├── .classpath │ ├── .project │ ├── .settings │ │ ├── org.eclipse.buildship.core.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.springframework.ide.eclipse.prefs │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── out │ │ └── production │ │ │ ├── classes │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── eshop │ │ │ │ └── gateway │ │ │ │ ├── ZuulApp.class │ │ │ │ └── filters │ │ │ │ └── AuthPreFilter.class │ │ │ └── resources │ │ │ ├── application.properties │ │ │ └── application.yml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── eshop │ │ │ └── gateway │ │ │ ├── ZuulApp.java │ │ │ └── filters │ │ │ └── AuthPreFilter.java │ │ └── resources │ │ ├── application.properties │ │ └── application.yml │ └── inventory-service │ ├── .classpath │ ├── .project │ ├── .settings │ ├── org.eclipse.buildship.core.prefs │ ├── org.eclipse.jdt.core.prefs │ └── org.springframework.ide.eclipse.prefs │ ├── build.gradle │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ └── main │ ├── java │ └── com │ │ └── example │ │ └── eshop │ │ └── inventory │ │ ├── InventoryApp.java │ │ ├── model │ │ └── Inventory.java │ │ ├── repository │ │ └── InventoryRepository.java │ │ ├── service │ │ └── InventoryService.java │ │ └── web │ │ └── InventoryController.java │ └── resources │ ├── application.yml │ └── bootstrap.yml ├── ch7 └── eblog-graphql-ch7 │ ├── build.gradle │ ├── eshop.iml │ ├── settings.gradle │ └── src │ └── main │ ├── java │ └── com │ │ └── example │ │ └── eblog │ │ ├── App.java │ │ ├── dto │ │ ├── AuthorInputRequest.java │ │ └── PostInputRequest.java │ │ ├── handler │ │ └── GraphQLConfig.java │ │ ├── model │ │ ├── Author.java │ │ ├── Post.java │ │ └── Status.java │ │ ├── repository │ │ ├── AuthorRepository.java │ │ └── PostRepository.java │ │ └── resolvers │ │ ├── MutationResolver.java │ │ └── QueryResolver.java │ └── resources │ ├── application.yml │ └── schema.graphqls ├── ch8 └── eblog-reactive-ch8 │ ├── build.gradle │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ └── main │ └── java │ └── com │ └── example │ └── eblog │ ├── App.java │ ├── config │ └── Config.java │ ├── dto │ └── PostInputRequest.java │ ├── model │ └── Post.java │ ├── repository │ └── PostRepository.java │ └── web │ └── PostController.java ├── ch9 └── websocket-example-ch9 │ ├── build.gradle │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ └── main │ └── java │ └── com │ └── example │ ├── Application.java │ └── web │ ├── MessageService.java │ ├── TweetController.java │ └── WSHandler.java └── errata.md /9781484244753.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/9781484244753.jpg -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Apress Source Code 2 | 3 | Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. 4 | 5 | ## How to Contribute 6 | 7 | 1. Make sure you have a GitHub account. 8 | 2. Fork the repository for the relevant book. 9 | 3. Create a new branch on which to make your change, e.g. 10 | `git checkout -b my_code_contribution` 11 | 4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. 12 | 5. Submit a pull request. 13 | 14 | Thank you for your contribution! -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Freeware License, some rights reserved 2 | 3 | Copyright (c) 2019 Raj Malhotra 4 | 5 | Permission is hereby granted, free of charge, to anyone obtaining a copy 6 | of this software and associated documentation files (the "Software"), 7 | to work with the Software within the limits of freeware distribution and fair use. 8 | This includes the rights to use, copy, and modify the Software for personal use. 9 | Users are also allowed and encouraged to submit corrections and modifications 10 | to the Software for the benefit of other users. 11 | 12 | It is not allowed to reuse, modify, or redistribute the Software for 13 | commercial use in any way, or for a user’s educational materials such as books 14 | or blog articles without prior permission from the copyright holder. 15 | 16 | The above copyright notice and this permission notice need to be included 17 | in all copies or substantial portions of the software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apress Source Code 2 | 3 | This repository accompanies [*Rapid Java Persistence and Microservices*](https://www.apress.com/9781484244753) by Raj Malhotra (Apress, 2019). 4 | 5 | [comment]: #cover 6 | ![Cover image](9781484244753.jpg) 7 | 8 | Download the files as a zip using the green button, or clone the repository to your machine using Git. 9 | 10 | ## Releases 11 | 12 | Release v1.0 corresponds to the code in the published book, without corrections or updates. 13 | 14 | ## Contributions 15 | 16 | See the file Contributing.md for more information on how you can contribute to this repository. -------------------------------------------------------------------------------- /ch10/serverless-example-ch10/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | 8 | java { 9 | group = 'com.example' 10 | version = '1.0' 11 | sourceCompatibility = JavaVersion.VERSION_1_8 12 | targetCompatibility = JavaVersion.VERSION_1_8 13 | } 14 | 15 | bootJar { 16 | archiveBaseName = 'serverless-example' 17 | version = '1.0' 18 | } 19 | 20 | repositories { 21 | mavenCentral() 22 | maven { url "https://repo.spring.io/snapshot" } 23 | maven { url "https://repo.spring.io/milestone" } 24 | } 25 | 26 | dependencies { 27 | compile("org.springframework.cloud:spring-cloud-starter-function-web") 28 | compile("org.springframework.cloud:spring-cloud-function-adapter-aws") 29 | compile("org.projectlombok:lombok:1.18.6") 30 | annotationProcessor 'org.projectlombok:lombok:1.18.6' 31 | } 32 | 33 | dependencyManagement { 34 | imports { 35 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:Greenwich.SR1" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ch10/serverless-example-ch10/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch10/serverless-example-ch10/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch10/serverless-example-ch10/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Mar 23 14:30:50 IST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-all.zip 7 | -------------------------------------------------------------------------------- /ch10/serverless-example-ch10/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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /ch10/serverless-example-ch10/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'serverless-example' 2 | 3 | -------------------------------------------------------------------------------- /ch10/serverless-example-ch10/src/main/java/com/example/App.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.Bean; 6 | import reactor.core.publisher.Flux; 7 | 8 | import java.util.function.Supplier; 9 | 10 | @SpringBootApplication 11 | public class App { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(App.class, args); 15 | } 16 | 17 | @Bean 18 | public Supplier> randomWords() { 19 | return () -> Flux.fromArray(new String[] { "Raj", "Malhotra"}); 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/.gradle/5.4/executionHistory/executionHistory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/.gradle/5.4/executionHistory/executionHistory.bin -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/.gradle/5.4/executionHistory/executionHistory.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/.gradle/5.4/executionHistory/executionHistory.lock -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/.gradle/5.4/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/.gradle/5.4/fileContent/fileContent.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/.gradle/5.4/fileContent/fileContent.lock -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/.gradle/5.4/fileHashes/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/.gradle/5.4/fileHashes/fileHashes.bin -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/.gradle/5.4/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/.gradle/5.4/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/.gradle/5.4/gc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/.gradle/5.4/gc.properties -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/.gradle/5.4/javaCompile/javaCompile.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/.gradle/5.4/javaCompile/javaCompile.lock -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/.gradle/buildOutputCleanup/buildOutputCleanup.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/.gradle/buildOutputCleanup/buildOutputCleanup.lock -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/.gradle/buildOutputCleanup/cache.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 17 20:16:52 IST 2019 2 | gradle.version=5.4 3 | -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/.gradle/buildOutputCleanup/outputFiles.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/.gradle/buildOutputCleanup/outputFiles.bin -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/.gradle/vcs-1/gc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/.gradle/vcs-1/gc.properties -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | 8 | java { 9 | group = 'com.example' 10 | version = '1.0' 11 | sourceCompatibility = JavaVersion.VERSION_1_8 12 | targetCompatibility = JavaVersion.VERSION_1_8 13 | } 14 | 15 | bootJar { 16 | archiveBaseName = 'messaging-example' 17 | version = '1.0' 18 | } 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencies { 25 | compile('org.projectlombok:lombok:1.18.6') 26 | compile("org.springframework.boot:spring-boot-starter-amqp") 27 | 28 | compile('org.apache.kafka:kafka-streams') 29 | compile('org.springframework.kafka:spring-kafka') 30 | annotationProcessor 'org.projectlombok:lombok:1.18.6' 31 | } 32 | -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/build/classes/java/main/com/example/Application.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/build/classes/java/main/com/example/Application.class -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/build/classes/java/main/com/example/rabbitmq/RabbitMQConfig.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/build/classes/java/main/com/example/rabbitmq/RabbitMQConfig.class -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Mar 21 13:58:00 IST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip 7 | -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows 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 | -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/src/main/java/com/example/Application.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.scheduling.annotation.EnableScheduling; 6 | 7 | @SpringBootApplication 8 | @EnableScheduling 9 | public class Application { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(Application.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/src/main/java/com/example/kafka/KafkaConsumer.java: -------------------------------------------------------------------------------- 1 | package com.example.kafka; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.kafka.annotation.KafkaListener; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.io.IOException; 9 | 10 | @Service 11 | @Slf4j 12 | public class KafkaConsumer { 13 | @KafkaListener(topics = "orders", groupId = "order_grp") 14 | public void consume(String message) throws IOException { 15 | log.info("Kafka Received :: {}", message); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/src/main/java/com/example/kafka/KafkaProducer.java: -------------------------------------------------------------------------------- 1 | package com.example.kafka; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.kafka.core.KafkaTemplate; 6 | import org.springframework.scheduling.annotation.Scheduled; 7 | import org.springframework.stereotype.Component; 8 | import org.springframework.stereotype.Service; 9 | 10 | import java.util.Calendar; 11 | 12 | @Service 13 | @Slf4j 14 | public class KafkaProducer { 15 | 16 | private static final String TOPIC = "orders"; 17 | 18 | @Autowired 19 | private KafkaTemplate kafkaTemplate; 20 | 21 | @Scheduled(fixedRate = 1000) 22 | public void sendMessage() { 23 | String message = "Next order received at " + Calendar.getInstance().getTime(); 24 | log.info("Kafka Message sent : {}", message); 25 | kafkaTemplate.send(TOPIC, message); 26 | } 27 | } -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/src/main/java/com/example/rabbitmq/Consumer.java: -------------------------------------------------------------------------------- 1 | package com.example.rabbitmq; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.amqp.rabbit.annotation.RabbitListener; 5 | import org.springframework.stereotype.Service; 6 | 7 | @Service 8 | @Slf4j 9 | public class Consumer { 10 | 11 | @RabbitListener(queues = "orders") 12 | public void receiveMessage(String message) { 13 | log.info("RabbitMQ Received :: {}", message); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/src/main/java/com/example/rabbitmq/Producer.java: -------------------------------------------------------------------------------- 1 | package com.example.rabbitmq; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.scheduling.annotation.Scheduled; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.Calendar; 10 | 11 | @Service 12 | @Slf4j 13 | public class Producer { 14 | 15 | @Autowired 16 | private RabbitTemplate rabbitTemplate; 17 | 18 | @Scheduled(fixedRate = 1000) 19 | public void send() { 20 | String message = "Next order received at " + Calendar.getInstance().getTime(); 21 | this.rabbitTemplate.convertAndSend("orders_exchange", "orders", message); 22 | log.info("RabbitMQ Message sent : {}", message); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/src/main/java/com/example/rabbitmq/RabbitMQConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.rabbitmq; 2 | 3 | import org.springframework.amqp.core.*; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | public class RabbitMQConfig { 9 | 10 | @Bean 11 | public Exchange ordersExchange() { 12 | return new DirectExchange("orders_exchange"); 13 | } 14 | 15 | @Bean 16 | public Queue ordersQueue() { 17 | return new Queue("orders"); 18 | } 19 | 20 | @Bean 21 | public Queue messagesQueue() { 22 | return new Queue("notifications"); 23 | } 24 | 25 | @Bean 26 | public Binding binding() { 27 | return BindingBuilder 28 | .bind(ordersQueue()) 29 | .to(ordersExchange()) 30 | .with("orders.*").noargs(); 31 | } 32 | 33 | @Bean 34 | public Binding binding2() { 35 | return BindingBuilder 36 | .bind(messagesQueue()) 37 | .to(ordersExchange()) 38 | .with("notifications.*").noargs(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.pattern.console=%d{yyyy-MM-dd} - %msg%n 2 | spring.main.banner-mode: off -------------------------------------------------------------------------------- /ch11/messaging-examples-ch11/src/main/resources/application.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch11/messaging-examples-ch11/src/main/resources/application.yml -------------------------------------------------------------------------------- /ch2/hello-dropwizard/application.yml: -------------------------------------------------------------------------------- 1 | blogName: Hello World! -------------------------------------------------------------------------------- /ch2/hello-dropwizard/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "java" 3 | id "com.github.johnrengelman.shadow" version "5.0.0" 4 | } 5 | 6 | group 'com.example' 7 | version '1.0' 8 | 9 | java { 10 | sourceCompatibility = JavaVersion.VERSION_11 11 | targetCompatibility = JavaVersion.VERSION_11 12 | } 13 | 14 | repositories { 15 | mavenCentral() 16 | } 17 | 18 | jar { 19 | manifest { 20 | attributes 'Main-Class': 'com.example.blogs.BlogApplication' 21 | } 22 | } 23 | 24 | dependencies { 25 | compile group: 'io.dropwizard', name: 'dropwizard-core', version: '1.3.9' 26 | compile('org.projectlombok:lombok:1.18.6') 27 | annotationProcessor 'org.projectlombok:lombok:1.18.6' 28 | testCompile group: 'junit', name: 'junit', version: '4.12' 29 | } 30 | 31 | -------------------------------------------------------------------------------- /ch2/hello-dropwizard/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch2/hello-dropwizard/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch2/hello-dropwizard/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Dec 14 15:16:07 IST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip 7 | -------------------------------------------------------------------------------- /ch2/hello-dropwizard/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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /ch2/hello-dropwizard/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'dropwizard-example' 2 | 3 | -------------------------------------------------------------------------------- /ch2/hello-dropwizard/src/main/java/com/example/blogs/BlogApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.blogs; 2 | 3 | import com.example.blogs.api.PostResource; 4 | import com.example.blogs.config.BlogAppConfig; 5 | import io.dropwizard.Application; 6 | import io.dropwizard.setup.Bootstrap; 7 | import io.dropwizard.setup.Environment; 8 | import lombok.Data; 9 | import lombok.extern.slf4j.Slf4j; 10 | 11 | @Data 12 | @Slf4j 13 | public class BlogApplication extends Application { 14 | 15 | @Override 16 | public String getName() { 17 | return "BlogApplication"; 18 | } 19 | 20 | @Override 21 | public void initialize(Bootstrap bootstrap) { 22 | log.info("Application initialized"); 23 | } 24 | 25 | @Override 26 | public void run(BlogAppConfig configuration, Environment environment) throws Exception { 27 | log.info("Application started"); 28 | final PostResource resource = new PostResource(configuration.getBlogName()); 29 | environment.jersey().register(resource); 30 | } 31 | 32 | public static void main(String[] args) throws Exception { 33 | new BlogApplication().run(args); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ch2/hello-dropwizard/src/main/java/com/example/blogs/api/PostResource.java: -------------------------------------------------------------------------------- 1 | package com.example.blogs.api; 2 | 3 | import com.codahale.metrics.annotation.Timed; 4 | import com.example.blogs.model.Post; 5 | 6 | import javax.ws.rs.GET; 7 | import javax.ws.rs.Path; 8 | import javax.ws.rs.Produces; 9 | import javax.ws.rs.QueryParam; 10 | import javax.ws.rs.core.MediaType; 11 | import java.util.Optional; 12 | 13 | @Path("/post") 14 | @Produces(MediaType.APPLICATION_JSON) 15 | public class PostResource { 16 | 17 | private String blogName; 18 | 19 | public PostResource(String blogName) { 20 | this.blogName = blogName; 21 | } 22 | 23 | @GET 24 | @Timed 25 | public Post getRandomPost(@QueryParam("name") Optional name) { 26 | return new Post(1l, name.orElse("This is a random post name") + " from " + blogName ); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ch2/hello-dropwizard/src/main/java/com/example/blogs/config/BlogAppConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.blogs.config; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.dropwizard.Configuration; 5 | import lombok.Data; 6 | import org.hibernate.validator.constraints.NotEmpty; 7 | 8 | public class BlogAppConfig extends Configuration { 9 | 10 | @NotEmpty 11 | @JsonProperty 12 | private String blogName; 13 | 14 | public String getBlogName() { 15 | return blogName; 16 | } 17 | 18 | public void setBlogName(String blogName) { 19 | this.blogName = blogName; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ch2/hello-dropwizard/src/main/java/com/example/blogs/model/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.blogs.model; 2 | 3 | import lombok.Data; 4 | import org.hibernate.validator.constraints.Length; 5 | 6 | @Data 7 | public class Post { 8 | 9 | private Long id; 10 | 11 | @Length(min = 5, max = 300) 12 | private String content; 13 | 14 | public Post(Long id, String content) { 15 | this.id = id; 16 | this.content = content; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ch2/hello-spark/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ch2/hello-spark/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | hello 4 | Project hello created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.wst.common.project.facet.core.builder 20 | 21 | 22 | 23 | 24 | org.springframework.ide.eclipse.core.springbuilder 25 | 26 | 27 | 28 | 29 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 30 | 31 | 32 | 33 | 34 | 35 | org.springframework.ide.eclipse.core.springnature 36 | org.eclipse.jdt.core.javanature 37 | org.eclipse.buildship.core.gradleprojectnature 38 | org.eclipse.wst.common.project.facet.core.nature 39 | 40 | 41 | -------------------------------------------------------------------------------- /ch2/hello-spark/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch2/hello-spark/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.source=1.8 5 | -------------------------------------------------------------------------------- /ch2/hello-spark/.settings/org.eclipse.wst.common.project.facet.core.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ch2/hello-spark/.springBeans: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1 4 | 5 | 6 | 7 | 8 | 9 | 10 | java:com.example.hello.HelloWorld 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ch2/hello-spark/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | 5 | java { 6 | group = 'com.example' 7 | version = '1.0' 8 | sourceCompatibility = JavaVersion.VERSION_11 9 | targetCompatibility = JavaVersion.VERSION_11 10 | } 11 | 12 | repositories { 13 | mavenCentral() 14 | } 15 | 16 | dependencies { 17 | compile "com.sparkjava:spark-core:2.8.0" 18 | } 19 | -------------------------------------------------------------------------------- /ch2/hello-spark/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch2/hello-spark/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch2/hello-spark/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Mar 30 11:47:41 IST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-all.zip 7 | -------------------------------------------------------------------------------- /ch2/hello-spark/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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /ch2/hello-spark/hello.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /ch2/hello-spark/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'hello-spark' 2 | -------------------------------------------------------------------------------- /ch2/hello-spark/src/main/java/com/example/hello/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package com.example.hello; 2 | 3 | import static spark.Spark.*; 4 | 5 | public class HelloWorld { 6 | public static void main(String[] args) { 7 | 8 | get("/hello", (request, response) -> { 9 | return "Hello World"; 10 | }); 11 | 12 | post("/", (request, response) -> { 13 | return "Hello World"; 14 | }); 15 | 16 | put("/", (request, response) -> { 17 | return "Hello World"; 18 | }); 19 | 20 | delete("/", (request, response) -> { 21 | return "Deleted - Hello World"; 22 | }); 23 | 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /ch2/hello-spring/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | 8 | java { 9 | group = 'com.example' 10 | version = '1.0' 11 | sourceCompatibility = JavaVersion.VERSION_1_8 12 | targetCompatibility = JavaVersion.VERSION_1_8 13 | } 14 | 15 | repositories { 16 | mavenCentral() 17 | } 18 | 19 | dependencies { 20 | 21 | compile("org.springframework.boot:spring-boot-starter") 22 | compile("org.springframework.boot:spring-boot-starter-web") 23 | 24 | compile("org.projectlombok:lombok:1.18.6") 25 | annotationProcessor("org.projectlombok:lombok:1.18.6") 26 | } 27 | -------------------------------------------------------------------------------- /ch2/hello-spring/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch2/hello-spring/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch2/hello-spring/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Dec 14 15:52:11 IST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /ch2/hello-spring/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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /ch2/hello-spring/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'hello-spring' 2 | -------------------------------------------------------------------------------- /ch2/hello-spring/src/main/java/com/example/hello/HelloApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.hello; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.boot.CommandLineRunner; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @SpringBootApplication 11 | @RestController 12 | @Slf4j 13 | public class HelloApplication implements CommandLineRunner { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(HelloApplication.class, args); 17 | } 18 | 19 | @Override 20 | public void run(String... args) throws Exception { 21 | log.info("App started"); 22 | } 23 | 24 | @GetMapping("/hello") 25 | public String hello() { 26 | return "Hello World"; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /ch2/hello-spring/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.servlet.context-path=/library -------------------------------------------------------------------------------- /ch2/hello-spring/src/test/java/com/example/hello/HelloApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.hello; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class HelloApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | 18 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | 8 | bootJar { 9 | baseName = 'blog-app' 10 | version = '1.0' 11 | } 12 | 13 | repositories { 14 | mavenCentral() 15 | } 16 | 17 | dependencies { 18 | 19 | compile('org.springframework.boot:spring-boot-starter-web') 20 | compile('org.springframework.boot:spring-boot-starter-jdbc') 21 | compile('org.springframework.boot:spring-boot-starter-data-jpa') 22 | compile("org.springframework.boot:spring-boot-starter-data-mongodb") 23 | 24 | compile('org.postgresql:postgresql:42.2.5') 25 | 26 | testCompile('junit:junit:4.12') 27 | testCompile('org.springframework.boot:spring-boot-starter-test') 28 | 29 | compile("org.projectlombok:lombok:1.18.6") 30 | annotationProcessor("org.projectlombok:lombok:1.18.6") 31 | } 32 | 33 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/BlogJpaApp.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app; 2 | 3 | import com.example.blog_app.repository.base.BaseRepositoryImpl; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.boot.CommandLineRunner; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 9 | 10 | @SpringBootApplication 11 | @Slf4j 12 | @EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class) 13 | public class BlogJpaApp implements CommandLineRunner { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(BlogJpaApp.class, args); 17 | } 18 | 19 | @Override 20 | public void run(String... args) throws Exception { 21 | log.info("App started"); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/model/jpa/Address.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.model.jpa; 2 | 3 | import javax.persistence.*; 4 | 5 | @Entity 6 | public class Address { 7 | 8 | @Id 9 | @GeneratedValue(strategy = GenerationType.IDENTITY) 10 | private Long id; 11 | private String address; 12 | 13 | @OneToOne(mappedBy = "address") 14 | private User user; 15 | 16 | } 17 | 18 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/model/jpa/Blog.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.model.jpa; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import lombok.*; 5 | 6 | import javax.persistence.*; 7 | import java.io.Serializable; 8 | import java.time.LocalDateTime; 9 | import java.util.Set; 10 | import java.util.UUID; 11 | 12 | @Data // generates getters, setters, equals and toString we well 13 | @Builder // generater builder for the field within 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @ToString(exclude = {"posts"}) 17 | @EqualsAndHashCode(exclude = {"posts"}) 18 | @Entity 19 | public class Blog implements Serializable { 20 | 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.IDENTITY) 23 | private Long id; 24 | 25 | /* 26 | 'guid' is useful to hide incremental 'id' from all external communications for security reasons. 27 | 'id' would be faster to index and query while doing pagination, filtering etc. 28 | */ 29 | @org.hibernate.annotations.Type(type = "pg-uuid") 30 | UUID guid; 31 | 32 | private String name; 33 | 34 | private String about; 35 | 36 | private LocalDateTime publishedAt; 37 | 38 | @JsonIgnore 39 | @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, 40 | orphanRemoval = true, mappedBy = "blog") 41 | private Set posts; 42 | 43 | @JsonIgnore 44 | @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) 45 | @JoinColumn(name = "blogId") 46 | private Set users; 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/model/jpa/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.model.jpa; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import lombok.Data; 5 | 6 | import javax.persistence.*; 7 | 8 | @Data 9 | @Entity 10 | public class Comment { 11 | 12 | @Id 13 | @GeneratedValue(strategy = GenerationType.IDENTITY) 14 | private Long id; 15 | 16 | //private Long postId; 17 | private Long parentId; 18 | private String content; 19 | 20 | @JsonIgnore 21 | @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 22 | @JoinColumn(name = "post_id") 23 | Post post; 24 | } 25 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/model/jpa/CommentLike.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.model.jpa; 2 | 3 | import lombok.*; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.GenerationType; 8 | import javax.persistence.Id; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @Entity 15 | public class CommentLike { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.IDENTITY) 19 | private Long id; 20 | 21 | private Long postId; 22 | private Long commentId; 23 | private Long userId; 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/model/jpa/File.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.model.jpa; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import lombok.*; 5 | 6 | import javax.persistence.*; 7 | import java.util.Set; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | @ToString(exclude = {"posts"}) 14 | @EqualsAndHashCode(exclude = {"posts"}) 15 | @Entity 16 | public class File { 17 | 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | private Long id; 21 | private String name; 22 | 23 | @JsonIgnore 24 | @ManyToMany(cascade = {CascadeType.MERGE,CascadeType.REFRESH}, fetch = FetchType.LAZY) 25 | @JoinTable( 26 | name = "post_files",joinColumns = { 27 | @JoinColumn(name = "file_id", referencedColumnName = "id")}, 28 | inverseJoinColumns={ 29 | @JoinColumn(name = "post_id", referencedColumnName = "id")}) 30 | private Set posts; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/model/jpa/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.model.jpa; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import lombok.*; 5 | import org.hibernate.annotations.Type; 6 | 7 | import javax.persistence.*; 8 | import java.io.Serializable; 9 | import java.util.Set; 10 | 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @ToString(exclude = {"blog", "user", "files"}) 16 | @EqualsAndHashCode(exclude = {"blog", "user", "files"}) 17 | @Entity 18 | public class Post implements Serializable { 19 | 20 | @Id 21 | @GeneratedValue(strategy = GenerationType.IDENTITY) 22 | private Long id; 23 | private String title; 24 | private String content; 25 | 26 | @Type(type = "com.example.blog_app.constants.PgArrayType") 27 | private String[] tags; 28 | 29 | @Column(name = "post_status") 30 | @Type(type = "com.example.blog_app.constants.PgEnumType", 31 | parameters = {@org.hibernate.annotations.Parameter(name = "enumClassName", 32 | value = "com.example.blog_app.model.jpa.PostStatus")}) 33 | PostStatus postStatus; 34 | 35 | @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 36 | @JoinColumn(name = "blog_id") 37 | private Blog blog; 38 | 39 | @JsonIgnore 40 | @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 41 | @JoinColumn(name = "author_id") 42 | private User user; 43 | 44 | @JsonIgnore 45 | @ManyToMany(cascade = {CascadeType.MERGE,CascadeType.REFRESH}, fetch = FetchType.LAZY) 46 | @JoinTable( 47 | name = "post_files",joinColumns = { 48 | @JoinColumn(name = "post_id", referencedColumnName = "id")}, 49 | inverseJoinColumns={ 50 | @JoinColumn(name = "file_id", referencedColumnName = "id")}) 51 | private Set files; 52 | } 53 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/model/jpa/PostFileJoinTable.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.model.jpa; 2 | 3 | 4 | public class PostFileJoinTable { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/model/jpa/PostStatus.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.model.jpa; 2 | 3 | import java.io.Serializable; 4 | 5 | public enum PostStatus implements Serializable { 6 | 7 | ACTIVE(1), NOT_ACTIVE(2); 8 | 9 | int status; 10 | 11 | PostStatus(int status) { 12 | this.status = status; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/model/jpa/User.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.model.jpa; 2 | 3 | import lombok.*; 4 | 5 | import javax.persistence.*; 6 | import java.io.Serializable; 7 | import java.time.LocalDateTime; 8 | import java.util.Set; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @ToString(exclude = {"posts"}) 15 | @EqualsAndHashCode(exclude = {"posts"}) 16 | @Entity 17 | @Table(name = "`user`") 18 | public class User implements Serializable { 19 | 20 | public User(String username, String password, String email) { 21 | this.username = username; 22 | this.password = password; 23 | this.email = email; 24 | } 25 | 26 | @Id 27 | @GeneratedValue(strategy = GenerationType.IDENTITY) 28 | private Long id; 29 | 30 | private Long blogId; 31 | 32 | private String username; 33 | private String password; 34 | private String email; 35 | private Boolean isActive; 36 | private Integer addressId; 37 | 38 | @Column(insertable = false, updatable = false) 39 | private LocalDateTime activatedAt; 40 | 41 | @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, 42 | mappedBy = "user", orphanRemoval = true) 43 | private Set posts; 44 | 45 | @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 46 | @JoinColumn(name = "addressId", insertable = false, updatable = false) 47 | private Address address; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/repository/BlogRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.repository; 2 | 3 | import com.example.blog_app.model.jpa.Blog; 4 | import com.example.blog_app.repository.base.BaseRepository; 5 | 6 | public interface BlogRepository extends BaseRepository { 7 | } 8 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/repository/CommentRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.repository; 2 | 3 | import com.example.blog_app.model.jpa.Comment; 4 | import com.example.blog_app.model.jpa.Post; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | public interface CommentRepository extends JpaRepository { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/repository/FileRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.repository; 2 | 3 | import com.example.blog_app.model.jpa.File; 4 | import com.example.blog_app.repository.base.BaseRepository; 5 | 6 | public interface FileRepository extends BaseRepository { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/repository/PostRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.repository; 2 | 3 | import com.example.blog_app.model.jpa.Post; 4 | import org.springframework.data.domain.PageRequest; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.data.jpa.repository.Query; 7 | 8 | import java.util.List; 9 | 10 | public interface PostRepository extends JpaRepository { 11 | 12 | @Query("Select p.id, p.title from Post p") 13 | List findPostWithIdAndTitle(PageRequest pageRequest); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.repository; 2 | 3 | import com.example.blog_app.model.jpa.User; 4 | import com.example.blog_app.repository.base.BaseRepository; 5 | import org.springframework.data.jpa.repository.Query; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.Optional; 9 | import java.util.stream.Stream; 10 | 11 | @Repository 12 | public interface UserRepository extends BaseRepository { 13 | 14 | void deleteByUsername(String username); 15 | 16 | Optional findByUsername(String username); 17 | 18 | @Query("select u from User u") 19 | Stream streamAll(); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/repository/base/BaseRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.repository.base; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.repository.NoRepositoryBean; 5 | 6 | import java.io.Serializable; 7 | 8 | @NoRepositoryBean 9 | public interface BaseRepository extends JpaRepository { 10 | void refresh(T t); 11 | } -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/repository/base/BaseRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.repository.base; 2 | 3 | import org.springframework.data.jpa.repository.support.JpaEntityInformation; 4 | import org.springframework.data.jpa.repository.support.SimpleJpaRepository; 5 | 6 | import javax.persistence.EntityManager; 7 | import javax.transaction.Transactional; 8 | import java.io.Serializable; 9 | 10 | public class BaseRepositoryImpl extends SimpleJpaRepository 11 | implements BaseRepository { 12 | 13 | private final EntityManager entityManager; 14 | 15 | public BaseRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) { 16 | super(entityInformation, entityManager); 17 | this.entityManager = entityManager; 18 | } 19 | 20 | @Override 21 | @Transactional 22 | public void refresh(T t) { 23 | entityManager.refresh(t); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/service/UserCRUDService.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.service; 2 | 3 | import com.example.blog_app.model.jpa.User; 4 | import com.example.blog_app.repository.UserRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | import org.springframework.transaction.annotation.Transactional; 8 | 9 | @Service 10 | public class UserCRUDService { 11 | 12 | @Autowired 13 | UserRepository userRepository; 14 | 15 | @Transactional 16 | public User createNewUser(User user) { 17 | user = userRepository.save(user); 18 | return user; 19 | } 20 | 21 | @Transactional 22 | public boolean deleteUser(String username) { 23 | userRepository.deleteByUsername(username); 24 | return true; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/java/com/example/blog_app/web/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.web; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class IndexController { 8 | 9 | @GetMapping("/") 10 | public String hello() { 11 | return "Hello"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | servlet: 4 | contextPath: /blog 5 | 6 | logging.file: logs/blogging-service.log 7 | 8 | spring: 9 | application: 10 | name: blog-service 11 | jpa: 12 | show-sql: true 13 | hibernate: 14 | ddl-auto: update 15 | generate-ddl: true 16 | datasource: 17 | username: postgres 18 | password: postgres 19 | url: jdbc:postgresql://localhost:5432/blogs 20 | driverClassName: org.postgresql.Driver 21 | 22 | spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation: true # 23 | 24 | logging: 25 | level: 26 | root: ERROR 27 | org.hibernate.SQL: ERROR 28 | org.springframework.data: ERROR 29 | com.example.blog_app: INFO 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; 2 | 3 | drop table if exists blog cascade; 4 | drop table if exists comment cascade; 5 | drop table if exists comment_like cascade; 6 | drop table if exists file cascade; 7 | drop table if exists post cascade; 8 | drop table if exists "user" cascade; 9 | drop table if exists post_files cascade; 10 | 11 | drop type if exists post_status_enum; 12 | Create type post_status_enum as ENUM ('ACTIVE', 'NOT_ACTIVE'); 13 | 14 | Create table if not exists blog ( 15 | id serial primary key not null, 16 | guid uuid default uuid_generate_v4(), 17 | name varchar(150), 18 | about text, 19 | published_at timestamp 20 | ); 21 | 22 | create table if not exists post ( 23 | id serial primary key not null, 24 | blog_id int, 25 | title varchar(150), 26 | content text, 27 | "user" int, 28 | postStatus post_status_enum default 'ACTIVE' 29 | ); 30 | 31 | create table if not exists comment ( 32 | id serial primary key not null, 33 | parent_id int, 34 | content text, 35 | post_id int 36 | ); 37 | 38 | create table if not exists "user" ( 39 | id serial primary key not null, 40 | username varchar(150), 41 | password varchar(150), 42 | email varchar(150), 43 | is_active boolean, 44 | activated_at timestamp DEFAULT (current_timestamp AT TIME ZONE 'UTC') 45 | ); 46 | 47 | create table comment_like (id bigserial not null, comment_id int8, post_id int8, user_id int8, primary key (id)); 48 | create table file (id bigserial not null, name varchar(255), primary key (id)); 49 | create table post_files (post_id int8 not null, file_id int8 not null, primary key (file_id, post_id)); 50 | 51 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/test/java/com/example/blog_app/BlogTestBase.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app; 2 | 3 | import com.example.blog_app.helper.DataGenerator; 4 | import com.example.blog_app.repository.BlogRepository; 5 | import com.example.blog_app.repository.FileRepository; 6 | import com.example.blog_app.repository.PostRepository; 7 | import com.example.blog_app.repository.UserRepository; 8 | import com.example.blog_app.service.UserCRUDService; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.web.client.TestRestTemplate; 11 | import org.springframework.stereotype.Component; 12 | 13 | @Component 14 | public class BlogTestBase { 15 | 16 | @Autowired 17 | DataGenerator dataGenerator; 18 | 19 | @Autowired 20 | UserRepository userRepository; 21 | 22 | @Autowired 23 | UserCRUDService userCRUDService; 24 | 25 | @Autowired 26 | PostRepository postRepository; 27 | 28 | @Autowired 29 | BlogRepository blogRepository; 30 | 31 | @Autowired 32 | FileRepository fileRepository; 33 | 34 | @Autowired 35 | protected TestRestTemplate restTemplate; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /ch3/blog-app-jpa-ch3/src/test/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: blog-service 4 | jpa: 5 | show-sql: true 6 | hibernate: 7 | ddl-auto: update 8 | generate-ddl: true 9 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | 8 | java { 9 | group = 'com.example' 10 | version = '1.0' 11 | sourceCompatibility = JavaVersion.VERSION_1_8 12 | targetCompatibility = JavaVersion.VERSION_1_8 13 | //sourceCompatibility = JavaVersion.VERSION_11 14 | //targetCompatibility = JavaVersion.VERSION_11 15 | } 16 | 17 | bootJar { 18 | archivesBaseName = 'eshop' 19 | version = '1.0' 20 | } 21 | 22 | repositories { 23 | mavenCentral() 24 | } 25 | 26 | dependencies { 27 | 28 | compile ([ 29 | "org.springframework.boot:spring-boot-starter-web", 30 | "org.springframework.boot:spring-boot-starter-jdbc", 31 | "org.springframework.boot:spring-boot-starter-data-jpa" 32 | ]) 33 | 34 | compile ([ 35 | "mysql:mysql-connector-java:8.0.15", 36 | "org.postgresql:postgresql:42.2.5", 37 | "org.projectlombok:lombok:1.18.6" 38 | ]) 39 | annotationProcessor 'org.projectlombok:lombok:1.18.6' 40 | 41 | testCompile("junit:junit") 42 | } 43 | 44 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch4/eshop-ch4/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch4/eshop-ch4/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/Application.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop; 2 | 3 | import com.example.eshop.model.dto.CustomerDto; 4 | import com.example.eshop.model.orders.Customer; 5 | import com.example.eshop.model.projection.CustomerProjection; 6 | import com.example.eshop.repository.history.PurchaseHistoryRepository; 7 | import com.example.eshop.repository.orders.CustomerRepository; 8 | import com.example.eshop.repository.orders.OrderRepository; 9 | import com.example.eshop.service.impl.CustomerService; 10 | import com.example.eshop.service.impl.ProductService; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.boot.CommandLineRunner; 14 | import org.springframework.boot.SpringApplication; 15 | import org.springframework.boot.autoconfigure.SpringBootApplication; 16 | 17 | import java.util.List; 18 | 19 | @SpringBootApplication 20 | @Slf4j 21 | public class Application implements CommandLineRunner { 22 | 23 | @Autowired 24 | ProductService productService; 25 | 26 | @Autowired 27 | CustomerService customerService; 28 | 29 | @Autowired 30 | OrderRepository orderRepository; 31 | 32 | @Autowired 33 | CustomerRepository customerRepository; 34 | 35 | @Autowired 36 | PurchaseHistoryRepository purchaseHistoryRepository; 37 | 38 | public static void main(String[] args) throws Exception { 39 | SpringApplication.run(Application.class, args); 40 | } 41 | 42 | @Override 43 | public void run(String... strings) throws Exception { 44 | customerService.registerNewCustomers(); 45 | productService.registerNewProducts(); 46 | productService.purchase(1l, 1l, 2, 400); 47 | productService.saveHistory(1l, 1l); 48 | 49 | log.info("Customers {}", customerService.findAll()); 50 | log.info("Products {}", productService.findAll()); 51 | log.info("Orders {}", orderRepository.findAll()); 52 | log.info("PurchaseHistory {}", purchaseHistoryRepository.findAll()); 53 | 54 | nPlusOneExample(); 55 | constructorMappingExample(); 56 | projectionsExample(); 57 | } 58 | 59 | public void nPlusOneExample() { 60 | List customerList = customerRepository.findCustomersWithOrderDetails(); 61 | log.info("Customers List with Order Details: {}", customerList); 62 | } 63 | 64 | public void constructorMappingExample() { 65 | List customersList = customerRepository.findCustomers(); 66 | log.info("Customers List with Constructors mapped query results: {}", customersList); 67 | } 68 | 69 | public void projectionsExample() { 70 | List customers = customerRepository.findAllCustomers(); 71 | log.info("Customers List with Projections"); 72 | customers.forEach(customer -> { 73 | log.info("Projections Example, Customer Name With Email: {}", customer.getCustomerNameWithEmail()); 74 | }); 75 | 76 | log.info("Projections Example, Find Single Customer : {}", 77 | customerRepository.findOneByName("Raj Malhotra").getCustomerNameWithEmail()); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/config/DbConfigPrimary.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.config; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.beans.factory.annotation.Qualifier; 5 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 6 | import org.springframework.boot.context.properties.ConfigurationProperties; 7 | import org.springframework.boot.jdbc.DataSourceBuilder; 8 | import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.context.annotation.Primary; 12 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 13 | import org.springframework.jdbc.core.JdbcTemplate; 14 | import org.springframework.orm.jpa.JpaTransactionManager; 15 | import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 16 | import org.springframework.transaction.PlatformTransactionManager; 17 | 18 | import javax.persistence.EntityManagerFactory; 19 | import javax.sql.DataSource; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | @Configuration 24 | @EnableAutoConfiguration 25 | @EnableJpaRepositories( 26 | entityManagerFactoryRef = "entityManagerFactory", 27 | transactionManagerRef = "transactionManager", 28 | basePackages = { "com.example.eshop.repository.orders" }) 29 | @Slf4j 30 | public class DbConfigPrimary { 31 | 32 | @Bean(name = "dataSource") 33 | @Primary 34 | @ConfigurationProperties(prefix = "spring.datasource.orders") 35 | public DataSource dataSourcePrimary() { 36 | return DataSourceBuilder.create().build(); 37 | } 38 | 39 | @Primary 40 | @Bean(name = "entityManagerFactory") 41 | public LocalContainerEntityManagerFactoryBean entityManagerFactory( 42 | EntityManagerFactoryBuilder builder, @Qualifier("dataSource") DataSource dataSource) 43 | { 44 | return builder 45 | .dataSource(dataSource) 46 | .packages("com.example.eshop.model.orders") 47 | .persistenceUnit("orders") 48 | .properties(jpaProperties()) 49 | .build(); 50 | } 51 | 52 | @Primary 53 | @Bean(name = "transactionManager") 54 | public PlatformTransactionManager transactionManager( 55 | @Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory 56 | ) { 57 | return new JpaTransactionManager(entityManagerFactory); 58 | } 59 | 60 | private Map jpaProperties() { 61 | Map props = new HashMap(); 62 | props.put("hibernte.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy"); 63 | props.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect"); 64 | props.put("hibernate.hbm2ddl.auto", "create-drop"); 65 | return props; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/config/DbConfigSecondary.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.config; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.beans.factory.annotation.Qualifier; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.boot.jdbc.DataSourceBuilder; 7 | import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 11 | import org.springframework.orm.jpa.JpaTransactionManager; 12 | import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 13 | import org.springframework.transaction.PlatformTransactionManager; 14 | 15 | import javax.persistence.EntityManagerFactory; 16 | import javax.sql.DataSource; 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | 20 | @Configuration 21 | @EnableJpaRepositories( 22 | entityManagerFactoryRef = "entityManagerFactoryHistory", 23 | transactionManagerRef = "transactionManagerHistory", 24 | basePackages = { "com.example.eshop.repository.history" }) 25 | @Slf4j 26 | public class DbConfigSecondary { 27 | 28 | @Bean(name = "dataSourceHistory") 29 | @ConfigurationProperties(prefix = "spring.datasource.history") 30 | public DataSource dataSourceSecondary() { 31 | return DataSourceBuilder.create().build(); 32 | } 33 | 34 | @Bean(name = "entityManagerFactoryHistory") 35 | public LocalContainerEntityManagerFactoryBean entityManagerFactory( 36 | EntityManagerFactoryBuilder builder, @Qualifier("dataSourceHistory") DataSource dataSource) 37 | { 38 | log.info("Secondary EM initialized"); 39 | return builder 40 | .dataSource(dataSource) 41 | .packages("com.example.eshop.model.history") 42 | .persistenceUnit("history") 43 | .properties(jpaProperties()) 44 | .build(); 45 | 46 | } 47 | 48 | @Bean(name = "transactionManagerHistory") 49 | public PlatformTransactionManager transactionManager( 50 | @Qualifier("entityManagerFactoryHistory") EntityManagerFactory entityManagerFactory 51 | ) { 52 | return new JpaTransactionManager(entityManagerFactory); 53 | } 54 | 55 | private Map jpaProperties() { 56 | Map props = new HashMap(); 57 | props.put("hibernte.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy"); 58 | props.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect"); 59 | props.put("hibernate.hbm2ddl.auto", "create-drop"); 60 | return props; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/converter/CustomerAddressConverter.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.converter; 2 | 3 | import com.example.eshop.model.type.CustomerAddress; 4 | 5 | import javax.persistence.AttributeConverter; 6 | 7 | public class CustomerAddressConverter implements AttributeConverter { 8 | 9 | @Override 10 | public String convertToDatabaseColumn(CustomerAddress customerAddress) { 11 | if(customerAddress == null) 12 | return ""; 13 | return customerAddress.getStreetAddress() + ", " + 14 | customerAddress.getCity() + ", " + 15 | customerAddress.getCountry(); 16 | } 17 | 18 | @Override 19 | public CustomerAddress convertToEntityAttribute(String value) { 20 | CustomerAddress customerAddress = null; 21 | if(value != null && value.contains(",")) { 22 | String[] tokens = value.split(","); 23 | customerAddress = new CustomerAddress(); 24 | customerAddress.setStreetAddress(tokens[0]); 25 | customerAddress.setCity(tokens[1]); 26 | customerAddress.setCountry(tokens[2]); 27 | } 28 | return customerAddress; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/model/dto/CustomerDto.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.model.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | @Data 7 | @AllArgsConstructor 8 | public class CustomerDto { 9 | private Long id; 10 | private String name; 11 | } 12 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/model/history/PurchaseHistory.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.model.history; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.*; 6 | import java.io.Serializable; 7 | import java.util.Date; 8 | 9 | @Data 10 | @Entity 11 | @Table(name="PurchaseHistory") 12 | public class PurchaseHistory implements Serializable { 13 | 14 | private static final long serialVersionUID = 1L; 15 | 16 | @Id 17 | @GeneratedValue(strategy=GenerationType.IDENTITY) 18 | private Long id; 19 | private Long customerId, productId; 20 | private Date createdDate; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/model/orders/Customer.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.model.orders; 2 | 3 | import java.io.Serializable; 4 | import java.time.LocalDateTime; 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | import javax.persistence.*; 9 | 10 | import com.example.eshop.converter.CustomerAddressConverter; 11 | import com.example.eshop.model.type.CustomerAddress; 12 | import com.fasterxml.jackson.annotation.JsonIgnore; 13 | import lombok.*; 14 | 15 | @Data 16 | @Entity 17 | @ToString(exclude = {"orders"}) 18 | @EqualsAndHashCode(exclude = {"orders"}) 19 | public class Customer implements Serializable { 20 | 21 | @Id 22 | @GeneratedValue(strategy=GenerationType.IDENTITY) 23 | private Long customerId; 24 | 25 | private String name, email, password; 26 | private LocalDateTime dateAdded; 27 | 28 | @Column 29 | @Convert(converter = CustomerAddressConverter.class) 30 | CustomerAddress customerAddress; 31 | 32 | //@JsonIgnore 33 | @OneToMany(fetch = FetchType.LAZY) 34 | @JoinColumn(name = "customerId") 35 | Set orders; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/model/orders/Order.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.model.orders; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.GenerationType; 8 | import javax.persistence.Id; 9 | import javax.persistence.Table; 10 | 11 | import lombok.*; 12 | 13 | @Data 14 | @Entity 15 | @Table(name="CustomerOrder") 16 | public class Order implements Serializable { 17 | 18 | @Id 19 | @GeneratedValue(strategy=GenerationType.IDENTITY) 20 | private Long orderId; 21 | private Long productId, customerId; 22 | private int quantity, price; 23 | 24 | } -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/model/orders/Product.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.model.orders; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.FetchType; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.JoinColumn; 11 | import javax.persistence.ManyToOne; 12 | 13 | import lombok.*; 14 | 15 | @Data 16 | @Entity 17 | public class Product implements Serializable { 18 | 19 | @Id 20 | @GeneratedValue(strategy=GenerationType.IDENTITY) 21 | private Long productId; 22 | 23 | private String name; 24 | private Integer price, quantity; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/model/projection/CustomerProjection.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.model.projection; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | 5 | import java.time.LocalDateTime; 6 | import java.util.Date; 7 | 8 | public interface CustomerProjection { 9 | 10 | String getName(); 11 | String getEmail(); 12 | 13 | @Value("#{target.name + '_' + target.email}") 14 | String getCustomerNameWithEmail(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/model/type/CustomerAddress.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.model.type; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | @Data 8 | public class CustomerAddress implements Serializable { 9 | private String streetAddress; 10 | private String city; 11 | private String country; 12 | } 13 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/repository/history/PurchaseHistoryRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.repository.history; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import com.example.eshop.model.history.PurchaseHistory; 5 | 6 | public interface PurchaseHistoryRepository extends JpaRepository{ } 7 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/repository/orders/CustomerRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.repository.orders; 2 | 3 | import com.example.eshop.model.dto.CustomerDto; 4 | import com.example.eshop.model.orders.Customer; 5 | import com.example.eshop.model.orders.Order; 6 | import com.example.eshop.model.projection.CustomerProjection; 7 | import org.springframework.data.jpa.repository.JpaRepository; 8 | import org.springframework.data.jpa.repository.Query; 9 | 10 | import java.util.Collection; 11 | import java.util.List; 12 | 13 | public interface CustomerRepository extends JpaRepository{ 14 | 15 | /* N+1 example */ 16 | @Query("Select c from Customer c left join fetch c.orders") 17 | List findCustomersWithOrderDetails(); 18 | 19 | // Query example with Constructor mapping 20 | @Query(value = 21 | "Select new com.example.eshop.model.dto.CustomerDto(c.id, c.name) from Customer c") 22 | List findCustomers(); 23 | 24 | // Projections examples 25 | @Query("Select c from Customer c") 26 | List findAllCustomers(); 27 | CustomerProjection findOneByName(String name); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/repository/orders/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.repository.orders; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.stereotype.Repository; 5 | import com.example.eshop.model.orders.Order; 6 | 7 | @Repository 8 | public interface OrderRepository extends JpaRepository{ } 9 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/repository/orders/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.repository.orders; 2 | 3 | import com.example.eshop.model.orders.Product; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface ProductRepository extends JpaRepository { } -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/service/impl/CustomerService.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.service.impl; 2 | 3 | import com.example.eshop.model.orders.Customer; 4 | import com.example.eshop.repository.orders.CustomerRepository; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.transaction.annotation.Isolation; 9 | import org.springframework.transaction.annotation.Propagation; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | import java.time.LocalDateTime; 13 | import java.util.List; 14 | 15 | @Service 16 | @Slf4j 17 | public class CustomerService { 18 | 19 | @Autowired 20 | CustomerRepository customerRepository; 21 | 22 | @Transactional(propagation=Propagation.REQUIRED, isolation=Isolation.DEFAULT) 23 | public void registerNewCustomers() { 24 | Customer customer = new Customer(); 25 | customer.setName("Raj Malhotra"); 26 | customer.setEmail("raj.malhotra@example.com"); 27 | customer.setPassword("password"); 28 | customer.setDateAdded(LocalDateTime.now()); 29 | customerRepository.saveAndFlush(customer); 30 | log.info("All registered customers: " + customerRepository.findAll()); 31 | } 32 | 33 | public List findAll() { 34 | return customerRepository.findAll(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/java/com/example/eshop/service/impl/ProductService.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.service.impl; 2 | 3 | import com.example.eshop.model.history.PurchaseHistory; 4 | import com.example.eshop.model.orders.Product; 5 | import com.example.eshop.repository.history.PurchaseHistoryRepository; 6 | import com.example.eshop.repository.orders.ProductRepository; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | import com.example.eshop.model.orders.Order; 13 | import com.example.eshop.repository.orders.OrderRepository; 14 | 15 | import java.util.Date; 16 | import java.util.List; 17 | 18 | @Service 19 | @Slf4j 20 | public class ProductService { 21 | 22 | @Autowired 23 | OrderRepository orderRepository; 24 | 25 | @Autowired 26 | ProductRepository productRepository; 27 | 28 | @Autowired 29 | PurchaseHistoryRepository purchaseHistoryRepository; 30 | 31 | @Transactional 32 | public Boolean purchase(Long productId, Long customerId, int quantity, int price) { 33 | Boolean success = Boolean.TRUE; 34 | Order order = new Order(); 35 | order.setCustomerId(customerId); 36 | order.setProductId(productId); 37 | order.setPrice(price); 38 | order.setQuantity(quantity); 39 | orderRepository.save(order); 40 | return success; 41 | } 42 | 43 | @Transactional 44 | public void saveHistory(Long customerId, Long productId) { 45 | PurchaseHistory ph = new PurchaseHistory(); 46 | ph.setCustomerId(customerId); 47 | ph.setProductId(productId); 48 | ph.setCreatedDate(new Date()); 49 | purchaseHistoryRepository.save(ph); 50 | } 51 | 52 | public void registerNewProducts() { 53 | Product product = new Product(); 54 | product.setName("Superb Java"); 55 | product.setPrice(400); 56 | product.setQuantity(3); 57 | productRepository.save(product); 58 | } 59 | 60 | public List findAll() { 61 | return productRepository.findAll(); 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.orders.jdbcUrl=jdbc:mysql://localhost:3306/db1 2 | spring.datasource.orders.username=root 3 | spring.datasource.orders.password=mysql 4 | spring.datasource.orders.driver-class-name: com.mysql.cj.jdbc.Driver 5 | spring.datasource.orders.dialect=org.hibernate.dialect.MySQL5InnoDBDialect 6 | 7 | spring.datasource.history.jdbcUrl=jdbc:postgresql://localhost:5432/db2 8 | spring.datasource.history.username=postgres 9 | spring.datasource.history.password=postgres 10 | spring.datasource.history.dialect=org.hibernate.dialect.PostgreSQLDialect 11 | 12 | spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation: true 13 | 14 | spring.jpa.hibernate.generate-ddl=false 15 | spring.jpa.hibernate.ddl-auto=create 16 | spring.jpa.hibernate.show-sql=false 17 | spring.jpa.properties.hibernate.format_sql=false 18 | spring.jpa.properties.hibernate.use_sql_comments=false 19 | spring.jpa.properties.hibernate.generate_statistics=false 20 | //logging.pattern.console=[%thread] %-5level %msg%n 21 | -------------------------------------------------------------------------------- /ch4/eshop-ch4/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | context-path: /eshop 3 | port: 8080 4 | 5 | spring: 6 | jpa: 7 | hibernate.ddl-auto: create-drop 8 | show-sql: false 9 | generate-ddl: false 10 | 11 | -------------------------------------------------------------------------------- /ch5/blog-spring-data-mongodb-ch5/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | 8 | bootJar { 9 | baseName = 'blog-app' 10 | version = '1.0' 11 | } 12 | 13 | repositories { 14 | mavenCentral() 15 | } 16 | 17 | dependencies { 18 | 19 | compile('org.springframework.boot:spring-boot-starter-web') 20 | compile("org.springframework.boot:spring-boot-starter-data-mongodb") 21 | compile('org.projectlombok:lombok:1.18.6') 22 | 23 | testCompile('org.junit.jupiter:junit-jupiter-api:5.4.0') 24 | testCompile('org.springframework.boot:spring-boot-starter-test') 25 | annotationProcessor("org.projectlombok:lombok:1.18.6") 26 | testAnnotationProcessor("org.projectlombok:lombok:1.18.6") 27 | } 28 | 29 | -------------------------------------------------------------------------------- /ch5/blog-spring-data-mongodb-ch5/src/main/java/com/example/blog_app/BlogApp.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | @Slf4j 9 | public class BlogApp { 10 | public static void main(String[] args) { 11 | SpringApplication.run(BlogApp.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ch5/blog-spring-data-mongodb-ch5/src/main/java/com/example/blog_app/model/mongo/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.model.mongo; 2 | 3 | import lombok.Data; 4 | import org.springframework.data.annotation.Id; 5 | 6 | @Data 7 | public class Comment { 8 | 9 | @Id 10 | private String id; 11 | private String content; 12 | 13 | public Comment(String content) { 14 | this.content = content; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ch5/blog-spring-data-mongodb-ch5/src/main/java/com/example/blog_app/model/mongo/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.model.mongo; 2 | 3 | import lombok.*; 4 | import org.springframework.data.annotation.Id; 5 | 6 | import java.io.Serializable; 7 | import java.util.Set; 8 | 9 | @Data 10 | @Builder 11 | @EqualsAndHashCode(exclude = {"comments"}) 12 | public class Post implements Serializable { 13 | 14 | @Id 15 | private String id; 16 | private String title; 17 | private String content; 18 | private PostStatus postStatus; 19 | private String blogName; 20 | private String userName; 21 | private Set comments; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /ch5/blog-spring-data-mongodb-ch5/src/main/java/com/example/blog_app/model/mongo/PostStatus.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.model.mongo; 2 | 3 | import java.io.Serializable; 4 | 5 | public enum PostStatus implements Serializable { 6 | 7 | ACTIVE(1), NOT_ACTIVE(2); 8 | 9 | int status; 10 | 11 | PostStatus(int status) { 12 | this.status = status; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ch5/blog-spring-data-mongodb-ch5/src/main/java/com/example/blog_app/repository/PostMongoRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app.repository; 2 | 3 | import com.example.blog_app.model.mongo.Post; 4 | import org.springframework.data.mongodb.repository.MongoRepository; 5 | 6 | import java.util.List; 7 | 8 | public interface PostMongoRepository extends MongoRepository { 9 | Post findByTitle(String title); 10 | List findByBlogName(String blogName); 11 | } 12 | -------------------------------------------------------------------------------- /ch5/blog-spring-data-mongodb-ch5/src/test/java/com/example/blog_app/BlogTests.java: -------------------------------------------------------------------------------- 1 | package com.example.blog_app; 2 | 3 | import com.example.blog_app.model.mongo.Comment; 4 | import com.example.blog_app.model.mongo.Post; 5 | import com.example.blog_app.model.mongo.PostStatus; 6 | import com.example.blog_app.repository.PostMongoRepository; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.junit.After; 9 | import org.junit.Assert; 10 | import org.junit.Before; 11 | import org.junit.Test; 12 | import org.junit.runner.RunWith; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.boot.test.context.SpringBootTest; 15 | import org.springframework.test.context.junit4.SpringRunner; 16 | 17 | import java.util.ArrayList; 18 | import java.util.HashSet; 19 | import java.util.List; 20 | import java.util.Set; 21 | import java.util.stream.IntStream; 22 | 23 | @RunWith(SpringRunner.class) 24 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) 25 | @Slf4j 26 | public class BlogTests { 27 | 28 | @Autowired 29 | PostMongoRepository postMongoRepository; 30 | 31 | List postList = null; 32 | 33 | @Before 34 | public void setup() { 35 | postList = new ArrayList<>(); 36 | IntStream.range(1,2).forEach(i->{ 37 | Post nextSamplePost = createNextSamplePost(i); 38 | postList.add(nextSamplePost); 39 | }); 40 | } 41 | 42 | private Post createNextSamplePost(int i) { 43 | Post post = Post.builder() 44 | .blogName("Blog" + i) 45 | .title("Blog Title" + i) 46 | .content("Blog" + i + " content") 47 | .postStatus(PostStatus.ACTIVE) 48 | .userName("User" + i) 49 | .build(); 50 | Set comments = new HashSet<>(); 51 | comments.add(new Comment("Comment" + (i+1)) ); 52 | comments.add(new Comment("Comment" + (i+2)) ); 53 | post.setComments(comments); 54 | return post; 55 | } 56 | 57 | @Test 58 | public void testAddNewPosts() { 59 | postMongoRepository.saveAll(postList); 60 | log.info("All objects: {}", postMongoRepository.findAll()); 61 | Post blogByTitle = postMongoRepository.findByTitle("Blog Title1"); 62 | Assert.assertEquals("Blog names do not match", blogByTitle.getBlogName(), "Blog1"); 63 | log.info("Achieved saving and retrieving back Posts from Mongo"); 64 | } 65 | 66 | @After 67 | public void tearDown() { 68 | postMongoRepository.deleteAll(); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /ch5/eblog-spring-data-jdbc-ch5/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | 8 | repositories { 9 | mavenCentral() 10 | } 11 | 12 | bootJar { 13 | baseName = 'eblog' 14 | version = '1.0' 15 | } 16 | 17 | repositories { 18 | mavenCentral() 19 | } 20 | 21 | dependencies { 22 | compile ([ 23 | "org.springframework.boot:spring-boot-starter-web", 24 | "org.springframework.boot:spring-boot-starter-data-jdbc:2.1.3.RELEASE", 25 | "org.springframework.data:spring-data-commons:2.1.5.RELEASE", 26 | "com.google.guava:guava:27.0.1-jre", 27 | "org.postgresql:postgresql:42.2.5", 28 | "org.projectlombok:lombok:1.18.6" 29 | ]) 30 | annotationProcessor("org.projectlombok:lombok:1.18.6") 31 | } 32 | 33 | -------------------------------------------------------------------------------- /ch5/eblog-spring-data-jdbc-ch5/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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /ch5/eblog-spring-data-jdbc-ch5/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'eblog-spring-data-jdbc-ch5' 2 | 3 | -------------------------------------------------------------------------------- /ch5/eblog-spring-data-jdbc-ch5/src/main/java/com/example/eblog/App.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog; 2 | 3 | import com.example.eblog.model.Author; 4 | import com.example.eblog.repository.AuthorRepository; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.CommandLineRunner; 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; 11 | 12 | import java.util.List; 13 | import java.util.stream.Collectors; 14 | 15 | @SpringBootApplication 16 | @EnableJdbcRepositories(basePackages = {"com.example.eblog.repository"}) 17 | @Slf4j 18 | public class App implements CommandLineRunner { 19 | 20 | @Autowired 21 | AuthorRepository authorRepository; 22 | 23 | public static void main(String[] args) { 24 | SpringApplication.run(App.class, args); 25 | } 26 | 27 | @Override 28 | public void run(String... args) throws Exception { 29 | List authorList = authorRepository.findByAge(35); 30 | //List authorList = authorRepository.findByAge(35).collect(Collectors.toList()); 31 | //List authorList = authorRepository.findByAge(35).get(); 32 | log.info("list: {}", authorList); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ch5/eblog-spring-data-jdbc-ch5/src/main/java/com/example/eblog/model/Author.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.model; 2 | 3 | import lombok.*; 4 | import org.springframework.data.annotation.Id; 5 | import org.springframework.data.annotation.PersistenceConstructor; 6 | 7 | import java.io.Serializable; 8 | import java.util.Set; 9 | 10 | @Data 11 | @AllArgsConstructor 12 | @ToString(exclude = {"posts"}) 13 | @EqualsAndHashCode(exclude = {"posts"}) 14 | public class Author implements Serializable { 15 | 16 | @Id 17 | private Long id; 18 | private String name; 19 | private int age; 20 | 21 | private Set posts; 22 | 23 | @PersistenceConstructor 24 | public Author(String name, int age) { 25 | this.name = name; 26 | this.age = age; 27 | } 28 | 29 | Author withId(Long id) { 30 | return new Author(id, this.name, this.age, this.posts); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ch5/eblog-spring-data-jdbc-ch5/src/main/java/com/example/eblog/model/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.model; 2 | 3 | import lombok.*; 4 | import org.springframework.data.annotation.Id; 5 | 6 | import java.io.Serializable; 7 | 8 | @Data 9 | @Builder 10 | @AllArgsConstructor 11 | @ToString(exclude = {"author"}) 12 | @EqualsAndHashCode(exclude = {"author"}) 13 | public class Post implements Serializable { 14 | 15 | @Id 16 | private Long id; 17 | 18 | private String title; 19 | private String content; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /ch5/eblog-spring-data-jdbc-ch5/src/main/java/com/example/eblog/repository/AuthorRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.repository; 2 | 3 | import com.example.eblog.model.Author; 4 | import org.springframework.data.jdbc.repository.query.Query; 5 | import org.springframework.data.repository.CrudRepository; 6 | import org.springframework.data.repository.Repository; 7 | import org.springframework.data.repository.query.Param; 8 | 9 | import java.util.List; 10 | import java.util.Optional; 11 | import java.util.stream.Stream; 12 | 13 | public interface AuthorRepository extends Repository { 14 | 15 | @Query("Select a.* from Author a") 16 | List findAuthorsWithPosts(); 17 | 18 | @Query(("Select * from Author where age= :age")) 19 | //List findByAge(Integer age); 20 | List findByAge(@Param("age") Integer age); 21 | //Stream findByAge(@Param("age") Integer age); 22 | //Optional> findByAge(@Param("age") Integer age); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /ch5/eblog-spring-data-jdbc-ch5/src/main/java/com/example/eblog/repository/PostRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.repository; 2 | 3 | import com.example.eblog.model.Post; 4 | import org.springframework.data.repository.CrudRepository; 5 | import org.springframework.data.repository.Repository; 6 | 7 | public interface PostRepository extends CrudRepository { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /ch5/eblog-spring-data-jdbc-ch5/src/main/java/com/example/eblog/web/TestController.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.web; 2 | 3 | import com.example.eblog.model.Author; 4 | import com.example.eblog.model.Post; 5 | import com.example.eblog.repository.AuthorRepository; 6 | import com.example.eblog.repository.PostRepository; 7 | import com.google.common.collect.Lists; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.data.domain.PageRequest; 11 | import org.springframework.data.domain.Sort; 12 | import org.springframework.web.bind.annotation.GetMapping; 13 | import org.springframework.web.bind.annotation.RequestParam; 14 | import org.springframework.web.bind.annotation.RestController; 15 | 16 | import java.util.List; 17 | 18 | @RestController 19 | @Slf4j 20 | public class TestController { 21 | 22 | @Autowired 23 | AuthorRepository authorRepository; 24 | 25 | @Autowired 26 | PostRepository postRepository; 27 | 28 | @GetMapping("/posts") 29 | public List recentPosts(@RequestParam Integer limit, @RequestParam Integer offset, @RequestParam String orderBy){ 30 | log.info("recentPosts, params: {}, {}", limit, offset); 31 | PageRequest pageRequest = PageRequest.of(limit, offset, Sort.Direction.DESC, orderBy); 32 | return Lists.newArrayList(postRepository.findAll()); 33 | } 34 | 35 | @GetMapping("/authors") 36 | public List authorsWithTopPosts() { 37 | log.info("authorsWithTopPosts"); 38 | return authorRepository.findAuthorsWithPosts(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ch5/eblog-spring-data-jdbc-ch5/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost:5432/eblog 2 | spring.datasource.username=postgres 3 | spring.datasource.password=postgres 4 | spring.datasource.driver-class-name: org.postgresql.Driver 5 | 6 | server.servlet.contextPath= /eblog 7 | server.port= 8201 8 | -------------------------------------------------------------------------------- /ch5/eshop-jdbc-template-ch5/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | 8 | bootJar { 9 | archiveBaseName = 'eshop' 10 | version = '1.0' 11 | } 12 | 13 | repositories { 14 | mavenCentral() 15 | } 16 | 17 | dependencies { 18 | 19 | compile ([ 20 | "org.springframework.boot:spring-boot-starter-jdbc", 21 | "org.springframework.boot:spring-boot-starter-test" 22 | ]) 23 | 24 | compile ([ 25 | "mysql:mysql-connector-java:8.0.15", 26 | "org.projectlombok:lombok:1.18.6" 27 | ]) 28 | 29 | testCompile("junit:junit") 30 | testCompile("org.projectlombok:lombok:1.18.6") 31 | annotationProcessor("org.projectlombok:lombok:1.18.6") 32 | testAnnotationProcessor("org.projectlombok:lombok:1.18.6") 33 | } 34 | -------------------------------------------------------------------------------- /ch5/eshop-jdbc-template-ch5/src/main/java/com/example/eshop/Application.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | @Slf4j 9 | public class Application { 10 | 11 | public static void main(String[] args) throws Exception { 12 | SpringApplication.run(Application.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ch5/eshop-jdbc-template-ch5/src/main/java/com/example/eshop/model/dto/CustomerOrder.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.model.dto; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class CustomerOrder { 7 | private Long customerId; 8 | private Long orderId; 9 | private Long productId; 10 | 11 | private String customerName; 12 | private String customerEmail; 13 | private String productName; 14 | private int quantity; 15 | private int price; 16 | } 17 | -------------------------------------------------------------------------------- /ch5/eshop-jdbc-template-ch5/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:mysql://localhost:3306/db1 2 | spring.datasource.username=root 3 | spring.datasource.password=mysql 4 | spring.datasource.driver-class-name: com.mysql.cj.jdbc.Driver 5 | -------------------------------------------------------------------------------- /ch5/eshop-jdbc-template-ch5/src/test/java/com/example/eshop/EshopAppTests.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop; 2 | 3 | import com.example.eshop.model.dto.CustomerOrder; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.jdbc.core.BeanPropertyRowMapper; 10 | import org.springframework.jdbc.core.JdbcTemplate; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | 13 | import java.util.List; 14 | 15 | @RunWith(SpringRunner.class) 16 | @SpringBootTest 17 | @Slf4j 18 | public class EshopAppTests { 19 | 20 | @Autowired 21 | JdbcTemplate jdbcTemplate; 22 | 23 | @Test 24 | public void testThroughJdbcTemplate() { 25 | String sql = "Select " + 26 | "c.customerId, o.orderId, p.productId," + 27 | "c.name as customerName, c.email as customerEmail, p.name as productName," + 28 | "p.quantity as quantity, p.price as price " + 29 | "from " + 30 | "Customer c inner join `Order` o on c.customerId = o.customerId inner join " + 31 | "Product p on o.productId = p.productId"; 32 | 33 | List customerWithOrdersList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(CustomerOrder.class)); 34 | log.info("Order Details: " + customerWithOrdersList); 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ch5/eshop-jdbc-template-ch5/src/test/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS Customer ( 2 | customerId int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 | dateAdded datetime DEFAULT NULL, 4 | email varchar(255) DEFAULT NULL, 5 | name varchar(255) DEFAULT NULL, 6 | password varchar(255) DEFAULT NULL 7 | ); 8 | 9 | CREATE TABLE IF NOT EXISTS `Order` ( -- escaping Order in `` characters 10 | orderId bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT, 11 | customerId int(11) DEFAULT NULL, 12 | price int(11) NOT NULL, 13 | productId bigint(20) DEFAULT NULL, 14 | quantity int(11) NOT NULL 15 | ); 16 | 17 | CREATE TABLE IF NOT EXISTS Product ( 18 | productId int(11) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, 19 | name varchar(255) DEFAULT NULL, 20 | quantity varchar(255) DEFAULT NULL, 21 | price smallint DEFAULT NULL 22 | ); 23 | 24 | Insert into Customer(name, email, password) VALUES('Raj', 'raj@example.com', 'password'); 25 | Insert into Product(name, quantity, price) VALUES('Laptop', 10, 1200); 26 | Insert into `Order`(customerId, productId, price, quantity) VALUES(1, 1, 1200, 1); 27 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/admin-service/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/admin-service/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | admin-service 4 | Project admin-service created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jdt.core.javanature 26 | org.eclipse.buildship.core.gradleprojectnature 27 | 28 | 29 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/admin-service/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/admin-service/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.source=1.8 5 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/admin-service/.settings/org.springframework.ide.eclipse.prefs: -------------------------------------------------------------------------------- 1 | boot.validation.initialized=true 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/admin-service/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | 8 | group = 'com.example' 9 | version = '1.0' 10 | 11 | sourceCompatibility = JavaVersion.VERSION_1_8 12 | targetCompatibility = JavaVersion.VERSION_1_8 13 | 14 | bootJar { 15 | baseName = 'admin-service' 16 | version = '1.0' 17 | } 18 | 19 | repositories { 20 | mavenCentral() 21 | } 22 | 23 | ext { 24 | set('springCloudVersion', 'Greenwich.RELEASE') 25 | } 26 | 27 | dependencies { 28 | compile("de.codecentric:spring-boot-admin-server:2.1.1") 29 | compile("de.codecentric:spring-boot-admin-server-ui:2.1.1") 30 | compile("org.projectlombok:lombok:1.18.6") 31 | annotationProcessor("org.projectlombok:lombok:1.18.6") 32 | } 33 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/admin-service/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch6/spring-cloud-ch6/admin-service/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/admin-service/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/admin-service/src/main/java/com/example/admin/AdminApp.java: -------------------------------------------------------------------------------- 1 | package com.example.admin; 2 | 3 | import de.codecentric.boot.admin.server.config.EnableAdminServer; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Configuration 9 | @EnableAutoConfiguration 10 | @EnableAdminServer 11 | public class AdminApp { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(AdminApp.class, args); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/admin-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 7777 3 | 4 | spring: 5 | application: 6 | name: admin-service 7 | boot: 8 | admin: 9 | context-path: /admin -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/config-service/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/config-service/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | config-service 4 | Project config-service created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jdt.core.javanature 26 | org.eclipse.buildship.core.gradleprojectnature 27 | 28 | 29 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/config-service/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/config-service/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.source=1.8 5 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/config-service/.settings/org.springframework.ide.eclipse.prefs: -------------------------------------------------------------------------------- 1 | boot.validation.initialized=true 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/config-service/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | apply plugin: 'project-report' 8 | 9 | java { 10 | group = 'com.example' 11 | version = '1.0' 12 | sourceCompatibility = JavaVersion.VERSION_1_8 13 | targetCompatibility = JavaVersion.VERSION_1_8 14 | } 15 | 16 | bootJar { 17 | archiveBaseName = 'config-service' 18 | version = '1.0' 19 | } 20 | 21 | repositories { 22 | mavenCentral() 23 | maven { url 'https://repo.spring.io/milestone' } 24 | } 25 | 26 | dependencies { 27 | implementation 'org.springframework.cloud:spring-cloud-config-server' 28 | implementation 'de.codecentric:spring-boot-admin-starter-client:2.1.3' 29 | implementation 'org.springframework.boot:spring-boot-starter-actuator' 30 | compile("org.projectlombok:lombok:1.18.6") 31 | annotationProcessor("org.projectlombok:lombok:1.18.6") 32 | } 33 | 34 | dependencyManagement { 35 | imports { 36 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:Greenwich.SR1" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/config-service/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch6/spring-cloud-ch6/config-service/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/config-service/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/config-service/src/main/java/com/example/config/ConfigApp.java: -------------------------------------------------------------------------------- 1 | package com.example.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.config.server.EnableConfigServer; 6 | 7 | @SpringBootApplication 8 | @EnableConfigServer 9 | public class ConfigApp { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(ConfigApp.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/config-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | boot: 3 | admin: 4 | client: 5 | url: http://localhost:7777/admin 6 | 7 | server: 8 | port: 8888 9 | servlet.context-path: /config 10 | 11 | management: 12 | endpoints: 13 | web: 14 | exposure: 15 | include: "*" 16 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/config-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: config-service 4 | security: 5 | user: 6 | name: user 7 | password: secret 8 | cloud: 9 | config: 10 | enabled: true 11 | server: 12 | git: 13 | uri: ${HOME}/work_all/git_repo 14 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/discovery-service/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/discovery-service/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | discovery-service 4 | Project discovery-service created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jdt.core.javanature 26 | org.eclipse.buildship.core.gradleprojectnature 27 | 28 | 29 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/discovery-service/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/discovery-service/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 3 | org.eclipse.jdt.core.compiler.compliance=11 4 | org.eclipse.jdt.core.compiler.source=11 5 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/discovery-service/.settings/org.springframework.ide.eclipse.prefs: -------------------------------------------------------------------------------- 1 | boot.validation.initialized=true 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/discovery-service/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | apply plugin: 'project-report' 8 | 9 | group = 'com.example' 10 | version = '1.0' 11 | sourceCompatibility = JavaVersion.VERSION_11 12 | targetCompatibility = JavaVersion.VERSION_11 13 | 14 | bootJar { 15 | baseName = 'discovery-service' 16 | version = '1.0' 17 | } 18 | 19 | repositories { 20 | mavenCentral() 21 | maven { url 'https://repo.spring.io/milestone' } 22 | } 23 | 24 | dependencies { 25 | implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server' 26 | implementation 'de.codecentric:spring-boot-admin-starter-client:2.1.3' 27 | implementation 'org.springframework.boot:spring-boot-starter-actuator' 28 | compile 'javax.xml.bind:jaxb-api:2.3.1' 29 | compile 'org.glassfish.jaxb:jaxb-runtime:2.3.1' 30 | compile("org.projectlombok:lombok:1.18.6") 31 | annotationProcessor("org.projectlombok:lombok:1.18.6") 32 | } 33 | 34 | dependencyManagement { 35 | imports { 36 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:Greenwich.SR1" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/discovery-service/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch6/spring-cloud-ch6/discovery-service/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/discovery-service/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Nov 26 12:32:22 IST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-all.zip 7 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/discovery-service/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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/discovery-service/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'discovery-service' 2 | 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/discovery-service/src/main/java/com/example/eshop/discovery/DiscoveryApp.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.discovery; 2 | 3 | import org.springframework.boot.WebApplicationType; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 7 | 8 | @SpringBootApplication 9 | @EnableEurekaServer 10 | public class DiscoveryApp { 11 | public static void main(String[] args) { 12 | new SpringApplicationBuilder(DiscoveryApp.class).web(WebApplicationType.SERVLET).run(args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/discovery-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8761 3 | 4 | spring: 5 | application: 6 | name: discovery-service 7 | boot: 8 | admin: 9 | client: 10 | url: http://localhost:7777/admin 11 | 12 | eureka: 13 | instance: 14 | hostname: localhost 15 | client: 16 | registerWithEureka: false 17 | fetchRegistry: false 18 | serviceUrl: 19 | defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ 20 | 21 | 22 | management: 23 | endpoints: 24 | web: 25 | exposure: 26 | include: "*" 27 | 28 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | eshop 4 | Project eshop created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jdt.core.javanature 26 | org.eclipse.buildship.core.gradleprojectnature 27 | 28 | 29 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 3 | org.eclipse.jdt.core.compiler.compliance=11 4 | org.eclipse.jdt.core.compiler.source=11 5 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/.settings/org.springframework.ide.eclipse.prefs: -------------------------------------------------------------------------------- 1 | boot.validation.initialized=true 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | 8 | group = 'com.example' 9 | version = '1.0' 10 | sourceCompatibility = JavaVersion.VERSION_11 11 | targetCompatibility = JavaVersion.VERSION_11 12 | 13 | bootJar { 14 | baseName = 'eshop' 15 | version = '1.0' 16 | } 17 | 18 | repositories { 19 | mavenCentral() 20 | } 21 | 22 | dependencies { 23 | compile ([ 24 | "javax.xml.bind:jaxb-api:2.3.1", 25 | "org.glassfish.jaxb:jaxb-runtime:2.3.2", 26 | "javax.activation:javax.activation-api:1.2.0" 27 | ]) 28 | 29 | compile ([ 30 | "org.projectlombok:lombok:1.18.6", 31 | "mysql:mysql-connector-java:8.0.15", 32 | "org.springframework.boot:spring-boot-starter-web", 33 | "org.springframework.boot:spring-boot-starter-data-jpa", 34 | "org.springframework.boot:spring-boot-starter-test", 35 | "org.springframework.cloud:spring-cloud-starter-sleuth", 36 | "org.springframework.boot:spring-boot-starter-actuator" 37 | ]) 38 | 39 | compile ([ 40 | "org.springframework.cloud:spring-cloud-starter-openfeign", 41 | "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client", 42 | "org.springframework.cloud:spring-cloud-starter-netflix-hystrix", 43 | "org.springframework.cloud:spring-cloud-starter-netflix-hystrix-dashboard" 44 | ]) 45 | compile("org.springframework.cloud:spring-cloud-starter-sleuth") 46 | compile("org.springframework.cloud:spring-cloud-starter-zipkin") 47 | compile group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1' 48 | 49 | compile ([ 50 | "de.codecentric:spring-boot-admin-starter-client:2.1.1", 51 | "io.springfox:springfox-swagger2:2.9.2", 52 | "io.springfox:springfox-swagger-ui:2.9.2" 53 | ]) 54 | annotationProcessor("org.projectlombok:lombok:1.18.6") 55 | testCompile("junit:junit") 56 | } 57 | 58 | dependencyManagement { 59 | imports { 60 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:Greenwich.SR1" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch6/spring-cloud-ch6/eshop/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/EshopApp.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 7 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 8 | import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; 9 | import org.springframework.cloud.openfeign.EnableFeignClients; 10 | 11 | @SpringBootApplication 12 | @EnableFeignClients 13 | @EnableDiscoveryClient 14 | @Slf4j 15 | @EnableCircuitBreaker 16 | @EnableHystrixDashboard 17 | public class EshopApp { 18 | 19 | public static void main(String[] args) throws Exception { 20 | SpringApplication.run(EshopApp.class, args); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import springfox.documentation.builders.ApiInfoBuilder; 6 | import springfox.documentation.builders.RequestHandlerSelectors; 7 | import springfox.documentation.service.ApiInfo; 8 | import springfox.documentation.service.Contact; 9 | import springfox.documentation.spi.DocumentationType; 10 | import springfox.documentation.spring.web.plugins.Docket; 11 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 12 | 13 | import static springfox.documentation.builders.PathSelectors.regex; 14 | 15 | @Configuration 16 | @EnableSwagger2 17 | public class SwaggerConfig { 18 | 19 | @Bean 20 | public Docket productApi() { 21 | return new Docket(DocumentationType.SWAGGER_2) 22 | .select() 23 | .apis(RequestHandlerSelectors.basePackage("com.example.eshop")) 24 | .paths(regex("/api.*")) 25 | .build().apiInfo(apiInfo()); 26 | } 27 | 28 | private ApiInfo apiInfo() { 29 | return new ApiInfoBuilder().title("Eshop Service API") 30 | .description("Eshop API reference for developers") 31 | .termsOfServiceUrl("http://localhost:8201/eshop") 32 | .contact(new Contact("Raj Malhotra", "http://www.example.com", "mraj6046@gmail.com")).license("Example License Title") 33 | .licenseUrl("http://localhost:8201/eshop/license").version("1.0").build(); 34 | } 35 | } -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/config/WebConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.config; 2 | 3 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.client.RestTemplate; 7 | 8 | @Configuration 9 | public class WebConfig { 10 | 11 | @Bean 12 | @LoadBalanced 13 | public RestTemplate restTemplate() { 14 | return new RestTemplate(); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/dto/LoginRequest.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.dto; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class LoginRequest { 7 | private String email; 8 | private String password; 9 | } 10 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/http/InventoryClient.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.http; 2 | 3 | import org.springframework.cloud.openfeign.FeignClient; 4 | import org.springframework.web.bind.annotation.PathVariable; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | 8 | import java.util.HashMap; 9 | 10 | @FeignClient("INVENTORY-SERVICE") 11 | public interface InventoryClient { 12 | 13 | @RequestMapping(method = RequestMethod.GET, value = "/inventory/api/inventory/{productId}") 14 | HashMap getInventory(@PathVariable("productId") Long productId); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/model/Customer.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.model; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.GenerationType; 8 | import javax.persistence.Id; 9 | import java.io.Serializable; 10 | 11 | @Data 12 | @Entity 13 | public class Customer implements Serializable { 14 | 15 | @Id 16 | @GeneratedValue(strategy=GenerationType.IDENTITY) 17 | private Long customerId; 18 | private String name, email, password; 19 | } 20 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/model/Order.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.model; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.GenerationType; 8 | import javax.persistence.Id; 9 | import javax.persistence.Table; 10 | 11 | import lombok.*; 12 | 13 | @Data 14 | @Entity 15 | @Table(name="`Order`") 16 | public class Order implements Serializable { 17 | 18 | @Id 19 | @GeneratedValue(strategy=GenerationType.IDENTITY) 20 | private Long orderId; 21 | private Long productId, customerId; 22 | private int quantity, price; 23 | 24 | } -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/model/Product.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.model; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.GenerationType; 8 | import javax.persistence.Id; 9 | import java.io.Serializable; 10 | 11 | @Data 12 | @Entity 13 | public class Product implements Serializable { 14 | 15 | @Id 16 | @GeneratedValue(strategy=GenerationType.IDENTITY) 17 | private Long productId; 18 | 19 | private String name; 20 | private Integer price, quantity; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/repository/CustomerRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.repository; 2 | 3 | import com.example.eshop.model.Customer; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface CustomerRepository extends JpaRepository{ } 7 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/repository/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.repository; 2 | 3 | import com.example.eshop.model.Order; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface OrderRepository extends JpaRepository{ } 7 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/repository/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.repository; 2 | 3 | import com.example.eshop.model.Product; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface ProductRepository extends JpaRepository { } -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/service/impl/CustomerService.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.service.impl; 2 | 3 | import com.example.eshop.model.Customer; 4 | import com.example.eshop.repository.CustomerRepository; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.transaction.annotation.Isolation; 9 | import org.springframework.transaction.annotation.Propagation; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | @Service 13 | @Slf4j 14 | public class CustomerService { 15 | 16 | @Autowired 17 | CustomerRepository customerRepository; 18 | 19 | @Transactional(propagation=Propagation.REQUIRED, isolation=Isolation.DEFAULT) 20 | public void registerNewCustomers() { 21 | Customer customer = new Customer(); 22 | customer.setName("Raj Malhotra"); 23 | customer.setEmail("raj.malhotra@example.com"); 24 | customer.setPassword("password"); 25 | customerRepository.saveAndFlush(customer); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/service/impl/OrderService.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.service.impl; 2 | 3 | import com.example.eshop.model.Order; 4 | import com.example.eshop.repository.OrderRepository; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 7 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.web.client.RestTemplate; 13 | 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | @Service 18 | @Slf4j 19 | public class OrderService { 20 | 21 | @Autowired 22 | OrderRepository orderRepository; 23 | 24 | @Autowired 25 | @LoadBalanced 26 | RestTemplate restTemplate; 27 | 28 | @HystrixCommand(fallbackMethod = "handleInventoryFailure", 29 | commandProperties = { 30 | @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"), 31 | @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2") 32 | }) 33 | public Order orderProduct() { 34 | 35 | Order order = null; 36 | 37 | Map map = null; 38 | ObjectMapper mapper = new ObjectMapper(); 39 | String resultJson = this.restTemplate 40 | .getForObject("http://INVENTORY-SERVICE/inventory/api/inventory/" + 1, String.class); 41 | 42 | try { 43 | map = mapper.readValue(resultJson.getBytes(), HashMap.class); 44 | log.info("Result from inventory service: {}", map); 45 | }catch(Exception e) { 46 | log.error("Error while reading back json value: {}", map); 47 | return null; 48 | } 49 | 50 | Integer qty = map.get("quantity"); 51 | if(qty >=2) 52 | order = createOrder(1l, 1l, 2, 400); 53 | 54 | log.info("Orders {}", orderRepository.findAll()); 55 | 56 | return order; 57 | } 58 | 59 | public Order createOrder(Long productId, Long customerId, int quantity, int price) { 60 | Order order = new Order(); 61 | order.setCustomerId(customerId); 62 | order.setProductId(productId); 63 | order.setPrice(price); 64 | order.setQuantity(quantity); 65 | order = orderRepository.save(order); 66 | return order; 67 | } 68 | 69 | private Order handleInventoryFailure() { 70 | log.error("Inventory Service is responding very slow"); 71 | return null; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/service/impl/OrderServiceWithFiegn.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.service.impl; 2 | 3 | import com.example.eshop.http.InventoryClient; 4 | import com.example.eshop.model.Order; 5 | import com.example.eshop.repository.OrderRepository; 6 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | import org.springframework.web.client.RestTemplate; 11 | 12 | import java.util.Map; 13 | 14 | @Service 15 | @Slf4j 16 | public class OrderServiceWithFiegn { 17 | 18 | @Autowired 19 | OrderRepository orderRepository; 20 | 21 | @Autowired 22 | InventoryClient inventoryClient; 23 | 24 | @HystrixCommand(fallbackMethod = "handleInventoryFailure") 25 | public Order orderProduct() { 26 | 27 | Order order = null; 28 | 29 | Map map = inventoryClient.getInventory(1l); 30 | log.info("Result from inventory service through feign: {}", map); 31 | 32 | Integer qty = map.get("quantity"); 33 | if(qty >=2) 34 | order = createOrder(1l, 1l, 2, 400); 35 | 36 | log.info("Orders {}", orderRepository.findAll()); 37 | 38 | return order; 39 | } 40 | 41 | public Order createOrder(Long productId, Long customerId, int quantity, int price) { 42 | Order order = new Order(); 43 | order.setCustomerId(customerId); 44 | order.setProductId(productId); 45 | order.setPrice(price); 46 | order.setQuantity(quantity); 47 | order = orderRepository.save(order); 48 | return order; 49 | } 50 | 51 | private Order handleInventoryFailure() { 52 | log.error("Cannot connect to inventory service with 20% requests failing in 10 seconds interval"); 53 | return null; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/service/impl/ProductService.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.service.impl; 2 | 3 | import com.example.eshop.model.Product; 4 | import com.example.eshop.repository.ProductRepository; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | @Slf4j 11 | public class ProductService { 12 | 13 | @Autowired 14 | ProductRepository productRepository; 15 | 16 | public void registerNewProducts() { 17 | Product product = new Product(); 18 | product.setName("Superb Java"); 19 | product.setPrice(400); 20 | product.setQuantity(3); 21 | productRepository.save(product); 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/java/com/example/eshop/web/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.web; 2 | 3 | import com.example.eshop.dto.LoginRequest; 4 | import io.jsonwebtoken.Jwts; 5 | import io.jsonwebtoken.SignatureAlgorithm; 6 | import lombok.*; 7 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import javax.servlet.ServletException; 14 | import java.util.Date; 15 | 16 | @RestController 17 | public class LoginController { 18 | 19 | String DEFAULT_EMAIL = "raj@example.com"; 20 | String DEFAULT_PASSWORD = "password"; 21 | 22 | @RequestMapping(value = "/login", method = RequestMethod.POST) 23 | public String login(@RequestBody LoginRequest loginRequest) throws ServletException { 24 | 25 | var jwtToken = ""; 26 | 27 | val email = loginRequest.getEmail(); 28 | val password = loginRequest.getPassword(); 29 | 30 | val bCryptPasswordEncoder = new BCryptPasswordEncoder(); 31 | val encodedPassword = bCryptPasswordEncoder.encode(password); 32 | 33 | if(!(DEFAULT_PASSWORD.equals(encodedPassword)) 34 | || (DEFAULT_EMAIL.equals(email))) { 35 | // throw error 36 | } 37 | 38 | jwtToken = Jwts.builder().setSubject(email) 39 | .claim("roles", "admin") 40 | .signWith(SignatureAlgorithm.HS256, "secretkey") 41 | .setIssuedAt(new Date()) 42 | .compact(); 43 | 44 | return jwtToken; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch6/spring-cloud-ch6/eshop/src/main/resources/application.properties -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/eshop/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | servlet: 3 | context-path: /eshop 4 | #port: 0 5 | port: 8081 6 | 7 | spring: 8 | application: 9 | name: eshop 10 | datasource: 11 | url: jdbc:mysql://localhost:3306/db1 12 | username: root 13 | password: mysql 14 | driver-class-name: com.mysql.cj.jdbc.Driver 15 | jpa: 16 | hibernate.ddl-auto: create-drop 17 | show-sql: true 18 | generate-ddl: true 19 | boot: 20 | admin: 21 | client: 22 | url: http://localhost:7777/admin 23 | 24 | eureka: 25 | client: 26 | serviceUrl: 27 | defaultZone: ${EUREKA_URI:http://localhost:8761/eureka} 28 | instance: 29 | preferIpAddress: false 30 | 31 | management: 32 | endpoints: 33 | web: 34 | exposure: 35 | include: "*" 36 | 37 | spring.zipkin.base-url: http://localhost:9411/ 38 | 39 | security: 40 | oauth2: 41 | client: 42 | clientId: SampleClientId 43 | clientSecret: secret 44 | resource: 45 | accessTokenUri: http://localhost:8083/auth/oauth/token 46 | tokenInfoUri: http://localhost:8083/auth/oauth/check_token 47 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | zuul-service 4 | Project zuul-service created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jdt.core.javanature 26 | org.eclipse.buildship.core.gradleprojectnature 27 | 28 | 29 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.source=1.8 5 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/.settings/org.springframework.ide.eclipse.prefs: -------------------------------------------------------------------------------- 1 | boot.validation.initialized=true 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | 8 | 9 | java { 10 | group = 'com.example' 11 | version = '1.0' 12 | sourceCompatibility = JavaVersion.VERSION_1_8 13 | targetCompatibility = JavaVersion.VERSION_1_8 14 | } 15 | 16 | bootJar { 17 | archiveBaseName = 'gateway-service' 18 | version = '1.0' 19 | } 20 | 21 | repositories { 22 | mavenCentral() 23 | } 24 | 25 | dependencies { 26 | 27 | compile ([ 28 | "javax.xml.bind:jaxb-api:2.3.1", 29 | "org.glassfish.jaxb:jaxb-runtime:2.3.2", 30 | "javax.activation:javax.activation-api:1.2.0" 31 | ]) 32 | 33 | compile("org.springframework.boot:spring-boot-starter-web") 34 | compile('org.springframework.cloud:spring-cloud-starter-netflix-zuul:2.1.1.RELEASE') 35 | compile("org.projectlombok:lombok:1.18.6") 36 | compile group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1' 37 | compile("org.projectlombok:lombok:1.18.6") 38 | annotationProcessor("org.projectlombok:lombok:1.18.6") 39 | } 40 | 41 | dependencyManagement { 42 | imports { 43 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:Greenwich.SR1" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch6/spring-cloud-ch6/gateway-service/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/out/production/classes/com/example/eshop/gateway/ZuulApp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch6/spring-cloud-ch6/gateway-service/out/production/classes/com/example/eshop/gateway/ZuulApp.class -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/out/production/classes/com/example/eshop/gateway/filters/AuthPreFilter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch6/spring-cloud-ch6/gateway-service/out/production/classes/com/example/eshop/gateway/filters/AuthPreFilter.class -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/out/production/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch6/spring-cloud-ch6/gateway-service/out/production/resources/application.properties -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/out/production/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: zuul 4 | boot: 5 | admin: 6 | client: 7 | url: http://localhost:7777/admin 8 | 9 | server: 10 | port: 9999 11 | 12 | zuul: 13 | ignoredServices: '*' 14 | sensitiveHeaders: Cookie,Set-Cookie 15 | routes: 16 | config: 17 | path: /config/** 18 | url: http://localhost:8888/config/ 19 | eshop: 20 | path: /eshop/** 21 | url: http://localhost:8081/eshop/ 22 | inventory: 23 | path: /inventory/** 24 | url: http://localhost:8082/inventory/ 25 | admin: 26 | path: /admin/** 27 | url: http://localhost:7777/admin/ 28 | 29 | management: 30 | endpoints: 31 | web: 32 | exposure: 33 | include: "*" 34 | 35 | spring.main.allow-bean-definition-overriding: true 36 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/src/main/java/com/example/eshop/gateway/ZuulApp.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.gateway; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 6 | 7 | @SpringBootApplication 8 | @EnableZuulProxy 9 | public class ZuulApp { 10 | public static void main(String[] args) { 11 | SpringApplication.run(ZuulApp.class, args); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/src/main/java/com/example/eshop/gateway/filters/AuthPreFilter.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.gateway.filters; 2 | 3 | import com.netflix.zuul.ZuulFilter; 4 | import com.netflix.zuul.context.RequestContext; 5 | import io.jsonwebtoken.Claims; 6 | import io.jsonwebtoken.Jwts; 7 | import io.jsonwebtoken.MalformedJwtException; 8 | import io.jsonwebtoken.SignatureException; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.stereotype.Component; 11 | 12 | import javax.servlet.http.HttpServletRequest; 13 | 14 | @Component 15 | @Slf4j 16 | public class AuthPreFilter extends ZuulFilter { 17 | 18 | //Check JWT headers and aall OAUTH service if required 19 | @Override 20 | public Object run() { 21 | 22 | RequestContext context = RequestContext.getCurrentContext(); 23 | HttpServletRequest request = context.getRequest(); 24 | 25 | final String token = request.getHeader("Authorization"); 26 | 27 | if (token == null) { 28 | context.setSendZuulResponse(false); 29 | context.setResponseStatusCode(401); 30 | context.setResponseBody("Authorization header is missing"); 31 | return null; 32 | } 33 | 34 | try { 35 | final Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody(); 36 | log.info("Claims: {}", claims); 37 | context.addZuulRequestHeader("Authorization", "Basic " + token); 38 | 39 | } catch (final MalformedJwtException e) { 40 | context.setSendZuulResponse(false); 41 | context.setResponseStatusCode(401); 42 | context.setResponseBody("API key is not valid"); 43 | } 44 | 45 | return null; 46 | } 47 | 48 | @Override 49 | public String filterType() { 50 | return "pre"; 51 | } 52 | 53 | @Override 54 | public int filterOrder() { 55 | return 0; 56 | } 57 | 58 | @Override 59 | public boolean shouldFilter() { 60 | return true; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/src/main/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch6/spring-cloud-ch6/gateway-service/src/main/resources/application.properties -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/gateway-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: zuul 4 | boot: 5 | admin: 6 | client: 7 | url: http://localhost:7777/admin 8 | 9 | server: 10 | port: 9999 11 | 12 | zuul: 13 | ignoredServices: '*' 14 | sensitiveHeaders: Cookie,Set-Cookie 15 | routes: 16 | config: 17 | path: /config/** 18 | url: http://localhost:8888/config/ 19 | eshop: 20 | path: /eshop/** 21 | url: http://localhost:8081/eshop/ 22 | inventory: 23 | path: /inventory/** 24 | url: http://localhost:8082/inventory/ 25 | admin: 26 | path: /admin/** 27 | url: http://localhost:7777/admin/ 28 | 29 | management: 30 | endpoints: 31 | web: 32 | exposure: 33 | include: "*" 34 | 35 | spring.main.allow-bean-definition-overriding: true 36 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | inventory-service 4 | Project inventory-service created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jdt.core.javanature 26 | org.eclipse.buildship.core.gradleprojectnature 27 | 28 | 29 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.source=1.8 5 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/.settings/org.springframework.ide.eclipse.prefs: -------------------------------------------------------------------------------- 1 | boot.validation.initialized=true 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | apply plugin: 'project-report' 8 | 9 | group = 'com.example.eshop' 10 | version = '1.0' 11 | sourceCompatibility = JavaVersion.VERSION_11 12 | targetCompatibility = JavaVersion.VERSION_11 13 | 14 | bootJar { 15 | baseName = 'inventory-service' 16 | version = '1.0' 17 | } 18 | 19 | repositories { 20 | mavenCentral() 21 | maven { url 'https://repo.spring.io/milestone' } 22 | } 23 | 24 | dependencies { 25 | 26 | compile ([ 27 | "org.springframework.boot:spring-boot-starter-web", 28 | "org.springframework.boot:spring-boot-starter-data-jpa", 29 | "org.springframework.boot:spring-boot-starter-test", 30 | "org.projectlombok:lombok:1.18.6", 31 | "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client", 32 | "org.springframework.cloud:spring-cloud-starter-config", 33 | ]) 34 | 35 | compile("org.springframework.cloud:spring-cloud-starter-sleuth") 36 | compile("org.springframework.cloud:spring-cloud-starter-zipkin") 37 | compile("de.codecentric:spring-boot-admin-starter-client:2.1.1") 38 | compile("org.springframework.boot:spring-boot-starter-actuator") 39 | 40 | runtime("com.h2database:h2") 41 | testCompile("junit:junit") 42 | 43 | annotationProcessor 'org.projectlombok:lombok:1.18.6' 44 | testAnnotationProcessor 'org.projectlombok:lombok:1.18.6' 45 | } 46 | 47 | dependencyManagement { 48 | imports { 49 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:Greenwich.SR1" 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch6/spring-cloud-ch6/inventory-service/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'inventory-service' 2 | 3 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/src/main/java/com/example/eshop/inventory/InventoryApp.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.inventory; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class InventoryApp { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(InventoryApp.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/src/main/java/com/example/eshop/inventory/model/Inventory.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.inventory.model; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.Id; 9 | import javax.persistence.Table; 10 | 11 | @Entity 12 | @Data 13 | @Builder 14 | @Table(name = "Inventory") 15 | public class Inventory { 16 | 17 | @Id 18 | @GeneratedValue 19 | private Long inventoryId; 20 | 21 | Long productId; 22 | Integer price; 23 | Integer quantity; 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/src/main/java/com/example/eshop/inventory/repository/InventoryRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.inventory.repository; 2 | 3 | import com.example.eshop.inventory.model.Inventory; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface InventoryRepository extends JpaRepository { 7 | } 8 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/src/main/java/com/example/eshop/inventory/service/InventoryService.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.inventory.service; 2 | 3 | import com.example.eshop.inventory.model.Inventory; 4 | import com.example.eshop.inventory.repository.InventoryRepository; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.Optional; 10 | 11 | @Service 12 | @Slf4j 13 | public class InventoryService { 14 | 15 | @Autowired 16 | InventoryRepository inventoryRepository; 17 | 18 | public Inventory getInventory(Long productId) { 19 | log.info("Inventory lookup request for productId: {}", productId); 20 | Optional inventory = inventoryRepository.findById(productId); 21 | return inventory.orElse(Inventory.builder() 22 | .inventoryId(1l) 23 | .productId(productId) 24 | .price(200) 25 | .quantity(2) 26 | .build()); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/src/main/java/com/example/eshop/inventory/web/InventoryController.java: -------------------------------------------------------------------------------- 1 | package com.example.eshop.inventory.web; 2 | 3 | import com.example.eshop.inventory.model.Inventory; 4 | import com.example.eshop.inventory.service.InventoryService; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | @RestController 12 | @Slf4j 13 | public class InventoryController { 14 | 15 | @Autowired 16 | InventoryService inventoryService; 17 | 18 | @GetMapping("/api/inventory/{productId}") 19 | public Inventory getInventoryForProduct(@PathVariable("productId") Long productId) { 20 | log.info("Inventory request for product: {}", productId); 21 | Inventory inventory = inventoryService.getInventory(productId); 22 | log.info("inventory : {}", inventory); 23 | return inventory; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | servlet: 3 | contextPath: /inventory 4 | #port: 0 5 | port: 8082 6 | 7 | spring: 8 | jpa: 9 | hibernate.ddl-auto: create 10 | show-sql: true 11 | generate-ddl: true 12 | datasource: 13 | name: inventorydb 14 | boot: 15 | admin: 16 | client: 17 | url: http://localhost:7777/admin 18 | 19 | management: 20 | endpoints: 21 | web: 22 | exposure: 23 | include: "*" 24 | 25 | eureka: 26 | client: 27 | serviceUrl: 28 | defaultZone: ${EUREKA_URI:http://localhost:8761/eureka} 29 | instance: 30 | preferIpAddress: true 31 | 32 | spring.main.allow-bean-definition-overriding: true 33 | spring.zipkin.base-url: http://localhost:9411/ 34 | -------------------------------------------------------------------------------- /ch6/spring-cloud-ch6/inventory-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: inventory-service 4 | profiles: 5 | active: prod 6 | cloud: 7 | config: 8 | uri: http://localhost:8888/config/ 9 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | 8 | java { 9 | group = 'com.example' 10 | version = '1.0' 11 | sourceCompatibility = JavaVersion.VERSION_1_8 12 | targetCompatibility = JavaVersion.VERSION_1_8 13 | } 14 | 15 | bootJar { 16 | archiveBaseName = 'eblog-service' 17 | version = '1.0' 18 | } 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencies { 25 | 26 | compile('org.springframework.boot:spring-boot-starter-web') 27 | compile('com.graphql-java:graphql-java-tools:5.2.4') 28 | compile('com.graphql-java:graphql-spring-boot-starter:5.0.2') 29 | compile('com.graphql-java:graphiql-spring-boot-starter:5.0.2') 30 | 31 | compile('org.springframework.boot:spring-boot-starter-data-jpa') 32 | compile('mysql:mysql-connector-java:8.0.15') 33 | compile('org.projectlombok:lombok:1.18.6') 34 | testCompile('junit:junit:4.12') 35 | annotationProcessor 'org.projectlombok:lombok:1.18.6' 36 | } 37 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/eshop.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'eblog-graphql-ch7' 2 | 3 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/java/com/example/eblog/App.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class App { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(App.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/java/com/example/eblog/dto/AuthorInputRequest.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.dto; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class AuthorInputRequest { 7 | String name; 8 | Integer age; 9 | } 10 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/java/com/example/eblog/dto/PostInputRequest.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.dto; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class PostInputRequest { 7 | String title; 8 | String content; 9 | Long authorId; 10 | } 11 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/java/com/example/eblog/handler/GraphQLConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.handler; 2 | 3 | import graphql.ExceptionWhileDataFetching; 4 | import graphql.GraphQLError; 5 | import graphql.servlet.GraphQLErrorHandler; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | @Configuration 13 | public class GraphQLConfig { 14 | 15 | @Bean 16 | public GraphQLErrorHandler errorHandler() { 17 | 18 | return new GraphQLErrorHandler() { 19 | 20 | @Override 21 | public List processErrors(List errors) { 22 | 23 | List clientErrors = errors.stream() 24 | .filter(this::isClientError) 25 | .collect(Collectors.toList()); 26 | 27 | // do anything with the client side errors 28 | 29 | List serverErrors = errors.stream() 30 | .filter(e -> !isClientError(e)) 31 | .collect(Collectors.toList()); 32 | 33 | // do anything with the server side errors 34 | 35 | return errors; 36 | } 37 | 38 | protected boolean isClientError(GraphQLError error) { 39 | return !(error instanceof ExceptionWhileDataFetching || error instanceof Throwable); 40 | } 41 | }; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/java/com/example/eblog/model/Author.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import lombok.*; 5 | 6 | import javax.persistence.*; 7 | import java.io.Serializable; 8 | import java.util.Set; 9 | 10 | @Data 11 | @Entity 12 | @NoArgsConstructor 13 | @ToString(exclude = {"posts"}) 14 | @EqualsAndHashCode(exclude = {"posts"}) 15 | public class Author implements Serializable { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.IDENTITY) 19 | private Long id; 20 | private String name; 21 | private int age; 22 | private Status status = Status.NON_ACTIVE; 23 | 24 | @OneToMany(fetch = FetchType.LAZY, mappedBy = "author") 25 | @JsonIgnore 26 | private Set posts; 27 | 28 | public Author(String name, Integer age) { 29 | this.name = name; 30 | this.age = age; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/java/com/example/eblog/model/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import lombok.*; 5 | 6 | import javax.persistence.*; 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @Entity 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @ToString(exclude = {"author"}) 15 | @EqualsAndHashCode(exclude = {"author"}) 16 | public class Post implements Serializable { 17 | 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | private Long id; 21 | 22 | private String title; 23 | private String content; 24 | private Status status; 25 | 26 | @ManyToOne(fetch = FetchType.LAZY) 27 | @JsonIgnore 28 | private Author author; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/java/com/example/eblog/model/Status.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.model; 2 | 3 | public enum Status { 4 | 5 | ACTIVE, NON_ACTIVE; 6 | 7 | public Status fromValue(String value) { 8 | return valueOf(value.toUpperCase()); 9 | } 10 | 11 | public String toValue(Status status) { 12 | return status.name().toLowerCase(); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/java/com/example/eblog/repository/AuthorRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.repository; 2 | 3 | import com.example.eblog.model.Author; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.data.jpa.repository.Query; 6 | 7 | import java.util.List; 8 | 9 | public interface AuthorRepository extends JpaRepository { 10 | 11 | @Query("Select distinct a from Author a left join fetch a.posts") 12 | List findAuthorsWithPosts(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/java/com/example/eblog/repository/PostRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.repository; 2 | 3 | import com.example.eblog.model.Post; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | @Repository 8 | public interface PostRepository extends JpaRepository { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/java/com/example/eblog/resolvers/MutationResolver.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.resolvers; 2 | 3 | import com.coxautodev.graphql.tools.GraphQLMutationResolver; 4 | import com.example.eblog.dto.AuthorInputRequest; 5 | import com.example.eblog.dto.PostInputRequest; 6 | import com.example.eblog.model.Author; 7 | import com.example.eblog.model.Post; 8 | import com.example.eblog.model.Status; 9 | import com.example.eblog.repository.AuthorRepository; 10 | import com.example.eblog.repository.PostRepository; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Service; 14 | 15 | @Service 16 | @Slf4j 17 | public class MutationResolver implements GraphQLMutationResolver { 18 | 19 | @Autowired 20 | AuthorRepository authorRepository; 21 | 22 | @Autowired 23 | PostRepository postRepository; 24 | 25 | public Post newPost(PostInputRequest postInputRequest){ 26 | 27 | Author author = authorRepository.findById(postInputRequest.getAuthorId()) 28 | .orElse(new Author("Raj", 35)); 29 | if(author.getId() == null) 30 | authorRepository.save(author); 31 | 32 | Post post = Post.builder() 33 | .title(postInputRequest.getTitle()) 34 | .content(postInputRequest.getContent()) 35 | .author(author) 36 | .status(Status.ACTIVE) 37 | .build(); 38 | 39 | post = postRepository.save(post); 40 | 41 | return post; 42 | } 43 | 44 | public Author newAuthor(AuthorInputRequest authorInputRequest) { 45 | Author author = new Author(authorInputRequest.getName(), authorInputRequest.getAge()); 46 | author = authorRepository.save(author); 47 | return author; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/java/com/example/eblog/resolvers/QueryResolver.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.resolvers; 2 | 3 | import com.coxautodev.graphql.tools.GraphQLQueryResolver; 4 | import com.example.eblog.model.Author; 5 | import com.example.eblog.model.Post; 6 | import com.example.eblog.repository.AuthorRepository; 7 | import com.example.eblog.repository.PostRepository; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.data.domain.PageRequest; 11 | import org.springframework.data.domain.Sort; 12 | import org.springframework.stereotype.Service; 13 | 14 | import java.util.List; 15 | 16 | @Service 17 | @Slf4j 18 | public class QueryResolver implements GraphQLQueryResolver { 19 | 20 | @Autowired 21 | AuthorRepository authorRepository; 22 | 23 | @Autowired 24 | PostRepository postRepository; 25 | 26 | public List recentPosts(Integer limit, Integer offset, String orderBy){ 27 | log.info("recentPosts, params: {}, {}", limit, offset); 28 | PageRequest pageRequest = PageRequest.of(limit, offset, Sort.Direction.DESC, orderBy); 29 | return postRepository.findAll(pageRequest).getContent(); 30 | } 31 | 32 | public List authorsWithTopPosts() { 33 | log.info("authorsWithTopPosts"); 34 | return authorRepository.findAuthorsWithPosts(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8201 3 | servlet: 4 | contextPath: /eblog 5 | 6 | graphql: 7 | servlet: 8 | mapping: /graphql 9 | enabled: true 10 | corsEnabled: true 11 | 12 | graphiql: 13 | mapping: /graphiql 14 | endpoint: /eblog/graphql 15 | enabled: true 16 | pageTitle: GraphiQL 17 | 18 | spring: 19 | datasource: 20 | url: jdbc:mysql://localhost:3306/eblog?autoReconnect=true 21 | username: root 22 | password: mysql 23 | driver-class-name: com.mysql.jdbc.Driver 24 | dialect=org: 25 | hibernate: 26 | dialect: MySQL5InnoDBDialect 27 | jpa: 28 | hibernate.ddl-auto: create 29 | show-sql: true 30 | generate-ddl: true 31 | -------------------------------------------------------------------------------- /ch7/eblog-graphql-ch7/src/main/resources/schema.graphqls: -------------------------------------------------------------------------------- 1 | type Post { 2 | id: ID! 3 | title: String! 4 | content: String! 5 | status: Status! 6 | author: Author! 7 | } 8 | 9 | type Author { 10 | id: ID! 11 | name: String! 12 | age: Int @deprecated(reason: "Field is deprecated!") 13 | posts: [Post]! 14 | status: Status! 15 | } 16 | 17 | enum Status { 18 | ACTIVE 19 | NON_ACTIVE 20 | } 21 | 22 | input PostInputRequest { 23 | title: String! 24 | content: String! 25 | authorId: Int! 26 | } 27 | 28 | input AuthorInputRequest { 29 | name: String! 30 | age: Int 31 | } 32 | 33 | type Mutation { 34 | newPost(input: PostInputRequest): Post! 35 | newAuthor(input: AuthorInputRequest): Author! 36 | } 37 | 38 | type Query { 39 | recentPosts(limit: Int, offset: Int, orderBy: String): [Post] 40 | authorsWithTopPosts: [Author] 41 | } 42 | 43 | -------------------------------------------------------------------------------- /ch8/eblog-reactive-ch8/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.3.RELEASE' 3 | id 'java' 4 | } 5 | 6 | apply plugin: 'io.spring.dependency-management' 7 | apply plugin: 'project-report' 8 | 9 | java { 10 | group = 'com.example' 11 | version = '1.0' 12 | sourceCompatibility = JavaVersion.VERSION_1_8 13 | targetCompatibility = JavaVersion.VERSION_1_8 14 | } 15 | 16 | bootJar { 17 | archiveBaseName = 'eblog-service' 18 | version = '1.0' 19 | } 20 | 21 | repositories { 22 | mavenCentral() 23 | maven { url "https://repo.spring.io/snapshot" } 24 | maven { url "http://repo.spring.io/libs-milestone" } 25 | } 26 | 27 | sourceCompatibility = JavaVersion.VERSION_11 28 | targetCompatibility = JavaVersion.VERSION_11 29 | 30 | dependencies { 31 | 32 | compile('org.springframework.boot:spring-boot-starter-webflux') 33 | compile("org.springframework.data:spring-data-r2dbc:1.0.0.M1") 34 | compile("io.r2dbc:r2dbc-spi:1.0.0.M7") 35 | compile("io.r2dbc:r2dbc-postgresql:1.0.0.M7") 36 | 37 | compile ("org.projectlombok:lombok:1.18.6") 38 | testCompile('junit:junit:4.12') 39 | annotationProcessor 'org.projectlombok:lombok:1.18.6' 40 | } 41 | -------------------------------------------------------------------------------- /ch8/eblog-reactive-ch8/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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /ch8/eblog-reactive-ch8/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'eblog-reactive-ch8' 2 | -------------------------------------------------------------------------------- /ch8/eblog-reactive-ch8/src/main/java/com/example/eblog/App.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories; 6 | 7 | @SpringBootApplication 8 | @EnableR2dbcRepositories 9 | public class App { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(App.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /ch8/eblog-reactive-ch8/src/main/java/com/example/eblog/config/Config.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.config; 2 | 3 | import io.r2dbc.postgresql.PostgresqlConnectionConfiguration; 4 | import io.r2dbc.postgresql.PostgresqlConnectionFactory; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.data.r2dbc.config.AbstractR2dbcConfiguration; 7 | 8 | @Configuration 9 | public class Config extends AbstractR2dbcConfiguration { 10 | 11 | @Override 12 | public PostgresqlConnectionFactory connectionFactory() { 13 | PostgresqlConnectionConfiguration connectionConfiguration = 14 | PostgresqlConnectionConfiguration.builder() 15 | .applicationName("eblog") 16 | .database("eblog") 17 | .host("localhost") 18 | .username("postgres") 19 | .password("postgres").build(); 20 | 21 | return new PostgresqlConnectionFactory(connectionConfiguration); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /ch8/eblog-reactive-ch8/src/main/java/com/example/eblog/dto/PostInputRequest.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.dto; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class PostInputRequest { 7 | String title; 8 | String content; 9 | } 10 | -------------------------------------------------------------------------------- /ch8/eblog-reactive-ch8/src/main/java/com/example/eblog/model/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import org.springframework.data.annotation.Id; 7 | import org.springframework.data.relational.core.mapping.Column; 8 | 9 | import java.io.Serializable; 10 | 11 | @Data 12 | @Builder 13 | @AllArgsConstructor 14 | public class Post implements Serializable { 15 | 16 | @Id 17 | private Long id; 18 | 19 | private String title; 20 | 21 | @Column("content") 22 | private String content; 23 | 24 | public Post() {} 25 | 26 | public Post(String title, String content) { 27 | this.title = title; 28 | this.content = content; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ch8/eblog-reactive-ch8/src/main/java/com/example/eblog/repository/PostRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.repository; 2 | 3 | import com.example.eblog.model.Post; 4 | import org.springframework.data.repository.reactive.ReactiveCrudRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | @Repository 8 | public interface PostRepository extends ReactiveCrudRepository { } 9 | 10 | 11 | -------------------------------------------------------------------------------- /ch8/eblog-reactive-ch8/src/main/java/com/example/eblog/web/PostController.java: -------------------------------------------------------------------------------- 1 | package com.example.eblog.web; 2 | 3 | import com.example.eblog.dto.PostInputRequest; 4 | import com.example.eblog.model.Post; 5 | import com.example.eblog.repository.PostRepository; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.data.domain.PageRequest; 9 | import org.springframework.data.domain.Sort; 10 | import org.springframework.data.repository.query.Param; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.RequestBody; 14 | import org.springframework.web.bind.annotation.RestController; 15 | import reactor.core.publisher.Flux; 16 | import reactor.core.publisher.Mono; 17 | 18 | @RestController 19 | @Slf4j 20 | public class PostController { 21 | 22 | @Autowired 23 | PostRepository postRepository; 24 | 25 | @PostMapping("/posts") 26 | public Mono newPost(@RequestBody PostInputRequest postInputRequest){ 27 | 28 | Post lclPost = Post.builder() 29 | .title(postInputRequest.getTitle()) 30 | .content(postInputRequest.getContent()) 31 | .build(); 32 | 33 | Mono post = postRepository.save(lclPost); 34 | 35 | return post; 36 | } 37 | 38 | @GetMapping("/posts") 39 | Flux allPosts() { 40 | return this.postRepository.findAll(); 41 | } 42 | 43 | @GetMapping("/recentPosts") 44 | public Flux recentPosts( 45 | @Param("limit") Integer limit, @Param("offset") Integer offset, 46 | @Param("orderBy") String orderBy){ 47 | 48 | log.info("recentPosts, params: {}, {}", limit, offset); 49 | PageRequest pageRequest = PageRequest.of(limit, offset, Sort.Direction.DESC, orderBy); 50 | return postRepository.findAll(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /ch9/websocket-example-ch9/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id "name.remal.fat-jar" version "1.0.124" 4 | } 5 | 6 | java { 7 | group = 'com.example' 8 | version = '1.0' 9 | sourceCompatibility = JavaVersion.VERSION_1_8 10 | targetCompatibility = JavaVersion.VERSION_1_8 11 | } 12 | 13 | jar { 14 | manifest { 15 | attributes 'Main-Class': 'com.example.Application' 16 | } 17 | } 18 | 19 | repositories { 20 | mavenCentral() 21 | } 22 | 23 | dependencies { 24 | compile("com.sparkjava:spark-core:2.9.0") 25 | compile group: 'org.json', name: 'json', version: '20180813' 26 | compile('org.projectlombok:lombok:1.18.6') 27 | annotationProcessor 'org.projectlombok:lombok:1.18.6' 28 | } 29 | -------------------------------------------------------------------------------- /ch9/websocket-example-ch9/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/rapid-java-persistence-and-microservices/cf92cf68df9f829d1449b8b1de92afca0077b797/ch9/websocket-example-ch9/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ch9/websocket-example-ch9/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Mar 19 07:43:30 IST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-all.zip 7 | -------------------------------------------------------------------------------- /ch9/websocket-example-ch9/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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /ch9/websocket-example-ch9/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'websocket-example' 2 | 3 | -------------------------------------------------------------------------------- /ch9/websocket-example-ch9/src/main/java/com/example/Application.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.example.web.TweetController; 4 | import com.example.web.WSHandler; 5 | 6 | import static spark.Spark.init; 7 | import static spark.Spark.webSocket; 8 | 9 | public class Application { 10 | public static void main(String[] args) { 11 | webSocket("/messages", WSHandler.class); 12 | TweetController tweetController = new TweetController(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ch9/websocket-example-ch9/src/main/java/com/example/web/MessageService.java: -------------------------------------------------------------------------------- 1 | package com.example.web; 2 | 3 | import org.eclipse.jetty.websocket.api.Session; 4 | 5 | import java.util.Map; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | import java.util.concurrent.atomic.AtomicInteger; 8 | 9 | public class MessageService { 10 | 11 | private static MessageService instance = new MessageService(); 12 | 13 | public static MessageService getInstance() { 14 | return instance; 15 | } 16 | 17 | private MessageService() {} 18 | 19 | AtomicInteger counter = new AtomicInteger(0); 20 | 21 | Map sessionMap = new ConcurrentHashMap<>(); 22 | 23 | public String newUserJoined(Session session) { 24 | String username = "User" + counter.addAndGet(1); 25 | sessionMap.put(session, username); 26 | return username; 27 | } 28 | 29 | public void broadcastMessage(String sender, String message) { 30 | System.out.println("Sending another message"); 31 | sessionMap.keySet().stream().filter(Session::isOpen).forEach(session -> { 32 | try { 33 | session.getRemote().sendString(sender + " : " + message); 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | } 37 | }); 38 | } 39 | 40 | public String removeUser(Session session) { 41 | String username = sessionMap.get(session); 42 | sessionMap.remove(session); 43 | return username; 44 | } 45 | 46 | public String getUser(Session session) { 47 | return sessionMap.get(session); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ch9/websocket-example-ch9/src/main/java/com/example/web/TweetController.java: -------------------------------------------------------------------------------- 1 | package com.example.web; 2 | 3 | import static spark.Spark.*; 4 | 5 | public class TweetController { 6 | 7 | MessageService messageService = MessageService.getInstance(); 8 | 9 | public TweetController() { 10 | 11 | post("/tweet", (request, response) -> { 12 | String message = request.queryParamOrDefault("message", "SERVER"); 13 | messageService.broadcastMessage("Server", message); 14 | return "Sent"; 15 | }); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ch9/websocket-example-ch9/src/main/java/com/example/web/WSHandler.java: -------------------------------------------------------------------------------- 1 | package com.example.web; 2 | 3 | import org.eclipse.jetty.websocket.api.Session; 4 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; 5 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; 6 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; 7 | import org.eclipse.jetty.websocket.api.annotations.WebSocket; 8 | 9 | @WebSocket 10 | public class WSHandler { 11 | 12 | MessageService messageService = MessageService.getInstance(); 13 | 14 | @OnWebSocketConnect 15 | public void onConnect(Session session) throws Exception { 16 | String username = messageService.newUserJoined(session); 17 | messageService.broadcastMessage("Server", username + " joined the chat"); 18 | } 19 | 20 | @OnWebSocketClose 21 | public void onClose(Session session, int statusCode, String reason) { 22 | String username = messageService.removeUser(session); 23 | messageService.broadcastMessage("Server", username + " left the chat"); 24 | } 25 | 26 | @OnWebSocketMessage 27 | public void onMessage(Session session, String message) { 28 | String username = messageService.getUser(session); 29 | messageService.broadcastMessage(username, message); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /errata.md: -------------------------------------------------------------------------------- 1 | # Errata for *Book Title* 2 | 3 | On **page xx** [Summary of error]: 4 | 5 | Details of error here. Highlight key pieces in **bold**. 6 | 7 | *** 8 | 9 | On **page xx** [Summary of error]: 10 | 11 | Details of error here. Highlight key pieces in **bold**. 12 | 13 | *** --------------------------------------------------------------------------------