├── .gitignore ├── Bookstore Project AWS Architecture.jpg ├── Postman ├── BookStoreApp.postman_collection.json └── BookStoreApp.postman_environment.json ├── README.md ├── bookstore-account-service ├── Dockerfile ├── dockerize ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── devd │ │ │ └── spring │ │ │ └── bookstoreaccountservice │ │ │ ├── BookstoreAccountServiceApplication.java │ │ │ ├── config │ │ │ ├── AccountServiceConfig.java │ │ │ ├── AuthForwardInterceptor.java │ │ │ ├── AuthorizationServerConfig.java │ │ │ ├── ResourceServerConfig.java │ │ │ └── SwaggerConfig.java │ │ │ ├── controller │ │ │ ├── AuthController.java │ │ │ ├── RoleController.java │ │ │ ├── UserController.java │ │ │ └── UserRoleController.java │ │ │ ├── exception │ │ │ ├── AccountServiceExceptionHandler.java │ │ │ └── SuccessCodeWithErrorResponse.java │ │ │ ├── repository │ │ │ ├── OAuthClientRepository.java │ │ │ ├── RoleRepository.java │ │ │ ├── UserRepository.java │ │ │ └── dao │ │ │ │ ├── OAuthClient.java │ │ │ │ ├── Role.java │ │ │ │ └── User.java │ │ │ ├── service │ │ │ ├── AppUserDetailsService.java │ │ │ ├── AuthService.java │ │ │ ├── RoleService.java │ │ │ ├── UserRoleService.java │ │ │ ├── UserService.java │ │ │ └── impl │ │ │ │ ├── AppUserDetailsServiceImpl.java │ │ │ │ ├── AuthServiceImpl.java │ │ │ │ ├── RoleServiceImpl.java │ │ │ │ ├── UserRoleServiceImpl.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── web │ │ │ ├── CreateOAuthClientRequest.java │ │ │ ├── CreateOAuthClientResponse.java │ │ │ ├── CreateRoleRequest.java │ │ │ ├── CreateUserRequest.java │ │ │ ├── CreateUserResponse.java │ │ │ ├── GetUserInfoResponse.java │ │ │ ├── GetUserResponse.java │ │ │ ├── JwtAuthenticationResponse.java │ │ │ ├── MapRoleToUsersRequest.java │ │ │ ├── MapUserToRolesRequest.java │ │ │ ├── SignInRequest.java │ │ │ ├── SignUpRequest.java │ │ │ ├── UpdateUserRequest.java │ │ │ └── UpdateUserRequestFromAdmin.java │ └── resources │ │ ├── JWTKeystore.p12 │ │ ├── application.yml │ │ ├── bootstrap.yml │ │ ├── db │ │ └── migration │ │ │ ├── V1__account_service_schema.sql │ │ │ └── V2__account_service_initial_data.sql │ │ ├── jwt-signing-public-key.txt │ │ └── logback-spring.xml │ └── test │ └── java │ └── com │ └── devd │ └── spring │ └── bookstoreaccountservice │ └── BookstoreAccountServiceApplicationTests.java ├── bookstore-api-gateway-service ├── Dockerfile ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── devd │ │ └── spring │ │ └── bookstoreapigatewayservice │ │ ├── BookstoreApiGatewayServiceApplication.java │ │ ├── config │ │ ├── AddTraceIdToHttpResponseConfig.java │ │ └── ApiGatewayConfig.java │ │ ├── exception │ │ ├── Error.java │ │ ├── ErrorResponse.java │ │ ├── GlobalExceptionHandler.java │ │ └── RunTimeExceptionPlaceHolder.java │ │ └── filters │ │ ├── ErrorFilter.java │ │ ├── PostFilter.java │ │ ├── PreFilter.java │ │ └── RouteFilter.java │ └── resources │ ├── application.yml │ ├── bootstrap.yml │ └── logback-spring.xml ├── bookstore-billing-service ├── .gitignore ├── Dockerfile ├── dockerize ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── devd │ │ │ └── spring │ │ │ └── bookstorebillingservice │ │ │ ├── BookstoreBillingServiceApplication.java │ │ │ ├── config │ │ │ ├── AuthForwardInterceptor.java │ │ │ ├── BillingResourceServiceConfig.java │ │ │ ├── BillingServiceConfig.java │ │ │ └── SwaggerConfig.java │ │ │ ├── controller │ │ │ └── AddressController.java │ │ │ ├── repository │ │ │ ├── AddressRepository.java │ │ │ └── dao │ │ │ │ └── AddressDao.java │ │ │ ├── service │ │ │ ├── AddressService.java │ │ │ └── impl │ │ │ │ └── AddressServiceImpl.java │ │ │ └── web │ │ │ ├── CreateAddressRequest.java │ │ │ ├── GetAddressResponse.java │ │ │ └── UpdateAddressRequest.java │ └── resources │ │ ├── application.yml │ │ ├── bootstrap.yml │ │ ├── db │ │ └── migration │ │ │ ├── V1__billing_service_schema.sql │ │ │ └── V2__billing_service_initial_data.sql │ │ ├── jwt-signing-public-key.txt │ │ └── logback-spring.xml │ └── test │ └── java │ └── com │ └── devd │ └── spring │ └── bookstorebillingservice │ └── BookstoreBillingAddressServiceImplApplicationTests.java ├── bookstore-catalog-service ├── .gitignore ├── Dockerfile ├── dockerize ├── images │ ├── 0547ab94-59f8-4352-b17b-0918d07913f2__pricePredudice.jpg │ ├── 1ecfd5c4-dba2-4feb-bd88-006105a8d5ab__alchemist.jpg │ ├── 25550dae-a893-4aa5-8b8f-967a91548fa5__oopWithCpp.jpg │ ├── 2603aa1d-3892-44cc-9481-fd485d80d270__businessAdventures.jpg │ ├── 27ba1db0-a5a3-477c-927c-7ceb36cf7ffa__theTimeMachine.jpg │ ├── 2b3ba80b-da93-4206-b50f-83008180a09e__sheHolmes.jpg │ ├── 3b315751-c5bd-4e73-aad2-df941826f453__The Great Indian Conspiracy.jpg │ ├── 46fb8d5b-2979-4c54-848f-512693b37818__52 Small Changes for the Mind- Improve Memory.jpg │ ├── 49935a41-7274-4b7f-9333-c3e85d59df18__belatedBacghelorparty.jpg │ ├── 4b050ba6-9573-4554-bdd4-26ae806c06aa__IntroEngLit.jpg │ ├── 622a7214-02cc-4f54-85fd-86fd8f3b6967__theScienceBook.jpg │ ├── 6a290abe-338f-4ece-8793-ccdd35a7745f__linux.jpg │ ├── 7d8b74e5-4321-4b49-9b2a-da4bf779d5be__theTheoryOfEverything.jpg │ ├── 8e6abb0e-180b-4e8e-856a-cb8491ff9454__greatGatsby.jpg │ ├── 8f8a275b-357e-4010-84dc-8d89bb5e2b95__Politics for Beginners.jpg │ ├── 990945b7-900e-432b-9b2c-79ea20302f6e__Productivity Superhero.jpg │ ├── ad5b1926-05ad-4aae-852d-f152ea838648__programmingInJava.jpg │ ├── af75f363-fdb9-4d8e-8066-6215f0520e9b__corePythonProg.jpg │ ├── b1175b20-e946-42a6-b63d-83e35b7a73fa__oneArrangedMurder.jpg │ ├── b9685c28-7f97-4fb7-9cf0-927ff3afc8f1__spaceEncyclo.jpg │ ├── c16108e1-8276-41ad-bf12-4aee4c0a7e65__IndModernLiterature.jpg │ ├── cad39d84-60aa-496d-9295-c3f47ec957fa__programmingInC.jpg │ ├── cef7540f-0810-4323-9950-98c5d8d5099d__Chandra Shekhar- The Last Icon of Ideological Politics.jpg │ ├── e6602eb6-3f67-4993-abc8-0b54a36bad1b__thousandSplendidSuns.jpg │ └── e9b319cc-e501-4f90-b608-74052d770e2d__theBusinessBook.jpg ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── devd │ │ │ └── spring │ │ │ └── bookstorecatalogservice │ │ │ ├── BookstoreCatalogServiceApplication.java │ │ │ ├── config │ │ │ ├── AuthForwardInterceptor.java │ │ │ ├── ResourceServerConfig.java │ │ │ └── SwaggerConfig.java │ │ │ ├── controller │ │ │ ├── CatalogController.java │ │ │ ├── ImageUploadController.java │ │ │ ├── ProductCategoryController.java │ │ │ ├── ProductController.java │ │ │ └── ReviewController.java │ │ │ ├── model │ │ │ └── ProductResource.java │ │ │ ├── repository │ │ │ ├── ProductCategoryRepository.java │ │ │ ├── ProductRepository.java │ │ │ ├── ReviewRepository.java │ │ │ └── dao │ │ │ │ ├── Product.java │ │ │ │ ├── ProductCategory.java │ │ │ │ └── Review.java │ │ │ ├── service │ │ │ ├── ProductCategoryService.java │ │ │ ├── ProductService.java │ │ │ ├── ReviewService.java │ │ │ └── impl │ │ │ │ ├── ProductCategoryServiceImpl.java │ │ │ │ ├── ProductServiceImpl.java │ │ │ │ └── ReviewServiceImpl.java │ │ │ └── web │ │ │ ├── CreateOrUpdateReviewRequest.java │ │ │ ├── CreateProductCategoryRequest.java │ │ │ ├── CreateProductRequest.java │ │ │ ├── ProductCategoriesPagedResponse.java │ │ │ ├── ProductResponse.java │ │ │ ├── ProductsPagedResponse.java │ │ │ ├── UpdateProductCategoryRequest.java │ │ │ └── UpdateProductRequest.java │ └── resources │ │ ├── application.yml │ │ ├── bootstrap.yml │ │ ├── db │ │ └── migration │ │ │ ├── V1__catalog_service_schema.sql │ │ │ └── V2__catalog_service_initial_data.sql │ │ ├── jwt-signing-public-key.txt │ │ └── logback-spring.xml │ └── test │ └── java │ └── com │ └── devd │ └── spring │ └── bookstorecatalogservice │ └── BookstoreCatalogServiceApplicationTests.java ├── bookstore-commons ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── devd │ └── spring │ └── bookstorecommons │ ├── config │ ├── AuditingConfig.java │ └── CommonConfig.java │ ├── exception │ ├── Error.java │ ├── ErrorResponse.java │ ├── GlobalExceptionHandler.java │ └── RunTimeExceptionPlaceHolder.java │ ├── security │ ├── GlobalResourceServerConfig.java │ ├── GlobalSecurityConfig.java │ └── SimpleCorsFilter.java │ └── util │ ├── CommonUtilityMethods.java │ └── DateAudit.java ├── bookstore-eureka-discovery-service ├── Dockerfile ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── devd │ │ └── spring │ │ └── bookstoreeurekadiscoveryservice │ │ └── BookstoreEurekaDiscoveryServiceApplication.java │ └── resources │ ├── application.yml │ ├── bootstrap.yml │ └── logback-spring.xml ├── bookstore-feign ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── devd │ └── spring │ └── bookstorecommons │ ├── config │ └── FeignConfig.java │ ├── feign │ ├── AccountFeignClient.java │ ├── BillingFeignClient.java │ ├── CatalogFeignClient.java │ ├── OrderFeignClient.java │ └── PaymentFeignClient.java │ └── web │ ├── CreatePaymentRequest.java │ ├── CreatePaymentResponse.java │ ├── GetAddressResponse.java │ ├── GetPaymentMethodResponse.java │ ├── GetProductResponse.java │ ├── GetUserInfoResponse.java │ └── GetUserResponse.java ├── bookstore-frontend-react-app ├── .eslintrc.json ├── .gitignore ├── .prettierrc.json ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt ├── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── actions │ │ ├── addressActions.js │ │ ├── cartActions.js │ │ ├── orderActions.js │ │ ├── paymentActions.js │ │ ├── productActions.js │ │ └── userActions.js │ ├── bootstrap.min.css │ ├── components │ │ ├── CartItem.js │ │ ├── CheckoutSteps.js │ │ ├── Footer.js │ │ ├── FormContainer.js │ │ ├── FullPageLoader.js │ │ ├── Header.js │ │ ├── Loader.js │ │ ├── Message.js │ │ ├── OrderItem.js │ │ ├── Paginate.js │ │ ├── Product.js │ │ └── Rating.js │ ├── constants │ │ ├── addressConstants.js │ │ ├── appConstants.js │ │ ├── cartConstants.js │ │ ├── orderConstants.js │ │ ├── paymentConstants.js │ │ ├── productConstants.js │ │ └── userConstants.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reducers │ │ ├── addressReducer.js │ │ ├── cartReducers.js │ │ ├── orderReducers.js │ │ ├── paymentReducers.js │ │ ├── productReducers.js │ │ └── userReducers.js │ ├── reportWebVitals.js │ ├── screens │ │ ├── CartScreen.js │ │ ├── HomeScreen.js │ │ ├── LoginScreen.js │ │ ├── OrderListScreen.js │ │ ├── OrderScreen.js │ │ ├── PaymentScreen.js │ │ ├── PlaceOrderScreen.js │ │ ├── ProductCreateScreen.js │ │ ├── ProductEditScreen.js │ │ ├── ProductListScreen.js │ │ ├── ProductScreen.js │ │ ├── ProfileScreen.js │ │ ├── RegisterScreen.js │ │ ├── ShippingScreen.js │ │ ├── UserEditScreen.js │ │ └── UserListScreen.js │ ├── service │ │ ├── CommonUtils.js │ │ └── RestApiCalls.js │ ├── setupTests.js │ └── store.js └── yarn.lock ├── bookstore-graphana ├── Dockerfile ├── dashboard.yml ├── datasource.yml ├── docker-all-dashboard.json ├── docker-container-dashboard.json └── services-dashboard.json ├── bookstore-order-service ├── .gitignore ├── Dockerfile ├── dockerize ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── devd │ │ │ └── spring │ │ │ └── bookstoreorderservice │ │ │ ├── BookstoreOrderServiceApplication.java │ │ │ ├── config │ │ │ ├── AuthForwardInterceptor.java │ │ │ ├── OrderServiceConfig.java │ │ │ ├── OrderServiceResourceServerConfig.java │ │ │ └── SwaggerConfig.java │ │ │ ├── controller │ │ │ ├── CartController.java │ │ │ ├── CartItemController.java │ │ │ └── OrderController.java │ │ │ ├── repository │ │ │ ├── CartItemRepository.java │ │ │ ├── CartRepository.java │ │ │ ├── OrderBillingAddressRepository.java │ │ │ ├── OrderItemRepository.java │ │ │ ├── OrderRepository.java │ │ │ ├── OrderShippingAddressRepository.java │ │ │ └── dao │ │ │ │ ├── Cart.java │ │ │ │ ├── CartItem.java │ │ │ │ ├── Order.java │ │ │ │ ├── OrderBillingAddress.java │ │ │ │ ├── OrderItem.java │ │ │ │ └── OrderShippingAddress.java │ │ │ ├── service │ │ │ ├── CartItemService.java │ │ │ ├── CartService.java │ │ │ ├── OrderService.java │ │ │ └── impl │ │ │ │ ├── CartItemServiceImpl.java │ │ │ │ ├── CartServiceImpl.java │ │ │ │ └── OrderServiceImpl.java │ │ │ └── web │ │ │ ├── Card.java │ │ │ ├── CartItemRequest.java │ │ │ ├── CreateCartResponse.java │ │ │ ├── CreateOrderRequest.java │ │ │ ├── CreateOrderResponse.java │ │ │ ├── PreviewOrderRequest.java │ │ │ └── PreviewOrderResponse.java │ └── resources │ │ ├── application.yml │ │ ├── bootstrap.yml │ │ ├── db │ │ └── migration │ │ │ ├── V1__order_service_schema.sql │ │ │ └── V2__order_service_initial_data.sql │ │ ├── jwt-signing-public-key.txt │ │ └── logback-spring.xml │ └── test │ └── java │ └── com │ └── devd │ └── spring │ └── bookstoreorderservice │ └── BookstoreOrderServiceApplicationTests.java ├── bookstore-payment-service ├── .gitignore ├── Dockerfile ├── dockerize ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── devd │ │ │ └── spring │ │ │ └── bookstorepaymentservice │ │ │ ├── BookstorePaymentServiceApplication.java │ │ │ ├── config │ │ │ ├── AuthForwardInterceptor.java │ │ │ ├── PaymentResourceServiceConfig.java │ │ │ ├── PaymentServiceConfig.java │ │ │ └── SwaggerConfig.java │ │ │ ├── controller │ │ │ ├── PaymentMethodController.java │ │ │ └── PaymentsController.java │ │ │ ├── repository │ │ │ ├── UserPaymentCustomerRepository.java │ │ │ └── dao │ │ │ │ └── UserPaymentCustomer.java │ │ │ ├── service │ │ │ ├── PaymentMethodService.java │ │ │ ├── PaymentsService.java │ │ │ └── impl │ │ │ │ ├── PaymentMethodServiceImpl.java │ │ │ │ └── PaymentsServiceImpl.java │ │ │ └── web │ │ │ ├── Card.java │ │ │ ├── CreatePaymentMethodRequest.java │ │ │ ├── CreatePaymentRequest.java │ │ │ ├── CreatePaymentResponse.java │ │ │ └── GetPaymentMethodResponse.java │ └── resources │ │ ├── application.yml │ │ ├── bootstrap.yml │ │ ├── db │ │ └── migration │ │ │ └── V1__payment-service-schema.sql │ │ ├── jwt-signing-public-key.txt │ │ └── logback-spring.xml │ └── test │ └── java │ └── com │ └── devd │ └── spring │ └── bookstorepaymentservice │ └── BookstorePaymentAddressServiceImplApplicationTests.java ├── bookstore-prometheus ├── Dockerfile └── prometheus.yml ├── bookstore-telegraph ├── Dockerfile ├── dockerize └── telegraf.conf ├── docker-compose.yml ├── images ├── 0547ab94-59f8-4352-b17b-0918d07913f2__pricePredudice.jpg ├── 1ecfd5c4-dba2-4feb-bd88-006105a8d5ab__alchemist.jpg ├── 25550dae-a893-4aa5-8b8f-967a91548fa5__oopWithCpp.jpg ├── 2603aa1d-3892-44cc-9481-fd485d80d270__businessAdventures.jpg ├── 27ba1db0-a5a3-477c-927c-7ceb36cf7ffa__theTimeMachine.jpg ├── 2b3ba80b-da93-4206-b50f-83008180a09e__sheHolmes.jpg ├── 3b315751-c5bd-4e73-aad2-df941826f453__The Great Indian Conspiracy.jpg ├── 46fb8d5b-2979-4c54-848f-512693b37818__52 Small Changes for the Mind- Improve Memory.jpg ├── 49935a41-7274-4b7f-9333-c3e85d59df18__belatedBacghelorparty.jpg ├── 4b050ba6-9573-4554-bdd4-26ae806c06aa__IntroEngLit.jpg ├── 622a7214-02cc-4f54-85fd-86fd8f3b6967__theScienceBook.jpg ├── 6a290abe-338f-4ece-8793-ccdd35a7745f__linux.jpg ├── 7d8b74e5-4321-4b49-9b2a-da4bf779d5be__theTheoryOfEverything.jpg ├── 8e6abb0e-180b-4e8e-856a-cb8491ff9454__greatGatsby.jpg ├── 8f8a275b-357e-4010-84dc-8d89bb5e2b95__Politics for Beginners.jpg ├── 990945b7-900e-432b-9b2c-79ea20302f6e__Productivity Superhero.jpg ├── ad5b1926-05ad-4aae-852d-f152ea838648__programmingInJava.jpg ├── af75f363-fdb9-4d8e-8066-6215f0520e9b__corePythonProg.jpg ├── b1175b20-e946-42a6-b63d-83e35b7a73fa__oneArrangedMurder.jpg ├── b9685c28-7f97-4fb7-9cf0-927ff3afc8f1__spaceEncyclo.jpg ├── c16108e1-8276-41ad-bf12-4aee4c0a7e65__IndModernLiterature.jpg ├── cad39d84-60aa-496d-9295-c3f47ec957fa__programmingInC.jpg ├── cef7540f-0810-4323-9950-98c5d8d5099d__Chandra Shekhar- The Last Icon of Ideological Politics.jpg ├── e6602eb6-3f67-4993-abc8-0b54a36bad1b__thousandSplendidSuns.jpg └── e9b319cc-e501-4f90-b608-74052d770e2d__theBusinessBook.jpg └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | */target/ 3 | /target/ 4 | !.mvn/wrapper/maven-wrapper.jar 5 | 6 | ### STS ### 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | .sts4-cache 14 | 15 | ### IntelliJ IDEA ### 16 | .idea 17 | *.idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | /build/ 29 | 30 | ### VS Code ### 31 | *.vscode/ 32 | *.mvn 33 | */Logs 34 | /Logs -------------------------------------------------------------------------------- /Bookstore Project AWS Architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/Bookstore Project AWS Architecture.jpg -------------------------------------------------------------------------------- /bookstore-account-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | 3 | VOLUME /tmp 4 | 5 | ARG JAR_FILE 6 | 7 | COPY target/${JAR_FILE} account-service.jar 8 | 9 | #Using Dokerize to check whether db is up, if it is then start this service. 10 | COPY dockerize dockerize 11 | 12 | CMD ./dockerize -wait tcp://bookstore-mysql-db:3306 -timeout 15m java -Djava.security.egd=file:/dev/./urandom -jar /account-service.jar -------------------------------------------------------------------------------- /bookstore-account-service/dockerize: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-account-service/dockerize -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/BookstoreAccountServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice; 2 | 3 | import com.devd.spring.bookstorecommons.security.GlobalResourceServerConfig; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.cloud.openfeign.EnableFeignClients; 8 | import org.springframework.context.annotation.ComponentScan; 9 | import org.springframework.context.annotation.FilterType; 10 | 11 | /** 12 | * @author: Devaraj Reddy, Date : 2019-05-16 13 | */ 14 | @SpringBootApplication 15 | @ComponentScan(basePackages = {"com.devd.spring"}, excludeFilters = { 16 | @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = GlobalResourceServerConfig.class)}) 17 | @EnableFeignClients 18 | @EnableDiscoveryClient 19 | public class BookstoreAccountServiceApplication { 20 | 21 | public static void main(String[] args) { 22 | SpringApplication.run(BookstoreAccountServiceApplication.class, args); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/config/AccountServiceConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | 5 | /** 6 | * @author: Devaraj Reddy, Date : 2019-07-14 7 | */ 8 | @Configuration 9 | public class AccountServiceConfig { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/config/AuthForwardInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.config; 2 | 3 | import feign.RequestInterceptor; 4 | import feign.RequestTemplate; 5 | import java.util.Objects; 6 | import javax.servlet.http.HttpServletRequest; 7 | import org.springframework.http.HttpHeaders; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.context.request.RequestContextHolder; 10 | import org.springframework.web.context.request.ServletRequestAttributes; 11 | 12 | /** 13 | * @author: Devaraj Reddy, Date : 2019-07-02 14 | */ 15 | 16 | /* 17 | This is required for Feign clients to make request to services. 18 | It takes the token from header and set the header in the feign request header. 19 | */ 20 | @Component 21 | public class AuthForwardInterceptor implements RequestInterceptor { 22 | 23 | @Override 24 | public void apply(RequestTemplate template) { 25 | HttpServletRequest request = ((ServletRequestAttributes) Objects 26 | .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); 27 | template.header(HttpHeaders.AUTHORIZATION, request.getHeader(HttpHeaders.AUTHORIZATION)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/config/ResourceServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.http.HttpMethod; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 8 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 9 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; 10 | import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; 11 | 12 | @Configuration 13 | @EnableResourceServer 14 | public class ResourceServerConfig extends ResourceServerConfigurerAdapter { 15 | 16 | @Autowired 17 | private ResourceServerTokenServices tokenServices; 18 | 19 | @Override 20 | public void configure(ResourceServerSecurityConfigurer resources) throws Exception { 21 | resources.resourceId("web").tokenServices(tokenServices); 22 | } 23 | 24 | @Override 25 | public void configure(HttpSecurity http) throws Exception { 26 | http 27 | .cors() 28 | .and() 29 | .headers() 30 | .frameOptions() 31 | .disable() 32 | .and() 33 | .requestMatchers() 34 | .and() 35 | .authorizeRequests() 36 | .antMatchers("/actuator/**", "/api-docs/**", "/h2-console/**", "/signin", "/authorize", "/signup").permitAll() 37 | .antMatchers(HttpMethod.POST, "/oauth/token").permitAll() 38 | .antMatchers("/**").authenticated(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/controller/AuthController.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.controller; 2 | 3 | import com.devd.spring.bookstoreaccountservice.service.AuthService; 4 | import com.devd.spring.bookstoreaccountservice.web.CreateOAuthClientRequest; 5 | import com.devd.spring.bookstoreaccountservice.web.CreateOAuthClientResponse; 6 | import com.devd.spring.bookstoreaccountservice.web.CreateUserResponse; 7 | import com.devd.spring.bookstoreaccountservice.web.SignUpRequest; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.security.access.prepost.PreAuthorize; 12 | import org.springframework.web.bind.annotation.CrossOrigin; 13 | import org.springframework.web.bind.annotation.PostMapping; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.RestController; 16 | 17 | import javax.validation.Valid; 18 | 19 | /** 20 | * @author: Devaraj Reddy, Date : 2019-05-18 21 | */ 22 | @RestController 23 | @CrossOrigin 24 | public class AuthController { 25 | 26 | @Autowired 27 | AuthService authService; 28 | 29 | @PostMapping("/client") 30 | @PreAuthorize("hasAuthority('ADMIN_USER')") 31 | public ResponseEntity createOAuthClient( 32 | @Valid @RequestBody CreateOAuthClientRequest createOAuthClientRequest) { 33 | 34 | CreateOAuthClientResponse oAuthClient = authService.createOAuthClient(createOAuthClientRequest); 35 | return new ResponseEntity<>(oAuthClient, HttpStatus.CREATED); 36 | } 37 | 38 | @PostMapping("/signup") 39 | public ResponseEntity registerUser(@Valid @RequestBody SignUpRequest signUpRequest) { 40 | 41 | CreateUserResponse createUserResponse = authService.registerUser(signUpRequest); 42 | 43 | return new ResponseEntity<>(createUserResponse, HttpStatus.CREATED); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/controller/RoleController.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.controller; 2 | 3 | import com.devd.spring.bookstoreaccountservice.repository.dao.Role; 4 | import com.devd.spring.bookstoreaccountservice.service.RoleService; 5 | import com.devd.spring.bookstoreaccountservice.web.CreateRoleRequest; 6 | import java.net.URI; 7 | import java.util.List; 8 | import javax.validation.Valid; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.security.access.prepost.PreAuthorize; 12 | import org.springframework.web.bind.annotation.GetMapping; 13 | import org.springframework.web.bind.annotation.PostMapping; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.RestController; 16 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 17 | 18 | /** 19 | * @author: Devaraj Reddy, Date : 2019-06-30 20 | */ 21 | @RestController 22 | public class RoleController { 23 | 24 | @Autowired 25 | private RoleService roleService; 26 | 27 | @PostMapping("/role") 28 | @PreAuthorize("hasAuthority('ADMIN_USER')") 29 | public ResponseEntity createRole(@RequestBody @Valid CreateRoleRequest createRoleRequest) { 30 | 31 | String userId = roleService.createRole(createRoleRequest); 32 | 33 | URI location = ServletUriComponentsBuilder 34 | .fromCurrentRequest().path("/{roleId}") 35 | .buildAndExpand(userId).toUri(); 36 | 37 | return ResponseEntity.created(location).build(); 38 | } 39 | 40 | @GetMapping("/roles") 41 | @PreAuthorize("hasAuthority('ADMIN_USER')") 42 | public ResponseEntity getAllRoles() { 43 | List allRoles = roleService.getAllRoles(); 44 | return ResponseEntity.ok(allRoles); 45 | 46 | } 47 | 48 | //TODO CRUD for role 49 | } 50 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/controller/UserRoleController.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.controller; 2 | 3 | import com.devd.spring.bookstoreaccountservice.service.UserRoleService; 4 | import com.devd.spring.bookstoreaccountservice.web.MapRoleToUsersRequest; 5 | import com.devd.spring.bookstoreaccountservice.web.MapUserToRolesRequest; 6 | import javax.validation.Valid; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | /** 14 | * @author: Devaraj Reddy, Date : 2019-06-30 15 | */ 16 | @RestController 17 | public class UserRoleController { 18 | 19 | @Autowired 20 | UserRoleService userRoleService; 21 | 22 | @PostMapping("/user/{userNameOrEmail}/roles") 23 | public void mapUserToRoles(@PathVariable("userNameOrEmail") String userNameOrEmail, 24 | @RequestBody @Valid MapUserToRolesRequest mapUserToRolesRequest) { 25 | 26 | userRoleService.mapUserToRoles(userNameOrEmail, mapUserToRolesRequest); 27 | 28 | } 29 | 30 | @PostMapping("/role/{roleName}/users") 31 | public void mapRoleToUsers(@PathVariable("roleName") String roleName, 32 | @RequestBody @Valid MapRoleToUsersRequest mapRoleToUsersRequest) { 33 | 34 | userRoleService.mapRoleToUsers(roleName, mapRoleToUsersRequest); 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/exception/SuccessCodeWithErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.exception; 2 | 3 | import com.devd.spring.bookstorecommons.exception.ErrorResponse; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @author: Devaraj Reddy, Date : 2019-06-30 8 | */ 9 | public class SuccessCodeWithErrorResponse extends RuntimeException { 10 | 11 | @Getter 12 | private ErrorResponse errorResponse; 13 | 14 | @Getter 15 | private String id; 16 | 17 | public SuccessCodeWithErrorResponse(String id, ErrorResponse errorResponse) { 18 | this.id = id; 19 | this.errorResponse = errorResponse; 20 | } 21 | 22 | public SuccessCodeWithErrorResponse(ErrorResponse errorResponse) { 23 | this.errorResponse = errorResponse; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/repository/OAuthClientRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.repository; 2 | 3 | import com.devd.spring.bookstoreaccountservice.repository.dao.OAuthClient; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | /** 7 | * @author: Devaraj Reddy, Date : 2019-05-18 8 | */ 9 | public interface OAuthClientRepository extends CrudRepository { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/repository/RoleRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.repository; 2 | 3 | import com.devd.spring.bookstoreaccountservice.repository.dao.Role; 4 | import java.util.List; 5 | import java.util.Optional; 6 | import org.springframework.data.repository.CrudRepository; 7 | 8 | /** 9 | * @author: Devaraj Reddy, Date : 2019-05-17 10 | */ 11 | public interface RoleRepository extends CrudRepository { 12 | 13 | Optional findByRoleName(String name); 14 | 15 | Boolean existsByRoleName(String roleName); 16 | 17 | @Override 18 | List findAll(); 19 | } 20 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.repository; 2 | 3 | 4 | import com.devd.spring.bookstoreaccountservice.repository.dao.User; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | import org.springframework.data.repository.CrudRepository; 9 | 10 | import javax.transaction.Transactional; 11 | 12 | /** 13 | * @author: Devaraj Reddy, Date : 2019-05-17 14 | */ 15 | @Transactional 16 | public interface UserRepository extends CrudRepository { 17 | 18 | Optional findByUserName(String username); 19 | 20 | Optional findByUserNameOrEmail(String uName, String eMail); 21 | 22 | Optional findByUserId(String userId); 23 | 24 | void deleteByUserId(String userId); 25 | 26 | Boolean existsByUserName(String userName); 27 | 28 | Boolean existsByEmail(String email); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/repository/dao/OAuthClient.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.repository.dao; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Entity; 5 | import javax.persistence.GeneratedValue; 6 | import javax.persistence.Id; 7 | import javax.persistence.Table; 8 | 9 | import com.devd.spring.bookstorecommons.util.DateAudit; 10 | import lombok.AllArgsConstructor; 11 | import lombok.Builder; 12 | import lombok.Data; 13 | import lombok.NoArgsConstructor; 14 | import org.hibernate.annotations.GenericGenerator; 15 | 16 | /** 17 | * @author: Devaraj Reddy, Date : 2019-05-18 18 | */ 19 | @Data 20 | @NoArgsConstructor 21 | @AllArgsConstructor 22 | @Entity 23 | @Table(name = "oauth_client_details") 24 | @Builder 25 | public class OAuthClient extends DateAudit { 26 | 27 | @Id 28 | @GeneratedValue(generator = "uuid") 29 | @GenericGenerator(name = "uuid", strategy = "uuid2") 30 | @Column(name = "CLIENT_ID", updatable = false, nullable = false) 31 | private String client_id; 32 | 33 | @Column(name = "CLIENT_SECRET", updatable = false, nullable = false) 34 | private String client_secret; 35 | private String authorized_grant_types; 36 | private String authorities; 37 | private String scope; 38 | private String resource_ids; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/repository/dao/Role.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.repository.dao; 2 | 3 | import com.devd.spring.bookstorecommons.util.DateAudit; 4 | import com.fasterxml.jackson.annotation.JsonIgnore; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | import javax.persistence.CascadeType; 8 | import javax.persistence.Column; 9 | import javax.persistence.Entity; 10 | import javax.persistence.FetchType; 11 | import javax.persistence.GeneratedValue; 12 | import javax.persistence.Id; 13 | import javax.persistence.ManyToMany; 14 | import javax.persistence.Table; 15 | import lombok.AllArgsConstructor; 16 | import lombok.Builder; 17 | import lombok.Getter; 18 | import lombok.NoArgsConstructor; 19 | import lombok.Setter; 20 | import org.hibernate.annotations.GenericGenerator; 21 | 22 | /** 23 | * @author: Devaraj Reddy, Date : 2019-05-17 24 | */ 25 | @Getter 26 | @Setter 27 | @NoArgsConstructor 28 | @AllArgsConstructor 29 | @Entity 30 | @Table(name = "ROLE") 31 | @Builder 32 | public class Role extends DateAudit { 33 | 34 | @Id 35 | @GeneratedValue(generator = "uuid") 36 | @GenericGenerator(name = "uuid", strategy = "uuid2") 37 | @Column(name = "ROLE_ID", updatable = false, nullable = false) 38 | private String id; 39 | 40 | @Column(name = "ROLE_NAME", nullable = false) 41 | private String roleName; 42 | 43 | @ManyToMany(fetch = FetchType.LAZY, 44 | cascade = CascadeType.ALL, 45 | mappedBy = "roles") 46 | @JsonIgnore 47 | private Set users = new HashSet<>(); 48 | 49 | @Column(name = "ROLE_DESCRIPTION") 50 | private String roleDescription; 51 | 52 | public void addUser(User user) { 53 | this.users.add(user); 54 | user.getRoles().add(this); 55 | } 56 | 57 | public void removeUser(User user) { 58 | this.users.remove(user); 59 | user.getRoles().remove(this); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/service/AppUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.service; 2 | 3 | import org.springframework.security.core.userdetails.UserDetails; 4 | import org.springframework.security.core.userdetails.UserDetailsService; 5 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 6 | 7 | /** 8 | * @author: Devaraj Reddy, Date : 2019-09-27 9 | */ 10 | public interface AppUserDetailsService extends UserDetailsService { 11 | 12 | @Override 13 | UserDetails loadUserByUsername(String userNameOrEmail) throws UsernameNotFoundException; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/service/AuthService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.service; 2 | 3 | import com.devd.spring.bookstoreaccountservice.web.CreateOAuthClientRequest; 4 | import com.devd.spring.bookstoreaccountservice.web.CreateOAuthClientResponse; 5 | import com.devd.spring.bookstoreaccountservice.web.CreateUserResponse; 6 | import com.devd.spring.bookstoreaccountservice.web.SignInRequest; 7 | import com.devd.spring.bookstoreaccountservice.web.SignUpRequest; 8 | 9 | /** 10 | * @author: Devaraj Reddy, Date : 2019-09-27 11 | */ 12 | public interface AuthService { 13 | 14 | CreateOAuthClientResponse createOAuthClient(CreateOAuthClientRequest createOAuthClientRequest); 15 | 16 | CreateUserResponse registerUser(SignUpRequest signUpRequest); 17 | } 18 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/service/RoleService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.service; 2 | 3 | import com.devd.spring.bookstoreaccountservice.repository.dao.Role; 4 | import com.devd.spring.bookstoreaccountservice.web.CreateRoleRequest; 5 | import java.util.List; 6 | 7 | /** 8 | * @author: Devaraj Reddy, Date : 2019-09-27 9 | */ 10 | public interface RoleService { 11 | 12 | String createRole(CreateRoleRequest createRoleRequest); 13 | 14 | List getAllRoles(); 15 | } 16 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/service/UserRoleService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.service; 2 | 3 | import com.devd.spring.bookstoreaccountservice.web.MapRoleToUsersRequest; 4 | import com.devd.spring.bookstoreaccountservice.web.MapUserToRolesRequest; 5 | 6 | /** 7 | * @author: Devaraj Reddy, Date : 2019-09-27 8 | */ 9 | public interface UserRoleService { 10 | 11 | void mapUserToRoles(String userNameOrEmail, MapUserToRolesRequest mapUserToRolesRequest); 12 | 13 | void removeRolesFromUser(String userNameOrEmail, MapUserToRolesRequest mapUserToRolesRequest); 14 | 15 | void mapRoleToUsers(String roleName, MapRoleToUsersRequest mapRoleToUsersRequest); 16 | } 17 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.service; 2 | 3 | import com.devd.spring.bookstoreaccountservice.web.CreateUserRequest; 4 | import com.devd.spring.bookstoreaccountservice.web.GetUserInfoResponse; 5 | import com.devd.spring.bookstoreaccountservice.web.GetUserResponse; 6 | import com.devd.spring.bookstoreaccountservice.web.UpdateUserRequest; 7 | import com.devd.spring.bookstoreaccountservice.web.UpdateUserRequestFromAdmin; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author: Devaraj Reddy, Date : 2019-09-27 13 | */ 14 | public interface UserService { 15 | 16 | String createUser(CreateUserRequest createUserRequest); 17 | 18 | GetUserResponse getUserByUserName(String userName); 19 | 20 | GetUserResponse getUserByUserId(String userId); 21 | 22 | GetUserInfoResponse getUserInfo(); 23 | 24 | void updateUserInfo(UpdateUserRequest updateUserRequest); 25 | 26 | void deleteUserById(String userId); 27 | 28 | List getAllUsers(); 29 | 30 | void updateUser(String userId, UpdateUserRequestFromAdmin updateUserRequestFromAdmin); 31 | } 32 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/service/impl/AppUserDetailsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.service.impl; 2 | 3 | import com.devd.spring.bookstoreaccountservice.repository.UserRepository; 4 | import com.devd.spring.bookstoreaccountservice.repository.dao.User; 5 | import com.devd.spring.bookstoreaccountservice.service.AppUserDetailsService; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Optional; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.security.core.GrantedAuthority; 11 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 12 | import org.springframework.security.core.userdetails.UserDetails; 13 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 14 | import org.springframework.stereotype.Service; 15 | 16 | /** 17 | * @author: Devaraj Reddy, Date : 2019-04-22 20:08 18 | */ 19 | @Service 20 | public class AppUserDetailsServiceImpl implements AppUserDetailsService { 21 | 22 | @Autowired 23 | private UserRepository userRepository; 24 | 25 | @Override 26 | public UserDetails loadUserByUsername(String userNameOrEmail) throws UsernameNotFoundException { 27 | 28 | Optional userOptional = userRepository 29 | .findByUserNameOrEmail(userNameOrEmail, userNameOrEmail); 30 | 31 | User user = userOptional.orElseThrow(() -> 32 | new UsernameNotFoundException(String.format("The username or email Id %s doesn't exist", 33 | userNameOrEmail)) 34 | ); 35 | 36 | List authorities = new ArrayList<>(); 37 | user.getRoles().forEach(role -> { 38 | authorities.add(new SimpleGrantedAuthority(role.getRoleName())); 39 | }); 40 | 41 | UserDetails userDetails = new org.springframework.security.core.userdetails. 42 | User(user.getUserName(), user.getPassword(), authorities); 43 | 44 | return userDetails; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/service/impl/RoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.service.impl; 2 | 3 | import com.devd.spring.bookstoreaccountservice.repository.RoleRepository; 4 | import com.devd.spring.bookstoreaccountservice.repository.dao.Role; 5 | import com.devd.spring.bookstoreaccountservice.service.RoleService; 6 | import com.devd.spring.bookstoreaccountservice.web.CreateRoleRequest; 7 | import java.util.List; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | 11 | /** 12 | * @author: Devaraj Reddy, Date : 2019-06-30 13 | */ 14 | @Service 15 | public class RoleServiceImpl implements RoleService { 16 | 17 | @Autowired 18 | RoleRepository roleRepository; 19 | 20 | 21 | @Override 22 | public String createRole(CreateRoleRequest createRoleRequest) { 23 | 24 | Role role = Role.builder() 25 | .roleName(createRoleRequest.getRoleName()) 26 | .roleDescription(createRoleRequest.getRoleDescription()) 27 | .build(); 28 | 29 | Role savedRole = roleRepository.save(role); 30 | return savedRole.getId(); 31 | } 32 | 33 | @Override 34 | public List getAllRoles() { 35 | List allRoles = roleRepository.findAll(); 36 | return allRoles; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/CreateOAuthClientRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import java.util.List; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, Date : 2019-06-30 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class CreateOAuthClientRequest { 15 | 16 | private List authorized_grant_types; 17 | private List authorities; 18 | private List scope; 19 | private List resource_ids; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/CreateOAuthClientResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, Date : 2019-06-30 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder 15 | public class CreateOAuthClientResponse { 16 | 17 | private String client_id; 18 | private String client_secret; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/CreateRoleRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import javax.validation.constraints.NotBlank; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | /** 10 | * @author: Devaraj Reddy, Date : 2019-06-30 11 | */ 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class CreateRoleRequest{ 16 | 17 | @NotBlank 18 | private String roleName; 19 | @NotBlank 20 | private String roleDescription; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/CreateUserRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import java.util.List; 4 | import javax.validation.constraints.Email; 5 | import javax.validation.constraints.NotBlank; 6 | import javax.validation.constraints.Size; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | /** 12 | * @author: Devaraj Reddy, Date : 2019-06-30 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class CreateUserRequest { 18 | 19 | private String userId; 20 | 21 | @NotBlank 22 | @Size(max = 40, message = "UserName length should not be grater than 40 characters") 23 | private String userName; 24 | 25 | @NotBlank 26 | @Size(min = 6, max = 20, message = "password length should not be between 6 and 20 characters") 27 | private String password; 28 | 29 | @NotBlank 30 | @Size(max = 40, message = "First Name length should not be grater than 40 characters") 31 | private String firstName; 32 | 33 | private String lastName; 34 | 35 | @NotBlank 36 | @Size(max = 40, message = "email length should not be grater than 40 characters") 37 | @Email 38 | private String email; 39 | 40 | private List roleNames; 41 | } 42 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/CreateUserResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, Date : 2019-06-30 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder 15 | public class CreateUserResponse { 16 | 17 | private String userId; 18 | private String userName; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/GetUserInfoResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, Date : 2019-10-07 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder 15 | public class GetUserInfoResponse { 16 | 17 | private String userId; 18 | private String userName; 19 | private String firstName; 20 | private String lastName; 21 | private String email; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/GetUserResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import com.devd.spring.bookstoreaccountservice.repository.dao.Role; 4 | import java.util.Set; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @author: Devaraj Reddy, Date : 2019-10-07 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @Builder 17 | public class GetUserResponse { 18 | 19 | private String userId; 20 | private String userName; 21 | private String firstName; 22 | private String lastName; 23 | private String email; 24 | private Set roles; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/JwtAuthenticationResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import lombok.Value; 4 | 5 | /** 6 | * @author devaraj.reddy 7 | */ 8 | @Value 9 | public class JwtAuthenticationResponse { 10 | 11 | private String access_token; 12 | private String token_type = "Bearer"; 13 | private String refresh_token; 14 | private Long expires_in; 15 | } 16 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/MapRoleToUsersRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import java.util.List; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, Date : 2019-07-01 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class MapRoleToUsersRequest { 15 | 16 | private List userNames; 17 | } 18 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/MapUserToRolesRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import java.util.List; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, Date : 2019-07-01 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class MapUserToRolesRequest { 15 | 16 | private List roleNames; 17 | } 18 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/SignInRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import javax.validation.constraints.NotBlank; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, Date : 2019-05-20 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class SignInRequest { 15 | 16 | @NotBlank 17 | private String usernameOrEmail; 18 | 19 | @NotBlank 20 | private String password; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/SignUpRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import javax.validation.constraints.Email; 4 | import javax.validation.constraints.NotBlank; 5 | import javax.validation.constraints.Size; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @author: Devaraj Reddy, Date : 2019-05-20 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class SignUpRequest { 17 | 18 | private String userId; 19 | 20 | @NotBlank 21 | @Size(max = 40, message = "UserName length should not be grater than 40 characters") 22 | private String userName; 23 | 24 | @NotBlank 25 | @Size(min = 6, max = 20, message = "password length should not be between 6 and 20 characters") 26 | private String password; 27 | 28 | @NotBlank 29 | @Size(max = 40, message = "First Name length should not be grater than 40 characters") 30 | private String firstName; 31 | 32 | private String lastName; 33 | 34 | @NotBlank 35 | @Size(max = 40, message = "email length should not be grater than 40 characters") 36 | @Email 37 | private String email; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/UpdateUserRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.validation.constraints.Email; 8 | import javax.validation.constraints.Size; 9 | 10 | /** 11 | * @author: Devaraj Reddy, Date : 2019-06-30 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class UpdateUserRequest { 17 | 18 | @Size(min = 6, max = 20, message = "password length should not be between 6 and 20 characters") 19 | private String password; 20 | 21 | @Size(max = 40, message = "First Name length should not be grater than 40 characters") 22 | private String firstName; 23 | 24 | private String lastName; 25 | 26 | @Size(max = 40, message = "email length should not be grater than 40 characters") 27 | @Email 28 | private String email; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/web/UpdateUserRequestFromAdmin.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.validation.constraints.Email; 8 | import javax.validation.constraints.Size; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | /** 13 | * @author: Devaraj Reddy, Date : 2019-06-30 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class UpdateUserRequestFromAdmin { 19 | 20 | @Size(max = 40, message = "First Name length should not be grater than 40 characters") 21 | private String firstName; 22 | 23 | private String lastName; 24 | 25 | @Size(max = 40, message = "email length should not be grater than 40 characters") 26 | @Email 27 | private String email; 28 | 29 | private List roles = new ArrayList<>(); 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /bookstore-account-service/src/main/resources/JWTKeystore.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-account-service/src/main/resources/JWTKeystore.p12 -------------------------------------------------------------------------------- /bookstore-account-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: bookstore-account-service 4 | profiles: 5 | active: ${SPRING_PROFILES_ACTIVE:local} 6 | 7 | management: 8 | endpoints: 9 | web: 10 | exposure: 11 | include: "*" 12 | 13 | --- 14 | 15 | spring: 16 | profiles: local, mysql 17 | cloud: 18 | bus: 19 | enabled: false 20 | consul: 21 | enabled: false #consul discovery set false, in this profile eureka discovery is enabled. 22 | 23 | eureka: 24 | client: 25 | serviceUrl: 26 | defaultZone: http://${EUREKA_HOST:localhost:8761}/eureka/ 27 | registerWithEureka: true 28 | enabled: true #eureka discovery is enabled in this profile 29 | instance: 30 | prefer-ip-address: false 31 | 32 | management: 33 | metrics: 34 | export: 35 | influx: 36 | enabled: false #influx metrics not pushing in this profile 37 | 38 | --- 39 | 40 | spring: 41 | profiles: docker 42 | cloud: 43 | consul: 44 | host: bookstore-consul-discovery 45 | port: 8500 46 | discovery: 47 | instanceId: ${spring.application.name}:${random.value} 48 | enabled: true #consul discovery is enabled in this profile 49 | 50 | management: 51 | metrics: 52 | export: 53 | statsd: 54 | enabled: true 55 | flavor: telegraf 56 | port: 8125 57 | influx: #pushing influx metrics. 58 | db: bookstore_influxdb_monitoring_metrics 59 | uri: http://bookstore-influxdb:8086 60 | auto-create-db: true 61 | endpoints: 62 | web: 63 | exposure: 64 | include: "*" 65 | 66 | eureka: 67 | client: 68 | enabled: false #eureka discovery set false, in this profile consul discovery is enabled. -------------------------------------------------------------------------------- /bookstore-account-service/src/main/resources/jwt-signing-public-key.txt: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0sp8Cy1+sJgJLToO9FvW 3 | cY4AXnp027T0diFOv8cjxD+KESAmZ7cL1jy91nQASn7dCM5qNL5KzJGrp43fIbf+ 4 | HzRv4snj7NoDF5UzgI/fJ/AA3BoIyhkt0QkiKEe2kQFbIfrD5RSHvjLecRnkV71i 5 | A27PqY+kk9QZ2TGTXoMKCADF8JIHHxf+RXVb/GdGi+zCWshXrvJsjR2ZayXFpNDf 6 | QrnsMj14Jxed16ioIdx8yf1fWZxHv9q+uev86CR4E8Xrwg0yJoYHpSdK1J4EvK35 7 | zA2gaGUcfgkZQS5M5bbhrZx1wy8N+8GNkYB0uDVZhnXc2xr4KBO7LGYeP0toA4rh 8 | 1wIDAQAB 9 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /bookstore-account-service/src/test/java/com/devd/spring/bookstoreaccountservice/BookstoreAccountServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreaccountservice; 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 | /** 9 | * @author: Devaraj Reddy, 10 | * Date : 2019-05-16 11 | */ 12 | @RunWith(SpringRunner.class) 13 | @SpringBootTest 14 | public class BookstoreAccountServiceApplicationTests { 15 | 16 | @Test 17 | public void contextLoads() { 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /bookstore-api-gateway-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | 3 | VOLUME /tmp 4 | 5 | ARG JAR_FILE 6 | 7 | COPY target/${JAR_FILE} gateway-server.jar 8 | 9 | ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/gateway-server.jar"] -------------------------------------------------------------------------------- /bookstore-api-gateway-service/src/main/java/com/devd/spring/bookstoreapigatewayservice/BookstoreApiGatewayServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreapigatewayservice; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 7 | 8 | /** 9 | * @author: Devaraj Reddy, 10 | * Date : 2019-05-14 11 | */ 12 | @SpringBootApplication 13 | @EnableZuulProxy 14 | @EnableDiscoveryClient 15 | public class BookstoreApiGatewayServiceApplication { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(BookstoreApiGatewayServiceApplication.class, args); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /bookstore-api-gateway-service/src/main/java/com/devd/spring/bookstoreapigatewayservice/config/AddTraceIdToHttpResponseConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreapigatewayservice.config; 2 | 3 | import brave.Span; 4 | import brave.Tracer; 5 | import java.io.IOException; 6 | import javax.servlet.FilterChain; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.ServletRequest; 9 | import javax.servlet.ServletResponse; 10 | import javax.servlet.http.HttpServletResponse; 11 | import org.springframework.cloud.sleuth.instrument.web.TraceWebServletAutoConfiguration; 12 | import org.springframework.core.annotation.Order; 13 | import org.springframework.stereotype.Component; 14 | import org.springframework.web.filter.GenericFilterBean; 15 | 16 | /** 17 | * @author: Devaraj Reddy, Date : 2019-10-05 18 | */ 19 | @Component 20 | @Order(TraceWebServletAutoConfiguration.TRACING_FILTER_ORDER + 1) 21 | public class AddTraceIdToHttpResponseConfig extends GenericFilterBean { 22 | 23 | private final Tracer tracer; 24 | 25 | AddTraceIdToHttpResponseConfig(Tracer tracer) { 26 | this.tracer = tracer; 27 | } 28 | 29 | @Override 30 | public void doFilter(ServletRequest request, ServletResponse response, 31 | FilterChain chain) throws IOException, ServletException { 32 | Span currentSpan = this.tracer.currentSpan(); 33 | if (currentSpan == null) { 34 | chain.doFilter(request, response); 35 | return; 36 | } 37 | // for readability we're returning trace id in a hex form 38 | ((HttpServletResponse) response).addHeader("ZIPKIN-TRACE-ID", 39 | currentSpan.context().traceIdString()); 40 | // we can also add some custom tags 41 | currentSpan.tag("custom", "tag"); 42 | chain.doFilter(request, response); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /bookstore-api-gateway-service/src/main/java/com/devd/spring/bookstoreapigatewayservice/config/ApiGatewayConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreapigatewayservice.config; 2 | 3 | import brave.sampler.Sampler; 4 | import com.devd.spring.bookstoreapigatewayservice.filters.PostFilter; 5 | import com.devd.spring.bookstoreapigatewayservice.filters.PreFilter; 6 | import com.devd.spring.bookstoreapigatewayservice.filters.RouteFilter; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * @author: Devaraj Reddy, 12 | * Date : 2019-05-15 13 | */ 14 | @Configuration 15 | public class ApiGatewayConfig { 16 | 17 | @Bean 18 | public Sampler sampler() { 19 | return Sampler.ALWAYS_SAMPLE; 20 | } 21 | 22 | @Bean 23 | public PreFilter preFilter() { 24 | return new PreFilter(); 25 | } 26 | 27 | @Bean 28 | public PostFilter postFilter() { 29 | return new PostFilter(); 30 | } 31 | 32 | @Bean 33 | public RouteFilter routeFilter() { 34 | return new RouteFilter(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /bookstore-api-gateway-service/src/main/java/com/devd/spring/bookstoreapigatewayservice/exception/Error.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreapigatewayservice.exception; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, Date : 2019-04-12 12:04 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder 15 | public class Error { 16 | 17 | private String code; 18 | private String message; 19 | } 20 | -------------------------------------------------------------------------------- /bookstore-api-gateway-service/src/main/java/com/devd/spring/bookstoreapigatewayservice/exception/ErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreapigatewayservice.exception; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.util.List; 9 | import java.util.UUID; 10 | 11 | /** 12 | * @author: Devaraj Reddy, Date : 2019-04-12 12:03 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Builder 18 | public class ErrorResponse { 19 | 20 | private UUID uuid; 21 | private List errors; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /bookstore-api-gateway-service/src/main/java/com/devd/spring/bookstoreapigatewayservice/exception/RunTimeExceptionPlaceHolder.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreapigatewayservice.exception; 2 | 3 | /** 4 | * @author: Devaraj Reddy, Date : 2019-05-20 5 | */ 6 | public class RunTimeExceptionPlaceHolder extends RuntimeException { 7 | 8 | int httpStatus; 9 | 10 | public RunTimeExceptionPlaceHolder(String message, int httpStatus) { 11 | super(message); 12 | this.httpStatus = httpStatus; 13 | } 14 | 15 | public int getHttpStatus() { 16 | return httpStatus; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /bookstore-api-gateway-service/src/main/java/com/devd/spring/bookstoreapigatewayservice/filters/PostFilter.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreapigatewayservice.filters; 2 | 3 | import com.netflix.zuul.ZuulFilter; 4 | import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; 5 | 6 | /** 7 | * @author: Devaraj Reddy, Date : 2019-10-02 8 | */ 9 | public class PostFilter extends ZuulFilter { 10 | 11 | @Override 12 | public String filterType() { 13 | return FilterConstants.POST_TYPE; 14 | } 15 | 16 | @Override 17 | public int filterOrder() { 18 | return 1; 19 | } 20 | 21 | @Override 22 | public boolean shouldFilter() { 23 | return true; 24 | } 25 | 26 | @Override 27 | public Object run() { 28 | System.out.println("Inside Response Filter"); 29 | return null; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /bookstore-api-gateway-service/src/main/java/com/devd/spring/bookstoreapigatewayservice/filters/PreFilter.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreapigatewayservice.filters; 2 | 3 | import com.netflix.zuul.ZuulFilter; 4 | import com.netflix.zuul.context.RequestContext; 5 | import javax.servlet.http.HttpServletRequest; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; 8 | 9 | /** 10 | * @author: Devaraj Reddy, 11 | * Date : 2019-05-14 22:12 12 | */ 13 | @Slf4j 14 | public class PreFilter extends ZuulFilter { 15 | 16 | @Override 17 | public String filterType() { 18 | return FilterConstants.PRE_TYPE; 19 | } 20 | 21 | @Override 22 | public int filterOrder() { 23 | return 1; 24 | } 25 | 26 | @Override 27 | public boolean shouldFilter() { 28 | return true; 29 | } 30 | 31 | @Override 32 | public Object run() { 33 | RequestContext ctx = RequestContext.getCurrentContext(); 34 | HttpServletRequest request = ctx.getRequest(); 35 | log.info("PreFilter: " + String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString())); 36 | return null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /bookstore-api-gateway-service/src/main/java/com/devd/spring/bookstoreapigatewayservice/filters/RouteFilter.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreapigatewayservice.filters; 2 | 3 | import com.netflix.zuul.ZuulFilter; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; 6 | 7 | /** 8 | * @author: Devaraj Reddy, Date : 2019-10-02 9 | */ 10 | @Slf4j 11 | public class RouteFilter extends ZuulFilter { 12 | 13 | @Override 14 | public String filterType() { 15 | return FilterConstants.ROUTE_TYPE; 16 | } 17 | 18 | @Override 19 | public int filterOrder() { 20 | return 1; 21 | } 22 | 23 | @Override 24 | public boolean shouldFilter() { 25 | return true; 26 | } 27 | 28 | @Override 29 | public Object run() { 30 | System.out.println("Inside Route Filter"); 31 | return null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /bookstore-api-gateway-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: ${SERVER_PORT:8765} 3 | 4 | spring: 5 | profiles: 6 | active: ${SPRING_PROFILES_ACTIVE:local} 7 | zipkin: 8 | base-url: http://${ZIPKIN_HOST:localhost:9411} 9 | enabled: true 10 | service: 11 | name: bookstore-api-gateway-service 12 | message-timeout: 10 13 | sleuth: 14 | sampler: 15 | probability: 1.0 16 | servlet: 17 | multipart: 18 | max-file-size: 10MB 19 | max-request-size: 10MB 20 | 21 | zuul: 22 | sensitiveHeaders: 23 | host: 24 | socket-timeout-millis: 30000 25 | connect-timeout-millis: 30000 26 | prefix: /api 27 | routes: 28 | billing: 29 | path: /billing/** 30 | serviceId: bookstore-billing-service 31 | catalog: 32 | path: /catalog/** 33 | serviceId: bookstore-catalog-service 34 | account: 35 | path: /account/** 36 | serviceId: bookstore-account-service 37 | order: 38 | path: /order/** 39 | serviceId: bookstore-order-service 40 | payment: 41 | path: /payment/** 42 | serviceId: bookstore-payment-service 43 | ribbon: 44 | eager-load: 45 | enabled: true 46 | ribbon-isolation-strategy: THREAD 47 | 48 | ribbon: 49 | ConnectTimeout: 10000 50 | ReadTimeout: 60000 51 | 52 | hystrix: 53 | command: 54 | default: 55 | execution: 56 | isolation: 57 | thread: 58 | timeoutInMilliseconds: 40000 59 | -------------------------------------------------------------------------------- /bookstore-api-gateway-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: bookstore-api-gateway-service 4 | profiles: 5 | active: ${SPRING_PROFILES_ACTIVE:local} 6 | 7 | management: 8 | endpoints: 9 | web: 10 | exposure: 11 | include: "*" 12 | 13 | --- 14 | 15 | spring: 16 | profiles: local 17 | cloud: 18 | bus: 19 | enabled: false 20 | consul: 21 | enabled: false #consul discovery set false, in this profile eureka discovery is enabled. 22 | 23 | eureka: 24 | client: 25 | serviceUrl: 26 | defaultZone: http://${EUREKA_HOST:localhost:8761}/eureka/ 27 | registerWithEureka: true 28 | enabled: true #eureka discovery is enabled in this profile 29 | instance: 30 | prefer-ip-address: false 31 | 32 | management: 33 | metrics: 34 | export: 35 | influx: 36 | enabled: false #influx metrics not pushing in this profile 37 | 38 | --- 39 | 40 | spring: 41 | profiles: docker 42 | cloud: 43 | consul: 44 | host: bookstore-consul-discovery 45 | port: 8500 46 | discovery: 47 | instanceId: ${spring.application.name}:${random.value} 48 | enabled: true #consul discovery is enabled in this profile 49 | 50 | management: 51 | metrics: 52 | export: 53 | statsd: 54 | enabled: true 55 | flavor: telegraf 56 | port: 8125 57 | influx: #pushing influx metrics. 58 | db: bookstore_influxdb_monitoring_metrics 59 | uri: http://bookstore-influxdb:8086 60 | auto-create-db: true 61 | endpoints: 62 | web: 63 | exposure: 64 | include: "*" 65 | 66 | eureka: 67 | client: 68 | enabled: false #eureka discovery set false, in this profile consul discovery is enabled. -------------------------------------------------------------------------------- /bookstore-billing-service/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | /target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | .sts4-cache 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | 20 | ### NetBeans ### 21 | /nbproject/private/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | /build/ 27 | 28 | ### VS Code ### 29 | .vscode/ 30 | -------------------------------------------------------------------------------- /bookstore-billing-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | 3 | VOLUME /tmp 4 | 5 | ARG JAR_FILE 6 | 7 | COPY target/${JAR_FILE} billing-service.jar 8 | 9 | #Using Dokerize to check whether db is up, if it is then start this service. 10 | COPY dockerize dockerize 11 | 12 | CMD ./dockerize -wait tcp://bookstore-mysql-db:3306 -timeout 15m java -Djava.security.egd=file:/dev/./urandom -jar /billing-service.jar -------------------------------------------------------------------------------- /bookstore-billing-service/dockerize: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-billing-service/dockerize -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/BookstoreBillingServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorebillingservice; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.openfeign.EnableFeignClients; 7 | import org.springframework.context.annotation.ComponentScan; 8 | 9 | @SpringBootApplication 10 | @ComponentScan(basePackages = {"com.devd.spring"}) 11 | @EnableFeignClients(basePackages = {"com.devd.spring"}) 12 | @EnableDiscoveryClient 13 | public class BookstoreBillingServiceApplication { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(BookstoreBillingServiceApplication.class, args); 17 | } 18 | 19 | } 20 | 21 | -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/config/AuthForwardInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorebillingservice.config; 2 | 3 | import feign.RequestInterceptor; 4 | import feign.RequestTemplate; 5 | import org.springframework.http.HttpHeaders; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.web.context.request.RequestContextHolder; 8 | import org.springframework.web.context.request.ServletRequestAttributes; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | import java.util.Objects; 12 | 13 | /** 14 | * @author: Devaraj Reddy, 15 | * Date : 2019-07-02 16 | */ 17 | 18 | /* 19 | This is required for Feign clients to make request to services. 20 | It takes the token from header and set the header in the feign request header. 21 | */ 22 | @Component 23 | public class AuthForwardInterceptor implements RequestInterceptor { 24 | 25 | @Override 26 | public void apply(RequestTemplate template) { 27 | HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); 28 | template.header(HttpHeaders.AUTHORIZATION, request.getHeader(HttpHeaders.AUTHORIZATION)); 29 | } 30 | } -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/config/BillingResourceServiceConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorebillingservice.config; 2 | 3 | import com.devd.spring.bookstorecommons.security.GlobalResourceServerConfig; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; 7 | import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; 8 | 9 | /** 10 | * @author: Devaraj Reddy, 11 | * Date : 2019-09-20 12 | */ 13 | @Configuration 14 | public class BillingResourceServiceConfig extends GlobalResourceServerConfig { 15 | 16 | @Autowired 17 | private ResourceServerTokenServices tokenServices; 18 | 19 | @Override 20 | public void configure(ResourceServerSecurityConfigurer resources) { 21 | resources.resourceId("web").tokenServices(tokenServices); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/config/BillingServiceConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorebillingservice.config; 2 | 3 | import feign.Logger; 4 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.client.RestTemplate; 8 | 9 | /** 10 | * @author: Devaraj Reddy, 11 | * Date : 2019-09-20 12 | */ 13 | @Configuration 14 | public class BillingServiceConfig { 15 | 16 | @Bean 17 | Logger.Level feignLoggerLevel() { 18 | return Logger.Level.FULL; 19 | } 20 | 21 | @LoadBalanced 22 | @Bean 23 | RestTemplate restTemplate() { 24 | return new RestTemplate(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/repository/AddressRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorebillingservice.repository; 2 | 3 | import com.devd.spring.bookstorebillingservice.repository.dao.AddressDao; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | /** 10 | * @author: Devaraj Reddy, 11 | * Date : 2019-09-20 12 | */ 13 | public interface AddressRepository extends CrudRepository { 14 | 15 | Optional> findByUserId(String userId); 16 | 17 | Optional findByAddressId(String addressId); 18 | 19 | Boolean existsByUserId(String userId); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/repository/dao/AddressDao.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorebillingservice.repository.dao; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Entity; 5 | import javax.persistence.GeneratedValue; 6 | import javax.persistence.Id; 7 | import javax.persistence.Table; 8 | import javax.validation.constraints.Pattern; 9 | 10 | import com.devd.spring.bookstorecommons.util.DateAudit; 11 | import lombok.AllArgsConstructor; 12 | import lombok.Builder; 13 | import lombok.Data; 14 | import lombok.NoArgsConstructor; 15 | import lombok.NonNull; 16 | import org.hibernate.annotations.GenericGenerator; 17 | 18 | /** 19 | * @author: Devaraj Reddy, 20 | * Date : 2019-09-20 21 | */ 22 | @Entity 23 | @Table(name = "ADDRESS") 24 | @Data 25 | @NoArgsConstructor 26 | @AllArgsConstructor 27 | @Builder 28 | public class AddressDao extends DateAudit { 29 | 30 | @Id 31 | @GeneratedValue(generator = "uuid") 32 | @GenericGenerator(name = "uuid", strategy = "uuid2") 33 | @Column(name = "ADDRESS_ID", updatable = false, nullable = false) 34 | private String addressId; 35 | 36 | @Column(name = "USER_ID", nullable = false) 37 | private String userId; 38 | 39 | @Column(name = "ADDRESS_LINE1", nullable = false) 40 | private String addressLine1; 41 | 42 | @Column(name = "ADDRESS_LINE2") 43 | private String addressLine2; 44 | 45 | @Column(name = "CITY", nullable = false) 46 | private String city; 47 | 48 | @Column(name = "STATE", nullable = false) 49 | private String state; 50 | 51 | @Column(name = "POSTAL_CODE", nullable = false) 52 | private String postalCode; 53 | 54 | @Pattern(regexp = "[A-Z]{2}", message = "2-letter ISO country code required") 55 | @NonNull 56 | private String country; 57 | 58 | @Column(name = "PHONE") 59 | private String phone; 60 | } 61 | -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/service/AddressService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorebillingservice.service; 2 | 3 | import com.devd.spring.bookstorebillingservice.web.CreateAddressRequest; 4 | import com.devd.spring.bookstorebillingservice.web.GetAddressResponse; 5 | import com.devd.spring.bookstorebillingservice.web.UpdateAddressRequest; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author: Devaraj Reddy, Date : 2019-09-27 11 | */ 12 | public interface AddressService { 13 | 14 | void createAddress(CreateAddressRequest createAddressRequest); 15 | 16 | List getAddress(); 17 | 18 | void updateAddress(UpdateAddressRequest updateAddressRequest); 19 | 20 | GetAddressResponse getAddressById(String addressId); 21 | 22 | void deleteAddressById(String addressId); 23 | } 24 | -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/web/CreateAddressRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorebillingservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.NonNull; 8 | 9 | import javax.validation.constraints.Pattern; 10 | 11 | /** 12 | * @author: Devaraj Reddy, 13 | * Date : 2019-09-20 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | public class CreateAddressRequest { 20 | 21 | @NonNull 22 | private String addressLine1; 23 | private String addressLine2; 24 | 25 | @NonNull 26 | private String city; 27 | 28 | @NonNull 29 | private String state; 30 | 31 | @NonNull 32 | private String postalCode; 33 | 34 | @Pattern(regexp = "[A-Z]{2}", message = "2-letter ISO country code required") 35 | @NonNull 36 | private String country; 37 | 38 | @NonNull 39 | private String phone; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/web/GetAddressResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorebillingservice.web; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: Devaraj Reddy, 8 | * Date : 2019-09-21 9 | */ 10 | @Data 11 | @Builder 12 | public class GetAddressResponse { 13 | 14 | private String addressId; 15 | private String userId; 16 | private String addressLine1; 17 | private String addressLine2; 18 | private String city; 19 | private String state; 20 | private String postalCode; 21 | private String country; 22 | private String phone; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/web/UpdateAddressRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorebillingservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.NonNull; 8 | 9 | import javax.validation.constraints.NotBlank; 10 | import javax.validation.constraints.Pattern; 11 | 12 | /** 13 | * @author Devaraj Reddy, Date : 06-Dec-2020 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | public class UpdateAddressRequest { 20 | 21 | @NotBlank 22 | private String addressId; 23 | 24 | @NonNull 25 | private String addressLine1; 26 | private String addressLine2; 27 | 28 | @NonNull 29 | private String city; 30 | 31 | @NonNull 32 | private String state; 33 | 34 | @NonNull 35 | private String postalCode; 36 | 37 | @Pattern(regexp = "[A-Z]{2}", message = "2-letter ISO country code required") 38 | @NonNull 39 | private String country; 40 | 41 | @NonNull 42 | private String phone; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: bookstore-billing-service 4 | profiles: 5 | active: ${SPRING_PROFILES_ACTIVE:local} 6 | 7 | management: 8 | endpoints: 9 | web: 10 | exposure: 11 | include: "*" 12 | 13 | --- 14 | 15 | spring: 16 | profiles: local, mysql 17 | cloud: 18 | bus: 19 | enabled: false 20 | consul: 21 | enabled: false #consul discovery set false, in this profile eureka discovery is enabled. 22 | 23 | eureka: 24 | client: 25 | serviceUrl: 26 | defaultZone: http://${EUREKA_HOST:localhost:8761}/eureka/ 27 | registerWithEureka: true 28 | enabled: true #eureka discovery is enabled in this profile 29 | instance: 30 | prefer-ip-address: false 31 | 32 | management: 33 | metrics: 34 | export: 35 | influx: 36 | enabled: false #influx metrics not pushing in this profile 37 | 38 | --- 39 | 40 | spring: 41 | profiles: docker 42 | cloud: 43 | consul: 44 | host: bookstore-consul-discovery 45 | port: 8500 46 | discovery: 47 | instanceId: ${spring.application.name}:${random.value} 48 | enabled: true #consul discovery is enabled in this profile 49 | 50 | management: 51 | metrics: 52 | export: 53 | statsd: 54 | enabled: true 55 | flavor: telegraf 56 | port: 8125 57 | influx: #pushing influx metrics. 58 | db: bookstore_influxdb_monitoring_metrics 59 | uri: http://bookstore-influxdb:8086 60 | auto-create-db: true 61 | endpoints: 62 | web: 63 | exposure: 64 | include: "*" 65 | 66 | eureka: 67 | client: 68 | enabled: false #eureka discovery set false, in this profile consul discovery is enabled. -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/resources/db/migration/V1__billing_service_schema.sql: -------------------------------------------------------------------------------- 1 | -- create address table 2 | CREATE TABLE IF NOT EXISTS ADDRESS ( 3 | ADDRESS_ID VARCHAR(255) NOT NULL, 4 | ADDRESS_LINE1 VARCHAR(255) NOT NULL, 5 | ADDRESS_LINE2 VARCHAR(255), 6 | CITY VARCHAR(255) NOT NULL, 7 | COUNTRY VARCHAR(255), 8 | PHONE VARCHAR(255), 9 | POSTAL_CODE VARCHAR(255), 10 | STATE VARCHAR(255), 11 | USER_ID VARCHAR(255) NOT NULL, 12 | CREATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 13 | UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 14 | PRIMARY KEY (ADDRESS_ID) 15 | ); 16 | -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/resources/db/migration/V2__billing_service_initial_data.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-billing-service/src/main/resources/db/migration/V2__billing_service_initial_data.sql -------------------------------------------------------------------------------- /bookstore-billing-service/src/main/resources/jwt-signing-public-key.txt: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0sp8Cy1+sJgJLToO9FvW 3 | cY4AXnp027T0diFOv8cjxD+KESAmZ7cL1jy91nQASn7dCM5qNL5KzJGrp43fIbf+ 4 | HzRv4snj7NoDF5UzgI/fJ/AA3BoIyhkt0QkiKEe2kQFbIfrD5RSHvjLecRnkV71i 5 | A27PqY+kk9QZ2TGTXoMKCADF8JIHHxf+RXVb/GdGi+zCWshXrvJsjR2ZayXFpNDf 6 | QrnsMj14Jxed16ioIdx8yf1fWZxHv9q+uev86CR4E8Xrwg0yJoYHpSdK1J4EvK35 7 | zA2gaGUcfgkZQS5M5bbhrZx1wy8N+8GNkYB0uDVZhnXc2xr4KBO7LGYeP0toA4rh 8 | 1wIDAQAB 9 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /bookstore-billing-service/src/test/java/com/devd/spring/bookstorebillingservice/BookstoreBillingAddressServiceImplApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorebillingservice; 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 BookstoreBillingAddressServiceImplApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /bookstore-catalog-service/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | /target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | .sts4-cache 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | 20 | ### NetBeans ### 21 | /nbproject/private/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | /build/ 27 | 28 | ### VS Code ### 29 | .vscode/ 30 | -------------------------------------------------------------------------------- /bookstore-catalog-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | 3 | VOLUME /tmp 4 | 5 | ARG JAR_FILE 6 | 7 | COPY target/${JAR_FILE} catalog-service.jar 8 | 9 | #Using Dokerize to check whether db is up, if it is then start this service. 10 | COPY dockerize dockerize 11 | 12 | COPY ./images /images 13 | 14 | CMD ./dockerize -wait tcp://bookstore-mysql-db:3306 -timeout 15m java -Djava.security.egd=file:/dev/./urandom -jar /catalog-service.jar -------------------------------------------------------------------------------- /bookstore-catalog-service/dockerize: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/dockerize -------------------------------------------------------------------------------- /bookstore-catalog-service/images/0547ab94-59f8-4352-b17b-0918d07913f2__pricePredudice.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/0547ab94-59f8-4352-b17b-0918d07913f2__pricePredudice.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/1ecfd5c4-dba2-4feb-bd88-006105a8d5ab__alchemist.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/1ecfd5c4-dba2-4feb-bd88-006105a8d5ab__alchemist.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/25550dae-a893-4aa5-8b8f-967a91548fa5__oopWithCpp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/25550dae-a893-4aa5-8b8f-967a91548fa5__oopWithCpp.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/2603aa1d-3892-44cc-9481-fd485d80d270__businessAdventures.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/2603aa1d-3892-44cc-9481-fd485d80d270__businessAdventures.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/27ba1db0-a5a3-477c-927c-7ceb36cf7ffa__theTimeMachine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/27ba1db0-a5a3-477c-927c-7ceb36cf7ffa__theTimeMachine.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/2b3ba80b-da93-4206-b50f-83008180a09e__sheHolmes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/2b3ba80b-da93-4206-b50f-83008180a09e__sheHolmes.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/3b315751-c5bd-4e73-aad2-df941826f453__The Great Indian Conspiracy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/3b315751-c5bd-4e73-aad2-df941826f453__The Great Indian Conspiracy.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/46fb8d5b-2979-4c54-848f-512693b37818__52 Small Changes for the Mind- Improve Memory.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/46fb8d5b-2979-4c54-848f-512693b37818__52 Small Changes for the Mind- Improve Memory.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/49935a41-7274-4b7f-9333-c3e85d59df18__belatedBacghelorparty.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/49935a41-7274-4b7f-9333-c3e85d59df18__belatedBacghelorparty.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/4b050ba6-9573-4554-bdd4-26ae806c06aa__IntroEngLit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/4b050ba6-9573-4554-bdd4-26ae806c06aa__IntroEngLit.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/622a7214-02cc-4f54-85fd-86fd8f3b6967__theScienceBook.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/622a7214-02cc-4f54-85fd-86fd8f3b6967__theScienceBook.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/6a290abe-338f-4ece-8793-ccdd35a7745f__linux.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/6a290abe-338f-4ece-8793-ccdd35a7745f__linux.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/7d8b74e5-4321-4b49-9b2a-da4bf779d5be__theTheoryOfEverything.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/7d8b74e5-4321-4b49-9b2a-da4bf779d5be__theTheoryOfEverything.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/8e6abb0e-180b-4e8e-856a-cb8491ff9454__greatGatsby.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/8e6abb0e-180b-4e8e-856a-cb8491ff9454__greatGatsby.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/8f8a275b-357e-4010-84dc-8d89bb5e2b95__Politics for Beginners.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/8f8a275b-357e-4010-84dc-8d89bb5e2b95__Politics for Beginners.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/990945b7-900e-432b-9b2c-79ea20302f6e__Productivity Superhero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/990945b7-900e-432b-9b2c-79ea20302f6e__Productivity Superhero.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/ad5b1926-05ad-4aae-852d-f152ea838648__programmingInJava.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/ad5b1926-05ad-4aae-852d-f152ea838648__programmingInJava.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/af75f363-fdb9-4d8e-8066-6215f0520e9b__corePythonProg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/af75f363-fdb9-4d8e-8066-6215f0520e9b__corePythonProg.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/b1175b20-e946-42a6-b63d-83e35b7a73fa__oneArrangedMurder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/b1175b20-e946-42a6-b63d-83e35b7a73fa__oneArrangedMurder.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/b9685c28-7f97-4fb7-9cf0-927ff3afc8f1__spaceEncyclo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/b9685c28-7f97-4fb7-9cf0-927ff3afc8f1__spaceEncyclo.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/c16108e1-8276-41ad-bf12-4aee4c0a7e65__IndModernLiterature.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/c16108e1-8276-41ad-bf12-4aee4c0a7e65__IndModernLiterature.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/cad39d84-60aa-496d-9295-c3f47ec957fa__programmingInC.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/cad39d84-60aa-496d-9295-c3f47ec957fa__programmingInC.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/cef7540f-0810-4323-9950-98c5d8d5099d__Chandra Shekhar- The Last Icon of Ideological Politics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/cef7540f-0810-4323-9950-98c5d8d5099d__Chandra Shekhar- The Last Icon of Ideological Politics.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/e6602eb6-3f67-4993-abc8-0b54a36bad1b__thousandSplendidSuns.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/e6602eb6-3f67-4993-abc8-0b54a36bad1b__thousandSplendidSuns.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/images/e9b319cc-e501-4f90-b608-74052d770e2d__theBusinessBook.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-catalog-service/images/e9b319cc-e501-4f90-b608-74052d770e2d__theBusinessBook.jpg -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/BookstoreCatalogServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.openfeign.EnableFeignClients; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.ComponentScan; 9 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 10 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 11 | 12 | @SpringBootApplication 13 | @EnableDiscoveryClient 14 | @ComponentScan("com.devd.spring") 15 | @EnableFeignClients(basePackages = "com.devd.spring") 16 | public class BookstoreCatalogServiceApplication { 17 | 18 | public static void main(String[] args) { 19 | SpringApplication.run(BookstoreCatalogServiceApplication.class, args); 20 | } 21 | 22 | @Bean 23 | public WebMvcConfigurer corsConfigurer() { 24 | return new WebMvcConfigurer() { 25 | @Override 26 | public void addCorsMappings(CorsRegistry registry) { 27 | registry.addMapping("*").allowedOrigins("*"); 28 | } 29 | }; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/config/AuthForwardInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.config; 2 | 3 | import feign.RequestInterceptor; 4 | import feign.RequestTemplate; 5 | import org.springframework.http.HttpHeaders; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.web.context.request.RequestContextHolder; 8 | import org.springframework.web.context.request.ServletRequestAttributes; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | import java.util.Objects; 12 | 13 | /** 14 | * @author: Devaraj Reddy, 15 | * Date : 2019-07-02 16 | */ 17 | 18 | /* 19 | This is required for Feign clients to make request to services. 20 | It takes the token from header and set the header in the feign request header. 21 | */ 22 | @Component 23 | public class AuthForwardInterceptor implements RequestInterceptor { 24 | 25 | @Override 26 | public void apply(RequestTemplate template) { 27 | HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); 28 | template.header(HttpHeaders.AUTHORIZATION, request.getHeader(HttpHeaders.AUTHORIZATION)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/config/ResourceServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.config; 2 | 3 | import com.devd.spring.bookstorecommons.security.GlobalResourceServerConfig; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.http.HttpMethod; 7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 8 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; 9 | import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; 10 | 11 | @Configuration 12 | public class ResourceServerConfig extends GlobalResourceServerConfig { 13 | 14 | @Autowired 15 | private ResourceServerTokenServices tokenServices; 16 | 17 | @Override 18 | public void configure(ResourceServerSecurityConfigurer resources) { 19 | resources.resourceId("web").tokenServices(tokenServices); 20 | } 21 | 22 | @Override 23 | public void configure(HttpSecurity http) throws Exception { 24 | http 25 | .authorizeRequests() 26 | .antMatchers("/actuator/**", "/api-docs/**", "/h2-console/**", "/signin").permitAll() 27 | .antMatchers(HttpMethod.POST, "/oauth/token").permitAll() 28 | .antMatchers(HttpMethod.GET, "/product**/**").permitAll() 29 | .antMatchers(HttpMethod.GET, "/review/**").permitAll() 30 | .antMatchers(HttpMethod.GET, "/image/**").permitAll() 31 | .antMatchers("/**").authenticated(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/controller/CatalogController.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.controller; 2 | 3 | import org.springframework.web.bind.annotation.RestController; 4 | 5 | /** 6 | * @author: Devaraj Reddy, 7 | * Date : 2019-06-03 8 | */ 9 | @RestController 10 | public class CatalogController { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/controller/ReviewController.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.controller; 2 | 3 | import com.devd.spring.bookstorecatalogservice.repository.dao.Review; 4 | import com.devd.spring.bookstorecatalogservice.service.ReviewService; 5 | import com.devd.spring.bookstorecatalogservice.web.CreateOrUpdateReviewRequest; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RequestParam; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import javax.validation.Valid; 15 | import java.util.List; 16 | 17 | /** 18 | * @author Devaraj Reddy, Date : 08-Nov-2020 19 | */ 20 | @RestController 21 | public class ReviewController { 22 | 23 | @Autowired 24 | ReviewService reviewService; 25 | 26 | @PostMapping("/review") 27 | public ResponseEntity createOrUpdateReview(@RequestBody @Valid CreateOrUpdateReviewRequest createOrUpdateReviewRequest) { 28 | 29 | reviewService.createOrUpdateReview(createOrUpdateReviewRequest); 30 | return ResponseEntity.ok().build(); 31 | } 32 | 33 | @GetMapping("/review") 34 | public ResponseEntity getAllReviewsForProduct(@RequestParam("productId") String productId) { 35 | List reviewsForProduct = reviewService.getReviewsForProduct(productId); 36 | return ResponseEntity.ok(reviewsForProduct); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/model/ProductResource.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.model; 2 | 3 | import com.devd.spring.bookstorecatalogservice.repository.dao.Product; 4 | import lombok.Data; 5 | import org.springframework.data.domain.Pageable; 6 | import org.springframework.hateoas.EntityModel; 7 | import org.springframework.hateoas.Link; 8 | 9 | 10 | /** 11 | * @author: Devaraj Reddy, 12 | * Date : 2019-08-27 13 | */ 14 | @Data 15 | public class ProductResource extends EntityModel { 16 | 17 | private Pageable pageable; 18 | 19 | public ProductResource(Product content, Link... links) { 20 | EntityModel.of(content, links); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/repository/ProductCategoryRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.repository; 2 | 3 | import com.devd.spring.bookstorecatalogservice.repository.dao.ProductCategory; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author: Devaraj Reddy, 9 | * Date : 2019-06-06 10 | */ 11 | @Repository 12 | public interface ProductCategoryRepository extends JpaRepository { 13 | } 14 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/repository/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.repository; 2 | 3 | import com.devd.spring.bookstorecatalogservice.repository.dao.Product; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author: Devaraj Reddy, 9 | * Date : 2019-06-06 10 | */ 11 | @Repository 12 | public interface ProductRepository extends JpaRepository { 13 | } 14 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/repository/ReviewRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.repository; 2 | 3 | import com.devd.spring.bookstorecatalogservice.repository.dao.Review; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | /** 11 | * @author Devaraj Reddy, Date : 07-Nov-2020 12 | */ 13 | @Repository 14 | public interface ReviewRepository extends JpaRepository { 15 | 16 | Optional findByUserIdAndProductId(String userId, String productId); 17 | 18 | Optional> findAllByProductId(String productId); 19 | 20 | // long countAllByProductIdAndReviewMessageNotNull (String productId); 21 | long countAllByProductId(String productId); 22 | } 23 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/repository/dao/ProductCategory.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.repository.dao; 2 | 3 | import com.devd.spring.bookstorecommons.util.DateAudit; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.NoArgsConstructor; 9 | import org.hibernate.annotations.GenericGenerator; 10 | 11 | import javax.persistence.CascadeType; 12 | import javax.persistence.Column; 13 | import javax.persistence.Entity; 14 | import javax.persistence.GeneratedValue; 15 | import javax.persistence.Id; 16 | import javax.persistence.OneToMany; 17 | import javax.persistence.Table; 18 | import java.util.List; 19 | 20 | /** 21 | * @author: Devaraj Reddy, 22 | * Date : 2019-06-04 23 | */ 24 | @EqualsAndHashCode(callSuper = true) 25 | @Data 26 | @AllArgsConstructor 27 | @NoArgsConstructor 28 | @Entity 29 | @Table(name = "PRODUCT_CATEGORY") 30 | @Builder 31 | public class ProductCategory extends DateAudit { 32 | 33 | @Id 34 | @GeneratedValue(generator = "uuid") 35 | @GenericGenerator(name = "uuid", strategy = "uuid2") 36 | @Column(name = "PRODUCT_CATEGORY_ID", updatable = false, nullable = false) 37 | private String productCategoryId; 38 | 39 | @Column(name = "PRODUCT_CATEGORY_NAME", nullable = false) 40 | private String productCategoryName; 41 | 42 | @OneToMany( 43 | mappedBy = "productCategory", 44 | cascade = CascadeType.ALL 45 | ) 46 | private List products; 47 | private String description; 48 | } 49 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/repository/dao/Review.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.repository.dao; 2 | 3 | import com.devd.spring.bookstorecommons.util.DateAudit; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.NoArgsConstructor; 9 | import org.hibernate.annotations.GenericGenerator; 10 | 11 | import javax.persistence.Column; 12 | import javax.persistence.Entity; 13 | import javax.persistence.GeneratedValue; 14 | import javax.persistence.Id; 15 | import javax.persistence.Table; 16 | import javax.validation.constraints.Max; 17 | import javax.validation.constraints.Min; 18 | 19 | /** 20 | * @author Devaraj Reddy, Date : 07-Nov-2020 21 | */ 22 | @EqualsAndHashCode(callSuper = true) 23 | @Data 24 | @Entity 25 | @Table(name = "REVIEW") 26 | @Builder 27 | @AllArgsConstructor 28 | @NoArgsConstructor 29 | public class Review extends DateAudit { 30 | 31 | @Id 32 | @GeneratedValue(generator = "uuid") 33 | @GenericGenerator(name = "uuid", strategy = "uuid2") 34 | @Column(name = "REVIEW_ID", updatable = false, nullable = false) 35 | private String reviewId; 36 | 37 | @Column(name = "PRODUCT_ID", updatable = false, nullable = false) 38 | private String productId; 39 | 40 | @Column(name = "USER_ID", nullable = false) 41 | private String userId; 42 | 43 | @Column(name = "USER_NAME", nullable = false) 44 | private String userName; 45 | 46 | @Column(name = "RATING_VALUE", nullable = false) 47 | @Min(1) 48 | @Max(5) 49 | private double ratingValue; 50 | 51 | @Column(name = "REVIEW_MESSAGE") 52 | private String reviewMessage; 53 | 54 | } 55 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/service/ProductCategoryService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.service; 2 | 3 | import com.devd.spring.bookstorecatalogservice.repository.dao.ProductCategory; 4 | import com.devd.spring.bookstorecatalogservice.web.CreateProductCategoryRequest; 5 | import com.devd.spring.bookstorecatalogservice.web.UpdateProductCategoryRequest; 6 | import javax.validation.Valid; 7 | import org.springframework.data.domain.Page; 8 | 9 | /** 10 | * @author: Devaraj Reddy, Date : 2019-09-27 11 | */ 12 | public interface ProductCategoryService { 13 | 14 | String createProductCategory(@Valid CreateProductCategoryRequest createProductCategoryRequest); 15 | 16 | ProductCategory getProductCategory(String productCategoryId); 17 | 18 | void deleteProductCategory(String productCategoryId); 19 | 20 | void updateProductCategory(UpdateProductCategoryRequest updateProductCategoryRequest); 21 | 22 | Page getAllProductCategories(String sort, Integer page, Integer size); 23 | } 24 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/service/ProductService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.service; 2 | 3 | import com.devd.spring.bookstorecatalogservice.repository.dao.Product; 4 | import com.devd.spring.bookstorecatalogservice.web.CreateProductRequest; 5 | import com.devd.spring.bookstorecatalogservice.web.ProductResponse; 6 | import com.devd.spring.bookstorecatalogservice.web.UpdateProductRequest; 7 | import javax.validation.Valid; 8 | import org.springframework.data.domain.Page; 9 | import org.springframework.data.domain.Pageable; 10 | 11 | /** 12 | * @author: Devaraj Reddy, Date : 2019-09-27 13 | */ 14 | public interface ProductService { 15 | 16 | String createProduct(@Valid CreateProductRequest createProductRequest); 17 | 18 | ProductResponse getProduct(String productId); 19 | 20 | void deleteProduct(String productId); 21 | 22 | void updateProduct(UpdateProductRequest updateProductRequest); 23 | 24 | Page findAllProducts(Pageable pageable); 25 | 26 | Page getAllProducts(String sort, Integer page, Integer size); 27 | } 28 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/service/ReviewService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.service; 2 | 3 | import com.devd.spring.bookstorecatalogservice.repository.dao.Review; 4 | import com.devd.spring.bookstorecatalogservice.web.CreateOrUpdateReviewRequest; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author Devaraj Reddy, Date : 08-Nov-2020 10 | */ 11 | public interface ReviewService { 12 | 13 | void createOrUpdateReview(CreateOrUpdateReviewRequest createOrUpdateReviewRequest); 14 | 15 | List getReviewsForProduct(String productId); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/web/CreateOrUpdateReviewRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.validation.constraints.Max; 8 | import javax.validation.constraints.Min; 9 | import javax.validation.constraints.NotEmpty; 10 | import javax.validation.constraints.NotNull; 11 | 12 | /** 13 | * @author Devaraj Reddy, Date : 07-Nov-2020 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class CreateOrUpdateReviewRequest { 19 | 20 | @NotNull(message = "productId should not be null!") 21 | @NotEmpty(message = "productId should not be empty!") 22 | private String productId; 23 | 24 | private String reviewMessage; 25 | 26 | @Min(value = 1) 27 | @Max(value = 5) 28 | private double ratingValue; 29 | } 30 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/web/CreateProductCategoryRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.validation.constraints.NotEmpty; 8 | import javax.validation.constraints.NotNull; 9 | 10 | 11 | /** 12 | * @author: Devaraj Reddy, 13 | * Date : 2019-06-06 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class CreateProductCategoryRequest { 19 | 20 | @NotNull(message = "productCategoryName should not be null!") 21 | @NotEmpty(message = "productCategoryName should not be empty!") 22 | private String productCategoryName; 23 | private String description; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/web/CreateProductRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.validation.constraints.Min; 8 | import javax.validation.constraints.NotEmpty; 9 | import javax.validation.constraints.NotNull; 10 | 11 | /** 12 | * @author: Devaraj Reddy, 13 | * Date : 2019-06-06 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class CreateProductRequest { 19 | 20 | @NotNull(message = "productName should not be null!") 21 | @NotEmpty(message = "productName should not be empty!") 22 | private String productName; 23 | 24 | private String description; 25 | 26 | @Min(value = 0) 27 | private double price; 28 | 29 | private String imageId; 30 | 31 | @NotNull(message = "productCategoryId should not be null!") 32 | @NotEmpty(message = "productCategoryId should not be empty!") 33 | private String productCategoryId; 34 | 35 | private int availableItemCount; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/web/ProductCategoriesPagedResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.web; 2 | 3 | import com.devd.spring.bookstorecatalogservice.repository.dao.ProductCategory; 4 | import lombok.Data; 5 | import org.springframework.data.domain.Page; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | /** 11 | * @author: Devaraj Reddy, 12 | * Date : 2019-08-29 13 | */ 14 | @Data 15 | public class ProductCategoriesPagedResponse { 16 | 17 | Page page; 18 | Map _links = new HashMap<>(); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/web/ProductResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author Devaraj Reddy, Date : 08-Nov-2020 9 | */ 10 | @Data 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class ProductResponse { 14 | 15 | private String productId; 16 | private String productName; 17 | private String description; 18 | private double price; 19 | private String productCategory; 20 | private int availableItemCount; 21 | private Double averageRating; 22 | private int noOfRatings; 23 | private String imageId; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/web/ProductsPagedResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.web; 2 | 3 | import lombok.Data; 4 | import org.springframework.data.domain.Page; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * @author: Devaraj Reddy, 11 | * Date : 2019-08-29 12 | */ 13 | @Data 14 | public class ProductsPagedResponse { 15 | 16 | Page page; 17 | Map _links = new HashMap<>(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/web/UpdateProductCategoryRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.validation.constraints.NotEmpty; 8 | import javax.validation.constraints.NotNull; 9 | 10 | /** 11 | * @author: Devaraj Reddy, 12 | * Date : 2019-06-06 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class UpdateProductCategoryRequest { 18 | 19 | @NotNull(message = "productCategoryId should not be null!") 20 | @NotEmpty(message = "productCategoryId should not be empty!") 21 | private String productCategoryId; 22 | 23 | @NotNull(message = "productCategoryName should not be null!") 24 | @NotEmpty(message = "productCategoryName should not be empty!") 25 | private String productCategoryName; 26 | private String description; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/web/UpdateProductRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.validation.constraints.Min; 8 | import javax.validation.constraints.NotEmpty; 9 | import javax.validation.constraints.NotNull; 10 | 11 | /** 12 | * @author: Devaraj Reddy, 13 | * Date : 2019-06-06 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class UpdateProductRequest { 19 | 20 | @NotNull(message = "productId should not be null!") 21 | @NotEmpty(message = "productId should not be empty!") 22 | private String productId; 23 | 24 | private String productName; 25 | 26 | private String description; 27 | 28 | @Min(value = 0) 29 | private Double price; 30 | 31 | private String imageId; 32 | 33 | private String productCategoryId; 34 | 35 | private Integer availableItemCount; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: bookstore-catalog-service 4 | profiles: 5 | active: ${SPRING_PROFILES_ACTIVE:local} 6 | 7 | management: 8 | endpoints: 9 | web: 10 | exposure: 11 | include: "*" 12 | 13 | --- 14 | 15 | spring: 16 | profiles: local, mysql 17 | cloud: 18 | bus: 19 | enabled: false 20 | consul: 21 | enabled: false #consul discovery set false, in this profile eureka discovery is enabled. 22 | 23 | eureka: 24 | client: 25 | serviceUrl: 26 | defaultZone: http://${EUREKA_HOST:localhost:8761}/eureka/ 27 | registerWithEureka: true 28 | enabled: true #eureka discovery is enabled in this profile 29 | instance: 30 | prefer-ip-address: false 31 | 32 | management: 33 | metrics: 34 | export: 35 | influx: 36 | enabled: false #influx metrics not pushing in this profile 37 | 38 | --- 39 | 40 | spring: 41 | profiles: docker 42 | cloud: 43 | consul: 44 | host: bookstore-consul-discovery 45 | port: 8500 46 | discovery: 47 | instanceId: ${spring.application.name}:${random.value} 48 | enabled: true #consul discovery is enabled in this profile 49 | 50 | management: 51 | metrics: 52 | export: 53 | statsd: 54 | enabled: true 55 | flavor: telegraf 56 | port: 8125 57 | influx: #pushing influx metrics. 58 | db: bookstore_influxdb_monitoring_metrics 59 | uri: http://bookstore-influxdb:8086 60 | auto-create-db: true 61 | endpoints: 62 | web: 63 | exposure: 64 | include: "*" 65 | 66 | eureka: 67 | client: 68 | enabled: false #eureka discovery set false, in this profile consul discovery is enabled. -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/resources/db/migration/V1__catalog_service_schema.sql: -------------------------------------------------------------------------------- 1 | create table PRODUCT ( 2 | product_id varchar(255) not null, 3 | available_item_count integer not null, 4 | product_description varchar(255), 5 | price double not null, 6 | product_name varchar(255) not null, 7 | product_category_id varchar(255), 8 | product_image_id varchar(255), 9 | CREATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 10 | UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 11 | primary key (product_id) 12 | ); 13 | 14 | create table PRODUCT_CATEGORY ( 15 | product_category_id varchar(255) not null, 16 | description varchar(255), 17 | product_category_name varchar(255) not null, 18 | CREATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 19 | UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 20 | primary key (product_category_id) 21 | ); 22 | 23 | alter table PRODUCT 24 | add constraint FKProductToProductCategory 25 | foreign key (product_category_id) 26 | references PRODUCT_CATEGORY(product_category_id); 27 | 28 | create table REVIEW ( 29 | review_id varchar(255) not null, 30 | user_id varchar(255), 31 | rating_value double not null, 32 | review_message varchar(1000), 33 | product_id varchar(255) not null, 34 | user_name varchar(255), 35 | CREATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 36 | UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 37 | primary key (review_id) 38 | ); -------------------------------------------------------------------------------- /bookstore-catalog-service/src/main/resources/jwt-signing-public-key.txt: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0sp8Cy1+sJgJLToO9FvW 3 | cY4AXnp027T0diFOv8cjxD+KESAmZ7cL1jy91nQASn7dCM5qNL5KzJGrp43fIbf+ 4 | HzRv4snj7NoDF5UzgI/fJ/AA3BoIyhkt0QkiKEe2kQFbIfrD5RSHvjLecRnkV71i 5 | A27PqY+kk9QZ2TGTXoMKCADF8JIHHxf+RXVb/GdGi+zCWshXrvJsjR2ZayXFpNDf 6 | QrnsMj14Jxed16ioIdx8yf1fWZxHv9q+uev86CR4E8Xrwg0yJoYHpSdK1J4EvK35 7 | zA2gaGUcfgkZQS5M5bbhrZx1wy8N+8GNkYB0uDVZhnXc2xr4KBO7LGYeP0toA4rh 8 | 1wIDAQAB 9 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /bookstore-catalog-service/src/test/java/com/devd/spring/bookstorecatalogservice/BookstoreCatalogServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecatalogservice; 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 BookstoreCatalogServiceApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /bookstore-commons/src/main/java/com/devd/spring/bookstorecommons/config/AuditingConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.data.domain.AuditorAware; 6 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 7 | import org.springframework.security.authentication.AnonymousAuthenticationToken; 8 | import org.springframework.security.core.Authentication; 9 | import org.springframework.security.core.context.SecurityContextHolder; 10 | 11 | import java.util.Optional; 12 | 13 | @Configuration 14 | @EnableJpaAuditing 15 | public class AuditingConfig { 16 | 17 | @Bean 18 | public AuditorAware auditorProvider() { 19 | return new SpringSecurityAuditAwareImpl(); 20 | } 21 | } 22 | 23 | class SpringSecurityAuditAwareImpl implements AuditorAware { 24 | 25 | @Override 26 | public Optional getCurrentAuditor() { 27 | Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 28 | 29 | if (authentication == null || 30 | !authentication.isAuthenticated() || 31 | authentication instanceof AnonymousAuthenticationToken) { 32 | return Optional.empty(); 33 | } 34 | 35 | String userPrincipal = (String)authentication.getPrincipal(); 36 | 37 | return Optional.ofNullable(userPrincipal); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /bookstore-commons/src/main/java/com/devd/spring/bookstorecommons/config/CommonConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.config; 2 | 3 | import org.dozer.DozerBeanMapper; 4 | import org.dozer.classmap.MappingFileData; 5 | import org.dozer.loader.DozerBuilder; 6 | import org.dozer.loader.api.BeanMappingBuilder; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * @author Devaraj Reddy, Date : 08-Dec-2020 12 | */ 13 | @Configuration 14 | public class CommonConfig { 15 | 16 | // @Bean 17 | // DozerBeanMapper dozerBeanMapper(){ 18 | // DozerBeanMapper dozerBeanMapper = new DozerBeanMapper(); 19 | // } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /bookstore-commons/src/main/java/com/devd/spring/bookstorecommons/exception/Error.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.exception; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, Date : 2019-04-12 12:04 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder 15 | public class Error { 16 | 17 | private String code; 18 | private String message; 19 | } 20 | -------------------------------------------------------------------------------- /bookstore-commons/src/main/java/com/devd/spring/bookstorecommons/exception/ErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.exception; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.util.List; 9 | import java.util.UUID; 10 | 11 | /** 12 | * @author: Devaraj Reddy, Date : 2019-04-12 12:03 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Builder 18 | public class ErrorResponse { 19 | 20 | private UUID uuid; 21 | private List errors; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /bookstore-commons/src/main/java/com/devd/spring/bookstorecommons/exception/RunTimeExceptionPlaceHolder.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.exception; 2 | 3 | /** 4 | * @author: Devaraj Reddy, Date : 2019-05-20 5 | */ 6 | public class RunTimeExceptionPlaceHolder extends RuntimeException { 7 | 8 | public RunTimeExceptionPlaceHolder(String message) { 9 | super(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /bookstore-commons/src/main/java/com/devd/spring/bookstorecommons/security/SimpleCorsFilter.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.security; 2 | 3 | import org.springframework.core.Ordered; 4 | import org.springframework.core.annotation.Order; 5 | import org.springframework.stereotype.Component; 6 | 7 | import javax.servlet.Filter; 8 | import javax.servlet.FilterChain; 9 | import javax.servlet.FilterConfig; 10 | import javax.servlet.ServletException; 11 | import javax.servlet.ServletRequest; 12 | import javax.servlet.ServletResponse; 13 | import javax.servlet.http.HttpServletRequest; 14 | import javax.servlet.http.HttpServletResponse; 15 | import java.io.IOException; 16 | 17 | /** 18 | * @author Devaraj Reddy, Date : 04-Dec-2020Ò 19 | */ 20 | @Component 21 | @Order(Ordered.HIGHEST_PRECEDENCE) 22 | public class SimpleCorsFilter implements Filter { 23 | 24 | public SimpleCorsFilter() { 25 | } 26 | 27 | @Override 28 | public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 29 | HttpServletResponse response = (HttpServletResponse) res; 30 | HttpServletRequest request = (HttpServletRequest) req; 31 | response.setHeader("Access-Control-Allow-Origin", "*"); 32 | response.setHeader("Access-Control-Allow-Methods", "*"); 33 | response.setHeader("Access-Control-Allow-Headers", "*"); 34 | 35 | if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { 36 | response.setStatus(HttpServletResponse.SC_OK); 37 | } else { 38 | chain.doFilter(req, res); 39 | } 40 | } 41 | 42 | @Override 43 | public void init(FilterConfig filterConfig) { 44 | } 45 | 46 | @Override 47 | public void destroy() { 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /bookstore-commons/src/main/java/com/devd/spring/bookstorecommons/util/CommonUtilityMethods.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.util; 2 | 3 | import org.springframework.security.core.Authentication; 4 | import org.springframework.security.oauth2.provider.OAuth2Authentication; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * @author Devaraj Reddy, Date : 06-Dec-2020 10 | */ 11 | public class CommonUtilityMethods { 12 | 13 | public static String getUserIdFromToken(Authentication authentication) { 14 | Map map = (Map)((OAuth2Authentication) authentication).getUserAuthentication().getDetails(); 15 | return map.get("user_id"); 16 | } 17 | 18 | public static String getUserNameFromToken(Authentication authentication) { 19 | Map map = (Map)((OAuth2Authentication) authentication).getUserAuthentication().getDetails(); 20 | return map.get("user_name"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /bookstore-commons/src/main/java/com/devd/spring/bookstorecommons/util/DateAudit.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.util; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import org.springframework.data.annotation.CreatedDate; 7 | import org.springframework.data.annotation.LastModifiedDate; 8 | import org.springframework.data.jpa.domain.support.AuditingEntityListener; 9 | 10 | import javax.persistence.Column; 11 | import javax.persistence.EntityListeners; 12 | import javax.persistence.MappedSuperclass; 13 | import java.io.Serializable; 14 | import java.time.Instant; 15 | 16 | @MappedSuperclass 17 | @EntityListeners(AuditingEntityListener.class) 18 | @JsonIgnoreProperties( 19 | value = {"created_at", "updated_at"}, 20 | allowGetters = true 21 | ) 22 | @Getter 23 | @Setter 24 | public abstract class DateAudit implements Serializable { 25 | 26 | @CreatedDate 27 | @Column(name = "CREATED_AT") 28 | private Instant createdAt; 29 | 30 | @LastModifiedDate 31 | @Column(name = "UPDATED_AT") 32 | private Instant updatedAt; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /bookstore-eureka-discovery-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | 3 | VOLUME /tmp 4 | 5 | ARG JAR_FILE 6 | 7 | COPY target/${JAR_FILE} eureka-app.jar 8 | 9 | ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/eureka-app.jar"] -------------------------------------------------------------------------------- /bookstore-eureka-discovery-service/src/main/java/com/devd/spring/bookstoreeurekadiscoveryservice/BookstoreEurekaDiscoveryServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreeurekadiscoveryservice; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | /** 8 | * @author: Devaraj Reddy, 9 | * Date : 2019-05-14 10 | */ 11 | @SpringBootApplication 12 | @EnableEurekaServer 13 | public class BookstoreEurekaDiscoveryServiceApplication { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(BookstoreEurekaDiscoveryServiceApplication.class, args); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /bookstore-eureka-discovery-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: ${SERVER_PORT:8761} 3 | 4 | eureka: 5 | client: 6 | registerWithEureka: false #telling the server not to register himself in the service registry 7 | fetchRegistry: false 8 | server: 9 | waitTimeInMsWhenSyncEmpty: 0 #wait time for subsequent sync 10 | instance: 11 | prefer-ip-address: false -------------------------------------------------------------------------------- /bookstore-eureka-discovery-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: bookstore-eureka-discovery-service 4 | 5 | management: 6 | metrics: 7 | export: 8 | influx: 9 | enabled: false #influx metrics not pushing -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/config/FeignConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.config; 2 | 3 | import feign.Logger; 4 | import feign.Request; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Configuration 9 | public class FeignConfig { 10 | 11 | @Bean 12 | Logger.Level feignLoggerLevel() { 13 | return Logger.Level.FULL; 14 | } 15 | 16 | @Bean 17 | public static Request.Options requestOptions() { 18 | int ribbonReadTimeout = 70000; 19 | int ribbonConnectionTimeout = 60000; 20 | return new Request.Options(ribbonConnectionTimeout, ribbonReadTimeout); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/feign/AccountFeignClient.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.feign; 2 | 3 | import com.devd.spring.bookstorecommons.web.GetUserInfoResponse; 4 | import com.devd.spring.bookstorecommons.web.GetUserResponse; 5 | import org.springframework.cloud.openfeign.FeignClient; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | 9 | /** 10 | * @author: Devaraj Reddy, 11 | * Date : 2019-07-02 12 | */ 13 | @FeignClient("bookstore-account-service") 14 | public interface AccountFeignClient { 15 | 16 | @GetMapping("/user") 17 | GetUserResponse getUserByUserName(@RequestParam("userName") String userName); 18 | 19 | @GetMapping("/user") 20 | GetUserResponse getUserById(@RequestParam("userId") String userId); 21 | 22 | @GetMapping("/userInfo") 23 | GetUserInfoResponse getUserInfo(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/feign/BillingFeignClient.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.feign; 2 | 3 | import com.devd.spring.bookstorecommons.web.GetAddressResponse; 4 | import org.springframework.cloud.openfeign.FeignClient; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | 8 | /** 9 | * @author: Devaraj Reddy, Date : 2019-07-02 10 | */ 11 | @FeignClient("bookstore-billing-service") 12 | public interface BillingFeignClient { 13 | 14 | @GetMapping("/address/{addressId}") 15 | GetAddressResponse getAddressById(@PathVariable("addressId") String addressId); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/feign/CatalogFeignClient.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.feign; 2 | 3 | import com.devd.spring.bookstorecommons.web.GetProductResponse; 4 | import org.springframework.cloud.openfeign.FeignClient; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | 8 | /** 9 | * @author: Devaraj Reddy, 10 | * Date : 2019-06-03 11 | */ 12 | @FeignClient("bookstore-catalog-service") 13 | public interface CatalogFeignClient { 14 | 15 | @GetMapping("/product/{productId}") 16 | GetProductResponse getProduct(@PathVariable("productId") String productId); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/feign/OrderFeignClient.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.feign; 2 | 3 | import org.springframework.cloud.openfeign.FeignClient; 4 | 5 | /** 6 | * @author: Devaraj Reddy, Date : 2019-07-02 7 | */ 8 | @FeignClient("bookstore-order-service") 9 | public interface OrderFeignClient { 10 | 11 | 12 | } 13 | -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/feign/PaymentFeignClient.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.feign; 2 | 3 | import com.devd.spring.bookstorecommons.web.CreatePaymentRequest; 4 | import com.devd.spring.bookstorecommons.web.CreatePaymentResponse; 5 | import com.devd.spring.bookstorecommons.web.GetPaymentMethodResponse; 6 | import org.springframework.cloud.openfeign.FeignClient; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | 11 | /** 12 | * @author Devaraj Reddy, Date : 15-Dec-2020 13 | */ 14 | @FeignClient("bookstore-payment-service") 15 | public interface PaymentFeignClient { 16 | 17 | @GetMapping("/paymentMethod/{paymentMethodId}") 18 | GetPaymentMethodResponse getMyPaymentMethodById(@PathVariable("paymentMethodId") String paymentMethodId); 19 | 20 | @PostMapping("/pay") 21 | CreatePaymentResponse doPayment(CreatePaymentRequest createPaymentRequest); 22 | } 23 | -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/web/CreatePaymentRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | 8 | /** 9 | * @author Devaraj Reddy - 17-Dec-2020 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class CreatePaymentRequest { 15 | private int amount; 16 | private String currency; 17 | private String paymentMethodId; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/web/CreatePaymentResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | * @author Devaraj Reddy - 17-Dec-2020 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @Builder 17 | public class CreatePaymentResponse { 18 | private String paymentId; 19 | private LocalDateTime paymentDate; 20 | private boolean captured; 21 | private String receipt_url; 22 | } 23 | -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/web/GetAddressResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, 10 | * Date : 2019-09-21 11 | */ 12 | @Data 13 | @Builder 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class GetAddressResponse { 17 | 18 | private String addressId; 19 | private String userId; 20 | private String addressLine1; 21 | private String addressLine2; 22 | private String city; 23 | private String state; 24 | private String postalCode; 25 | private String country; 26 | private String phone; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/web/GetPaymentMethodResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author Devaraj Reddy, Date : 14-Dec-2020 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder 15 | public class GetPaymentMethodResponse { 16 | 17 | private String paymentMethodId; 18 | private String cardType; 19 | private String cardLast4Digits; 20 | private Long cardExpirationMonth; 21 | private Long cardExpirationYear; 22 | private String cardCountry; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/web/GetProductResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, 10 | * Date : 2019-06-04 11 | */ 12 | @Data 13 | @Builder 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class GetProductResponse { 17 | 18 | private String productId; 19 | private String productName; 20 | private String description; 21 | private double price; 22 | private String productCategory; 23 | private int availableItemCount; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/web/GetUserInfoResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, Date : 2019-10-07 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder 15 | public class GetUserInfoResponse { 16 | 17 | private String userId; 18 | private String userName; 19 | private String firstName; 20 | private String lastName; 21 | private String email; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/web/GetUserResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorecommons.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author: Devaraj Reddy, 9 | * Date : 2019-06-17 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class GetUserResponse { 15 | 16 | private String userId; 17 | private String userName; 18 | private String password; 19 | private String firstName; 20 | private String lastName; 21 | private String email; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/.eslintrc.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true, 6 | "quoteProps": "consistent", 7 | "printWidth": 140, 8 | "jsxSingleQuote": true, 9 | "jsxBracketSameLine": false 10 | } 11 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/README.md: -------------------------------------------------------------------------------- 1 | # BookStore ReactJS App 2 | 3 | This is the UI where customers can buy books and Admin can maintain inventory, orders, users etc. 4 | 5 | ## Run the App in Local Machine 6 | Install the required dependencies 7 | ``` 8 | yarn install 9 | ``` 10 | 11 | Start the application. 12 | ``` 13 | yarn start 14 | ``` -------------------------------------------------------------------------------- /bookstore-frontend-react-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bookstore-frontend-react-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.4", 7 | "@testing-library/react": "^11.1.0", 8 | "@testing-library/user-event": "^12.1.10", 9 | "axios": "^0.21.0", 10 | "bootstrap": "^4.5.3", 11 | "jwt-decode": "^3.1.2", 12 | "qs": "^6.9.4", 13 | "react": "^17.0.1", 14 | "react-bootstrap": "^1.4.0", 15 | "react-dom": "^17.0.1", 16 | "react-paginate": "^7.0.0", 17 | "react-paypal-button-v2": "^2.6.2", 18 | "react-redux": "^7.2.2", 19 | "react-router-bootstrap": "^0.25.0", 20 | "react-router-dom": "^5.2.0", 21 | "react-router-redux": "^4.0.8", 22 | "react-scripts": "4.0.0", 23 | "redux": "^4.0.5", 24 | "redux-devtools-extension": "^2.13.8", 25 | "redux-thunk": "^2.3.0", 26 | "web-vitals": "^0.2.4" 27 | }, 28 | "scripts": { 29 | "start": "react-scripts start", 30 | "build": "react-scripts build", 31 | "test": "react-scripts test", 32 | "eject": "react-scripts eject" 33 | }, 34 | "eslintConfig": { 35 | "extends": [ 36 | "react-app", 37 | "react-app/jest" 38 | ] 39 | }, 40 | "browserslist": { 41 | "production": [ 42 | ">0.2%", 43 | "not dead", 44 | "not op_mini all" 45 | ], 46 | "development": [ 47 | "last 1 chrome version", 48 | "last 1 firefox version", 49 | "last 1 safari version" 50 | ] 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-frontend-react-app/public/favicon.ico -------------------------------------------------------------------------------- /bookstore-frontend-react-app/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-frontend-react-app/public/logo192.png -------------------------------------------------------------------------------- /bookstore-frontend-react-app/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-frontend-react-app/public/logo512.png -------------------------------------------------------------------------------- /bookstore-frontend-react-app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/App.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Kaushan+Script&display=swap'); 2 | 3 | body { 4 | margin: 0; 5 | padding: 0; 6 | } 7 | 8 | button { 9 | border-radius: 5px !important; 10 | } 11 | 12 | a { 13 | border-radius: 5px !important; 14 | } 15 | 16 | p { 17 | font-family: sans-serif !important; 18 | } 19 | 20 | .bookstore-brand { 21 | font-family: 'Kaushan Script', cursive; 22 | font-size: 2em !important; 23 | font-weight: 800; 24 | clip-path: polygon(0 30%, 100% 11%, 100% 75%, 0 92%); 25 | 26 | background: rgb(2, 0, 36); 27 | background: linear-gradient(84deg, rgba(2, 0, 36, 1) 21%, rgba(0, 0, 179, 1) 63%, rgba(191, 0, 76, 1) 92%); 28 | padding: 5px; 29 | } 30 | 31 | .bookstore-brand:hover { 32 | color: aquamarine !important; 33 | } 34 | 35 | .fp-container { 36 | position: fixed; 37 | width: 100%; 38 | height: 100%; 39 | top: 0; 40 | left: 0; 41 | background: #111c1fad; 42 | } 43 | 44 | .fp-container .fp-loader { 45 | top: 45%; 46 | left: 48%; 47 | z-index: 10000; 48 | position: absolute; 49 | } 50 | 51 | .pagination { 52 | display: flex; 53 | padding-left: 0; 54 | list-style: none; 55 | border-radius: 0.25rem; 56 | } 57 | 58 | .page-item.active { 59 | z-index: 3; 60 | color: #fff; 61 | /* background-color: #d9230f; */ 62 | /* border-color: #d9230f; */ 63 | } 64 | 65 | .page-item:first-child .page-link { 66 | margin-left: 0; 67 | border-top-left-radius: 0.25rem; 68 | border-bottom-left-radius: 0.25rem; 69 | } 70 | 71 | .page-link { 72 | position: relative; 73 | display: block; 74 | padding: 0.5rem 0.75rem; 75 | margin-left: -1px; 76 | line-height: 1.25; 77 | color: #d9230f; 78 | background-color: #fff; 79 | border: 1px solid #eee; 80 | } 81 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/actions/paymentActions.js: -------------------------------------------------------------------------------- 1 | import { 2 | PAYMENT_METHOD_ADD_REQUEST, 3 | PAYMENT_METHOD_ADD_SUCCESS, 4 | PAYMENT_METHOD_ADD_FAIL, 5 | PAYMENT_METHOD_ADD_RESET, 6 | PAYMENT_METHOD_LIST_MY_REQUEST, 7 | PAYMENT_METHOD_LIST_MY_SUCCESS, 8 | PAYMENT_METHOD_LIST_MY_FAIL, 9 | PAYMENT_METHOD_LIST_MY_RESET 10 | } from '../constants/paymentConstants'; 11 | 12 | import { getErrorMessage } from '../service/CommonUtils'; 13 | import { getAllPaymentMethodsApi, savePaymentMethodApi } from '../service/RestApiCalls'; 14 | 15 | export const savePaymentMethodAction = (cardRequestBody) => async (dispatch) => { 16 | try { 17 | dispatch({ 18 | type: PAYMENT_METHOD_ADD_REQUEST 19 | }); 20 | 21 | //save payment 22 | await savePaymentMethodApi(cardRequestBody); 23 | 24 | dispatch({ 25 | type: PAYMENT_METHOD_ADD_SUCCESS 26 | }); 27 | dispatch(getMyPaymentMethodsAction()); 28 | } catch (error) { 29 | dispatch({ 30 | type: PAYMENT_METHOD_ADD_FAIL, 31 | payload: getErrorMessage(error) 32 | }); 33 | } 34 | }; 35 | 36 | export const getMyPaymentMethodsAction = () => async (dispatch) => { 37 | try { 38 | dispatch({ 39 | type: PAYMENT_METHOD_LIST_MY_REQUEST 40 | }); 41 | 42 | //Get All my payment methods 43 | const paymentMethodsList = await getAllPaymentMethodsApi(); 44 | 45 | dispatch({ 46 | type: PAYMENT_METHOD_LIST_MY_SUCCESS, 47 | payload: paymentMethodsList 48 | }); 49 | } catch (error) { 50 | dispatch({ 51 | type: PAYMENT_METHOD_LIST_MY_FAIL, 52 | payload: getErrorMessage(error) 53 | }); 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/components/CheckoutSteps.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Nav } from 'react-bootstrap'; 3 | import { LinkContainer } from 'react-router-bootstrap'; 4 | 5 | const CheckoutSteps = ({ step1, step2, step3, step4 }) => { 6 | return ( 7 | 48 | ); 49 | }; 50 | 51 | export default CheckoutSteps; 52 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/components/Footer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Footer = () => { 4 | return
; 5 | }; 6 | 7 | export default Footer; 8 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/components/FormContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Container, Row, Col } from 'react-bootstrap'; 3 | 4 | const FormContainer = ({ children }) => { 5 | return ( 6 | 7 | 8 | 9 | {children} 10 | 11 | 12 | 13 | ); 14 | }; 15 | 16 | export default FormContainer; 17 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/components/FullPageLoader.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const FullPageLoader = () => { 4 | return ( 5 |
6 |
7 | 8 |
9 |
10 | ); 11 | }; 12 | 13 | export default FullPageLoader; 14 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/components/Loader.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Spinner } from 'react-bootstrap'; 3 | 4 | const Loader = () => { 5 | return ( 6 |
7 | 17 | Loading... 18 | 19 |
20 | ); 21 | }; 22 | 23 | export default Loader; 24 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/components/Message.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Alert } from 'react-bootstrap'; 3 | 4 | const Message = ({ variant, children }) => { 5 | return ( 6 |
7 | {children} 8 |
9 | ); 10 | }; 11 | 12 | Message.defaultProps = { 13 | variant: 'info' 14 | }; 15 | 16 | export default Message; 17 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/components/Paginate.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Pagination } from 'react-bootstrap'; 3 | import { LinkContainer } from 'react-router-bootstrap'; 4 | 5 | const Paginate = ({ pages, page, isAdmin = false, link }) => { 6 | return ( 7 | pages > 1 && ( 8 | 9 | {[...Array(pages).keys()].map((x) => ( 10 | 11 | {x + 1} 12 | 13 | ))} 14 | 15 | ) 16 | ); 17 | }; 18 | 19 | export default Paginate; 20 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/components/Product.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { BACKEND_API_GATEWAY_URL } from '../constants/appConstants'; 3 | import { Card } from 'react-bootstrap'; 4 | import Rating from './Rating'; 5 | import { Link } from 'react-router-dom'; 6 | 7 | const Product = (props) => { 8 | const product = props.product; 9 | return ( 10 | <> 11 | 12 | 13 | 18 | 19 | 20 | 21 | 22 | {product.productName} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |

${product.price}

32 |
33 |
34 |
35 | 36 | ); 37 | }; 38 | 39 | export default Product; 40 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/components/Rating.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Rating = ({ value, text, color }) => { 4 | return ( 5 |
6 | 7 | = 1 ? 'fas fa-star' : value >= 0.5 ? 'fas fa-star-half-alt' : 'far fa-star'}> 8 | 9 | 10 | = 2 ? 'fas fa-star' : value >= 1.5 ? 'fas fa-star-half-alt' : 'far fa-star'}> 11 | 12 | 13 | = 3 ? 'fas fa-star' : value >= 2.5 ? 'fas fa-star-half-alt' : 'far fa-star'}> 14 | 15 | 16 | = 4 ? 'fas fa-star' : value >= 4.5 ? 'fas fa-star-half-alt' : 'far fa-star'}> 17 | 18 | 19 | = 5 ? 'fas fa-star' : value >= 3.5 ? 'fas fa-star-half-alt' : 'far fa-star'}> 20 | 21 | {text && [{text && text}]} 22 |
23 | ); 24 | }; 25 | 26 | Rating.defaultProps = { 27 | color: '#fee825' 28 | }; 29 | 30 | export default Rating; 31 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/constants/addressConstants.js: -------------------------------------------------------------------------------- 1 | export const ADDRESS_ADD_REQUEST = 'ADDRESS_ADD_REQUEST'; 2 | export const ADDRESS_ADD_SUCCESS = 'ADDRESS_ADD_SUCCESS'; 3 | export const ADDRESS_ADD_FAIL = 'ADDRESS_ADD_FAIL'; 4 | export const ADDRESS_ADD_RESET = 'ADDRESS_ADD_RESET'; 5 | 6 | export const ADDRESS_LIST_MY_REQUEST = 'ADDRESS_LIST_MY_REQUEST'; 7 | export const ADDRESS_LIST_MY_SUCCESS = 'ADDRESS_LIST_MY_SUCCESS'; 8 | export const ADDRESS_LIST_MY_FAIL = 'ADDRESS_LIST_MY_FAIL'; 9 | export const ADDRESS_LIST_MY_RESET = 'ADDRESS_LIST_MY_RESET'; 10 | 11 | export const ADDRESS_DELETE_REQUEST = 'ADDRESS_DELETE_REQUEST'; 12 | export const ADDRESS_DELETE_SUCCESS = 'ADDRESS_DELETE_SUCCESS'; 13 | export const ADDRESS_DELETE_FAIL = 'ADDRESS_DELETE_FAIL'; 14 | export const ADDRESS_DELETE_RESET = 'ADDRESS_DELETE_RESET'; 15 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/constants/appConstants.js: -------------------------------------------------------------------------------- 1 | export const BACKEND_API_GATEWAY_URL = 'http://localhost:8765'; 2 | export const APP_CLIENT_ID = '93ed453e-b7ac-4192-a6d4-c45fae0d99ac'; 3 | export const APP_CLIENT_SECRET = 'client.devd123'; 4 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/constants/cartConstants.js: -------------------------------------------------------------------------------- 1 | export const CART_CLEAR_ITEMS = 'CART_RESET'; 2 | export const CART_REMOVE_ITEM = 'CART_REMOVE_ITEM'; 3 | export const CART_SAVE_SHIPPING_ADDRESS = 'CART_SAVE_SHIPPING_ADDRESS'; 4 | export const CART_SAVE_PAYMENT_METHOD = 'CART_SAVE_PAYMENT_METHOD'; 5 | 6 | export const CART_DETAILS_REQUEST = 'CART_DETAILS_REQUEST'; 7 | export const CART_DETAILS_SUCCESS = 'CART_DETAILS_SUCCESS'; 8 | export const CART_DETAILS_FAIL = 'CART_DETAILS_FAIL'; 9 | export const CART_DETAILS_RESET = 'CART_DETAILS_RESET'; 10 | 11 | export const CART_ADD_ITEM_REQUEST = 'CART_ADD_ITEM_REQUEST'; 12 | export const CART_ADD_ITEM_SUCCESS = 'CART_ADD_ITEM_SUCCESS'; 13 | export const CART_ADD_ITEM_FAIL = 'CART_ADD_ITEM_FAIL'; 14 | export const CART_ADD_ITEM_RESET = 'CART_ADD_ITEM_RESET'; 15 | 16 | export const CART_REMOVE_ITEM_REQUEST = 'CART_REMOVE_ITEM_REQUEST'; 17 | export const CART_REMOVE_ITEM_SUCCESS = 'CART_REMOVE_ITEM_SUCCESS'; 18 | export const CART_REMOVE_ITEM_FAIL = 'CART_REMOVE_ITEM_FAIL'; 19 | export const CART_REMOVE_ITEM_RESET = 'CART_REMOVE_ITEM_RESET'; 20 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/constants/orderConstants.js: -------------------------------------------------------------------------------- 1 | export const ORDER_PREVIEW_REQUEST = 'ORDER_PREVIEW_REQUEST'; 2 | export const ORDER_PREVIEW_SUCCESS = 'ORDER_PREVIEW_SUCCESS'; 3 | export const ORDER_PREVIEW_FAIL = 'ORDER_PREVIEW_FAIL'; 4 | export const ORDER_PREVIEW_RESET = 'ORDER_PREVIEW_RESET'; 5 | 6 | export const ORDER_CREATE_REQUEST = 'ORDER_CREATE_REQUEST'; 7 | export const ORDER_CREATE_SUCCESS = 'ORDER_CREATE_SUCCESS'; 8 | export const ORDER_CREATE_FAIL = 'ORDER_CREATE_FAIL'; 9 | export const ORDER_CREATE_RESET = 'ORDER_CREATE_RESET'; 10 | 11 | export const ORDER_DETAILS_REQUEST = 'ORDER_DETAILS_REQUEST'; 12 | export const ORDER_DETAILS_SUCCESS = 'ORDER_DETAILS_SUCCESS'; 13 | export const ORDER_DETAILS_FAIL = 'ORDER_DETAILS_FAIL'; 14 | 15 | export const ORDER_PAY_REQUEST = 'ORDER_PAY_REQUEST'; 16 | export const ORDER_PAY_SUCCESS = 'ORDER_PAY_SUCCESS'; 17 | export const ORDER_PAY_FAIL = 'ORDER_PAY_FAIL'; 18 | export const ORDER_PAY_RESET = 'ORDER_PAY_RESET'; 19 | 20 | export const ORDER_LIST_MY_REQUEST = 'ORDER_LIST_MY_REQUEST'; 21 | export const ORDER_LIST_MY_SUCCESS = 'ORDER_LIST_MY_SUCCESS'; 22 | export const ORDER_LIST_MY_FAIL = 'ORDER_LIST_MY_FAIL'; 23 | export const ORDER_LIST_MY_RESET = 'ORDER_LIST_MY_RESET'; 24 | 25 | export const ORDER_LIST_REQUEST = 'ORDER_LIST_REQUEST'; 26 | export const ORDER_LIST_SUCCESS = 'ORDER_LIST_SUCCESS'; 27 | export const ORDER_LIST_FAIL = 'ORDER_LIST_FAIL'; 28 | export const ORDER_LIST_RESET = 'ORDER_LIST_RESET'; 29 | 30 | export const ORDER_DELIVER_REQUEST = 'ORDER_DELIVER_REQUEST'; 31 | export const ORDER_DELIVER_SUCCESS = 'ORDER_DELIVER_SUCCESS'; 32 | export const ORDER_DELIVER_FAIL = 'ORDER_DELIVER_FAIL'; 33 | export const ORDER_DELIVER_RESET = 'ORDER_DELIVER_RESET'; 34 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/constants/paymentConstants.js: -------------------------------------------------------------------------------- 1 | export const PAYMENT_METHOD_ADD_REQUEST = 'PAYMENT_METHOD_ADD_REQUEST'; 2 | export const PAYMENT_METHOD_ADD_SUCCESS = 'PAYMENT_METHOD_ADD_SUCCESS'; 3 | export const PAYMENT_METHOD_ADD_FAIL = 'PAYMENT_METHOD_ADD_FAIL'; 4 | export const PAYMENT_METHOD_ADD_RESET = 'PAYMENT_METHOD_ADD_RESET'; 5 | 6 | export const PAYMENT_METHOD_LIST_MY_REQUEST = 'PAYMENT_METHOD_LIST_MY_REQUEST'; 7 | export const PAYMENT_METHOD_LIST_MY_SUCCESS = 'PAYMENT_METHOD_LIST_MY_SUCCESS'; 8 | export const PAYMENT_METHOD_LIST_MY_FAIL = 'PAYMENT_METHOD_LIST_MY_FAIL'; 9 | export const PAYMENT_METHOD_LIST_MY_RESET = 'PAYMENT_METHOD_LIST_MY_RESET'; 10 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/constants/userConstants.js: -------------------------------------------------------------------------------- 1 | export const USER_LOGIN_REQUEST = 'USER_LOGIN_REQUEST'; 2 | export const USER_LOGIN_SUCCESS = 'USER_LOGIN_SUCCESS'; 3 | export const USER_LOGIN_FAIL = 'USER_LOGIN_FAIL'; 4 | export const USER_LOGOUT = 'USER_LOGOUT'; 5 | 6 | export const USER_REGISTER_REQUEST = 'USER_REGISTER_REQUEST'; 7 | export const USER_REGISTER_SUCCESS = 'USER_REGISTER_SUCCESS'; 8 | export const USER_REGISTER_FAIL = 'USER_REGISTER_FAIL'; 9 | export const USER_REGISTER_RESET = 'USER_REGISTER_RESET'; 10 | 11 | export const USER_DETAILS_REQUEST = 'USER_DETAILS_REQUEST'; 12 | export const USER_DETAILS_SUCCESS = 'USER_DETAILS_SUCCESS'; 13 | export const USER_DETAILS_FAIL = 'USER_DETAILS_FAIL'; 14 | export const USER_DETAILS_RESET = 'USER_DETAILS_RESET'; 15 | 16 | export const USER_UPDATE_PROFILE_REQUEST = 'USER_UPDATE_PROFILE_REQUEST'; 17 | export const USER_UPDATE_PROFILE_SUCCESS = 'USER_UPDATE_PROFILE_SUCCESS'; 18 | export const USER_UPDATE_PROFILE_FAIL = 'USER_UPDATE_PROFILE_FAIL'; 19 | export const USER_UPDATE_PROFILE_RESET = 'USER_UPDATE_PROFILE_RESET'; 20 | 21 | export const USER_LIST_REQUEST = 'USER_LIST_REQUEST'; 22 | export const USER_LIST_SUCCESS = 'USER_LIST_SUCCESS'; 23 | export const USER_LIST_FAIL = 'USER_LIST_FAIL'; 24 | export const USER_LIST_RESET = 'USER_LIST_RESET'; 25 | 26 | export const USER_DELETE_REQUEST = 'USER_DELETE_REQUEST'; 27 | export const USER_DELETE_SUCCESS = 'USER_DELETE_SUCCESS'; 28 | export const USER_DELETE_FAIL = 'USER_DELETE_FAIL'; 29 | 30 | export const USER_UPDATE_REQUEST = 'USER_UPDATE_REQUEST'; 31 | export const USER_UPDATE_SUCCESS = 'USER_UPDATE_SUCCESS'; 32 | export const USER_UPDATE_FAIL = 'USER_UPDATE_FAIL'; 33 | export const USER_UPDATE_RESET = 'USER_UPDATE_RESET'; 34 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 4 | 'Helvetica Neue', sans-serif; 5 | -webkit-font-smoothing: antialiased; 6 | -moz-osx-font-smoothing: grayscale; 7 | } 8 | 9 | code { 10 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; 11 | } 12 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | import store from './store'; 5 | import './bootstrap.min.css'; 6 | import './index.css'; 7 | import reportWebVitals from './reportWebVitals'; 8 | import { Provider } from 'react-redux'; 9 | 10 | ReactDOM.render( 11 | 12 | 13 | 14 | 15 | , 16 | document.getElementById('root') 17 | ); 18 | 19 | // If you want to start measuring performance in your app, pass a function 20 | // to log results (for example: reportWebVitals(console.log)) 21 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 22 | reportWebVitals(); 23 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/reducers/paymentReducers.js: -------------------------------------------------------------------------------- 1 | import { 2 | PAYMENT_METHOD_ADD_REQUEST, 3 | PAYMENT_METHOD_ADD_SUCCESS, 4 | PAYMENT_METHOD_ADD_FAIL, 5 | PAYMENT_METHOD_ADD_RESET, 6 | PAYMENT_METHOD_LIST_MY_REQUEST, 7 | PAYMENT_METHOD_LIST_MY_SUCCESS, 8 | PAYMENT_METHOD_LIST_MY_FAIL, 9 | PAYMENT_METHOD_LIST_MY_RESET 10 | } from '../constants/paymentConstants'; 11 | 12 | export const paymentMethodSaveReducer = (state = {}, action) => { 13 | switch (action.type) { 14 | case PAYMENT_METHOD_ADD_REQUEST: 15 | return { 16 | ...state, 17 | loading: true 18 | }; 19 | case PAYMENT_METHOD_ADD_SUCCESS: 20 | return { 21 | loading: false, 22 | success: true 23 | }; 24 | case PAYMENT_METHOD_ADD_FAIL: 25 | return { 26 | loading: false, 27 | error: action.payload 28 | }; 29 | case PAYMENT_METHOD_ADD_RESET: 30 | return {}; 31 | default: 32 | return state; 33 | } 34 | }; 35 | 36 | export const paymentMethodListMyReducer = (state = { paymentMethods: [] }, action) => { 37 | switch (action.type) { 38 | case PAYMENT_METHOD_LIST_MY_REQUEST: 39 | return { 40 | ...state, 41 | loading: true 42 | }; 43 | case PAYMENT_METHOD_LIST_MY_SUCCESS: 44 | return { 45 | loading: false, 46 | paymentMethods: action.payload 47 | }; 48 | case PAYMENT_METHOD_LIST_MY_FAIL: 49 | return { 50 | loading: false, 51 | error: action.payload 52 | }; 53 | case PAYMENT_METHOD_LIST_MY_RESET: 54 | return { paymentMethods: [] }; 55 | default: 56 | return state; 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = (onPerfEntry) => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/service/CommonUtils.js: -------------------------------------------------------------------------------- 1 | import jwtDecode from 'jwt-decode'; 2 | 3 | export const getErrorMessage = (error) => { 4 | return error 5 | ? error.response 6 | ? error.response.data 7 | ? error.response.data.error_description 8 | ? error.response.data.error_description 9 | : error.response.data.errors.length > 0 10 | ? error.response.data.errors[0].message 11 | : error.message 12 | : error.message 13 | : error.message 14 | : 'Something went wrong'; 15 | }; 16 | 17 | export const isAdmin = () => { 18 | const userInfoLocalStorage = localStorage.getItem('userInfo'); 19 | if (userInfoLocalStorage) { 20 | const token = JSON.parse(userInfoLocalStorage).token; 21 | let decodedToken = jwtDecode(token); 22 | return decodedToken?.authorities?.includes('ADMIN_USER'); 23 | } 24 | return false; 25 | }; 26 | -------------------------------------------------------------------------------- /bookstore-frontend-react-app/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /bookstore-graphana/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM grafana/grafana 2 | 3 | # Add in the configuration file from the local directory. 4 | ADD datasource.yml /etc/grafana/provisioning/datasources/datasource.yml 5 | ADD dashboard.yml /etc/grafana/provisioning/dashboards/dashboard.yml 6 | ADD services-dashboard.json /var/lib/grafana/dashboards/services-dashboard.json 7 | ADD docker-container-dashboard.json /var/lib/grafana/dashboards/docker-container-dashboard.json 8 | ADD docker-all-dashboard.json /var/lib/grafana/dashboards/docker-all-dashboard.json -------------------------------------------------------------------------------- /bookstore-graphana/dashboard.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | providers: 4 | # an unique provider name 5 | - name: 'Bookstore' 6 | # org id. will default to orgId 1 if not specified 7 | orgId: 1 8 | # name of the dashboard folder. Required 9 | folder: '' 10 | # folder UID. will be automatically generated if not specified 11 | folderUid: '' 12 | # provider type. Required 13 | type: file 14 | # disable dashboard deletion 15 | disableDeletion: false 16 | # enable dashboard editing 17 | editable: true 18 | # how often Grafana will scan for changed dashboards 19 | updateIntervalSeconds: 10 20 | options: 21 | # path to dashboard files on disk. Required 22 | path: /var/lib/grafana/dashboards -------------------------------------------------------------------------------- /bookstore-order-service/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | /target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | .sts4-cache 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | 20 | ### NetBeans ### 21 | /nbproject/private/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | /build/ 27 | 28 | ### VS Code ### 29 | .vscode/ 30 | -------------------------------------------------------------------------------- /bookstore-order-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | 3 | VOLUME /tmp 4 | 5 | ARG JAR_FILE 6 | 7 | COPY target/${JAR_FILE} order-service.jar 8 | 9 | #Using Dokerize to check whether db is up, if it is then start this service. 10 | COPY dockerize dockerize 11 | 12 | CMD ./dockerize -wait tcp://bookstore-mysql-db:3306 -timeout 15m java -Djava.security.egd=file:/dev/./urandom -jar /order-service.jar -------------------------------------------------------------------------------- /bookstore-order-service/dockerize: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-order-service/dockerize -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/BookstoreOrderServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 6 | import org.springframework.cloud.openfeign.EnableFeignClients; 7 | import org.springframework.context.annotation.ComponentScan; 8 | 9 | /** 10 | * @author: Devaraj Reddy, 11 | * Date : 2019-13-06 12 | */ 13 | @SpringBootApplication(scanBasePackages = {"com.devd.spring.bookstorecommons"}) 14 | @ComponentScan(basePackages = {"com.devd.spring"}) 15 | //, excludeFilters={ 16 | // @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=GlobalSecurityConfig.class)}) 17 | @EnableFeignClients(value = "com.devd.spring") 18 | @EnableEurekaClient 19 | public class BookstoreOrderServiceApplication { 20 | 21 | public static void main(String[] args) { 22 | SpringApplication.run(BookstoreOrderServiceApplication.class, args); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/config/AuthForwardInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.config; 2 | 3 | import feign.RequestInterceptor; 4 | import feign.RequestTemplate; 5 | import org.springframework.http.HttpHeaders; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.web.context.request.RequestContextHolder; 8 | import org.springframework.web.context.request.ServletRequestAttributes; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | import java.util.Objects; 12 | 13 | /** 14 | * @author: Devaraj Reddy, 15 | * Date : 2019-07-02 16 | */ 17 | 18 | /* 19 | This is required for Feign clients to make request to services. 20 | It takes the token from header and set the header in the feign request header. 21 | */ 22 | @Component 23 | public class AuthForwardInterceptor implements RequestInterceptor { 24 | 25 | @Override 26 | public void apply(RequestTemplate template) { 27 | HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); 28 | template.header(HttpHeaders.AUTHORIZATION, request.getHeader(HttpHeaders.AUTHORIZATION)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/config/OrderServiceConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.config; 2 | 3 | import feign.Logger; 4 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.client.RestTemplate; 8 | 9 | /** 10 | * @author: Devaraj Reddy, 11 | * Date : 2019-07-01 12 | */ 13 | @Configuration 14 | public class OrderServiceConfig { 15 | 16 | @LoadBalanced 17 | @Bean 18 | RestTemplate restTemplate() { 19 | return new RestTemplate(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/config/OrderServiceResourceServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.config; 2 | 3 | import com.devd.spring.bookstorecommons.security.GlobalResourceServerConfig; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; 7 | import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; 8 | 9 | @Configuration 10 | public class OrderServiceResourceServerConfig extends GlobalResourceServerConfig { 11 | 12 | @Autowired 13 | private ResourceServerTokenServices tokenServices; 14 | 15 | @Override 16 | public void configure(ResourceServerSecurityConfigurer resources) { 17 | resources.resourceId("web").tokenServices(tokenServices); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/CartController.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.controller; 2 | 3 | import com.devd.spring.bookstoreorderservice.web.CreateCartResponse; 4 | import com.devd.spring.bookstoreorderservice.service.CartService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.security.access.prepost.PreAuthorize; 9 | import org.springframework.web.bind.annotation.CrossOrigin; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PostMapping; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | /** 15 | * @author: Devaraj Reddy, 16 | * Date : 2019-07-02 17 | */ 18 | @RestController 19 | @CrossOrigin 20 | public class CartController { 21 | 22 | @Autowired 23 | private CartService cartService; 24 | 25 | @PostMapping("/cart") 26 | @PreAuthorize("hasAuthority('STANDARD_USER') or hasAuthority('ADMIN_USER')" ) 27 | public ResponseEntity createCart() { 28 | 29 | String cartId = cartService.createCart(); 30 | 31 | CreateCartResponse createCartResponse = CreateCartResponse.builder() 32 | .cartId(cartId) 33 | .build(); 34 | 35 | return ResponseEntity.status(HttpStatus.CREATED).body(createCartResponse); 36 | } 37 | 38 | @GetMapping("/cart") 39 | public ResponseEntity getCart(){ 40 | 41 | return ResponseEntity.ok(cartService.getCart()); 42 | 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/CartItemController.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.controller; 2 | 3 | import com.devd.spring.bookstoreorderservice.service.CartItemService; 4 | import com.devd.spring.bookstoreorderservice.web.CartItemRequest; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.web.bind.annotation.CrossOrigin; 8 | import org.springframework.web.bind.annotation.DeleteMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | import org.springframework.web.bind.annotation.ResponseStatus; 14 | import org.springframework.web.bind.annotation.RestController; 15 | 16 | /** 17 | * @author: Devaraj Reddy, 18 | * Date : 2019-06-17 19 | */ 20 | @RestController 21 | @CrossOrigin 22 | public class CartItemController { 23 | 24 | @Autowired 25 | CartItemService cartItemService; 26 | 27 | @PostMapping("/cart/cartItem") 28 | @ResponseStatus(value = HttpStatus.OK) 29 | public void addCartItem(@RequestBody CartItemRequest cartItemRequest) { 30 | cartItemService.addCartItem(cartItemRequest); 31 | } 32 | 33 | @DeleteMapping("/cart/cartItem/{cartItemId}") 34 | @ResponseStatus(value = HttpStatus.NO_CONTENT) 35 | public void removeCartItem(@PathVariable(value = "cartItemId") String cartItemId) { 36 | cartItemService.removeCartItem(cartItemId); 37 | } 38 | 39 | @DeleteMapping("/cart/cartItem") 40 | @ResponseStatus(value = HttpStatus.NO_CONTENT) 41 | public void removeAllCartItems(@RequestParam(value = "cartId") String cartId) { 42 | cartItemService.removeAllCartItems(cartId); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/CartItemRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.repository; 2 | 3 | import com.devd.spring.bookstoreorderservice.repository.dao.CartItem; 4 | import org.springframework.data.jpa.repository.Modifying; 5 | import org.springframework.data.repository.CrudRepository; 6 | 7 | import javax.transaction.Transactional; 8 | import java.util.Optional; 9 | 10 | /** 11 | * @author: Devaraj Reddy, 12 | * Date : 2019-07-13 13 | */ 14 | 15 | public interface CartItemRepository extends CrudRepository { 16 | 17 | @Modifying 18 | @Transactional 19 | void deleteByCartItemId(String cartItemId); 20 | 21 | Optional findByCartItemId(String cartItemId); 22 | } 23 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/CartRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.repository; 2 | 3 | import com.devd.spring.bookstoreorderservice.repository.dao.Cart; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | import javax.transaction.Transactional; 7 | import java.util.Optional; 8 | 9 | /** 10 | * @author: Devaraj Reddy, 11 | * Date : 2019-07-08 12 | */ 13 | @Transactional 14 | public interface CartRepository extends CrudRepository { 15 | 16 | Cart findCartByUserName(String userName); 17 | 18 | Optional findByCartId(String cartId); 19 | } 20 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/OrderBillingAddressRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.repository; 2 | 3 | import com.devd.spring.bookstoreorderservice.repository.dao.OrderBillingAddress; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | /** 7 | * @author Devaraj Reddy, Date : 07-Dec-2020 8 | */ 9 | public interface OrderBillingAddressRepository extends CrudRepository { 10 | OrderBillingAddress findByOrderId(String orderId); 11 | } 12 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/OrderItemRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.repository; 2 | 3 | import com.devd.spring.bookstoreorderservice.repository.dao.OrderItem; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | /** 7 | * @author: Devaraj Reddy, 8 | * Date : 2019-09-18 9 | */ 10 | public interface OrderItemRepository extends CrudRepository { 11 | } 12 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.repository; 2 | 3 | import com.devd.spring.bookstoreorderservice.repository.dao.Order; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author: Devaraj Reddy, 10 | * Date : 2019-09-18 11 | */ 12 | public interface OrderRepository extends CrudRepository { 13 | 14 | Order findByOrderId(String orderId); 15 | 16 | List findByUserId(String userId); 17 | } 18 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/OrderShippingAddressRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.repository; 2 | 3 | import com.devd.spring.bookstoreorderservice.repository.dao.OrderShippingAddress; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | /** 7 | * @author Devaraj Reddy, Date : 07-Dec-2020 8 | */ 9 | public interface OrderShippingAddressRepository extends CrudRepository { 10 | OrderShippingAddress findByOrderId(String orderId); 11 | } 12 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/dao/OrderItem.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.repository.dao; 2 | 3 | import com.devd.spring.bookstorecommons.util.DateAudit; 4 | import com.fasterxml.jackson.annotation.JsonIgnore; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | import org.hibernate.annotations.GenericGenerator; 9 | 10 | import javax.persistence.CascadeType; 11 | import javax.persistence.Column; 12 | import javax.persistence.Entity; 13 | import javax.persistence.GeneratedValue; 14 | import javax.persistence.Id; 15 | import javax.persistence.JoinColumn; 16 | import javax.persistence.ManyToOne; 17 | import javax.persistence.Table; 18 | 19 | /** 20 | * @author: Devaraj Reddy, 21 | * Date : 2019-09-18 22 | */ 23 | @Entity 24 | @Table(name = "ORDER_ITEM") 25 | @Data 26 | @NoArgsConstructor 27 | @AllArgsConstructor 28 | public class OrderItem extends DateAudit { 29 | 30 | @Id 31 | @GeneratedValue(generator = "uuid") 32 | @GenericGenerator(name = "uuid", strategy = "uuid2") 33 | @Column(name = "ORDER_ITEM_ID", updatable = false, nullable = false) 34 | private String orderItemId; 35 | 36 | @ManyToOne(cascade = CascadeType.ALL) 37 | @JoinColumn(name = "ORDER_ID") 38 | @JsonIgnore 39 | private Order order; 40 | 41 | @Column(name = "PRODUCT_ID", nullable = false) 42 | private String productId; 43 | 44 | @Column(name = "QUANTITY", nullable = false) 45 | private int quantity; 46 | 47 | @Column(name = "ORDER_ITEM_PRICE", nullable = false) 48 | private double orderItemPrice; 49 | 50 | @Column(name = "ORDER_EXTENDED_PRICE", nullable = false) 51 | private double orderExtendedPrice; 52 | 53 | } 54 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/CartItemService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.service; 2 | 3 | import com.devd.spring.bookstoreorderservice.repository.dao.CartItem; 4 | import com.devd.spring.bookstoreorderservice.web.CartItemRequest; 5 | 6 | /** 7 | * @author: Devaraj Reddy, 8 | * Date : 2019-06-17 9 | */ 10 | public interface CartItemService { 11 | 12 | void addCartItem(CartItemRequest cartItemRequest); 13 | void removeCartItem(String cartItemId); 14 | CartItem getCartItem(String cartItemId); 15 | void removeAllCartItems(String cartId); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/CartService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.service; 2 | 3 | import com.devd.spring.bookstoreorderservice.repository.dao.Cart; 4 | 5 | /** 6 | * @author: Devaraj Reddy, 7 | * Date : 2019-06-17 8 | */ 9 | public interface CartService { 10 | 11 | Cart getCart(); 12 | 13 | Cart getCartByCartId(String cartId); 14 | 15 | String createCart(); 16 | 17 | Cart getCartByUserName(String userName); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/OrderService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.service; 2 | 3 | import com.devd.spring.bookstoreorderservice.web.CreateOrderRequest; 4 | import com.devd.spring.bookstoreorderservice.web.CreateOrderResponse; 5 | import com.devd.spring.bookstoreorderservice.web.PreviewOrderRequest; 6 | import com.devd.spring.bookstoreorderservice.web.PreviewOrderResponse; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author: Devaraj Reddy, 12 | * Date : 2019-09-20 13 | */ 14 | public interface OrderService { 15 | 16 | CreateOrderResponse createOrder(CreateOrderRequest createOrderRequest); 17 | 18 | PreviewOrderResponse previewOrder(PreviewOrderRequest previewOrderRequest); 19 | 20 | CreateOrderResponse getOrderById(String orderId); 21 | 22 | List getMyOrders(); 23 | 24 | List getAllOrders(); 25 | } 26 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/web/Card.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author Devaraj Reddy, Date : 25-Jul-2020 9 | */ 10 | @Data 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class Card { 14 | private String paymentMethodId; 15 | private String cardBrand; 16 | private String last4Digits; 17 | } 18 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/web/CartItemRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.validation.constraints.Min; 9 | import javax.validation.constraints.NotEmpty; 10 | import javax.validation.constraints.NotNull; 11 | 12 | /** 13 | * @author: Devaraj Reddy, 14 | * Date : 2019-08-29 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | @Builder 20 | public class CartItemRequest { 21 | 22 | @NotNull(message = "productId should not be null!") 23 | @NotEmpty(message = "productId should not be empty!") 24 | private String productId; 25 | 26 | @Min(message = "quantity should be greater than 0", value = 1) 27 | private Integer quantity; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/web/CreateCartResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author: Devaraj Reddy, 10 | * Date : 2019-07-13 11 | */ 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @Builder 16 | public class CreateCartResponse { 17 | private String cartId; 18 | } 19 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/web/CreateOrderRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.validation.constraints.NotBlank; 9 | 10 | /** 11 | * @author Devaraj Reddy, Date : 06-Dec-2020 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @Builder 17 | public class CreateOrderRequest { 18 | private String billingAddressId; 19 | @NotBlank 20 | private String shippingAddressId; 21 | @NotBlank 22 | private String paymentMethodId; 23 | } 24 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/web/CreateOrderResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.web; 2 | 3 | import com.devd.spring.bookstoreorderservice.repository.dao.OrderBillingAddress; 4 | import com.devd.spring.bookstoreorderservice.repository.dao.OrderItem; 5 | import com.devd.spring.bookstoreorderservice.repository.dao.OrderShippingAddress; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | import java.time.Instant; 12 | import java.time.LocalDateTime; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | /** 17 | * @author: Devaraj Reddy, 18 | * Date : 2019-09-20 19 | */ 20 | @Data 21 | @NoArgsConstructor 22 | @AllArgsConstructor 23 | @Builder 24 | public class CreateOrderResponse { 25 | private String orderId; 26 | private List orderItems = new ArrayList<>(); 27 | private OrderShippingAddress shippingAddress; 28 | private OrderBillingAddress billingAddress; 29 | private Card card; 30 | private Double itemsTotalPrice; 31 | private Double taxPrice; 32 | private Double shippingPrice; 33 | private Double totalPrice; 34 | private boolean isPaid; 35 | private LocalDateTime paymentDate; 36 | private boolean isDelivered; 37 | private String paymentReceiptUrl; 38 | private LocalDateTime deliveredDate; 39 | private Instant created_at; 40 | } 41 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/web/PreviewOrderRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.validation.constraints.NotBlank; 9 | 10 | /** 11 | * @author Devaraj Reddy, Date : 06-Dec-2020 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @Builder 17 | public class PreviewOrderRequest { 18 | private String billingAddressId; 19 | @NotBlank 20 | private String shippingAddressId; 21 | @NotBlank 22 | private String paymentMethodId; 23 | } 24 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/web/PreviewOrderResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice.web; 2 | 3 | import com.devd.spring.bookstorecommons.web.GetAddressResponse; 4 | import com.devd.spring.bookstoreorderservice.repository.dao.OrderItem; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | /** 14 | * @author Devaraj Reddy, Date : 06-Dec-2020 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | @Builder 20 | public class PreviewOrderResponse { 21 | private List orderItems = new ArrayList<>(); 22 | private GetAddressResponse shippingAddress; 23 | private GetAddressResponse billingAddress; 24 | private Card card; 25 | private Double itemsTotalPrice; 26 | private Double taxPrice; 27 | private Double shippingPrice; 28 | private Double totalPrice; 29 | } 30 | -------------------------------------------------------------------------------- /bookstore-order-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: bookstore-order-service 4 | profiles: 5 | active: ${SPRING_PROFILES_ACTIVE:local} 6 | 7 | management: 8 | endpoints: 9 | web: 10 | exposure: 11 | include: "*" 12 | 13 | --- 14 | 15 | spring: 16 | profiles: local, mysql 17 | cloud: 18 | bus: 19 | enabled: false 20 | consul: 21 | enabled: false #consul discovery set false, in this profile eureka discovery is enabled. 22 | 23 | eureka: 24 | client: 25 | serviceUrl: 26 | defaultZone: http://${EUREKA_HOST:localhost:8761}/eureka/ 27 | registerWithEureka: true 28 | enabled: true #eureka discovery is enabled in this profile 29 | instance: 30 | prefer-ip-address: false 31 | 32 | management: 33 | metrics: 34 | export: 35 | influx: 36 | enabled: false #influx metrics not pushing in this profile 37 | 38 | --- 39 | 40 | spring: 41 | profiles: docker 42 | cloud: 43 | consul: 44 | host: bookstore-consul-discovery 45 | port: 8500 46 | discovery: 47 | instanceId: ${spring.application.name}:${random.value} 48 | enabled: true #consul discovery is enabled in this profile 49 | 50 | management: 51 | metrics: 52 | export: 53 | statsd: 54 | enabled: true 55 | flavor: telegraf 56 | port: 8125 57 | influx: #pushing influx metrics. 58 | db: bookstore_influxdb_monitoring_metrics 59 | uri: http://bookstore-influxdb:8086 60 | auto-create-db: true 61 | endpoints: 62 | web: 63 | exposure: 64 | include: "*" 65 | 66 | eureka: 67 | client: 68 | enabled: false #eureka discovery set false, in this profile consul discovery is enabled. -------------------------------------------------------------------------------- /bookstore-order-service/src/main/resources/db/migration/V2__order_service_initial_data.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-order-service/src/main/resources/db/migration/V2__order_service_initial_data.sql -------------------------------------------------------------------------------- /bookstore-order-service/src/main/resources/jwt-signing-public-key.txt: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0sp8Cy1+sJgJLToO9FvW 3 | cY4AXnp027T0diFOv8cjxD+KESAmZ7cL1jy91nQASn7dCM5qNL5KzJGrp43fIbf+ 4 | HzRv4snj7NoDF5UzgI/fJ/AA3BoIyhkt0QkiKEe2kQFbIfrD5RSHvjLecRnkV71i 5 | A27PqY+kk9QZ2TGTXoMKCADF8JIHHxf+RXVb/GdGi+zCWshXrvJsjR2ZayXFpNDf 6 | QrnsMj14Jxed16ioIdx8yf1fWZxHv9q+uev86CR4E8Xrwg0yJoYHpSdK1J4EvK35 7 | zA2gaGUcfgkZQS5M5bbhrZx1wy8N+8GNkYB0uDVZhnXc2xr4KBO7LGYeP0toA4rh 8 | 1wIDAQAB 9 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /bookstore-order-service/src/test/java/com/devd/spring/bookstoreorderservice/BookstoreOrderServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstoreorderservice; 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 BookstoreOrderServiceApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /bookstore-payment-service/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | /target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | .sts4-cache 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | 20 | ### NetBeans ### 21 | /nbproject/private/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | /build/ 27 | 28 | ### VS Code ### 29 | .vscode/ 30 | -------------------------------------------------------------------------------- /bookstore-payment-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | 3 | VOLUME /tmp 4 | 5 | ARG JAR_FILE 6 | 7 | COPY target/${JAR_FILE} payment-service.jar 8 | 9 | #Using Dokerize to check whether db is up, if it is then start this service. 10 | COPY dockerize dockerize 11 | 12 | CMD ./dockerize -wait tcp://bookstore-mysql-db:3306 -timeout 15m java -Djava.security.egd=file:/dev/./urandom -jar /payment-service.jar 13 | -------------------------------------------------------------------------------- /bookstore-payment-service/dockerize: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-payment-service/dockerize -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/BookstorePaymentServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice; 2 | 3 | import com.stripe.Stripe; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.cloud.openfeign.EnableFeignClients; 8 | import org.springframework.context.annotation.ComponentScan; 9 | 10 | /** 11 | * @author Devaraj Reddy, Date : 25-Jul-2020 12 | */ 13 | @SpringBootApplication 14 | @ComponentScan(basePackages = {"com.devd.spring"}) 15 | @EnableFeignClients(basePackages = {"com.devd.spring"}) 16 | @EnableDiscoveryClient 17 | public class BookstorePaymentServiceApplication { 18 | 19 | public static void main(String[] args) { 20 | SpringApplication.run(BookstorePaymentServiceApplication.class, args); 21 | Stripe.apiKey = "sk_test_51HyGx6G9R9y827ntfKTizO243LzKHnaNIucO8i7apU0zuTIE5iNAes6l64aoWczGwiCnnBNsvvrgS95nfpbWa2cw00FnScmrhd"; 22 | } 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/config/AuthForwardInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.config; 2 | 3 | import feign.RequestInterceptor; 4 | import feign.RequestTemplate; 5 | import org.springframework.http.HttpHeaders; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.web.context.request.RequestContextHolder; 8 | import org.springframework.web.context.request.ServletRequestAttributes; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | import java.util.Objects; 12 | 13 | /** 14 | * @author Devaraj Reddy, Date : 25-Jul-2020 15 | */ 16 | 17 | /* 18 | This is required for Feign clients to make request to services. 19 | It takes the token from header and set the header in the feign request header. 20 | */ 21 | @Component 22 | public class AuthForwardInterceptor implements RequestInterceptor { 23 | 24 | @Override 25 | public void apply(RequestTemplate template) { 26 | HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); 27 | template.header(HttpHeaders.AUTHORIZATION, request.getHeader(HttpHeaders.AUTHORIZATION)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/config/PaymentResourceServiceConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.config; 2 | 3 | import com.devd.spring.bookstorecommons.security.GlobalResourceServerConfig; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; 7 | import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; 8 | 9 | /** 10 | * @author Devaraj Reddy, Date : 25-Jul-2020 11 | */ 12 | @Configuration 13 | public class PaymentResourceServiceConfig extends GlobalResourceServerConfig { 14 | 15 | @Autowired 16 | private ResourceServerTokenServices tokenServices; 17 | 18 | @Override 19 | public void configure(ResourceServerSecurityConfigurer resources) { 20 | resources.resourceId("web").tokenServices(tokenServices); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/config/PaymentServiceConfig.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.config; 2 | 3 | import feign.Logger; 4 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.client.RestTemplate; 8 | 9 | /** 10 | * @author Devaraj Reddy, Date : 25-Jul-2020 11 | */ 12 | @Configuration 13 | public class PaymentServiceConfig { 14 | 15 | @Bean 16 | Logger.Level feignLoggerLevel() { 17 | return Logger.Level.FULL; 18 | } 19 | 20 | @LoadBalanced 21 | @Bean 22 | RestTemplate restTemplate() { 23 | return new RestTemplate(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/controller/PaymentsController.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.controller; 2 | 3 | import com.devd.spring.bookstorepaymentservice.service.PaymentsService; 4 | import com.devd.spring.bookstorepaymentservice.web.CreatePaymentRequest; 5 | import com.devd.spring.bookstorepaymentservice.web.CreatePaymentResponse; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.http.ResponseEntity; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import javax.validation.Valid; 15 | 16 | /** 17 | * @author Devaraj Reddy, Date : 25-Jul-2020 18 | */ 19 | @RestController 20 | @Slf4j 21 | public class PaymentsController { 22 | 23 | @Autowired 24 | private PaymentsService paymentsService; 25 | 26 | @PostMapping("/pay") 27 | public ResponseEntity doPayment(@RequestBody @Valid CreatePaymentRequest createPaymentRequest) { 28 | CreatePaymentResponse paymentRequest = paymentsService.createPaymentRequest(createPaymentRequest); 29 | return new ResponseEntity<>(paymentRequest, HttpStatus.CREATED); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/repository/UserPaymentCustomerRepository.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.repository; 2 | 3 | import com.devd.spring.bookstorepaymentservice.repository.dao.UserPaymentCustomer; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author Devaraj Reddy, Date : 14-Dec-2020 9 | */ 10 | @Repository 11 | public interface UserPaymentCustomerRepository extends JpaRepository { 12 | 13 | UserPaymentCustomer findByUserId(String userId); 14 | } 15 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/repository/dao/UserPaymentCustomer.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.repository.dao; 2 | 3 | import com.devd.spring.bookstorecommons.util.DateAudit; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Getter; 7 | import lombok.NoArgsConstructor; 8 | import lombok.Setter; 9 | import org.hibernate.annotations.GenericGenerator; 10 | 11 | import javax.persistence.Column; 12 | import javax.persistence.Entity; 13 | import javax.persistence.GeneratedValue; 14 | import javax.persistence.Id; 15 | import javax.persistence.Table; 16 | 17 | /** 18 | * @author Devaraj Reddy, Date : 14-Dec-2020 19 | */ 20 | @Getter 21 | @Setter 22 | @NoArgsConstructor 23 | @AllArgsConstructor 24 | @Entity 25 | @Table(name = "USER_PAYMENT_CUSTOMER") 26 | @Builder 27 | public class UserPaymentCustomer extends DateAudit { 28 | @Id 29 | @GeneratedValue(generator = "uuid") 30 | @GenericGenerator(name = "uuid", strategy = "uuid2") 31 | @Column(name = "ID", updatable = false, nullable = false) 32 | private String userPaymentCustomerId; 33 | 34 | @Column(name = "USER_ID", nullable = false, unique = true) 35 | private String userId; 36 | 37 | @Column(name = "USER_NAME", nullable = false, unique = true) 38 | private String userName; 39 | 40 | @Column(name = "PAYMENT_CUSTOMER_ID", nullable = false, unique = true) 41 | private String paymentCustomerId; 42 | } 43 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/service/PaymentMethodService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.service; 2 | 3 | import com.devd.spring.bookstorepaymentservice.web.CreatePaymentMethodRequest; 4 | import com.devd.spring.bookstorepaymentservice.web.GetPaymentMethodResponse; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author Devaraj Reddy, Date : 25-Jul-2020 10 | */ 11 | public interface PaymentMethodService { 12 | void createPaymentMethod(CreatePaymentMethodRequest createPaymentMethodRequest); 13 | 14 | List getAllMyPaymentMethods(); 15 | 16 | GetPaymentMethodResponse getMyPaymentMethodById(String paymentMethodId); 17 | } 18 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/service/PaymentsService.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.service; 2 | 3 | import com.devd.spring.bookstorepaymentservice.web.CreatePaymentRequest; 4 | import com.devd.spring.bookstorepaymentservice.web.CreatePaymentResponse; 5 | 6 | /** 7 | * @author Devaraj Reddy, Date : 25-Jul-2020 8 | */ 9 | public interface PaymentsService { 10 | CreatePaymentResponse createPaymentRequest(CreatePaymentRequest createPaymentRequest); 11 | } 12 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/web/Card.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author Devaraj Reddy, Date : 25-Jul-2020 9 | */ 10 | @Data 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class Card { 14 | private String firstName; 15 | private String lastName; 16 | private String cardNumber; 17 | private String last4Digits; 18 | private int expirationMonth; 19 | private int expirationYear; 20 | private int cvv; 21 | } 22 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/web/CreatePaymentMethodRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.validation.constraints.NotNull; 8 | 9 | /** 10 | * @author Devaraj Reddy, Date : 25-Jul-2020 11 | */ 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class CreatePaymentMethodRequest { 16 | 17 | @NotNull 18 | private Card card; 19 | } 20 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/web/CreatePaymentRequest.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | 9 | /** 10 | * @author Devaraj Reddy - 17-Dec-2020 11 | */ 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class CreatePaymentRequest { 16 | 17 | private int amount; 18 | @NotBlank 19 | private String currency; 20 | @NotBlank 21 | private String paymentMethodId; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/web/CreatePaymentResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | * @author Devaraj Reddy - 17-Dec-2020 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @Builder 17 | public class CreatePaymentResponse { 18 | private String paymentId; 19 | private LocalDateTime paymentDate; 20 | private boolean captured; 21 | private String receipt_url; 22 | } 23 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/web/GetPaymentMethodResponse.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author Devaraj Reddy, Date : 14-Dec-2020 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder 15 | public class GetPaymentMethodResponse { 16 | 17 | private String paymentMethodId; 18 | private String cardType; 19 | private String cardLast4Digits; 20 | private Long cardExpirationMonth; 21 | private Long cardExpirationYear; 22 | private String cardCountry; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: bookstore-payment-service 4 | profiles: 5 | active: ${SPRING_PROFILES_ACTIVE:local} 6 | 7 | management: 8 | endpoints: 9 | web: 10 | exposure: 11 | include: "*" 12 | 13 | --- 14 | 15 | spring: 16 | profiles: local, mysql 17 | cloud: 18 | bus: 19 | enabled: false 20 | consul: 21 | enabled: false #consul discovery set false, in this profile eureka discovery is enabled. 22 | 23 | eureka: 24 | client: 25 | serviceUrl: 26 | defaultZone: http://${EUREKA_HOST:localhost:8761}/eureka/ 27 | registerWithEureka: true 28 | enabled: true #eureka discovery is enabled in this profile 29 | instance: 30 | prefer-ip-address: false 31 | 32 | management: 33 | metrics: 34 | export: 35 | influx: 36 | enabled: false #influx metrics not pushing in this profile 37 | 38 | --- 39 | 40 | spring: 41 | profiles: docker 42 | cloud: 43 | consul: 44 | host: bookstore-consul-discovery 45 | port: 8500 46 | discovery: 47 | instanceId: ${spring.application.name}:${random.value} 48 | enabled: true #consul discovery is enabled in this profile 49 | 50 | management: 51 | metrics: 52 | export: 53 | statsd: 54 | enabled: true 55 | flavor: telegraf 56 | port: 8125 57 | influx: #pushing influx metrics. 58 | db: bookstore_influxdb_monitoring_metrics 59 | uri: http://bookstore-influxdb:8086 60 | auto-create-db: true 61 | endpoints: 62 | web: 63 | exposure: 64 | include: "*" 65 | 66 | eureka: 67 | client: 68 | enabled: false #eureka discovery set false, in this profile consul discovery is enabled. 69 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/resources/db/migration/V1__payment-service-schema.sql: -------------------------------------------------------------------------------- 1 | -- CREATE USER_PAYMENT_CUSTOMER TABLE 2 | CREATE TABLE IF NOT EXISTS USER_PAYMENT_CUSTOMER ( 3 | ID VARCHAR(255) NOT NULL UNIQUE, 4 | USER_ID VARCHAR(255) NOT NULL UNIQUE, 5 | USER_NAME VARCHAR(255) NOT NULL UNIQUE, 6 | PAYMENT_CUSTOMER_ID VARCHAR(255) NOT NULL UNIQUE, 7 | CREATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 8 | UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 9 | PRIMARY KEY (USER_ID) 10 | ); 11 | CREATE UNIQUE INDEX USER_PAYMENT_CUSTOMER_USER_ID_INDEX ON USER_PAYMENT_CUSTOMER (USER_ID); 12 | -------------------------------------------------------------------------------- /bookstore-payment-service/src/main/resources/jwt-signing-public-key.txt: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0sp8Cy1+sJgJLToO9FvW 3 | cY4AXnp027T0diFOv8cjxD+KESAmZ7cL1jy91nQASn7dCM5qNL5KzJGrp43fIbf+ 4 | HzRv4snj7NoDF5UzgI/fJ/AA3BoIyhkt0QkiKEe2kQFbIfrD5RSHvjLecRnkV71i 5 | A27PqY+kk9QZ2TGTXoMKCADF8JIHHxf+RXVb/GdGi+zCWshXrvJsjR2ZayXFpNDf 6 | QrnsMj14Jxed16ioIdx8yf1fWZxHv9q+uev86CR4E8Xrwg0yJoYHpSdK1J4EvK35 7 | zA2gaGUcfgkZQS5M5bbhrZx1wy8N+8GNkYB0uDVZhnXc2xr4KBO7LGYeP0toA4rh 8 | 1wIDAQAB 9 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /bookstore-payment-service/src/test/java/com/devd/spring/bookstorepaymentservice/BookstorePaymentAddressServiceImplApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.devd.spring.bookstorepaymentservice; 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 BookstorePaymentAddressServiceImplApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /bookstore-prometheus/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM prom/prometheus 2 | 3 | # Add in the configuration file from the local directory. 4 | ADD prometheus.yml /etc/prometheus/prometheus.yml -------------------------------------------------------------------------------- /bookstore-prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | # my global config 2 | global: 3 | scrape_interval: 5s # Set the scrape interval to every 15 seconds. Default is every 1 minute. 4 | evaluation_interval: 5s # Evaluate rules every 15 seconds. The default is every 1 minute. 5 | # scrape_timeout is set to the global default (10s). 6 | 7 | # Alertmanager configuration 8 | alerting: 9 | alertmanagers: 10 | - static_configs: 11 | - targets: 12 | # - alertmanager:9093 13 | 14 | # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. 15 | rule_files: 16 | # - "first_rules.yml" 17 | # - "second_rules.yml" 18 | 19 | # A scrape configuration containing exactly one endpoint to scrape: 20 | # Here it's Prometheus itself. 21 | scrape_configs: 22 | # Added to get services from Eureka-Consul-Adapter 23 | - job_name: 'bookstore-consul-discovery' 24 | metrics_path: '/actuator/prometheus' 25 | scrape_interval: 5s 26 | static_configs: 27 | consul_sd_configs: 28 | - server: 'bookstore-consul-discovery:8500' # Host Ip where Consul is running. 29 | relabel_configs: 30 | - source_labels: ['__meta_consul_tags'] 31 | action: keep 32 | - source_labels: ['__meta_consul_service'] 33 | target_label: job -------------------------------------------------------------------------------- /bookstore-telegraph/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM telegraf 2 | 3 | # Add in the configuration file from the local directory. 4 | ADD telegraf.conf /etc/telegraf/telegraf.conf 5 | 6 | #Using Dokerize to check whether db is up, if it is then start this service. 7 | COPY dockerize dockerize 8 | 9 | CMD ./dockerize -wait tcp://bookstore-influxdb:8086 -timeout 15m telegraf 10 | -------------------------------------------------------------------------------- /bookstore-telegraph/dockerize: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/bookstore-telegraph/dockerize -------------------------------------------------------------------------------- /images/0547ab94-59f8-4352-b17b-0918d07913f2__pricePredudice.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/0547ab94-59f8-4352-b17b-0918d07913f2__pricePredudice.jpg -------------------------------------------------------------------------------- /images/1ecfd5c4-dba2-4feb-bd88-006105a8d5ab__alchemist.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/1ecfd5c4-dba2-4feb-bd88-006105a8d5ab__alchemist.jpg -------------------------------------------------------------------------------- /images/25550dae-a893-4aa5-8b8f-967a91548fa5__oopWithCpp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/25550dae-a893-4aa5-8b8f-967a91548fa5__oopWithCpp.jpg -------------------------------------------------------------------------------- /images/2603aa1d-3892-44cc-9481-fd485d80d270__businessAdventures.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/2603aa1d-3892-44cc-9481-fd485d80d270__businessAdventures.jpg -------------------------------------------------------------------------------- /images/27ba1db0-a5a3-477c-927c-7ceb36cf7ffa__theTimeMachine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/27ba1db0-a5a3-477c-927c-7ceb36cf7ffa__theTimeMachine.jpg -------------------------------------------------------------------------------- /images/2b3ba80b-da93-4206-b50f-83008180a09e__sheHolmes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/2b3ba80b-da93-4206-b50f-83008180a09e__sheHolmes.jpg -------------------------------------------------------------------------------- /images/3b315751-c5bd-4e73-aad2-df941826f453__The Great Indian Conspiracy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/3b315751-c5bd-4e73-aad2-df941826f453__The Great Indian Conspiracy.jpg -------------------------------------------------------------------------------- /images/46fb8d5b-2979-4c54-848f-512693b37818__52 Small Changes for the Mind- Improve Memory.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/46fb8d5b-2979-4c54-848f-512693b37818__52 Small Changes for the Mind- Improve Memory.jpg -------------------------------------------------------------------------------- /images/49935a41-7274-4b7f-9333-c3e85d59df18__belatedBacghelorparty.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/49935a41-7274-4b7f-9333-c3e85d59df18__belatedBacghelorparty.jpg -------------------------------------------------------------------------------- /images/4b050ba6-9573-4554-bdd4-26ae806c06aa__IntroEngLit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/4b050ba6-9573-4554-bdd4-26ae806c06aa__IntroEngLit.jpg -------------------------------------------------------------------------------- /images/622a7214-02cc-4f54-85fd-86fd8f3b6967__theScienceBook.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/622a7214-02cc-4f54-85fd-86fd8f3b6967__theScienceBook.jpg -------------------------------------------------------------------------------- /images/6a290abe-338f-4ece-8793-ccdd35a7745f__linux.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/6a290abe-338f-4ece-8793-ccdd35a7745f__linux.jpg -------------------------------------------------------------------------------- /images/7d8b74e5-4321-4b49-9b2a-da4bf779d5be__theTheoryOfEverything.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/7d8b74e5-4321-4b49-9b2a-da4bf779d5be__theTheoryOfEverything.jpg -------------------------------------------------------------------------------- /images/8e6abb0e-180b-4e8e-856a-cb8491ff9454__greatGatsby.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/8e6abb0e-180b-4e8e-856a-cb8491ff9454__greatGatsby.jpg -------------------------------------------------------------------------------- /images/8f8a275b-357e-4010-84dc-8d89bb5e2b95__Politics for Beginners.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/8f8a275b-357e-4010-84dc-8d89bb5e2b95__Politics for Beginners.jpg -------------------------------------------------------------------------------- /images/990945b7-900e-432b-9b2c-79ea20302f6e__Productivity Superhero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/990945b7-900e-432b-9b2c-79ea20302f6e__Productivity Superhero.jpg -------------------------------------------------------------------------------- /images/ad5b1926-05ad-4aae-852d-f152ea838648__programmingInJava.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/ad5b1926-05ad-4aae-852d-f152ea838648__programmingInJava.jpg -------------------------------------------------------------------------------- /images/af75f363-fdb9-4d8e-8066-6215f0520e9b__corePythonProg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/af75f363-fdb9-4d8e-8066-6215f0520e9b__corePythonProg.jpg -------------------------------------------------------------------------------- /images/b1175b20-e946-42a6-b63d-83e35b7a73fa__oneArrangedMurder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/b1175b20-e946-42a6-b63d-83e35b7a73fa__oneArrangedMurder.jpg -------------------------------------------------------------------------------- /images/b9685c28-7f97-4fb7-9cf0-927ff3afc8f1__spaceEncyclo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/b9685c28-7f97-4fb7-9cf0-927ff3afc8f1__spaceEncyclo.jpg -------------------------------------------------------------------------------- /images/c16108e1-8276-41ad-bf12-4aee4c0a7e65__IndModernLiterature.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/c16108e1-8276-41ad-bf12-4aee4c0a7e65__IndModernLiterature.jpg -------------------------------------------------------------------------------- /images/cad39d84-60aa-496d-9295-c3f47ec957fa__programmingInC.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/cad39d84-60aa-496d-9295-c3f47ec957fa__programmingInC.jpg -------------------------------------------------------------------------------- /images/cef7540f-0810-4323-9950-98c5d8d5099d__Chandra Shekhar- The Last Icon of Ideological Politics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/cef7540f-0810-4323-9950-98c5d8d5099d__Chandra Shekhar- The Last Icon of Ideological Politics.jpg -------------------------------------------------------------------------------- /images/e6602eb6-3f67-4993-abc8-0b54a36bad1b__thousandSplendidSuns.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/e6602eb6-3f67-4993-abc8-0b54a36bad1b__thousandSplendidSuns.jpg -------------------------------------------------------------------------------- /images/e9b319cc-e501-4f90-b608-74052d770e2d__theBusinessBook.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdcores/BookStoreApp-Distributed-Application/1a14fa38cd3827ccdf3e3e99d61d9254a40f3d8b/images/e9b319cc-e501-4f90-b608-74052d770e2d__theBusinessBook.jpg --------------------------------------------------------------------------------