├── README.md ├── e-commerce App ├── .idea │ ├── $PRODUCT_WORKSPACE_FILE$ │ ├── .gitignore │ ├── .name │ ├── codeStyles │ │ └── Project.xml │ ├── compiler.xml │ ├── dbnavigator.xml │ ├── encodings.xml │ ├── misc.xml │ ├── uiDesigner.xml │ └── vcs.xml ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── demo │ │ │ │ ├── SareetaApplication.java │ │ │ │ ├── controllers │ │ │ │ ├── CartController.java │ │ │ │ ├── ItemController.java │ │ │ │ ├── OrderController.java │ │ │ │ └── UserController.java │ │ │ │ ├── model │ │ │ │ ├── persistence │ │ │ │ │ ├── Cart.java │ │ │ │ │ ├── EcommerceUser.java │ │ │ │ │ ├── Item.java │ │ │ │ │ ├── UserOrder.java │ │ │ │ │ └── repositories │ │ │ │ │ │ ├── CartRepository.java │ │ │ │ │ │ ├── ItemRepository.java │ │ │ │ │ │ ├── OrderRepository.java │ │ │ │ │ │ └── UserRepository.java │ │ │ │ └── requests │ │ │ │ │ ├── CreateUserRequest.java │ │ │ │ │ └── ModifyCartRequest.java │ │ │ │ ├── security │ │ │ │ ├── JwtAuthenticationFilter.java │ │ │ │ ├── JwtAuthorizationFilter.java │ │ │ │ ├── SecurityConstant.java │ │ │ │ └── WebSecurityConfiguration.java │ │ │ │ └── service │ │ │ │ └── UserDetailsServiceImpl.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── data.sql │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── demo │ │ ├── SareetaApplicationTests.java │ │ ├── TestUnits.java │ │ └── controllers │ │ └── UserControllerTest.java └── target │ ├── app.log │ ├── classes │ ├── application.properties │ ├── com │ │ └── example │ │ │ └── demo │ │ │ ├── SareetaApplication.class │ │ │ ├── controllers │ │ │ ├── CartController.class │ │ │ ├── ItemController.class │ │ │ ├── OrderController.class │ │ │ └── UserController.class │ │ │ ├── model │ │ │ ├── persistence │ │ │ │ ├── Cart.class │ │ │ │ ├── EcommerceUser.class │ │ │ │ ├── Item.class │ │ │ │ ├── UserOrder.class │ │ │ │ └── repositories │ │ │ │ │ ├── CartRepository.class │ │ │ │ │ ├── ItemRepository.class │ │ │ │ │ ├── OrderRepository.class │ │ │ │ │ └── UserRepository.class │ │ │ └── requests │ │ │ │ ├── CreateUserRequest.class │ │ │ │ └── ModifyCartRequest.class │ │ │ ├── security │ │ │ ├── JwtAuthenticationFilter.class │ │ │ ├── JwtAuthorizationFilter.class │ │ │ ├── SecurityConstant.class │ │ │ └── WebSecurityConfiguration.class │ │ │ └── service │ │ │ └── UserDetailsServiceImpl.class │ └── data.sql │ ├── maven-status │ └── maven-compiler-plugin │ │ ├── compile │ │ └── default-compile │ │ │ ├── createdFiles.lst │ │ │ └── inputFiles.lst │ │ └── testCompile │ │ └── default-testCompile │ │ ├── createdFiles.lst │ │ └── inputFiles.lst │ └── test-classes │ ├── META-INF │ └── auth-course.kotlin_module │ └── com │ └── example │ └── demo │ ├── SareetaApplicationTests.class │ ├── TestUnits.class │ └── controllers │ └── UserControllerTest.class ├── lab ├── DogRestApi │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ ├── MavenWrapperDownloader.java │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── udacity │ │ │ │ └── DogRestApi │ │ │ │ ├── DogRestApiApplication.java │ │ │ │ ├── config │ │ │ │ ├── SpringSecurityConfig.java │ │ │ │ └── SwaggerConfig.java │ │ │ │ ├── entity │ │ │ │ └── Dog.java │ │ │ │ ├── repository │ │ │ │ └── DogRepository.java │ │ │ │ ├── service │ │ │ │ ├── DogNotFoundException.java │ │ │ │ ├── DogService.java │ │ │ │ └── DogServiceImpl.java │ │ │ │ └── web │ │ │ │ └── DogController.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── data.sql │ │ └── test │ │ └── java │ │ └── com │ │ └── udacity │ │ └── DogRestApi │ │ ├── DogRestApiApplicationTests.java │ │ └── web │ │ ├── DogControllerIntegrationTest.java │ │ └── DogControllerUnitTest.java ├── JDBC_Flyway │ ├── .gitignore │ ├── README.md │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── udacity │ │ │ └── course3 │ │ │ └── lesson1 │ │ │ └── exercise1 │ │ │ └── exercise1 │ │ │ └── Application.java │ │ └── resources │ │ └── db │ │ └── migration │ │ └── V01__CreateTable.sql ├── graphql │ ├── DogGraphQL │ │ ├── .gitignore │ │ ├── .mvn │ │ │ └── wrapper │ │ │ │ ├── MavenWrapperDownloader.java │ │ │ │ ├── maven-wrapper.jar │ │ │ │ └── maven-wrapper.properties │ │ ├── mvnw │ │ ├── mvnw.cmd │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── udacity │ │ │ │ │ └── DogGraphQL │ │ │ │ │ ├── DogGraphQlApplication.java │ │ │ │ │ ├── Entity │ │ │ │ │ └── Dog.java │ │ │ │ │ ├── exception │ │ │ │ │ ├── BreedNotFoundException.java │ │ │ │ │ └── DogNotFoundException.java │ │ │ │ │ ├── mutator │ │ │ │ │ └── Mutation.java │ │ │ │ │ ├── repository │ │ │ │ │ └── DogRepository.java │ │ │ │ │ └── resolver │ │ │ │ │ └── Query.java │ │ │ └── resources │ │ │ │ ├── application.properties │ │ │ │ ├── data.sql │ │ │ │ └── graphql │ │ │ │ └── dog.graphqls │ │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── udacity │ │ │ └── DogGraphQL │ │ │ └── DogGraphQlApplicationTests.java │ └── graphql_airport │ │ ├── .gitignore │ │ ├── .mvn │ │ └── wrapper │ │ │ ├── MavenWrapperDownloader.java │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ │ ├── mvnw │ │ ├── mvnw.cmd │ │ ├── pom.xml │ │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── udacity │ │ │ │ └── graphql │ │ │ │ ├── GraphqlApplication.java │ │ │ │ ├── entity │ │ │ │ └── Location.java │ │ │ │ ├── exception │ │ │ │ └── LocationNotFoundException.java │ │ │ │ ├── mutator │ │ │ │ └── Mutation.java │ │ │ │ ├── repository │ │ │ │ └── LocationRepository.java │ │ │ │ ├── resolver │ │ │ │ └── Query.java │ │ │ │ ├── service │ │ │ │ ├── LocationService.java │ │ │ │ └── LocationServiceImpl.java │ │ │ │ └── web │ │ │ │ └── LocationController.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── dataTest.sql │ │ │ └── graphql │ │ │ └── location.graphqls │ │ └── test │ │ └── java │ │ └── com │ │ └── udacity │ │ └── graphql │ │ └── GraphqlApplicationTests.java └── microservices │ ├── dogMicroservice │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ ├── MavenWrapperDownloader.java │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── udacity │ │ │ │ └── dogMicroservice │ │ │ │ ├── DogMicroserviceApplication.java │ │ │ │ ├── entity │ │ │ │ └── Dog.java │ │ │ │ └── repository │ │ │ │ └── DogRepository.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── data.sql │ │ └── test │ │ └── java │ │ └── com │ │ └── udacity │ │ └── dogMicroservice │ │ └── DogMicroserviceApplicationTests.java │ └── eureka │ ├── .gitignore │ ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── udacity │ │ │ └── MicroService │ │ │ └── MicroServiceApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── udacity │ └── MicroService │ └── MicroServiceApplicationTests.java └── projects ├── ReviewsAPI ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── udacity │ │ │ └── course3 │ │ │ └── reviews │ │ │ ├── ReviewsApplication.java │ │ │ ├── controller │ │ │ ├── CommentsController.java │ │ │ ├── ProductsController.java │ │ │ └── ReviewsController.java │ │ │ ├── entity │ │ │ ├── Comment.java │ │ │ ├── Product.java │ │ │ └── Review.java │ │ │ └── repository │ │ │ ├── CommentRepository.java │ │ │ ├── ProductRepository.java │ │ │ └── ReviewRepository.java │ └── resources │ │ ├── application.properties │ │ └── db │ │ └── migration │ │ ├── .gitkeep │ │ ├── V01__CreateTable.sql │ │ └── V02__CreateTable2.sql │ └── test │ └── java │ └── com │ └── udacity │ └── course3 │ └── reviews │ ├── CommentRepositoryTest.java │ ├── ProductRepositoryTest.java │ ├── ReviewsApplicationTests.java │ └── ReviewsRepositoryTest.java ├── chatroom ├── .idea │ ├── .name │ ├── compiler.xml │ ├── encodings.xml │ ├── misc.xml │ ├── vcs.xml │ └── workspace.xml ├── README.md ├── chatroom-starter.ipr ├── chatroom-starter.iws ├── pom.xml ├── src │ └── main │ │ ├── java │ │ └── edu │ │ │ └── udacity │ │ │ └── java │ │ │ └── nano │ │ │ ├── WebSocketChatApplication.java │ │ │ └── chat │ │ │ ├── Message.java │ │ │ ├── WebSocketChatServer.java │ │ │ └── WebSocketConfig.java │ │ ├── resources │ │ ├── application.yml │ │ ├── static │ │ │ └── img │ │ │ │ └── login-bg.jpg │ │ └── templates │ │ │ ├── chat.html │ │ │ └── login.html │ │ └── test │ │ └── edu │ │ └── udacity │ │ └── java │ │ └── nano │ │ └── chat │ │ └── WebSocketChatServerTest.java └── target │ ├── chatroom-starter-0.0.1-SNAPSHOT.jar │ ├── chatroom-starter-0.0.1-SNAPSHOT.jar.original │ ├── classes │ ├── application.yml │ ├── edu │ │ └── udacity │ │ │ └── java │ │ │ └── nano │ │ │ ├── WebSocketChatApplication.class │ │ │ └── chat │ │ │ ├── Message$Type.class │ │ │ ├── Message.class │ │ │ ├── WebSocketChatServer.class │ │ │ └── WebSocketConfig.class │ ├── static │ │ └── img │ │ │ └── login-bg.jpg │ └── templates │ │ ├── chat.html │ │ └── login.html │ ├── maven-archiver │ └── pom.properties │ ├── maven-status │ └── maven-compiler-plugin │ │ └── compile │ │ └── default-compile │ │ ├── createdFiles.lst │ │ └── inputFiles.lst │ └── test-classes │ └── edu │ └── udacity │ └── java │ └── nano │ └── chat │ └── WebSocketChatServerTest.class └── vehiclesAPI ├── .gitignore ├── LICENSE ├── README.md ├── boogle-maps ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── udacity │ │ │ └── boogle │ │ │ └── maps │ │ │ ├── Address.java │ │ │ ├── BoogleMapsApplication.java │ │ │ ├── MapsController.java │ │ │ └── MockAddressRepository.java │ └── resources │ │ ├── adresses.json │ │ └── application.properties │ └── test │ └── java │ └── com │ └── udacity │ └── boogle │ └── maps │ └── BoogleMapsApplicationTests.java ├── pricing-service ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── udacity │ │ │ └── pricing │ │ │ ├── PricingServiceApplication.java │ │ │ ├── api │ │ │ └── PricingController.java │ │ │ ├── domain │ │ │ └── price │ │ │ │ ├── Price.java │ │ │ │ └── PriceRepository.java │ │ │ └── service │ │ │ ├── PriceException.java │ │ │ └── PricingService.java │ └── resources │ │ ├── application.properties │ │ └── prices.json │ └── test │ └── java │ └── com │ └── udacity │ └── pricing │ ├── PricingServiceApplicationTests.java │ └── web │ ├── PricingControllerIntegrationTest.java │ └── PricingControllerUnitTest.java ├── util └── intellij-java-google-style.xml └── vehicles-api ├── .gitignore ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── udacity │ │ └── vehicles │ │ ├── VehiclesApiApplication.java │ │ ├── api │ │ ├── ApiError.java │ │ ├── CarController.java │ │ ├── CarResourceAssembler.java │ │ └── ErrorController.java │ │ ├── client │ │ ├── maps │ │ │ ├── Address.java │ │ │ └── MapsClient.java │ │ └── prices │ │ │ ├── Price.java │ │ │ └── PriceClient.java │ │ ├── config │ │ └── SwaggerConfig.java │ │ ├── domain │ │ ├── Condition.java │ │ ├── Location.java │ │ ├── car │ │ │ ├── Car.java │ │ │ ├── CarRepository.java │ │ │ └── Details.java │ │ └── manufacturer │ │ │ ├── Manufacturer.java │ │ │ └── ManufacturerRepository.java │ │ └── service │ │ ├── CarNotFoundException.java │ │ └── CarService.java └── resources │ └── application.properties └── test └── java └── com └── udacity └── vehicles ├── VehiclesApiApplicationTests.java └── api └── CarControllerTest.java /README.md: -------------------------------------------------------------------------------- 1 | # JavaDeveloper-NanoDegree 2 | 3 | ## SUMMARY 4 | UDACITY JAVA DEVELOPER NANO DEGREE Course practices and projects. 5 | 6 | ## CONTENTS 7 | ### **1. lab** 8 | - RestAPI 9 | - JDBC_Flyway 10 | - graphql 11 | - Microservices 12 | 13 | ### **2. projects** 14 | - **ChatRoom**
15 | : Built a chatroom using websocket and STOMP with Spring Boot MVC framework 16 | - **Vehicles API**
17 | : Create a REST-based API that communicates with a location and pricing service using Spring Boot, along with converting the existing Pricing Serivce API to a microservice registered on a Eureka Server 18 | - **Reviews API**
19 | : Built a both Mongo DB and MySQL part of persistence layer for a REST API that supports sorting and filtering customer reviews in an ecommerce application. 20 | - **eCommerce API**
21 | : Implemented handling of authorization with security using JWT for login, search purchase history and cart details. 22 | 23 | ### 24 | 25 | -------------------------------------------------------------------------------- /e-commerce App/.idea/$PRODUCT_WORKSPACE_FILE$: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | 17 | 18 | 1.8 19 | 20 | 25 | 26 | 27 | 28 | 29 | 30 | 1.8 31 | 32 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /e-commerce App/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /workspace.xml -------------------------------------------------------------------------------- /e-commerce App/.idea/.name: -------------------------------------------------------------------------------- 1 | auth-course -------------------------------------------------------------------------------- /e-commerce App/.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /e-commerce App/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /e-commerce App/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /e-commerce App/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /e-commerce App/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /e-commerce App/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | com.example 12 | auth-course 13 | 0.0.1-SNAPSHOT 14 | auth-course 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 3.1.1 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-data-jpa 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-tomcat 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-security 38 | 39 | 40 | com.h2database 41 | h2 42 | runtime 43 | 44 | 45 | org.springframework.security 46 | spring-security-test 47 | test 48 | 49 | 50 | com.auth0 51 | java-jwt 52 | 3.4.0 53 | 54 | 55 | org.springframework.security 56 | spring-security-core 57 | 5.1.5.RELEASE 58 | compile 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-starter-test 63 | test 64 | 65 | 66 | org.slf4j 67 | slf4j-log4j12 68 | 1.7.25 69 | test 70 | 71 | 72 | junit 73 | junit 74 | 4.12 75 | test 76 | 77 | 78 | 79 | 80 | 81 | 82 | org.springframework.boot 83 | spring-boot-maven-plugin 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/SareetaApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.domain.EntityScan; 6 | import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 9 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 10 | import org.springframework.security.crypto.password.PasswordEncoder; 11 | 12 | @EnableJpaRepositories("com.example.demo.model.persistence.repositories") 13 | @EntityScan("com.example.demo.model.persistence") 14 | @SpringBootApplication(exclude = { SecurityAutoConfiguration.class }) 15 | 16 | public class SareetaApplication { 17 | 18 | public static void main(String[] args) { 19 | SpringApplication.run(SareetaApplication.class, args); 20 | } 21 | 22 | @Bean 23 | public PasswordEncoder bcryptPaswordEncoder() { 24 | return new BCryptPasswordEncoder(); 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/controllers/CartController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controllers; 2 | 3 | import java.util.Optional; 4 | import java.util.stream.IntStream; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import com.example.demo.model.persistence.Cart; 15 | import com.example.demo.model.persistence.Item; 16 | import com.example.demo.model.persistence.EcommerceUser; 17 | import com.example.demo.model.persistence.repositories.CartRepository; 18 | import com.example.demo.model.persistence.repositories.ItemRepository; 19 | import com.example.demo.model.persistence.repositories.UserRepository; 20 | import com.example.demo.model.requests.ModifyCartRequest; 21 | 22 | @RestController 23 | @RequestMapping("/api/cart") 24 | public class CartController { 25 | 26 | @Autowired 27 | private UserRepository userRepository; 28 | 29 | @Autowired 30 | private CartRepository cartRepository; 31 | 32 | @Autowired 33 | private ItemRepository itemRepository; 34 | 35 | @PostMapping("/addToCart") 36 | public ResponseEntity addTocart(@RequestBody ModifyCartRequest request) { 37 | EcommerceUser user = userRepository.findByUsername(request.getUsername()); 38 | if(user == null) { 39 | return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); 40 | } 41 | Optional item = itemRepository.findById(request.getItemId()); 42 | if(!item.isPresent()) { 43 | return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); 44 | } 45 | Cart cart = user.getCart(); 46 | IntStream.range(0, request.getQuantity()) 47 | .forEach(i -> cart.addItem(item.get())); 48 | cartRepository.save(cart); 49 | return ResponseEntity.ok(cart); 50 | } 51 | 52 | @PostMapping("/removeFromCart") 53 | public ResponseEntity removeFromcart(@RequestBody ModifyCartRequest request) { 54 | EcommerceUser user = userRepository.findByUsername(request.getUsername()); 55 | if(user == null) { 56 | return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); 57 | } 58 | Optional item = itemRepository.findById(request.getItemId()); 59 | if(!item.isPresent()) { 60 | return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); 61 | } 62 | Cart cart = user.getCart(); 63 | IntStream.range(0, request.getQuantity()) 64 | .forEach(i -> cart.removeItem(item.get())); 65 | cartRepository.save(cart); 66 | return ResponseEntity.ok(cart); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/controllers/ItemController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controllers; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import com.example.demo.model.persistence.Item; 13 | import com.example.demo.model.persistence.repositories.ItemRepository; 14 | 15 | @RestController 16 | @RequestMapping("/api/item") 17 | public class ItemController { 18 | 19 | @Autowired 20 | private ItemRepository itemRepository; 21 | 22 | @GetMapping 23 | public ResponseEntity> getItems() { 24 | return ResponseEntity.ok(itemRepository.findAll()); 25 | } 26 | 27 | @GetMapping("/{id}") 28 | public ResponseEntity getItemById(@PathVariable Long id) { 29 | return ResponseEntity.of(itemRepository.findById(id)); 30 | } 31 | 32 | @GetMapping("/name/{name}") 33 | public ResponseEntity> getItemsByName(@PathVariable String name) { 34 | List items = itemRepository.findByName(name); 35 | return items == null || items.isEmpty() ? ResponseEntity.notFound().build() 36 | : ResponseEntity.ok(items); 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/controllers/OrderController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controllers; 2 | 3 | import java.util.List; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.bind.annotation.PostMapping; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import com.example.demo.model.persistence.EcommerceUser; 16 | import com.example.demo.model.persistence.UserOrder; 17 | import com.example.demo.model.persistence.repositories.OrderRepository; 18 | import com.example.demo.model.persistence.repositories.UserRepository; 19 | 20 | @RestController 21 | @RequestMapping("/api/order") 22 | public class OrderController { 23 | 24 | private static final Logger log = LoggerFactory.getLogger(OrderController.class); 25 | 26 | @Autowired 27 | private UserRepository userRepository; 28 | 29 | @Autowired 30 | private OrderRepository orderRepository; 31 | 32 | 33 | @PostMapping("/submit/{username}") 34 | public ResponseEntity submit(@PathVariable String username) { 35 | EcommerceUser user = userRepository.findByUsername(username); 36 | if(user == null) { 37 | log.error("'{}' not found!", username); 38 | return ResponseEntity.notFound().build(); 39 | } 40 | UserOrder order = UserOrder.createFromCart(user.getCart()); 41 | orderRepository.save(order); 42 | log.info("Order success with id: '{}'", order.getId()); 43 | return ResponseEntity.ok(order); 44 | } 45 | 46 | @GetMapping("/history/{username}") 47 | public ResponseEntity> getOrdersForUser(@PathVariable String username) { 48 | EcommerceUser user = userRepository.findByUsername(username); 49 | if(user == null) { 50 | log.error("'{}' not found!", username); 51 | return ResponseEntity.notFound().build(); 52 | } 53 | return ResponseEntity.ok(orderRepository.findByUser(user)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/controllers/UserController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controllers; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.security.crypto.password.PasswordEncoder; 8 | import org.springframework.web.bind.annotation.GetMapping; 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.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import com.example.demo.model.persistence.Cart; 16 | import com.example.demo.model.persistence.EcommerceUser; 17 | import com.example.demo.model.persistence.repositories.CartRepository; 18 | import com.example.demo.model.persistence.repositories.UserRepository; 19 | import com.example.demo.model.requests.CreateUserRequest; 20 | 21 | @RestController 22 | @RequestMapping("/api/user") 23 | public class UserController { 24 | 25 | private static final Logger log = LoggerFactory.getLogger(UserController.class); 26 | 27 | @Autowired 28 | private UserRepository userRepository; 29 | 30 | @Autowired 31 | private CartRepository cartRepository; 32 | 33 | @Autowired 34 | private PasswordEncoder bcryptEncoder; 35 | 36 | @GetMapping("/id/{id}") 37 | public ResponseEntity findById(@PathVariable Long id) { 38 | return ResponseEntity.of(userRepository.findById(id)); 39 | } 40 | 41 | @GetMapping("/{username}") 42 | public ResponseEntity findByUserName(@PathVariable String username) { 43 | EcommerceUser user = userRepository.findByUsername(username); 44 | return user == null ? ResponseEntity.notFound().build() : ResponseEntity.ok(user); 45 | } 46 | 47 | @PostMapping("/create") 48 | public ResponseEntity createUser(@RequestBody CreateUserRequest createUserRequest) { 49 | EcommerceUser user = new EcommerceUser(); 50 | user.setUsername(createUserRequest.getUsername()); 51 | log.info("User name set with value: " + createUserRequest.getUsername()); 52 | Cart cart = new Cart(); 53 | cartRepository.save(cart); 54 | user.setCart(cart); 55 | 56 | if (createUserRequest.getPassword().length() < 7 || createUserRequest.getPassword() == null 57 | || !createUserRequest.getPassword().equals(createUserRequest.getConfirmPassword())) { 58 | log.error("Error with user password. Can not create {}", createUserRequest.getUsername()); 59 | return ResponseEntity.badRequest().build(); 60 | } 61 | user.setPassword(bcryptEncoder.encode(createUserRequest.getPassword())); 62 | userRepository.save(user); 63 | log.info("Create {} Success!", createUserRequest.getUsername()); 64 | return ResponseEntity.ok(user); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/model/persistence/Cart.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model.persistence; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import javax.persistence.Column; 8 | import javax.persistence.Entity; 9 | import javax.persistence.GeneratedValue; 10 | import javax.persistence.GenerationType; 11 | import javax.persistence.Id; 12 | import javax.persistence.ManyToMany; 13 | import javax.persistence.OneToOne; 14 | import javax.persistence.Table; 15 | 16 | import com.fasterxml.jackson.annotation.JsonProperty; 17 | 18 | @Entity 19 | @Table(name = "cart") 20 | public class Cart { 21 | 22 | @Id 23 | @GeneratedValue(strategy = GenerationType.IDENTITY) 24 | @JsonProperty 25 | @Column 26 | private Long id; 27 | 28 | @ManyToMany 29 | @JsonProperty 30 | @Column 31 | private List items; 32 | 33 | @OneToOne(mappedBy = "cart") 34 | @JsonProperty 35 | private EcommerceUser user; 36 | 37 | @Column 38 | @JsonProperty 39 | private BigDecimal total; 40 | 41 | public BigDecimal getTotal() { 42 | return total; 43 | } 44 | 45 | public void setTotal(BigDecimal total) { 46 | this.total = total; 47 | } 48 | 49 | public EcommerceUser getUser() { 50 | return user; 51 | } 52 | 53 | public void setUser(EcommerceUser user) { 54 | this.user = user; 55 | } 56 | 57 | public Long getId() { 58 | return id; 59 | } 60 | 61 | public void setId(Long id) { 62 | this.id = id; 63 | } 64 | 65 | public List getItems() { 66 | return items; 67 | } 68 | 69 | public void setItems(List items) { 70 | this.items = items; 71 | } 72 | 73 | public void addItem(Item item) { 74 | if(items == null) { 75 | items = new ArrayList<>(); 76 | } 77 | items.add(item); 78 | if(total == null) { 79 | total = new BigDecimal(0); 80 | } 81 | total = total.add(item.getPrice()); 82 | } 83 | 84 | public void removeItem(Item item) { 85 | if(items == null) { 86 | items = new ArrayList<>(); 87 | } 88 | items.remove(item); 89 | if(total == null) { 90 | total = new BigDecimal(0); 91 | } 92 | total = total.subtract(item.getPrice()); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/model/persistence/EcommerceUser.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model.persistence; 2 | 3 | import javax.persistence.CascadeType; 4 | import javax.persistence.Column; 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.GenerationType; 8 | import javax.persistence.Id; 9 | import javax.persistence.JoinColumn; 10 | import javax.persistence.OneToOne; 11 | import javax.persistence.Table; 12 | 13 | import com.fasterxml.jackson.annotation.JsonIgnore; 14 | import com.fasterxml.jackson.annotation.JsonProperty; 15 | 16 | 17 | @Entity 18 | @Table(name = "user") 19 | public class EcommerceUser { 20 | 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.IDENTITY) 23 | @JsonProperty 24 | private long id; 25 | 26 | @Column(nullable = false, unique = true) 27 | @JsonProperty 28 | private String username; 29 | 30 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) 31 | @Column(nullable = false) 32 | private String password; 33 | 34 | @OneToOne(cascade = CascadeType.ALL) 35 | @JoinColumn(name = "cart_id", referencedColumnName = "id") 36 | @JsonIgnore 37 | private Cart cart; 38 | 39 | public Cart getCart() { 40 | return cart; 41 | } 42 | 43 | public void setCart(Cart cart) { 44 | this.cart = cart; 45 | } 46 | 47 | public long getId() { 48 | return id; 49 | } 50 | 51 | public void setId(long id) { 52 | this.id = id; 53 | } 54 | 55 | public String getUsername() { 56 | return username; 57 | } 58 | 59 | public void setUsername(String username) { 60 | this.username = username; 61 | } 62 | 63 | public String getPassword() { 64 | return password; 65 | } 66 | 67 | public void setPassword(String password) { 68 | this.password = password; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/model/persistence/Item.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model.persistence; 2 | 3 | import java.math.BigDecimal; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.JoinColumn; 11 | import javax.persistence.ManyToOne; 12 | import javax.persistence.Table; 13 | 14 | import com.fasterxml.jackson.annotation.JsonIgnore; 15 | import com.fasterxml.jackson.annotation.JsonProperty; 16 | 17 | @Entity 18 | @Table(name = "item") 19 | public class Item { 20 | 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.IDENTITY) 23 | @JsonProperty 24 | private Long id; 25 | 26 | @Column(nullable = false) 27 | @JsonProperty 28 | private String name; 29 | 30 | @Column(nullable = false) 31 | @JsonProperty 32 | private BigDecimal price; 33 | 34 | @Column(nullable = false) 35 | @JsonProperty 36 | private String description; 37 | 38 | @Override 39 | public int hashCode() { 40 | final int prime = 31; 41 | int result = 1; 42 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 43 | return result; 44 | } 45 | 46 | @Override 47 | public boolean equals(Object obj) { 48 | if (this == obj) 49 | return true; 50 | if (obj == null) 51 | return false; 52 | if (getClass() != obj.getClass()) 53 | return false; 54 | Item other = (Item) obj; 55 | if (id == null) { 56 | if (other.id != null) 57 | return false; 58 | } else if (!id.equals(other.id)) 59 | return false; 60 | return true; 61 | } 62 | 63 | public Long getId() { 64 | return id; 65 | } 66 | 67 | public void setId(Long id) { 68 | this.id = id; 69 | } 70 | 71 | public String getName() { 72 | return name; 73 | } 74 | 75 | public void setName(String name) { 76 | this.name = name; 77 | } 78 | 79 | public BigDecimal getPrice() { 80 | return price; 81 | } 82 | 83 | public void setPrice(BigDecimal price) { 84 | this.price = price; 85 | } 86 | 87 | public String getDescription() { 88 | return description; 89 | } 90 | 91 | public void setDescription(String description) { 92 | this.description = description; 93 | } 94 | 95 | 96 | 97 | } 98 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/model/persistence/UserOrder.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model.persistence; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import javax.persistence.CascadeType; 8 | import javax.persistence.Column; 9 | import javax.persistence.Entity; 10 | import javax.persistence.GeneratedValue; 11 | import javax.persistence.GenerationType; 12 | import javax.persistence.Id; 13 | import javax.persistence.JoinColumn; 14 | import javax.persistence.ManyToMany; 15 | import javax.persistence.ManyToOne; 16 | import javax.persistence.Table; 17 | 18 | import com.fasterxml.jackson.annotation.JsonProperty; 19 | 20 | @Entity 21 | @Table(name = "user_order") 22 | public class UserOrder { 23 | 24 | @Id 25 | @GeneratedValue(strategy = GenerationType.IDENTITY) 26 | @JsonProperty 27 | @Column 28 | private Long id; 29 | 30 | @ManyToMany(cascade = CascadeType.ALL) 31 | @JsonProperty 32 | @Column 33 | private List items; 34 | 35 | @ManyToOne 36 | @JoinColumn(name="user_id", nullable = false, referencedColumnName = "id") 37 | @JsonProperty 38 | private EcommerceUser user; 39 | 40 | @JsonProperty 41 | @Column 42 | private BigDecimal total; 43 | 44 | public Long getId() { 45 | return id; 46 | } 47 | 48 | public void setId(Long id) { 49 | this.id = id; 50 | } 51 | 52 | public List getItems() { 53 | return items; 54 | } 55 | 56 | public void setItems(List items) { 57 | this.items = items; 58 | } 59 | 60 | public EcommerceUser getUser() { 61 | return user; 62 | } 63 | 64 | public void setUser(EcommerceUser user) { 65 | this.user = user; 66 | } 67 | 68 | public BigDecimal getTotal() { 69 | return total; 70 | } 71 | 72 | public void setTotal(BigDecimal total) { 73 | this.total = total; 74 | } 75 | 76 | public static UserOrder createFromCart(Cart cart) { 77 | UserOrder order = new UserOrder(); 78 | order.setItems(cart.getItems().stream().collect(Collectors.toList())); 79 | order.setTotal(cart.getTotal()); 80 | order.setUser(cart.getUser()); 81 | return order; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/model/persistence/repositories/CartRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model.persistence.repositories; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | 5 | import com.example.demo.model.persistence.Cart; 6 | import com.example.demo.model.persistence.EcommerceUser; 7 | 8 | public interface CartRepository extends JpaRepository { 9 | Cart findByUser(EcommerceUser user); 10 | } 11 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/model/persistence/repositories/ItemRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model.persistence.repositories; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import com.example.demo.model.persistence.Item; 8 | 9 | public interface ItemRepository extends JpaRepository { 10 | public List findByName(String name); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/model/persistence/repositories/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model.persistence.repositories; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import com.example.demo.model.persistence.EcommerceUser; 8 | import com.example.demo.model.persistence.UserOrder; 9 | 10 | public interface OrderRepository extends JpaRepository { 11 | List findByUser(EcommerceUser user); 12 | } 13 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/model/persistence/repositories/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model.persistence.repositories; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | 5 | import com.example.demo.model.persistence.EcommerceUser; 6 | 7 | public interface UserRepository extends JpaRepository { 8 | EcommerceUser findByUsername(String username); 9 | } 10 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/model/requests/CreateUserRequest.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model.requests; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | public class CreateUserRequest { 6 | 7 | @JsonProperty 8 | private String username; 9 | 10 | @JsonProperty 11 | private String password; 12 | 13 | @JsonProperty 14 | private String confirmPassword; 15 | 16 | public String getUsername() { 17 | return username; 18 | } 19 | 20 | public void setUsername(String username) { 21 | this.username = username; 22 | } 23 | 24 | public String getPassword() { 25 | return password; 26 | } 27 | 28 | public void setPassword(String password) { 29 | this.password = password; 30 | } 31 | 32 | public String getConfirmPassword() { 33 | return confirmPassword; 34 | } 35 | 36 | public void setConfirmPassword(String confirmPassword) { 37 | this.confirmPassword = confirmPassword; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/model/requests/ModifyCartRequest.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model.requests; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | public class ModifyCartRequest { 6 | 7 | @JsonProperty 8 | private String username; 9 | 10 | @JsonProperty 11 | private long itemId; 12 | 13 | @JsonProperty 14 | private int quantity; 15 | 16 | public String getUsername() { 17 | return username; 18 | } 19 | 20 | public void setUsername(String username) { 21 | this.username = username; 22 | } 23 | 24 | public long getItemId() { 25 | return itemId; 26 | } 27 | 28 | public void setItemId(long itemId) { 29 | this.itemId = itemId; 30 | } 31 | 32 | public int getQuantity() { 33 | return quantity; 34 | } 35 | 36 | public void setQuantity(int quantity) { 37 | this.quantity = quantity; 38 | } 39 | 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/security/JwtAuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.security; 2 | 3 | import com.auth0.jwt.JWT; 4 | import com.example.demo.model.requests.CreateUserRequest; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import org.springframework.security.authentication.AuthenticationManager; 7 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 8 | import org.springframework.security.core.Authentication; 9 | import org.springframework.security.core.AuthenticationException; 10 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 11 | import org.springframework.security.core.userdetails.User; 12 | 13 | import javax.servlet.FilterChain; 14 | import javax.servlet.ServletException; 15 | import javax.servlet.http.HttpServletRequest; 16 | import javax.servlet.http.HttpServletResponse; 17 | import java.io.IOException; 18 | import java.util.ArrayList; 19 | import java.util.Date; 20 | 21 | import static com.auth0.jwt.algorithms.Algorithm.HMAC512; 22 | import static com.example.demo.security.SecurityConstant.*; 23 | 24 | public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { 25 | 26 | private AuthenticationManager authenticationManager; 27 | 28 | public JwtAuthenticationFilter(AuthenticationManager authenticationManager) { 29 | this.authenticationManager = authenticationManager; 30 | } 31 | 32 | @Override 33 | public Authentication attemptAuthentication(HttpServletRequest req, 34 | HttpServletResponse res) throws AuthenticationException { 35 | try { 36 | CreateUserRequest creds = new ObjectMapper() 37 | .readValue(req.getInputStream(), CreateUserRequest.class); 38 | 39 | return authenticationManager.authenticate( 40 | new UsernamePasswordAuthenticationToken( 41 | creds.getUsername(), 42 | creds.getPassword(), 43 | new ArrayList<>()) 44 | ); 45 | } catch (IOException e) { 46 | throw new RuntimeException(e); 47 | } 48 | } 49 | 50 | @Override 51 | protected void successfulAuthentication(HttpServletRequest req, 52 | HttpServletResponse res, 53 | FilterChain chain, 54 | Authentication auth) throws IOException, ServletException { 55 | 56 | String token = JWT.create() 57 | .withSubject(((User) auth.getPrincipal()).getUsername()) 58 | .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) 59 | .sign(HMAC512(SECRET.getBytes())); 60 | res.addHeader(HEADER_STRING, TOKEN_PREFIX + token); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/security/JwtAuthorizationFilter.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.security; 2 | 3 | import com.auth0.jwt.JWT; 4 | import com.auth0.jwt.algorithms.Algorithm; 5 | import org.springframework.security.authentication.AuthenticationManager; 6 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; 9 | 10 | import javax.servlet.FilterChain; 11 | import javax.servlet.ServletException; 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.io.IOException; 15 | import java.util.ArrayList; 16 | 17 | import static com.example.demo.security.SecurityConstant.*; 18 | 19 | public class JwtAuthorizationFilter extends BasicAuthenticationFilter { 20 | 21 | public JwtAuthorizationFilter(AuthenticationManager authenticationManager) { 22 | super(authenticationManager); 23 | } 24 | 25 | @Override 26 | protected void doFilterInternal(HttpServletRequest req, 27 | HttpServletResponse res, 28 | FilterChain chain) throws IOException, ServletException { 29 | String header = req.getHeader(HEADER_STRING); 30 | 31 | if (header == null || !header.startsWith(TOKEN_PREFIX)) { 32 | chain.doFilter(req, res); 33 | return; 34 | } 35 | 36 | UsernamePasswordAuthenticationToken authentication = getAuthentication(req); 37 | SecurityContextHolder.getContext().setAuthentication(authentication); 38 | chain.doFilter(req, res); 39 | } 40 | 41 | private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) { 42 | String token = request.getHeader(HEADER_STRING); 43 | if (token != null) { 44 | // parse the token. 45 | String user = JWT.require(Algorithm.HMAC512(SECRET.getBytes())) 46 | .build() 47 | .verify(token.replace(TOKEN_PREFIX, "")) 48 | .getSubject(); 49 | 50 | if (user != null) { 51 | return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>()); 52 | } 53 | return null; 54 | } 55 | return null; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/security/SecurityConstant.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.security; 2 | 3 | public class SecurityConstant { 4 | public static final String SECRET = "SecretKeyToGenJWTs"; 5 | public static final long EXPIRATION_TIME = 864_000_000; // 10 days 6 | public static final String TOKEN_PREFIX = "Bearer "; 7 | public static final String HEADER_STRING = "Authorization"; 8 | public static final String SIGN_UP_URL = "/api/user/create"; 9 | } 10 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/security/WebSecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.security; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.http.HttpMethod; 7 | import org.springframework.security.authentication.AuthenticationManager; 8 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 9 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 11 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 12 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 13 | import org.springframework.security.config.http.SessionCreationPolicy; 14 | import org.springframework.security.core.userdetails.UserDetailsService; 15 | import org.springframework.security.crypto.password.PasswordEncoder; 16 | 17 | import static com.example.demo.security.SecurityConstant.SIGN_UP_URL; 18 | 19 | @Configuration 20 | @EnableWebSecurity 21 | @EnableGlobalMethodSecurity(prePostEnabled = true) 22 | public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { 23 | 24 | @Autowired 25 | private UserDetailsService userDetailsService; 26 | 27 | @Autowired 28 | private PasswordEncoder bCryptPasswordEncoder; 29 | 30 | @Override 31 | protected void configure(HttpSecurity http) throws Exception { 32 | http.cors().and().csrf().disable().authorizeRequests() 33 | .antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll() 34 | .anyRequest().authenticated() 35 | .and() 36 | .addFilter(new JwtAuthenticationFilter(authenticationManager())) 37 | .addFilter(new JwtAuthorizationFilter(authenticationManager())) 38 | // this disables session creation on Spring Security 39 | .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); 40 | } 41 | 42 | @Override 43 | @Bean 44 | public AuthenticationManager authenticationManagerBean() throws Exception{ 45 | return super.authenticationManagerBean(); 46 | } 47 | 48 | @Override 49 | public void configure(AuthenticationManagerBuilder auth) throws Exception { 50 | auth.parentAuthenticationManager(authenticationManagerBean()) 51 | .userDetailsService(userDetailsService) 52 | .passwordEncoder(bCryptPasswordEncoder); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /e-commerce App/src/main/java/com/example/demo/service/UserDetailsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | import com.example.demo.model.persistence.EcommerceUser; 4 | import com.example.demo.model.persistence.repositories.UserRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.core.userdetails.User; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | import org.springframework.security.core.userdetails.UserDetailsService; 9 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.util.Collections; 13 | 14 | @Service 15 | public class UserDetailsServiceImpl implements UserDetailsService { 16 | 17 | @Autowired 18 | private UserRepository userRepository; 19 | 20 | @Override 21 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 22 | 23 | EcommerceUser ecommerceUser = userRepository.findByUsername(username); 24 | if(ecommerceUser == null){ 25 | throw new UsernameNotFoundException(username); 26 | } 27 | return new User(ecommerceUser.getUsername(), 28 | ecommerceUser.getPassword(), Collections.emptyList()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /e-commerce App/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.driver-class-name=org.h2.Driver 2 | spring.datasource.url=jdbc:h2:mem:bootapp;DB_CLOSE_DELAY=-1 3 | spring.datasource.username=sa 4 | spring.datasource.password= 5 | spring.jpa.hibernate.ddl-auto=update 6 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect 7 | 8 | # Log file 9 | logging.file=target/app.log -------------------------------------------------------------------------------- /e-commerce App/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | insert into item (name, price, description) values ('Round Widget', 2.99, 'A widget that is round'); 2 | insert into item (name, price, description) values ('Square Widget', 1.99, 'A widget that is square'); -------------------------------------------------------------------------------- /e-commerce App/src/test/java/com/example/demo/SareetaApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 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 SareetaApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /e-commerce App/src/test/java/com/example/demo/TestUnits.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | public class TestUnits { 6 | 7 | public static void injectObjects(Object target, String fieldName, Object toInject){ 8 | 9 | boolean wasPrivate = false; 10 | try { 11 | Field f = target.getClass().getDeclaredField(fieldName); 12 | 13 | if(!f.isAccessible()){ 14 | f.setAccessible(true); 15 | wasPrivate = true; 16 | } 17 | f.set(target, toInject); 18 | if(wasPrivate){ 19 | f.setAccessible(false); 20 | } 21 | } catch (NoSuchFieldException | IllegalAccessException e) { 22 | e.printStackTrace(); 23 | } 24 | 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /e-commerce App/target/classes/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.driver-class-name=org.h2.Driver 2 | spring.datasource.url=jdbc:h2:mem:bootapp;DB_CLOSE_DELAY=-1 3 | spring.datasource.username=sa 4 | spring.datasource.password= 5 | spring.jpa.hibernate.ddl-auto=update 6 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect 7 | 8 | # Log file 9 | logging.file=target/app.log -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/SareetaApplication.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/SareetaApplication.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/controllers/CartController.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/controllers/CartController.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/controllers/ItemController.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/controllers/ItemController.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/controllers/OrderController.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/controllers/OrderController.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/controllers/UserController.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/controllers/UserController.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/model/persistence/Cart.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/model/persistence/Cart.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/model/persistence/EcommerceUser.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/model/persistence/EcommerceUser.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/model/persistence/Item.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/model/persistence/Item.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/model/persistence/UserOrder.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/model/persistence/UserOrder.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/model/persistence/repositories/CartRepository.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/model/persistence/repositories/CartRepository.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/model/persistence/repositories/ItemRepository.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/model/persistence/repositories/ItemRepository.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/model/persistence/repositories/OrderRepository.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/model/persistence/repositories/OrderRepository.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/model/persistence/repositories/UserRepository.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/model/persistence/repositories/UserRepository.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/model/requests/CreateUserRequest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/model/requests/CreateUserRequest.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/model/requests/ModifyCartRequest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/model/requests/ModifyCartRequest.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/security/JwtAuthenticationFilter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/security/JwtAuthenticationFilter.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/security/JwtAuthorizationFilter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/security/JwtAuthorizationFilter.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/security/SecurityConstant.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/security/SecurityConstant.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/security/WebSecurityConfiguration.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/security/WebSecurityConfiguration.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/com/example/demo/service/UserDetailsServiceImpl.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/classes/com/example/demo/service/UserDetailsServiceImpl.class -------------------------------------------------------------------------------- /e-commerce App/target/classes/data.sql: -------------------------------------------------------------------------------- 1 | insert into item (name, price, description) values ('Round Widget', 2.99, 'A widget that is round'); 2 | insert into item (name, price, description) values ('Square Widget', 1.99, 'A widget that is square'); -------------------------------------------------------------------------------- /e-commerce App/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst -------------------------------------------------------------------------------- /e-commerce App/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst: -------------------------------------------------------------------------------- 1 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/model/persistence/UserOrder.java 2 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/model/requests/ModifyCartRequest.java 3 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/security/SecurityConstant.java 4 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/service/UserDetailsServiceImpl.java 5 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/controllers/ItemController.java 6 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/model/requests/CreateUserRequest.java 7 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/security/JwtAuthenticationFilter.java 8 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/security/WebSecurityConfiguration.java 9 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/model/persistence/EcommerceUser.java 10 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/model/persistence/repositories/CartRepository.java 11 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/model/persistence/repositories/OrderRepository.java 12 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/controllers/CartController.java 13 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/model/persistence/repositories/UserRepository.java 14 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/controllers/UserController.java 15 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/controllers/OrderController.java 16 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/SareetaApplication.java 17 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/model/persistence/repositories/ItemRepository.java 18 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/model/persistence/Cart.java 19 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/security/JwtAuthorizationFilter.java 20 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/main/java/com/example/demo/model/persistence/Item.java 21 | -------------------------------------------------------------------------------- /e-commerce App/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst -------------------------------------------------------------------------------- /e-commerce App/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst: -------------------------------------------------------------------------------- 1 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/test/java/com/example/demo/controllers/UserControllerTest.java 2 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/test/java/com/example/demo/SareetaApplicationTests.java 3 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree/e-commerce App/src/test/java/com/example/demo/TestUnits.java 4 | -------------------------------------------------------------------------------- /e-commerce App/target/test-classes/META-INF/auth-course.kotlin_module: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /e-commerce App/target/test-classes/com/example/demo/SareetaApplicationTests.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/test-classes/com/example/demo/SareetaApplicationTests.class -------------------------------------------------------------------------------- /e-commerce App/target/test-classes/com/example/demo/TestUnits.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/test-classes/com/example/demo/TestUnits.class -------------------------------------------------------------------------------- /e-commerce App/target/test-classes/com/example/demo/controllers/UserControllerTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/e-commerce App/target/test-classes/com/example/demo/controllers/UserControllerTest.class -------------------------------------------------------------------------------- /lab/DogRestApi/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ 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 | -------------------------------------------------------------------------------- /lab/DogRestApi/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/lab/DogRestApi/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /lab/DogRestApi/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /lab/DogRestApi/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.6.RELEASE 9 | 10 | 11 | com.udacity 12 | DogRestApi 13 | 0.0.1-SNAPSHOT 14 | DogRestApi 15 | The Dog REST API Lab 16 | 17 | 18 | 11 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-data-jpa 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | 32 | com.h2database 33 | h2 34 | runtime 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-test 39 | test 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | io.springfox 53 | springfox-swagger-ui 54 | 2.9.2 55 | 56 | 57 | 58 | io.springfox 59 | springfox-swagger2 60 | 2.9.2 61 | compile 62 | 63 | 64 | 65 | 66 | 67 | 68 | org.springframework.boot 69 | spring-boot-maven-plugin 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/main/java/com/udacity/DogRestApi/DogRestApiApplication.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogRestApi; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DogRestApiApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DogRestApiApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/main/java/com/udacity/DogRestApi/config/SpringSecurityConfig.java: -------------------------------------------------------------------------------- 1 | //package com.udacity.DogRestApi.config; 2 | // 3 | //import org.apache.tomcat.util.buf.UEncoder; 4 | //import org.springframework.beans.factory.annotation.Autowired; 5 | //import org.springframework.context.annotation.Bean; 6 | //import org.springframework.context.annotation.Configuration; 7 | //import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 8 | //import org.springframework.security.config.annotation.web.builders.HttpSecurity; 9 | //import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 10 | //import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 11 | //import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 12 | //import org.springframework.security.crypto.password.PasswordEncoder; 13 | // 14 | //@Configuration 15 | //@EnableWebSecurity 16 | //public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { 17 | // 18 | // @Override 19 | // protected void configure(HttpSecurity http) throws Exception{ 20 | // http 21 | // .csrf().disable() 22 | // .authorizeRequests() 23 | // .anyRequest() 24 | // .authenticated() 25 | // .and() 26 | // .httpBasic(); 27 | // } 28 | // 29 | // @Autowired 30 | // public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{ 31 | // auth.inMemoryAuthentication() 32 | // .withUser("admin") 33 | // .password(encoder().encode("password")) 34 | // .roles("USER"); 35 | // } 36 | // 37 | // @Bean 38 | // public PasswordEncoder encoder(){ 39 | // return new BCryptPasswordEncoder(); 40 | // } 41 | // 42 | //} 43 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/main/java/com/udacity/DogRestApi/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogRestApi.config; 2 | 3 | 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import springfox.documentation.builders.PathSelectors; 7 | import springfox.documentation.builders.RequestHandlerSelectors; 8 | import springfox.documentation.service.ApiInfo; 9 | import springfox.documentation.service.Contact; 10 | import springfox.documentation.spi.DocumentationType; 11 | import springfox.documentation.spring.web.plugins.Docket; 12 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 13 | 14 | import java.util.Collections; 15 | 16 | @Configuration 17 | @EnableSwagger2 18 | public class SwaggerConfig { 19 | 20 | @Bean 21 | public Docket api(){ 22 | return new Docket(DocumentationType.SWAGGER_2) 23 | .select() 24 | .apis(RequestHandlerSelectors.any()) 25 | .paths(PathSelectors.any()) 26 | .build() 27 | .apiInfo(apiInfo()); 28 | 29 | } 30 | 31 | private ApiInfo apiInfo(){ 32 | return new ApiInfo( 33 | "Dog Rest API", 34 | "This API returns a list of dogs", 35 | "1.0", 36 | "http://wwww.udacity.com/tos", 37 | new Contact("Udacious Student", "www.udacity.com", "myeaddress@udacity.com" ), 38 | "License of API", "http://www.udacity.com/license", Collections.emptyList()); 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/main/java/com/udacity/DogRestApi/entity/Dog.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogRestApi.entity; 2 | 3 | import javax.persistence.*; 4 | 5 | @Entity 6 | public class Dog { 7 | @Id 8 | @GeneratedValue(strategy = GenerationType.AUTO) 9 | private Long id; 10 | 11 | private String name; 12 | private String breed; 13 | private String origin; 14 | 15 | public Dog(Long id, String name, String breed, String origin) { 16 | this.id = id; 17 | this.name = name; 18 | this.breed = breed; 19 | this.origin = origin; 20 | } 21 | 22 | public Dog(String name, String breed) { 23 | this.name = name; 24 | this.breed = breed; 25 | } 26 | 27 | public Dog() {} 28 | 29 | public Long getId() { 30 | return id; 31 | } 32 | 33 | public void setId(Long id) { 34 | this.id = id; 35 | } 36 | 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | public void setName(String name) { 42 | this.name = name; 43 | } 44 | 45 | public String getBreed() { 46 | return breed; 47 | } 48 | 49 | public void setBreed(String breed) { 50 | this.breed = breed; 51 | } 52 | 53 | public String getOrigin() { 54 | return origin; 55 | } 56 | 57 | public void setOrigin(String origin) { 58 | this.origin = origin; 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/main/java/com/udacity/DogRestApi/repository/DogRepository.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogRestApi.repository; 2 | 3 | import com.udacity.DogRestApi.entity.Dog; 4 | import org.springframework.data.jpa.repository.Query; 5 | import org.springframework.data.repository.CrudRepository; 6 | 7 | import java.util.List; 8 | 9 | public interface DogRepository extends CrudRepository { 10 | @Query("select d.id, d.breed from Dog d where d.id=:id") 11 | String findBreedById(Long id); 12 | 13 | @Query("select d.id, d.breed from Dog d") 14 | List findAllBreed(); 15 | 16 | @Query("select d.id, d.name from Dog d") 17 | List findAllName(); 18 | } 19 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/main/java/com/udacity/DogRestApi/service/DogNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogRestApi.service; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.web.bind.annotation.ResponseStatus; 5 | 6 | @ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Dog not found") 7 | public class DogNotFoundException extends RuntimeException { 8 | 9 | public DogNotFoundException() { 10 | } 11 | 12 | public DogNotFoundException(String message) { 13 | super(message); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/main/java/com/udacity/DogRestApi/service/DogService.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogRestApi.service; 2 | 3 | import com.udacity.DogRestApi.entity.Dog; 4 | 5 | import java.util.List; 6 | 7 | public interface DogService { 8 | List retrieveDogs(); 9 | List retrieveDogBreed(); 10 | String retrieveDogBreedById(Long id); 11 | List retrieveDogNames(); 12 | } 13 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/main/java/com/udacity/DogRestApi/service/DogServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogRestApi.service; 2 | 3 | import com.udacity.DogRestApi.entity.Dog; 4 | import com.udacity.DogRestApi.repository.DogRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.List; 9 | import java.util.Optional; 10 | 11 | @Service 12 | public class DogServiceImpl implements DogService { 13 | @Autowired 14 | DogRepository dogRepository; 15 | 16 | public List retrieveDogs() { 17 | return (List) dogRepository.findAll(); 18 | } 19 | 20 | public List retrieveDogBreed() { 21 | return (List) dogRepository.findAllBreed(); 22 | } 23 | 24 | public String retrieveDogBreedById(Long id) { 25 | Optional optionalBreed = Optional.ofNullable(dogRepository.findBreedById(id)); 26 | String breed = optionalBreed.orElseThrow(DogNotFoundException::new); 27 | return breed; 28 | } 29 | 30 | public List retrieveDogNames() { 31 | return (List) dogRepository.findAllName(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/main/java/com/udacity/DogRestApi/web/DogController.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogRestApi.web; 2 | 3 | import com.udacity.DogRestApi.entity.Dog; 4 | import com.udacity.DogRestApi.service.DogService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import java.util.List; 13 | 14 | @RestController 15 | public class DogController { 16 | private DogService dogService; 17 | 18 | @Autowired 19 | public void setDogService(DogService dogService) { 20 | this.dogService = dogService; 21 | } 22 | 23 | @GetMapping("/dogs") 24 | public ResponseEntity> getAllDogs() { 25 | List list = dogService.retrieveDogs(); 26 | return new ResponseEntity>(list, HttpStatus.OK); 27 | } 28 | 29 | @GetMapping("/dogs/breed") 30 | public ResponseEntity> getDogBreeds() { 31 | List list = dogService.retrieveDogBreed(); 32 | return new ResponseEntity>(list, HttpStatus.OK); 33 | } 34 | 35 | @GetMapping("/{id}/breed") 36 | public ResponseEntity getBreedByID(@PathVariable Long id) { 37 | String breed = dogService.retrieveDogBreedById(id); 38 | return new ResponseEntity(breed, HttpStatus.OK); 39 | } 40 | 41 | @GetMapping("/dogs/name") 42 | public ResponseEntity> getDogNames() { 43 | List list = dogService.retrieveDogNames(); 44 | return new ResponseEntity>(list, HttpStatus.OK); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.h2.console.enabled=true 2 | spring.h2.console.path=/h2 3 | 4 | spring.datasource.url=jdbc:h2:mem:dogdata 5 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO dog (id, name, breed, origin) VALUES (1, 'Fluffy', 'Pomeranian', 'Mountain View, CA'); 2 | INSERT INTO dog (id, name, breed, origin) VALUES (2, 'Spot', 'Pit Bull', 'Austin, TX'); 3 | INSERT INTO dog (id, name, breed, origin) VALUES (3, 'Ginger', 'Cocker Spaniel', 'Kansas City, KS'); 4 | INSERT INTO dog (id, name, breed, origin) VALUES (4, 'Lady', 'Direwolf', 'The North'); 5 | INSERT INTO dog (id, name, breed, origin) VALUES (5, 'Sasha', 'Husky', 'Buffalo, NY'); -------------------------------------------------------------------------------- /lab/DogRestApi/src/test/java/com/udacity/DogRestApi/DogRestApiApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogRestApi; 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 DogRestApiApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/test/java/com/udacity/DogRestApi/web/DogControllerIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogRestApi.web; 2 | 3 | import com.udacity.DogRestApi.entity.Dog; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.boot.test.web.client.TestRestTemplate; 10 | import org.springframework.boot.web.server.LocalServerPort; 11 | import org.springframework.http.HttpStatus; 12 | import org.springframework.http.ResponseEntity; 13 | import org.springframework.test.context.junit4.SpringRunner; 14 | 15 | import java.util.List; 16 | 17 | import static org.hamcrest.CoreMatchers.equalTo; 18 | import static org.hamcrest.MatcherAssert.assertThat; 19 | 20 | @RunWith(SpringRunner.class) 21 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 22 | @AutoConfigureMockMvc 23 | public class DogControllerIntegrationTest { 24 | 25 | @LocalServerPort 26 | private int port; 27 | 28 | @Autowired 29 | private TestRestTemplate restTemplate; 30 | 31 | @Test 32 | public void getAllDogs(){ 33 | ResponseEntity response = this.restTemplate.getForEntity("http://localhost:" + port + "/dogs/", List.class); 34 | 35 | assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); 36 | } 37 | 38 | @Test 39 | public void getBreedByID(){ 40 | ResponseEntity response = this.restTemplate.getForEntity("http://localhost:" + port + "/1/breed/", String.class); 41 | 42 | assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /lab/DogRestApi/src/test/java/com/udacity/DogRestApi/web/DogControllerUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogRestApi.web; 2 | 3 | import com.udacity.DogRestApi.service.DogService; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 8 | import org.springframework.boot.test.mock.mockito.MockBean; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | import org.springframework.test.web.servlet.MockMvc; 12 | 13 | import static org.mockito.Mockito.verify; 14 | import static org.mockito.internal.verification.VerificationModeFactory.times; 15 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 16 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 17 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 18 | 19 | @RunWith(SpringRunner.class) 20 | @WebMvcTest(DogController.class) 21 | public class DogControllerUnitTest { 22 | 23 | @Autowired 24 | private MockMvc mockMvc; 25 | 26 | @MockBean 27 | DogService dogService; 28 | 29 | @Test 30 | public void getAllDogs() throws Exception{ 31 | mockMvc.perform(get("/dogs/")) 32 | .andExpect(status().isOk()) 33 | .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) 34 | .andExpect(content().json("[]")); 35 | 36 | verify(dogService, times(1)).retrieveDogs(); 37 | } 38 | 39 | @Test 40 | public void getDogs() throws Exception { 41 | mockMvc.perform(get("/1/breed/")) 42 | .andExpect(status().isOk()); 43 | 44 | verify(dogService, times(1)).retrieveDogBreedById((long) 1); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lab/JDBC_Flyway/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ 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 | 33 | .DS_Store -------------------------------------------------------------------------------- /lab/JDBC_Flyway/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ### Exercise Instructions 4 | 5 | * Write the SQL to create the _member_ table in src/main/resources/db/migration/V01__CreateTable.sql. 6 | * Follow the steps in Application class. 7 | 8 | ### Reference Documentation 9 | For further reference, please consider the following sections: 10 | 11 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) 12 | * [Flyway Migration](https://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#howto-execute-flyway-database-migrations-on-startup) 13 | * [JDBC API](https://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-sql) -------------------------------------------------------------------------------- /lab/JDBC_Flyway/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | com.udacity.course3.lesson1.exercise1 6 | exercise1 7 | 0.0.1-SNAPSHOT 8 | exercise1 9 | Java Developer - Lesson 1 - Exercise 1 10 | 11 | 12 | 1.8 13 | 14 | 15 | 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-compiler-plugin 20 | 21 | 8 22 | 8 23 | 24 | 25 | 26 | org.codehaus.mojo 27 | exec-maven-plugin 28 | 1.6.0 29 | 30 | 31 | 32 | java 33 | 34 | 35 | 36 | 37 | com.udacity.course3.lesson1.exercise1.exercise1.Application 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot 48 | 2.1.3.RELEASE 49 | 50 | 51 | org.flywaydb 52 | flyway-core 53 | 5.2.4 54 | 55 | 56 | 57 | mysql 58 | mysql-connector-java 59 | runtime 60 | 6.0.6 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /lab/JDBC_Flyway/src/main/java/com/udacity/course3/lesson1/exercise1/exercise1/Application.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.lesson1.exercise1.exercise1; 2 | 3 | 4 | import org.flywaydb.core.Flyway; 5 | import java.sql.*; 6 | import java.util.Properties; 7 | 8 | public class Application { 9 | 10 | public static void main(String[] args) throws SQLException { 11 | // STEP 1: Create the JDBC URL for JDND-C3 database 12 | String jdbcUrl = "jdbc:mysql://localhost:3306/JDND_C3?serverTimezone=UTC&useSSL=false"; 13 | Properties properties = new Properties(); 14 | properties.setProperty("user", "root"); 15 | properties.setProperty("password", "root"); 16 | 17 | // STEP 2: Setup and Run Flyway migration that creates the member table using its Java API 18 | // https://flywaydb.org/getstarted/firststeps/api#integrating-flyway 19 | // Note the above link talks about connecting to H2 database, for this exercise, MySQL is used. Adapt the code accordingly. 20 | Flyway flyway = Flyway.configure().dataSource(jdbcUrl, "root", "root").load(); 21 | flyway.baseline(); 22 | flyway.migrate(); 23 | 24 | // STEP 3: Obtain a connection to the JDND-C3 database 25 | // Connection connection = DriverManager.getConnection(jdbcUrl, properties); 26 | // System.out.println("connected: "+ connection.getMetaData()); 27 | // // STEP 4: Use Statement to INSERT 2 records into the member table 28 | // // NOTE: The member table is created using Flyway by placing the migration file in src/main/resources/db/migration 29 | // 30 | // String insertTableSQL = "INSERT INTO member" 31 | // + "(ID, NAME) VALUES" 32 | // + "(?,?)"; 33 | // PreparedStatement preparedStatement = connection.prepareStatement(insertTableSQL); 34 | // preparedStatement.setString(1, "Sarah"); 35 | // preparedStatement.setString(2 ,"James"); 36 | // 37 | // preparedStatement.executeUpdate(); 38 | // // STEP 5: Read ALL the rows from the member table and print them here 39 | // Statement stmt = connection.createStatement(); 40 | // ResultSet set = stmt.executeQuery("SELECT * FROM MEMBER"); 41 | // while(set.next()){ 42 | // int id = set.getInt("ID"); 43 | // String name = set.getString("NAME"); 44 | // 45 | // System.out.println("ID: "+ id); 46 | // System.out.println("NAME: " + name); 47 | // } 48 | 49 | 50 | // STEP 6: verify that all inserted rows have been printed 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /lab/JDBC_Flyway/src/main/resources/db/migration/V01__CreateTable.sql: -------------------------------------------------------------------------------- 1 | 2 | CREATE TABLE member( 3 | ID int not null, 4 | NAME varchar(300) not null 5 | ); 6 | -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ 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 | -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/lab/graphql/DogGraphQL/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.7.RELEASE 9 | 10 | 11 | com.udacity 12 | DogGraphQL 13 | 0.0.1-SNAPSHOT 14 | DogGraphQL 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-data-jpa 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | 32 | com.h2database 33 | h2 34 | runtime 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-test 39 | test 40 | 41 | 42 | com.graphql-java 43 | graphql-spring-boot-starter 44 | 5.0.2 45 | 46 | 47 | 48 | com.graphql-java 49 | graphql-java-tools 50 | 5.2.4 51 | 52 | 53 | 54 | com.graphql-java 55 | graphiql-spring-boot-starter 56 | 5.0.2 57 | 58 | 59 | 60 | 61 | 62 | 63 | org.springframework.boot 64 | spring-boot-maven-plugin 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/src/main/java/com/udacity/DogGraphQL/DogGraphQlApplication.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogGraphQL; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DogGraphQlApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DogGraphQlApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/src/main/java/com/udacity/DogGraphQL/Entity/Dog.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogGraphQL.Entity; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | 8 | @Entity 9 | public class Dog { 10 | 11 | @Id 12 | @GeneratedValue(strategy = GenerationType.AUTO) 13 | private Long id; 14 | private String name; 15 | private String breed; 16 | private String origin; 17 | 18 | public Dog(Long id, String name, String breed, String origin){ 19 | this.id = id; 20 | this.name = name; 21 | this.breed = breed; 22 | this.origin = origin; 23 | } 24 | 25 | public Dog(String name, String breed, String origin){ 26 | this.name = name; 27 | this.breed = breed; 28 | this.origin = origin; 29 | } 30 | 31 | public Dog(){} 32 | 33 | public String getName() { 34 | return name; 35 | } 36 | 37 | public void setName(String name) { 38 | this.name = name; 39 | } 40 | 41 | public String getBreed() { 42 | return breed; 43 | } 44 | 45 | public void setBreed(String breed) { 46 | breed = breed; 47 | } 48 | 49 | public String getOrigin() { 50 | return origin; 51 | } 52 | 53 | public void setOrigin(String origin) { 54 | origin = origin; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/src/main/java/com/udacity/DogGraphQL/exception/BreedNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogGraphQL.exception; 2 | 3 | import graphql.ErrorType; 4 | import graphql.GraphQLError; 5 | import graphql.language.SourceLocation; 6 | 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public class BreedNotFoundException extends RuntimeException implements GraphQLError { 12 | 13 | private Map extensions = new HashMap<>(); 14 | 15 | public BreedNotFoundException(String message, String invalidBreed){ 16 | super(message); 17 | extensions.put("invalidBreedId", invalidBreed); 18 | 19 | } 20 | 21 | @Override 22 | public List getLocations() { 23 | return null; 24 | } 25 | 26 | @Override 27 | public ErrorType getErrorType() { 28 | return ErrorType.DataFetchingException; 29 | } 30 | 31 | @Override 32 | public Map getExtensions() { 33 | return extensions; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/src/main/java/com/udacity/DogGraphQL/exception/DogNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogGraphQL.exception; 2 | 3 | import graphql.ErrorType; 4 | import graphql.GraphQLError; 5 | import graphql.language.SourceLocation; 6 | 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public class DogNotFoundException extends RuntimeException implements GraphQLError { 12 | 13 | private Map extensions = new HashMap<>(); 14 | 15 | public DogNotFoundException(String message, Long invalidDogId){ 16 | super(message); 17 | extensions.put("invalidDogId", invalidDogId); 18 | } 19 | 20 | 21 | @Override 22 | public List getLocations() { 23 | return null; 24 | } 25 | 26 | @Override 27 | public Map getExtensions(){ 28 | return extensions; 29 | } 30 | 31 | @Override 32 | public ErrorType getErrorType() { 33 | return ErrorType.DataFetchingException; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/src/main/java/com/udacity/DogGraphQL/mutator/Mutation.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogGraphQL.mutator; 2 | 3 | import com.coxautodev.graphql.tools.GraphQLMutationResolver; 4 | import com.udacity.DogGraphQL.Entity.Dog; 5 | import com.udacity.DogGraphQL.exception.BreedNotFoundException; 6 | import com.udacity.DogGraphQL.exception.DogNotFoundException; 7 | import com.udacity.DogGraphQL.repository.DogRepository; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.util.Optional; 11 | 12 | @Component 13 | public class Mutation implements GraphQLMutationResolver { 14 | private DogRepository dogRepository; 15 | 16 | public Mutation(DogRepository dogRepository){ 17 | this.dogRepository = dogRepository; 18 | } 19 | 20 | public boolean deleteDogBreed(String breed){ 21 | boolean deleted = false; 22 | Iterable allDogs = dogRepository.findAll(); 23 | 24 | for(Dog d: allDogs){ 25 | if(d.getBreed().equals(breed)){ 26 | dogRepository.delete(d); 27 | deleted = true; 28 | } 29 | } 30 | if(!deleted){ 31 | throw new BreedNotFoundException("Breed not found", breed); 32 | } 33 | 34 | return deleted; 35 | } 36 | 37 | public Dog updateDogName(String newName, Long id){ 38 | Optional optionalDog = dogRepository.findById(id); 39 | 40 | if(optionalDog.isPresent()){ 41 | Dog dog = optionalDog.get(); 42 | 43 | dog.setName(newName); 44 | dogRepository.save(dog); 45 | return dog; 46 | } 47 | else{ 48 | throw new DogNotFoundException("Dog not found", id); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/src/main/java/com/udacity/DogGraphQL/repository/DogRepository.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogGraphQL.repository; 2 | 3 | import com.udacity.DogGraphQL.Entity.Dog; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | public interface DogRepository extends CrudRepository { 7 | 8 | 9 | } 10 | -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/src/main/java/com/udacity/DogGraphQL/resolver/Query.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogGraphQL.resolver; 2 | 3 | import com.coxautodev.graphql.tools.GraphQLQueryResolver; 4 | import com.udacity.DogGraphQL.Entity.Dog; 5 | import com.udacity.DogGraphQL.exception.DogNotFoundException; 6 | import com.udacity.DogGraphQL.repository.DogRepository; 7 | import org.springframework.stereotype.Component; 8 | 9 | import javax.swing.text.html.Option; 10 | import java.util.Optional; 11 | 12 | @Component 13 | public class Query implements GraphQLQueryResolver { 14 | 15 | private DogRepository dogRepository; 16 | 17 | public Query(DogRepository dogRepository){ 18 | this.dogRepository = dogRepository; 19 | } 20 | 21 | public Iterable findAllDogs(){ 22 | return dogRepository.findAll(); 23 | } 24 | 25 | public Dog findDogById(Long id){ 26 | Optional optionalDog = dogRepository.findById(id); 27 | if(optionalDog.isPresent()){ 28 | return optionalDog.get(); 29 | } 30 | else{ 31 | throw new DogNotFoundException("Dog not found", id); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | spring.h2.console.enabled=true 3 | spring.h2.console.path=/h2 4 | spring.datasource.url=jdbc:h2:mem:dogdata 5 | 6 | graphql.servlet.mapping=/graphql 7 | graphql.servlet.enabled=true 8 | graphql.servlet.corsEnabled=true 9 | 10 | graphiql.enabled=true 11 | graphiql.endpoint=/graphql 12 | graphiql.mapping=graphiql -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO dog (id, name, breed, origin) VALUES (1, 'Fluffy', 'Pomeranian', 'Mountain View, CA'); 2 | INSERT INTO dog (id, name, breed, origin) VALUES (2, 'Spot', 'Pit Bull', 'Austin, TX'); 3 | INSERT INTO dog (id, name, breed, origin) VALUES (3, 'Ginger', 'Cocker Spaniel', 'Kansas City, KS'); 4 | INSERT INTO dog (id, name, breed, origin) VALUES (4, 'Lady', 'Direwolf', 'The North'); 5 | INSERT INTO dog (id, name, breed, origin) VALUES (5, 'Sasha', 'Husky', 'Buffalo, NY'); -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/src/main/resources/graphql/dog.graphqls: -------------------------------------------------------------------------------- 1 | type Dog { 2 | id: ID! 3 | name: String! 4 | breed: String! 5 | origin: String! 6 | } 7 | 8 | type Query { 9 | findAllDogs: [Dog]! 10 | findDogById(id:ID!): Dog! 11 | } 12 | 13 | type Mutation { 14 | deleteDogBreed(breed:String!) : Boolean 15 | updateDogName(newName: String!, id:ID!) : Dog! 16 | } -------------------------------------------------------------------------------- /lab/graphql/DogGraphQL/src/test/java/com/udacity/DogGraphQL/DogGraphQlApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.udacity.DogGraphQL; 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 DogGraphQlApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ 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 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/lab/graphql/graphql_airport/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.8.RELEASE 9 | 10 | 11 | com.udacity 12 | graphql 13 | 0.0.1-SNAPSHOT 14 | graphql 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-data-jpa 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | 32 | com.h2database 33 | h2 34 | runtime 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-test 39 | test 40 | 41 | 42 | 43 | com.graphql-java 44 | graphql-java-tools 45 | 5.2.4 46 | 47 | 48 | com.graphql-java 49 | graphql-spring-boot-starter 50 | 5.0.2 51 | 52 | 53 | com.graphql-java 54 | graphiql-spring-boot-starter 55 | 5.0.2 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | org.springframework.boot 68 | spring-boot-maven-plugin 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/main/java/com/udacity/graphql/GraphqlApplication.java: -------------------------------------------------------------------------------- 1 | package com.udacity.graphql; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class GraphqlApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(GraphqlApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/main/java/com/udacity/graphql/entity/Location.java: -------------------------------------------------------------------------------- 1 | package com.udacity.graphql.entity; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | 8 | @Entity 9 | public class Location { 10 | 11 | @Id 12 | @GeneratedValue(strategy = GenerationType.AUTO) 13 | private Long id; 14 | private String name; 15 | private String address; 16 | 17 | public Location(Long id, String name, String address){ 18 | this.id = id; 19 | this.name = name; 20 | this.address = address; 21 | } 22 | 23 | public Location(String name, String address){ 24 | this.name = name; 25 | this.address = address; 26 | } 27 | 28 | public Location(){} 29 | 30 | public Long getId() { 31 | return id; 32 | } 33 | 34 | public void setId(Long id) { 35 | this.id = id; 36 | } 37 | 38 | public String getName() { 39 | return name; 40 | } 41 | 42 | public void setName(String name) { 43 | this.name = name; 44 | } 45 | 46 | public String getAddress() { 47 | return address; 48 | } 49 | 50 | public void setAddress(String address) { 51 | this.address = address; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/main/java/com/udacity/graphql/exception/LocationNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.udacity.graphql.exception; 2 | 3 | import graphql.ErrorType; 4 | import graphql.GraphQLError; 5 | import graphql.language.SourceLocation; 6 | 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public class LocationNotFoundException extends RuntimeException implements GraphQLError { 12 | private Map extensions = new HashMap<>(); 13 | 14 | public LocationNotFoundException(String message, Long invalidLocationId){ 15 | super(message); 16 | extensions.put("invalidLocationId", invalidLocationId); 17 | } 18 | 19 | 20 | @Override 21 | public List getLocations() { 22 | return null; 23 | } 24 | 25 | @Override 26 | public ErrorType getErrorType() { 27 | return ErrorType.DataFetchingException; 28 | } 29 | 30 | @Override 31 | public Map getExtensions() { 32 | return extensions; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/main/java/com/udacity/graphql/mutator/Mutation.java: -------------------------------------------------------------------------------- 1 | package com.udacity.graphql.mutator; 2 | 3 | import com.coxautodev.graphql.tools.GraphQLMutationResolver; 4 | import com.udacity.graphql.entity.Location; 5 | import com.udacity.graphql.exception.LocationNotFoundException; 6 | import com.udacity.graphql.repository.LocationRepository; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.Optional; 10 | 11 | @Component 12 | public class Mutation implements GraphQLMutationResolver { 13 | 14 | private LocationRepository locationRepository; 15 | 16 | public Mutation(LocationRepository locationRepository){ 17 | this.locationRepository = locationRepository; 18 | } 19 | 20 | public Location newLocation(String name, String address){ 21 | Location location = new Location(name, address); 22 | locationRepository.save(location); 23 | return location; 24 | } 25 | 26 | public boolean deleteLocation(Long id){ 27 | locationRepository.deleteById(id); 28 | return true; 29 | } 30 | 31 | public Location updateLocationName(String newName, Long id){ 32 | Optional optionalLocation = locationRepository.findById(id); 33 | 34 | if(optionalLocation.isPresent()){ 35 | Location location = optionalLocation.get(); 36 | location.setName(newName); 37 | 38 | locationRepository.save(location); 39 | return location; 40 | } 41 | else{ 42 | throw new LocationNotFoundException("Location Not Found", id); 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/main/java/com/udacity/graphql/repository/LocationRepository.java: -------------------------------------------------------------------------------- 1 | package com.udacity.graphql.repository; 2 | 3 | import com.udacity.graphql.entity.Location; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | public interface LocationRepository extends CrudRepository { 7 | } 8 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/main/java/com/udacity/graphql/resolver/Query.java: -------------------------------------------------------------------------------- 1 | package com.udacity.graphql.resolver; 2 | 3 | import com.coxautodev.graphql.tools.GraphQLQueryResolver; 4 | import com.udacity.graphql.entity.Location; 5 | import com.udacity.graphql.repository.LocationRepository; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | public class Query implements GraphQLQueryResolver { 10 | 11 | private LocationRepository locationRepository; 12 | 13 | public Query(LocationRepository locationRepository){ 14 | this.locationRepository = locationRepository; 15 | } 16 | 17 | public Iterable findAllLocations(){ 18 | return locationRepository.findAll(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/main/java/com/udacity/graphql/service/LocationService.java: -------------------------------------------------------------------------------- 1 | package com.udacity.graphql.service; 2 | 3 | import com.udacity.graphql.entity.Location; 4 | 5 | import java.util.List; 6 | 7 | public interface LocationService { 8 | List retrieveLocations(); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/main/java/com/udacity/graphql/service/LocationServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.udacity.graphql.service; 2 | 3 | import com.udacity.graphql.entity.Location; 4 | import com.udacity.graphql.repository.LocationRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.List; 9 | 10 | @Service 11 | public class LocationServiceImpl implements LocationService { 12 | 13 | @Autowired 14 | LocationRepository locationRepository; 15 | 16 | @Override 17 | public List retrieveLocations() { 18 | return (List) locationRepository.findAll(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/main/java/com/udacity/graphql/web/LocationController.java: -------------------------------------------------------------------------------- 1 | package com.udacity.graphql.web; 2 | 3 | import com.udacity.graphql.entity.Location; 4 | import com.udacity.graphql.service.LocationService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | import org.springframework.http.HttpStatus; 10 | 11 | import java.util.List; 12 | 13 | @RestController 14 | public class LocationController { 15 | 16 | 17 | private LocationService locationService; 18 | 19 | @Autowired 20 | public void setLocationService(LocationService locationService){ 21 | this.locationService = locationService; 22 | } 23 | 24 | @GetMapping("/location") 25 | public ResponseEntity> getAllLocations(){ 26 | List list = locationService.retrieveLocations(); 27 | return new ResponseEntity>(list, HttpStatus.OK); 28 | } 29 | 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.h2.console.enabled = true 2 | spring.h2.console.path = /h2 3 | sping.datasource.url = jdbc:h2:mem:locationtracker 4 | 5 | graphql.servlet.mapping = /graphql 6 | graphql.servlet.enabled = true 7 | graphql.servlet.corsEnabled=true 8 | 9 | graphiql.enabled = true 10 | graphiql.endpoint = /graphql 11 | graphiql.mapping = graphiql -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/main/resources/dataTest.sql: -------------------------------------------------------------------------------- 1 | 2 | INSERT INTO location (id, name, address) VALUES (1, 'ATL Airport','Atlanta airport location'); 3 | INSERT INTO location (id, name, address) VALUES (2, 'MIA Airport','Miami airport location'); 4 | INSERT INTO location (id, name, address) VALUES (3, 'LAX Airport','Los Angeles airport location'); 5 | INSERT INTO location (id, name, address) VALUES (4, 'PHX Airport','Phoenix airport location'); 6 | INSERT INTO location (id, name, address) VALUES (5, 'ORD Airport','Chicago airport location'); 7 | -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/main/resources/graphql/location.graphqls: -------------------------------------------------------------------------------- 1 | type Location{ 2 | id:ID! 3 | name:String! 4 | address:String! 5 | } 6 | 7 | type Query{ 8 | findAllLocations:[Location]! 9 | } 10 | 11 | type Mutation{ 12 | newLocation(name:String!, address:String) : Location! 13 | deleteLocation(id:ID!) : Boolean 14 | updateLocationName(newName:String!, id:ID!) : Location! 15 | } -------------------------------------------------------------------------------- /lab/graphql/graphql_airport/src/test/java/com/udacity/graphql/GraphqlApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.udacity.graphql; 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 GraphqlApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /lab/microservices/dogMicroservice/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ 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 | -------------------------------------------------------------------------------- /lab/microservices/dogMicroservice/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/lab/microservices/dogMicroservice/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /lab/microservices/dogMicroservice/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /lab/microservices/dogMicroservice/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.8.RELEASE 9 | 10 | 11 | com.udacity 12 | dogMicroservice 13 | 0.0.1-SNAPSHOT 14 | dogMicroservice 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | Greenwich.SR2 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-data-jpa 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-data-rest 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | org.springframework.cloud 37 | spring-cloud-starter-config 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-netflix-eureka-client 42 | 43 | 44 | 45 | com.h2database 46 | h2 47 | runtime 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-test 52 | test 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.cloud 60 | spring-cloud-dependencies 61 | ${spring-cloud.version} 62 | pom 63 | import 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | org.springframework.boot 72 | spring-boot-maven-plugin 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /lab/microservices/dogMicroservice/src/main/java/com/udacity/dogMicroservice/DogMicroserviceApplication.java: -------------------------------------------------------------------------------- 1 | package com.udacity.dogMicroservice; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 6 | 7 | @SpringBootApplication 8 | @EnableEurekaClient 9 | public class DogMicroserviceApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(DogMicroserviceApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab/microservices/dogMicroservice/src/main/java/com/udacity/dogMicroservice/entity/Dog.java: -------------------------------------------------------------------------------- 1 | package com.udacity.dogMicroservice.entity; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | 8 | @Entity 9 | public class Dog { 10 | 11 | @Id 12 | @GeneratedValue(strategy = GenerationType.AUTO) 13 | private Long id; 14 | private String name; 15 | private String breed; 16 | private String origin; 17 | 18 | public Dog(){} 19 | 20 | public Dog(Long id, String name, String breed, String origin){ 21 | this.id = id; 22 | this.name = name; 23 | this.breed = breed; 24 | this.origin = origin; 25 | } 26 | 27 | public Dog(String name, String breed, String origin){ 28 | this.name = name; 29 | this.breed = breed; 30 | this.origin = origin; 31 | } 32 | 33 | public Long getId() { 34 | return id; 35 | } 36 | 37 | public void setId(Long id) { 38 | this.id = id; 39 | } 40 | 41 | public String getName() { 42 | return name; 43 | } 44 | 45 | public void setName(String name) { 46 | this.name = name; 47 | } 48 | 49 | public String getBreed() { 50 | return breed; 51 | } 52 | 53 | public void setBreed(String breed) { 54 | this.breed = breed; 55 | } 56 | 57 | public String getOrigin() { 58 | return origin; 59 | } 60 | 61 | public void setOrigin(String origin) { 62 | this.origin = origin; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lab/microservices/dogMicroservice/src/main/java/com/udacity/dogMicroservice/repository/DogRepository.java: -------------------------------------------------------------------------------- 1 | package com.udacity.dogMicroservice.repository; 2 | 3 | import com.udacity.dogMicroservice.entity.Dog; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | public interface DogRepository extends CrudRepository { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /lab/microservices/dogMicroservice/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | spring.h2.console.enabled=true 3 | spring.h2.console.path=/h2 4 | spring.datasource.url=jdbc:h2:mem:dogs 5 | 6 | 7 | spring.application.name=dog-service 8 | server.port=8762 9 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 10 | eureka.client.service-url.default-zone=http://localhost:8761/eureka/ 11 | eureka.instance.prefer-ip-address=true -------------------------------------------------------------------------------- /lab/microservices/dogMicroservice/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO dog (id, name, breed, origin) VALUES (1, 'Fluffy', 'Pomeranian', 'Mountain View, CA'); 2 | INSERT INTO dog (id, name, breed, origin) VALUES (2, 'Spot', 'Pit Bull', 'Austin, TX'); 3 | INSERT INTO dog (id, name, breed, origin) VALUES (3, 'Ginger', 'Cocker Spaniel', 'Kansas City, KS'); 4 | INSERT INTO dog (id, name, breed, origin) VALUES (4, 'Lady', 'Direwolf', 'The North'); 5 | INSERT INTO dog (id, name, breed, origin) VALUES (5, 'Sasha', 'Husky', 'Buffalo, NY'); -------------------------------------------------------------------------------- /lab/microservices/dogMicroservice/src/test/java/com/udacity/dogMicroservice/DogMicroserviceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.udacity.dogMicroservice; 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 DogMicroserviceApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /lab/microservices/eureka/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ 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 | -------------------------------------------------------------------------------- /lab/microservices/eureka/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/lab/microservices/eureka/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /lab/microservices/eureka/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /lab/microservices/eureka/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.8.RELEASE 9 | 10 | 11 | com.udacity 12 | MicroService 13 | 0.0.1-SNAPSHOT 14 | MicroService 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | Greenwich.SR2 20 | 21 | 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-config 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter-netflix-eureka-server 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | test 36 | 37 | 38 | javax.xml.bind 39 | jaxb-api 40 | 2.4.0-b180725.0427 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.springframework.cloud 48 | spring-cloud-dependencies 49 | ${spring-cloud.version} 50 | pom 51 | import 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-maven-plugin 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /lab/microservices/eureka/src/main/java/com/udacity/MicroService/MicroServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.udacity.MicroService; 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 | @SpringBootApplication 8 | @EnableEurekaServer 9 | public class MicroServiceApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(MicroServiceApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab/microservices/eureka/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name = eureka-server 2 | server.port = 8761 3 | 4 | eureka.client.register-with-eureka=false 5 | eureka.client.fetch-registry = false 6 | loggin.level.com.netflix.eureka = ON 7 | loggin.level.com.netflix.discovery = ON -------------------------------------------------------------------------------- /lab/microservices/eureka/src/test/java/com/udacity/MicroService/MicroServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.udacity.MicroService; 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 MicroServiceApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/.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 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/ReviewsAPI/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /projects/ReviewsAPI/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/README.md: -------------------------------------------------------------------------------- 1 | # Reviews API 2 | Supports operations for writing reviews and listing reviews for a product but with no sorting or filtering. 3 | 4 | ### Prerequisites 5 | MySQL needs to be installed and configured. Instructions provided separately. 6 | 7 | ### Getting Started 8 | * Configure the MySQL Datasource in application.properties. 9 | * Add Flyway scripts in src/main/resources/db/migration. 10 | * Define JPA Entities and relationships. 11 | * Define Spring Data JPA Repositories. 12 | * Add tests for JPA Repositories. 13 | 14 | ### Reference Documentation 15 | For further reference, please consider the following sections: 16 | 17 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) 18 | 19 | ### Guides 20 | The following guides illustrate how to use some features concretely: 21 | 22 | * [Accessing JPA Data with REST](https://spring.io/guides/gs/accessing-data-rest/) 23 | * [Accessing Data with JPA](https://spring.io/guides/gs/accessing-data-jpa/) 24 | * [Accessing data with MySQL](https://spring.io/guides/gs/accessing-data-mysql/) -------------------------------------------------------------------------------- /projects/ReviewsAPI/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | com.udacity.course3 12 | reviews 13 | 0.0.1-SNAPSHOT 14 | reviews 15 | Midterm Project for Data Stores and Persistence 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-data-jpa 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | org.flywaydb 32 | flyway-core 33 | 34 | 35 | 36 | mysql 37 | mysql-connector-java 38 | runtime 39 | 40 | 41 | com.h2database 42 | h2 43 | test 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | test 49 | 50 | 51 | 52 | 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-maven-plugin 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/java/com/udacity/course3/reviews/ReviewsApplication.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ReviewsApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ReviewsApplication.class, args); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/java/com/udacity/course3/reviews/controller/ProductsController.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews.controller; 2 | 3 | import com.udacity.course3.reviews.entity.Product; 4 | import com.udacity.course3.reviews.repository.ProductRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import java.util.List; 11 | import java.util.Optional; 12 | 13 | /** 14 | * Spring REST controller for working with product entity. 15 | */ 16 | @RestController 17 | @RequestMapping("/products") 18 | public class ProductsController { 19 | 20 | @Autowired 21 | ProductRepository productRepository; 22 | /** 23 | * Creates a product. 24 | * 25 | * 1. Accept product as argument. Use {@link RequestBody} annotation. 26 | * 2. Save product. 27 | */ 28 | @RequestMapping(value = "/", method = RequestMethod.POST) 29 | @ResponseStatus(HttpStatus.CREATED) 30 | public void createProduct(@RequestBody Product product) { 31 | 32 | product.setName(product.getName()); 33 | product.setInfo(product.getInfo()); 34 | productRepository.save(product); 35 | } 36 | /** 37 | * Finds a product by id. 38 | * 39 | * @param id The id of the product. 40 | * @return The product if found, or a 404 not found. 41 | */ 42 | @RequestMapping(value = "/{id}") 43 | public ResponseEntity findById(@PathVariable("id") Integer id) { 44 | Optional product = productRepository.findById(id); 45 | if(!product.isPresent()){ 46 | return new ResponseEntity<>(HttpStatus.NOT_FOUND); 47 | } 48 | return new ResponseEntity<>(product, HttpStatus.OK); 49 | } 50 | 51 | /** 52 | * Lists all products. 53 | * 54 | * @return The list of products. 55 | */ 56 | @RequestMapping(value = "/", method = RequestMethod.GET) 57 | public List listProducts() { 58 | return productRepository.findAll(); 59 | } 60 | } -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/java/com/udacity/course3/reviews/controller/ReviewsController.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews.controller; 2 | 3 | import com.udacity.course3.reviews.entity.Product; 4 | import com.udacity.course3.reviews.entity.Review; 5 | import com.udacity.course3.reviews.repository.ProductRepository; 6 | import com.udacity.course3.reviews.repository.ReviewRepository; 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.*; 11 | 12 | import java.util.List; 13 | import java.util.Optional; 14 | 15 | /** 16 | * Spring REST controller for working with review entity. 17 | */ 18 | @RestController 19 | public class ReviewsController { 20 | 21 | @Autowired 22 | ReviewRepository reviewRepository; 23 | 24 | @Autowired 25 | ProductRepository productRepository; 26 | 27 | /** 28 | * Creates a review for a product. 29 | *

30 | * 1. Add argument for review entity. Use {@link RequestBody} annotation. 31 | * 2. Check for existence of product. 32 | * 3. If product not found, return NOT_FOUND. 33 | * 4. If found, save review. 34 | * 35 | * @param productId The id of the product. 36 | * @return The created review or 404 if product id is not found. 37 | */ 38 | @RequestMapping(value = "/reviews/products/{productId}", method = RequestMethod.POST) 39 | public ResponseEntity createReviewForProduct(@PathVariable("productId") Integer productId, @RequestBody Review reviews) { 40 | Optional product = productRepository.findById(productId); 41 | if(product.isPresent()){ 42 | reviews.setProductID(productId); 43 | reviews.setContent(reviews.getContent()); 44 | reviewRepository.save(reviews); 45 | } 46 | else{ 47 | return new ResponseEntity<>(HttpStatus.NOT_FOUND); 48 | } 49 | return new ResponseEntity<>(reviews, HttpStatus.OK); 50 | } 51 | 52 | /** 53 | * Lists reviews by product. 54 | * 55 | * @param productId The id of the product. 56 | * @return The list of reviews. 57 | */ 58 | @RequestMapping(value = "/reviews/products/{productId}", method = RequestMethod.GET) 59 | public ResponseEntity> listReviewsForProduct(@PathVariable("productId") Integer productId) { 60 | List reviews = reviewRepository.findByProductID(productId); 61 | return new ResponseEntity<>(reviews, HttpStatus.OK); 62 | } 63 | } -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/java/com/udacity/course3/reviews/entity/Comment.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews.entity; 2 | 3 | import javax.persistence.*; 4 | 5 | @Entity 6 | @Table(name="comments") 7 | public class Comment { 8 | 9 | @Id 10 | @GeneratedValue(strategy = GenerationType.IDENTITY) 11 | @Column(name = "commentID") 12 | private int commentID; 13 | 14 | @Column(name = "content") 15 | private String content; 16 | 17 | @Column(name="reviewID") 18 | private int reviewID; 19 | 20 | public int getCommentID() { 21 | return commentID; 22 | } 23 | 24 | public void setCommentID(int commentID) { 25 | this.commentID = commentID; 26 | } 27 | 28 | public String getContent() { 29 | return content; 30 | } 31 | 32 | public void setContent(String content) { 33 | this.content = content; 34 | } 35 | 36 | public int getReviewID() { 37 | return reviewID; 38 | } 39 | 40 | public void setReviewID(int reviewID) { 41 | this.reviewID = reviewID; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/java/com/udacity/course3/reviews/entity/Product.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews.entity; 2 | 3 | import javax.persistence.*; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | @Entity 8 | @Table(name = "products") 9 | public class Product { 10 | 11 | @Id 12 | @GeneratedValue(strategy = GenerationType.IDENTITY) 13 | @Column(name = "productID") 14 | private int productID; 15 | 16 | @Column(name = "name") 17 | private String name; 18 | 19 | @Column(name = "info") 20 | private String info; 21 | 22 | @OneToMany 23 | @JoinColumn(name = "reviewID") 24 | private List review = new ArrayList<>(); 25 | 26 | public int getProductID() { 27 | return productID; 28 | } 29 | 30 | public void setProductID(int id) {this.productID = productID;} 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | public void setName(String name) { 37 | this.name = name; 38 | } 39 | 40 | public String getInfo() { 41 | return info; 42 | } 43 | 44 | public void setInfo(String info) { 45 | this.info = info; 46 | } 47 | 48 | public List getReview() { 49 | return review; 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/java/com/udacity/course3/reviews/entity/Review.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews.entity; 2 | 3 | import javax.persistence.*; 4 | import javax.xml.bind.annotation.XmlAnyAttribute; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | @Entity 9 | @Table(name= "reviews") 10 | public class Review { 11 | 12 | @Id 13 | @GeneratedValue(strategy = GenerationType.IDENTITY) 14 | @Column(name = "reviewID") 15 | private int reviewID; 16 | 17 | @Column(name = "productID") 18 | private int productID; 19 | 20 | @Column(name = "content") 21 | private String content; 22 | 23 | @OneToMany 24 | @JoinColumn(name = "commentID") 25 | private List comment = new ArrayList<>(); 26 | 27 | public int getReviewID() { 28 | return reviewID; 29 | } 30 | 31 | public int getProductID() { 32 | return productID; 33 | } 34 | 35 | public void setProductID(int productID) { 36 | this.productID = productID; 37 | } 38 | 39 | public String getContent() { 40 | return content; 41 | } 42 | 43 | public void setContent(String content) { 44 | this.content = content; 45 | } 46 | 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/java/com/udacity/course3/reviews/repository/CommentRepository.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews.repository; 2 | 3 | import com.udacity.course3.reviews.entity.Comment; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | 8 | public interface CommentRepository extends JpaRepository { 9 | 10 | List findByReviewID(Integer reviewID); 11 | } 12 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/java/com/udacity/course3/reviews/repository/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews.repository; 2 | 3 | import com.udacity.course3.reviews.entity.Product; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | @Repository 10 | public interface ProductRepository extends JpaRepository { 11 | 12 | List findById(int id); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/java/com/udacity/course3/reviews/repository/ReviewRepository.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews.repository; 2 | 3 | import com.udacity.course3.reviews.entity.Review; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | 8 | public interface ReviewRepository extends JpaRepository { 9 | List findByProductID(Integer productID); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # FIXME: Follow instructions to setup MySQL and add the following properties 2 | spring.datasource.url=jdbc:mysql://localhost:3306/JDND_C3?serverTimezone=UTC 3 | spring.datasource.username=root 4 | spring.datasource.password=root 5 | 6 | spring.jpa.show-sql=true 7 | 8 | # DO NOT MODIFY 9 | # Don't let JPA/Hibernate create the schema 10 | spring.jpa.generate-ddl=false 11 | spring.jpa.hibernate.ddl-auto=none -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/resources/db/migration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/ReviewsAPI/src/main/resources/db/migration/.gitkeep -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/resources/db/migration/V01__CreateTable.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE products ( 2 | productID INT(11) NOT NULL AUTO_INCREMENT, 3 | name VARCHAR(100) NOT NULL, 4 | info VARCHAR(300) NOT NULL, 5 | PRIMARY KEY (productID) 6 | ); 7 | 8 | create table reviews( 9 | reviewID int(11) not null auto_increment, 10 | productID int(11) not null, 11 | content varchar(300) not null, 12 | primary key (reviewID), 13 | constraint review_fk foreign key (productID) references products (productID) 14 | ); 15 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/main/resources/db/migration/V02__CreateTable2.sql: -------------------------------------------------------------------------------- 1 | create table comments( 2 | commentID int(11) not null auto_increment, 3 | reviewID int(11) not null, 4 | content varchar(300) not null, 5 | primary key (commentID), 6 | constraint comment_fk foreign key (reviewID) references reviews (reviewID) 7 | ); -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/test/java/com/udacity/course3/reviews/CommentRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews; 2 | 3 | import com.udacity.course3.reviews.entity.Comment; 4 | import com.udacity.course3.reviews.entity.Product; 5 | import com.udacity.course3.reviews.entity.Review; 6 | import com.udacity.course3.reviews.repository.CommentRepository; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 11 | import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; 12 | import org.springframework.test.context.junit4.SpringRunner; 13 | 14 | import javax.persistence.EntityManager; 15 | import java.util.List; 16 | 17 | import static org.hamcrest.Matchers.is; 18 | import static org.hamcrest.core.IsNull.notNullValue; 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertThat; 21 | 22 | @RunWith(SpringRunner.class) 23 | @DataJpaTest 24 | public class CommentRepositoryTest { 25 | 26 | @Autowired 27 | private EntityManager entityManager; 28 | 29 | @Autowired 30 | private TestEntityManager testEntityManager; 31 | 32 | @Autowired 33 | private CommentRepository commentRepository; 34 | 35 | @Test 36 | public void testFindComment(){ 37 | 38 | //Create product 39 | Product product = new Product(); 40 | product.setName("testProduct1"); 41 | product.setInfo("info for product1"); 42 | entityManager.persist(product); 43 | 44 | //Create Review 45 | Review review = new Review(); 46 | review.setProductID(product.getProductID()); 47 | review.setContent("review for product1"); 48 | entityManager.persist(review); 49 | 50 | 51 | //Create Comment 52 | Comment comment = new Comment(); 53 | comment.setReviewID(review.getReviewID()); 54 | comment.setContent("comment for review"); 55 | entityManager.persist(comment); 56 | 57 | List realComment = commentRepository.findByReviewID(review.getReviewID()); 58 | assertThat(realComment, is(notNullValue())); 59 | assertEquals(review.getReviewID(), realComment.get(0).getReviewID()); 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/test/java/com/udacity/course3/reviews/ProductRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews; 2 | 3 | import com.udacity.course3.reviews.entity.Product; 4 | import com.udacity.course3.reviews.repository.ProductRepository; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 9 | import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; 10 | import org.springframework.jdbc.core.JdbcTemplate; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | 13 | import javax.persistence.EntityManager; 14 | import javax.sql.DataSource; 15 | 16 | import java.util.List; 17 | 18 | import static org.hamcrest.Matchers.*; 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertThat; 21 | 22 | 23 | @RunWith(SpringRunner.class) 24 | @DataJpaTest 25 | public class ProductRepositoryTest { 26 | 27 | @Autowired 28 | private DataSource dataSource; 29 | @Autowired private JdbcTemplate jdbcTemplate; 30 | @Autowired private EntityManager entityManager; 31 | @Autowired private TestEntityManager testEntityManager; 32 | @Autowired private ProductRepository productRepository; 33 | 34 | @Test 35 | public void injectedComponentsAreNotNull(){ 36 | assertThat(dataSource, is(notNullValue())); 37 | assertThat(jdbcTemplate, is(notNullValue())); 38 | assertThat(entityManager, is(notNullValue())); 39 | assertThat(testEntityManager, is(notNullValue())); 40 | assertThat(productRepository, is(notNullValue())); 41 | } 42 | 43 | @Test 44 | public void testFindProductById(){ 45 | 46 | Product product = new Product(); 47 | product.setName("testProduct1"); 48 | product.setInfo("info for product1"); 49 | 50 | entityManager.persist(product); 51 | 52 | List realProduct = productRepository.findById(product.getProductID()); 53 | assertThat(realProduct, is(notNullValue())); 54 | assertEquals(product.getProductID(), realProduct.get(0).getProductID()); 55 | } 56 | 57 | } 58 | 59 | 60 | -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/test/java/com/udacity/course3/reviews/ReviewsApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | @RunWith(SpringRunner.class) 10 | @DataJpaTest 11 | public class ReviewsApplicationTests { 12 | 13 | @Test 14 | public void contextLoads() { 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /projects/ReviewsAPI/src/test/java/com/udacity/course3/reviews/ReviewsRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.udacity.course3.reviews; 2 | 3 | import com.udacity.course3.reviews.entity.Product; 4 | import com.udacity.course3.reviews.entity.Review; 5 | import com.udacity.course3.reviews.repository.ReviewRepository; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import javax.persistence.EntityManager; 13 | import java.util.List; 14 | 15 | import static org.hamcrest.Matchers.is; 16 | import static org.hamcrest.Matchers.notNullValue; 17 | import static org.junit.Assert.assertEquals; 18 | import static org.junit.Assert.assertThat; 19 | 20 | @RunWith(SpringRunner.class) 21 | @DataJpaTest 22 | public class ReviewsRepositoryTest { 23 | 24 | 25 | @Autowired private EntityManager entityManager; 26 | @Autowired private ReviewRepository reviewRepository; 27 | 28 | 29 | @Test 30 | public void testFindReviewByProductId(){ 31 | 32 | //Create product 33 | Product product = new Product(); 34 | 35 | product.setName("testProduct1"); 36 | product.setInfo("info for product1"); 37 | 38 | entityManager.persist(product); 39 | 40 | //Create Review 41 | Review review = new Review(); 42 | review.setProductID(product.getProductID()); 43 | review.setContent("review for product1"); 44 | 45 | entityManager.persist(review); 46 | 47 | List realReview = reviewRepository.findByProductID(product.getProductID()); 48 | assertThat(realReview, is(notNullValue())); 49 | assertEquals(product.getProductID(), realReview.get(0).getProductID()); 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /projects/chatroom/.idea/.name: -------------------------------------------------------------------------------- 1 | chatroom-starter -------------------------------------------------------------------------------- /projects/chatroom/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /projects/chatroom/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /projects/chatroom/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /projects/chatroom/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /projects/chatroom/README.md: -------------------------------------------------------------------------------- 1 | # Project 1 2 | 3 | # Chat Room 4 | The Simple ChatRoom Application implementation using WebSocket. 5 | 6 | ## Background 7 | WebSocket is a communication protocol that makes it possible to establish a two-way communication channel between a 8 | server and a client. 9 | 10 | ## Screen-Shots 11 | Result: 12 | 13 | 14 | Test Results: 15 | 1) Login and Join Test 16 | 2) Send Chat and leave Chat Test 17 | 18 | -------------------------------------------------------------------------------- /projects/chatroom/src/main/java/edu/udacity/java/nano/WebSocketChatApplication.java: -------------------------------------------------------------------------------- 1 | package edu.udacity.java.nano; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | import org.springframework.web.servlet.ModelAndView; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | import java.net.UnknownHostException; 11 | 12 | @SpringBootApplication 13 | @RestController 14 | public class WebSocketChatApplication { 15 | 16 | public static void main(String[] args) { 17 | SpringApplication.run(WebSocketChatApplication.class, args); 18 | } 19 | 20 | /** 21 | * Login Page 22 | */ 23 | @GetMapping("/") 24 | public ModelAndView login() { 25 | return new ModelAndView("login"); 26 | } 27 | 28 | /** 29 | * Chatroom Page 30 | */ 31 | @GetMapping("/index") 32 | public ModelAndView index(String username, HttpServletRequest request) throws UnknownHostException { 33 | 34 | ModelAndView mv = new ModelAndView(); 35 | mv.addObject("username", username); 36 | mv.setViewName("chat"); 37 | 38 | return mv; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /projects/chatroom/src/main/java/edu/udacity/java/nano/chat/Message.java: -------------------------------------------------------------------------------- 1 | package edu.udacity.java.nano.chat; 2 | 3 | /** 4 | * WebSocket message model 5 | */ 6 | public class Message { 7 | 8 | private String name; 9 | 10 | //message status 11 | public enum Type{ 12 | ENTER, SPEAK, LEAVE 13 | } 14 | public Message(){} 15 | public Message(String text){ 16 | this.name = text; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public void setName (String name) { 24 | this.name = name; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /projects/chatroom/src/main/java/edu/udacity/java/nano/chat/WebSocketChatServer.java: -------------------------------------------------------------------------------- 1 | package edu.udacity.java.nano.chat; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONObject; 5 | import org.springframework.stereotype.Component; 6 | 7 | import javax.websocket.*; 8 | import javax.websocket.server.ServerEndpoint; 9 | import java.util.Map; 10 | import java.util.concurrent.ConcurrentHashMap; 11 | 12 | /** 13 | * WebSocket Server 14 | * 15 | * @see ServerEndpoint WebSocket Client 16 | * @see Session WebSocket Session 17 | */ 18 | 19 | @Component 20 | @ServerEndpoint("/chat/{username}") 21 | public class WebSocketChatServer { 22 | 23 | /** 24 | * All chat sessions. 25 | */ 26 | private static Map onlineSessions = new ConcurrentHashMap<>(); 27 | 28 | private static void sendMessageToAll(String msg){ 29 | 30 | onlineSessions.forEach((username, session)-> { 31 | try{ 32 | onlineSessions.get(username).getBasicRemote().sendText(msg); 33 | } 34 | catch(Exception e){ 35 | e.printStackTrace(); 36 | } 37 | 38 | }); 39 | } 40 | 41 | /** 42 | * Open connection, 1) add session, 2) add user. 43 | */ 44 | @OnOpen 45 | public void onOpen(Session session) { 46 | 47 | Message message = new Message(); 48 | message.setName(session.getPathParameters().get("username")); 49 | onlineSessions.put(message.getName(), session); 50 | } 51 | 52 | /** 53 | * Send message, 1) get username and session, 2) send message to all. 54 | */ 55 | @OnMessage 56 | public void onMessage(Session session, String jsonStr) { 57 | JSONObject jsonObject = JSON.parseObject(jsonStr); 58 | jsonObject.put("type", Message.Type.SPEAK); 59 | jsonObject.put("onlineCount", onlineSessions.size()); 60 | jsonStr = jsonObject.toJSONString(); 61 | 62 | sendMessageToAll(jsonStr); 63 | } 64 | 65 | /** 66 | * Close connection, 1) remove session, 2) update user. 67 | */ 68 | @OnClose 69 | public void onClose(Session session) throws Exception { 70 | 71 | onlineSessions.remove(session.getPathParameters().get("username")); 72 | 73 | } 74 | 75 | /** 76 | * Print exception. 77 | */ 78 | @OnError 79 | public void onError(Session session, Throwable error) { 80 | error.printStackTrace(); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /projects/chatroom/src/main/java/edu/udacity/java/nano/chat/WebSocketConfig.java: -------------------------------------------------------------------------------- 1 | package edu.udacity.java.nano.chat; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.socket.server.standard.ServerEndpointExporter; 6 | 7 | @Configuration 8 | public class WebSocketConfig { 9 | 10 | @Bean 11 | public ServerEndpointExporter serverEndpointExporter() { 12 | return new ServerEndpointExporter(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /projects/chatroom/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | thymeleaf: 3 | cache: false 4 | 5 | debug: 6 | true 7 | 8 | logging: 9 | level: 10 | root: 11 | DEBUG 12 | -------------------------------------------------------------------------------- /projects/chatroom/src/main/resources/static/img/login-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/chatroom/src/main/resources/static/img/login-bg.jpg -------------------------------------------------------------------------------- /projects/chatroom/target/chatroom-starter-0.0.1-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/chatroom/target/chatroom-starter-0.0.1-SNAPSHOT.jar -------------------------------------------------------------------------------- /projects/chatroom/target/chatroom-starter-0.0.1-SNAPSHOT.jar.original: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/chatroom/target/chatroom-starter-0.0.1-SNAPSHOT.jar.original -------------------------------------------------------------------------------- /projects/chatroom/target/classes/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | thymeleaf: 3 | cache: false 4 | 5 | debug: 6 | true 7 | 8 | logging: 9 | level: 10 | root: 11 | DEBUG 12 | -------------------------------------------------------------------------------- /projects/chatroom/target/classes/edu/udacity/java/nano/WebSocketChatApplication.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/chatroom/target/classes/edu/udacity/java/nano/WebSocketChatApplication.class -------------------------------------------------------------------------------- /projects/chatroom/target/classes/edu/udacity/java/nano/chat/Message$Type.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/chatroom/target/classes/edu/udacity/java/nano/chat/Message$Type.class -------------------------------------------------------------------------------- /projects/chatroom/target/classes/edu/udacity/java/nano/chat/Message.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/chatroom/target/classes/edu/udacity/java/nano/chat/Message.class -------------------------------------------------------------------------------- /projects/chatroom/target/classes/edu/udacity/java/nano/chat/WebSocketChatServer.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/chatroom/target/classes/edu/udacity/java/nano/chat/WebSocketChatServer.class -------------------------------------------------------------------------------- /projects/chatroom/target/classes/edu/udacity/java/nano/chat/WebSocketConfig.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/chatroom/target/classes/edu/udacity/java/nano/chat/WebSocketConfig.class -------------------------------------------------------------------------------- /projects/chatroom/target/classes/static/img/login-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/chatroom/target/classes/static/img/login-bg.jpg -------------------------------------------------------------------------------- /projects/chatroom/target/maven-archiver/pom.properties: -------------------------------------------------------------------------------- 1 | #Created by Apache Maven 3.6.1 2 | version=0.0.1-SNAPSHOT 3 | groupId=edu.udacity.java.nano 4 | artifactId=chatroom-starter 5 | -------------------------------------------------------------------------------- /projects/chatroom/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst: -------------------------------------------------------------------------------- 1 | edu/udacity/java/nano/chat/WebSocketConfig.class 2 | edu/udacity/java/nano/chat/Message.class 3 | edu/udacity/java/nano/WebSocketChatApplication.class 4 | edu/udacity/java/nano/chat/WebSocketChatServer.class 5 | edu/udacity/java/nano/chat/Message$Type.class 6 | -------------------------------------------------------------------------------- /projects/chatroom/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst: -------------------------------------------------------------------------------- 1 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree-Projects/chatroom/src/main/java/edu/udacity/java/nano/WebSocketChatApplication.java 2 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree-Projects/chatroom/src/main/java/edu/udacity/java/nano/chat/Message.java 3 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree-Projects/chatroom/src/main/java/edu/udacity/java/nano/chat/WebSocketConfig.java 4 | /Users/yoon/Desktop/JavaDeveloper-NanoDegree-Projects/chatroom/src/main/java/edu/udacity/java/nano/chat/WebSocketChatServer.java 5 | -------------------------------------------------------------------------------- /projects/chatroom/target/test-classes/edu/udacity/java/nano/chat/WebSocketChatServerTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/chatroom/target/test-classes/edu/udacity/java/nano/chat/WebSocketChatServerTest.class -------------------------------------------------------------------------------- /projects/vehiclesAPI/.gitignore: -------------------------------------------------------------------------------- 1 | apache-activemq-5.15.9/ 2 | apache-activemq-5.15.9-bin.tar.gz 3 | .DS_Store 4 | 5 | ### IntelliJ IDEA ### 6 | .idea/ 7 | *.iws 8 | *.iml 9 | *.ipr 10 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Udacity 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/README.md: -------------------------------------------------------------------------------- 1 | # VehiclesAPI-Project 2 | 3 | Implemened a Vehicles API using Java and Spring Boot that can communicate with separate location and pricing services. 4 | 5 | ## Components 6 | 7 | - [Vehicles API](vehicles-api/README.md) 8 | - [Pricing Service](pricing-service/README.md) 9 | - [Boogle Maps](boogle-maps/README.md) 10 | 11 | ## Dependencies 12 | The project requires the use of Maven and Spring Boot, along with Java v11. 13 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/boogle-maps/.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 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/boogle-maps/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/vehiclesAPI/boogle-maps/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /projects/vehiclesAPI/boogle-maps/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/boogle-maps/README.md: -------------------------------------------------------------------------------- 1 | # Boogle Maps 2 | 3 | This is a Mock that simulates a Maps WebService where, given a latitude 4 | longitude, will return a random address. 5 | 6 | ## Instructions 7 | 8 | Via shell it can be started using 9 | 10 | ``` 11 | $ mvn clean package 12 | ``` 13 | 14 | ``` 15 | $ java -jar target/boogle-maps-0.0.1-SNAPSHOT.jar 16 | ``` 17 | 18 | The service is available by default on port `9191`. You can check it on the 19 | command line by using 20 | 21 | ``` 22 | $ curl http://localhost:9191/maps\?lat\=20.0\&lon\=30.0 23 | ``` 24 | 25 | You can also import it as a Maven project on your preferred IDE and 26 | run the class `BoogleMapsApplication`. -------------------------------------------------------------------------------- /projects/vehiclesAPI/boogle-maps/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | com.udacity 12 | boogle-maps 13 | 0.0.1-SNAPSHOT 14 | boogle-maps 15 | A Maps mock 16 | 17 | 18 | 11 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-devtools 30 | runtime 31 | true 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-test 36 | test 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-maven-plugin 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/boogle-maps/src/main/java/com/udacity/boogle/maps/Address.java: -------------------------------------------------------------------------------- 1 | package com.udacity.boogle.maps; 2 | 3 | /** 4 | * Declares a class to store an address, city, state and zip code. 5 | */ 6 | public class Address { 7 | 8 | private String address; 9 | private String city; 10 | private String state; 11 | private String zip; 12 | 13 | public Address() { 14 | } 15 | 16 | public Address(String address, String city, String state, String zip) { 17 | this.address = address; 18 | this.city = city; 19 | this.state = state; 20 | this.zip = zip; 21 | } 22 | 23 | public String getAddress() { 24 | return address; 25 | } 26 | 27 | public void setAddress(String address) { 28 | this.address = address; 29 | } 30 | 31 | public String getCity() { 32 | return city; 33 | } 34 | 35 | public void setCity(String city) { 36 | this.city = city; 37 | } 38 | 39 | public String getState() { 40 | return state; 41 | } 42 | 43 | public void setState(String state) { 44 | this.state = state; 45 | } 46 | 47 | public String getZip() { 48 | return zip; 49 | } 50 | 51 | public void setZip(String zip) { 52 | this.zip = zip; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/boogle-maps/src/main/java/com/udacity/boogle/maps/BoogleMapsApplication.java: -------------------------------------------------------------------------------- 1 | package com.udacity.boogle.maps; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class BoogleMapsApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(BoogleMapsApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/boogle-maps/src/main/java/com/udacity/boogle/maps/MapsController.java: -------------------------------------------------------------------------------- 1 | package com.udacity.boogle.maps; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestParam; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | @RestController 9 | @RequestMapping("/maps") 10 | public class MapsController { 11 | 12 | @GetMapping 13 | public Address get(@RequestParam Double lat, @RequestParam Double lon) { 14 | return MockAddressRepository.getRandom(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/boogle-maps/src/main/resources/adresses.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/vehiclesAPI/boogle-maps/src/main/resources/adresses.json -------------------------------------------------------------------------------- /projects/vehiclesAPI/boogle-maps/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=9191 2 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/boogle-maps/src/test/java/com/udacity/boogle/maps/BoogleMapsApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.udacity.boogle.maps; 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 BoogleMapsApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-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 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/vehiclesAPI/pricing-service/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/README.md: -------------------------------------------------------------------------------- 1 | # Pricing Service 2 | 3 | The Pricing Service is a REST WebService that simulates a backend that 4 | would store and retrieve the price of a vehicle given a vehicle id as 5 | input. In this project, you will convert it to a microservice. 6 | 7 | 8 | ## Features 9 | 10 | - REST WebService integrated with Spring Boot 11 | 12 | ## Instructions 13 | 14 | #### TODOs 15 | 16 | - Convert the Pricing Service to be a microservice. 17 | - Add an additional test to check whether the application appropriately generates a price for a given vehicle ID 18 | 19 | #### Run the code 20 | 21 | To run this service you execute: 22 | 23 | ``` 24 | $ mvn clean package 25 | ``` 26 | 27 | ``` 28 | $ java -jar target/pricing-service-0.0.1-SNAPSHOT.jar 29 | ``` 30 | 31 | It can also be imported in your IDE as a Maven project. 32 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | com.udacity 12 | pricing-service 13 | 0.0.1-SNAPSHOT 14 | pricing-service 15 | Pricing Service 16 | 17 | 18 | 11 19 | 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-devtools 36 | runtime 37 | true 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-test 43 | test 44 | 45 | 46 | 47 | org.springframework.cloud 48 | spring-cloud-starter-config 49 | 50 | 51 | org.springframework.cloud 52 | spring-cloud-starter-netflix-eureka-client 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.cloud 60 | spring-cloud-starter-parent 61 | Greenwich.RELEASE 62 | pom 63 | import 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | org.springframework.boot 72 | spring-boot-maven-plugin 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/src/main/java/com/udacity/pricing/PricingServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.udacity.pricing; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 6 | 7 | /** 8 | * Creates a Spring Boot Application to run the Pricing Service. 9 | */ 10 | @SpringBootApplication 11 | @EnableEurekaClient 12 | public class PricingServiceApplication { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(PricingServiceApplication.class, args); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/src/main/java/com/udacity/pricing/api/PricingController.java: -------------------------------------------------------------------------------- 1 | package com.udacity.pricing.api; 2 | 3 | import com.udacity.pricing.domain.price.Price; 4 | import com.udacity.pricing.service.PriceException; 5 | import com.udacity.pricing.service.PricingService; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestParam; 10 | import org.springframework.web.bind.annotation.RestController; 11 | import org.springframework.web.server.ResponseStatusException; 12 | 13 | /** 14 | * Implements a REST-based controller for the pricing service. 15 | */ 16 | @RestController 17 | @RequestMapping("/services/price") 18 | public class PricingController { 19 | 20 | /** 21 | * Gets the price for a requested vehicle. 22 | * @param vehicleId ID number of the vehicle for which the price is requested 23 | * @return price of the vehicle, or error that it was not found. 24 | */ 25 | @GetMapping 26 | public Price get(@RequestParam Long vehicleId) { 27 | try { 28 | return PricingService.getPrice(vehicleId); 29 | } catch (PriceException ex) { 30 | throw new ResponseStatusException( 31 | HttpStatus.NOT_FOUND, "Price Not Found", ex); 32 | } 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/src/main/java/com/udacity/pricing/domain/price/Price.java: -------------------------------------------------------------------------------- 1 | package com.udacity.pricing.domain.price; 2 | 3 | import java.math.BigDecimal; 4 | 5 | /** 6 | * Represents the price of a given vehicle, including currency. 7 | */ 8 | public class Price { 9 | 10 | private String currency; 11 | private BigDecimal price; 12 | private Long vehicleId; 13 | 14 | public Price() { 15 | } 16 | 17 | public Price(String currency, BigDecimal price, Long vehicleId) { 18 | this.currency = currency; 19 | this.price = price; 20 | this.vehicleId = vehicleId; 21 | } 22 | 23 | public String getCurrency() { 24 | return currency; 25 | } 26 | 27 | public void setCurrency(String currency) { 28 | this.currency = currency; 29 | } 30 | 31 | public BigDecimal getPrice() { 32 | return price; 33 | } 34 | 35 | public void setPrice(BigDecimal price) { 36 | this.price = price; 37 | } 38 | 39 | public Long getVehicleId() { 40 | return vehicleId; 41 | } 42 | 43 | public void setVehicleId(Long vehicleId) { 44 | this.vehicleId = vehicleId; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/src/main/java/com/udacity/pricing/domain/price/PriceRepository.java: -------------------------------------------------------------------------------- 1 | package com.udacity.pricing.domain.price; 2 | 3 | import org.springframework.stereotype.Repository; 4 | 5 | @Repository 6 | public class PriceRepository { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/src/main/java/com/udacity/pricing/service/PriceException.java: -------------------------------------------------------------------------------- 1 | package com.udacity.pricing.service; 2 | 3 | public class PriceException extends Exception { 4 | 5 | public PriceException(String message) { 6 | super(message); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/src/main/java/com/udacity/pricing/service/PricingService.java: -------------------------------------------------------------------------------- 1 | package com.udacity.pricing.service; 2 | 3 | import com.udacity.pricing.domain.price.Price; 4 | 5 | import java.math.BigDecimal; 6 | import java.math.RoundingMode; 7 | import java.util.Map; 8 | import java.util.concurrent.ThreadLocalRandom; 9 | import java.util.stream.Collectors; 10 | import java.util.stream.LongStream; 11 | 12 | /** 13 | * Implements the pricing service to get prices for each vehicle. 14 | */ 15 | public class PricingService { 16 | 17 | /** 18 | * Holds {ID: Price} pairings (current implementation allows for 20 vehicles) 19 | */ 20 | private static final Map PRICES = LongStream 21 | .range(1, 20) 22 | .mapToObj(i -> new Price("USD", randomPrice(), i)) 23 | .collect(Collectors.toMap(Price::getVehicleId, p -> p)); 24 | 25 | /** 26 | * If a valid vehicle ID, gets the price of the vehicle from the stored array. 27 | * @param vehicleId ID number of the vehicle the price is requested for. 28 | * @return price of the requested vehicle 29 | * @throws PriceException vehicleID was not found 30 | */ 31 | public static Price getPrice(Long vehicleId) throws PriceException { 32 | 33 | if (!PRICES.containsKey(vehicleId)) { 34 | throw new PriceException("Cannot find price for Vehicle " + vehicleId); 35 | } 36 | 37 | return PRICES.get(vehicleId); 38 | } 39 | 40 | /** 41 | * Gets a random price to fill in for a given vehicle ID. 42 | * @return random price for a vehicle 43 | */ 44 | private static BigDecimal randomPrice() { 45 | return new BigDecimal(ThreadLocalRandom.current().nextDouble(1, 5)) 46 | .multiply(new BigDecimal(5000d)).setScale(2, RoundingMode.HALF_UP); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=pricing-service 2 | server.port=8082 3 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 4 | eureka.client.service-url.default-zone=http://localhost:8761/eureka/ 5 | eureka.instance.prefer-ip-address=true -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/src/main/resources/prices.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/vehiclesAPI/pricing-service/src/main/resources/prices.json -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/src/test/java/com/udacity/pricing/PricingServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.udacity.pricing; 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 PricingServiceApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/src/test/java/com/udacity/pricing/web/PricingControllerIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.udacity.pricing.web; 2 | 3 | import com.udacity.pricing.domain.price.Price; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.boot.test.web.client.TestRestTemplate; 10 | import org.springframework.boot.web.server.LocalServerPort; 11 | import org.springframework.http.HttpStatus; 12 | import org.springframework.http.ResponseEntity; 13 | import org.springframework.test.context.junit4.SpringRunner; 14 | 15 | import java.util.List; 16 | 17 | import static org.hamcrest.CoreMatchers.equalTo; 18 | import static org.hamcrest.MatcherAssert.assertThat; 19 | 20 | @RunWith(SpringRunner.class) 21 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 22 | @AutoConfigureMockMvc 23 | public class PricingControllerIntegrationTest { 24 | 25 | @LocalServerPort 26 | private int port; 27 | 28 | @Autowired 29 | private TestRestTemplate restTemplate; 30 | 31 | @Test 32 | public void getPrice(){ 33 | ResponseEntity response = this.restTemplate.getForEntity("http://localhost:" + port + "/services/price?vehicleId=1", Price.class); 34 | 35 | System.out.println("Get Price for id = 1: "+ response.getBody().getPrice() + ", currency: "+response.getBody().getCurrency()); 36 | assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); 37 | 38 | 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/pricing-service/src/test/java/com/udacity/pricing/web/PricingControllerUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.udacity.pricing.web; 2 | 3 | import com.udacity.pricing.api.PricingController; 4 | import com.udacity.pricing.service.PricingService; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 10 | import org.springframework.boot.test.mock.mockito.MockBean; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | import org.springframework.test.web.servlet.MockMvc; 13 | 14 | 15 | import static org.mockito.ArgumentMatchers.any; 16 | import static org.mockito.internal.verification.VerificationModeFactory.times; 17 | import static org.mockito.Mockito.verify; 18 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 19 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 20 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 21 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 22 | 23 | 24 | 25 | @RunWith(SpringRunner.class) 26 | @WebMvcTest(PricingController.class) 27 | public class PricingControllerUnitTest { 28 | 29 | @Autowired 30 | private MockMvc mockMvc; 31 | 32 | @MockBean 33 | PricingService pricingService; 34 | 35 | @Test 36 | public void priceGet() throws Exception{ 37 | 38 | mockMvc.perform(get("/services/price").param("vehicleId", String.valueOf(1))) 39 | .andExpect(status().isOk()) 40 | .andDo(print()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/.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 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarahyoon/JavaDeveloper-NanoDegree/d3458cf482c725b9e4024c26ac859b47467d361c/projects/vehiclesAPI/vehicles-api/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/README.md: -------------------------------------------------------------------------------- 1 | # Vehicles API 2 | 3 | A REST API to maintain vehicle data and to provide a complete 4 | view of vehicle details including price and address. 5 | 6 | ## Features 7 | 8 | - REST API exploring the main HTTP verbs and features 9 | - Hateoas 10 | - Custom API Error handling using `ControllerAdvice` 11 | - Swagger API docs 12 | - HTTP WebClient 13 | - MVC Test 14 | - Automatic model mapping 15 | 16 | ## Instructions 17 | 18 | #### TODOs 19 | 20 | - Implement the `TODOs` within the `CarService.java` and `CarController.java` files 21 | - Add additional tests to the `CarControllerTest.java` file based on the `TODOs` 22 | - Implement API documentation using Swagger 23 | 24 | #### Run the Code 25 | 26 | To properly run this application you need to start the Orders API and 27 | the Service API first. 28 | 29 | 30 | ``` 31 | $ mvn clean package 32 | ``` 33 | 34 | ``` 35 | $ java -jar target/vehicles-api-0.0.1-SNAPSHOT.jar 36 | ``` 37 | 38 | Import it in your favorite IDE as a Maven Project. 39 | 40 | ## Operations 41 | 42 | Swagger UI: http://localhost:8080/swagger-ui.html 43 | 44 | ### Create a Vehicle 45 | 46 | `POST` `/cars` 47 | ```json 48 | { 49 | "condition":"USED", 50 | "details":{ 51 | "body":"sedan", 52 | "model":"Impala", 53 | "manufacturer":{ 54 | "code":101, 55 | "name":"Chevrolet" 56 | }, 57 | "numberOfDoors":4, 58 | "fuelType":"Gasoline", 59 | "engine":"3.6L V6", 60 | "mileage":32280, 61 | "modelYear":2018, 62 | "productionYear":2018, 63 | "externalColor":"white" 64 | }, 65 | "location":{ 66 | "lat":40.73061, 67 | "lon":-73.935242 68 | } 69 | } 70 | ``` 71 | 72 | ### Retrieve a Vehicle 73 | 74 | `GET` `/cars/{id}` 75 | 76 | This feature retrieves the Vehicle data from the database 77 | and access the Pricing Service and Boogle Maps to enrich 78 | the Vehicle information to be presented 79 | 80 | ### Update a Vehicle 81 | 82 | `PUT` `/cars/{id}` 83 | 84 | ```json 85 | { 86 | "condition":"USED", 87 | "details":{ 88 | "body":"sedan", 89 | "model":"Impala", 90 | "manufacturer":{ 91 | "code":101, 92 | "name":"Chevrolet" 93 | }, 94 | "numberOfDoors":4, 95 | "fuelType":"Gasoline", 96 | "engine":"3.6L V6", 97 | "mileage":32280, 98 | "modelYear":2018, 99 | "productionYear":2018, 100 | "externalColor":"white" 101 | }, 102 | "location":{ 103 | "lat":40.73061, 104 | "lon":-73.935242 105 | } 106 | } 107 | ``` 108 | 109 | ### Delete a Vehicle 110 | 111 | `DELETE` `/cars/{id}` 112 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/VehiclesApiApplication.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles; 2 | 3 | import com.udacity.vehicles.domain.manufacturer.Manufacturer; 4 | import com.udacity.vehicles.domain.manufacturer.ManufacturerRepository; 5 | import org.modelmapper.ModelMapper; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.boot.CommandLineRunner; 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 12 | import org.springframework.web.reactive.function.client.WebClient; 13 | 14 | /** 15 | * Launches a Spring Boot application for the Vehicles API, 16 | * initializes the car manufacturers in the database, 17 | * and launches web clients to communicate with maps and pricing. 18 | */ 19 | @SpringBootApplication 20 | @EnableJpaAuditing 21 | public class VehiclesApiApplication { 22 | 23 | public static void main(String[] args) { 24 | SpringApplication.run(VehiclesApiApplication.class, args); 25 | } 26 | 27 | /** 28 | * Initializes the car manufacturers available to the Vehicle API. 29 | * @param repository where the manufacturer information persists. 30 | * @return the car manufacturers to add to the related repository 31 | */ 32 | @Bean 33 | CommandLineRunner initDatabase(ManufacturerRepository repository) { 34 | return args -> { 35 | repository.save(new Manufacturer(100, "Audi")); 36 | repository.save(new Manufacturer(101, "Chevrolet")); 37 | repository.save(new Manufacturer(102, "Ford")); 38 | repository.save(new Manufacturer(103, "BMW")); 39 | repository.save(new Manufacturer(104, "Dodge")); 40 | }; 41 | } 42 | 43 | @Bean 44 | public ModelMapper modelMapper() { 45 | return new ModelMapper(); 46 | } 47 | 48 | /** 49 | * Web Client for the maps (location) API 50 | * @param endpoint where to communicate for the maps API 51 | * @return created maps endpoint 52 | */ 53 | @Bean(name="maps") 54 | public WebClient webClientMaps(@Value("${maps.endpoint}") String endpoint) { 55 | return WebClient.create(endpoint); 56 | } 57 | 58 | /** 59 | * Web Client for the pricing API 60 | * @param endpoint where to communicate for the pricing API 61 | * @return created pricing endpoint 62 | */ 63 | @Bean(name="pricing") 64 | public WebClient webClientPricing(@Value("${pricing.endpoint}") String endpoint) { 65 | return WebClient.create(endpoint); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/api/ApiError.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.api; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import java.util.List; 5 | 6 | /** 7 | * Declares methods to return errors and other messages from the API. 8 | */ 9 | @JsonInclude(JsonInclude.Include.NON_NULL) 10 | class ApiError { 11 | 12 | private final String message; 13 | private final List errors; 14 | 15 | ApiError(String message, List errors) { 16 | this.message = message; 17 | this.errors = errors; 18 | } 19 | 20 | public String getMessage() { 21 | return message; 22 | } 23 | 24 | public List getErrors() { 25 | return errors; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/api/CarResourceAssembler.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.api; 2 | 3 | import com.udacity.vehicles.domain.car.Car; 4 | import org.springframework.hateoas.Resource; 5 | import org.springframework.hateoas.ResourceAssembler; 6 | import org.springframework.stereotype.Component; 7 | 8 | import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*; 9 | 10 | /** 11 | * Maps the CarController to the Car class using HATEOAS 12 | */ 13 | @Component 14 | public class CarResourceAssembler implements ResourceAssembler> { 15 | 16 | @Override 17 | public Resource toResource(Car car) { 18 | return new Resource<>(car, 19 | linkTo(methodOn(CarController.class).get(car.getId())).withSelfRel(), 20 | linkTo(methodOn(CarController.class).list()).withRel("cars")); 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/api/ErrorController.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.api; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | import org.springframework.hateoas.VndErrors; 6 | import org.springframework.http.HttpHeaders; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.MethodArgumentNotValidException; 10 | import org.springframework.web.bind.annotation.ControllerAdvice; 11 | import org.springframework.web.context.request.WebRequest; 12 | import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; 13 | 14 | /** 15 | * Implements the Error controller related to any errors handled by the Vehicles API 16 | */ 17 | @ControllerAdvice 18 | public class ErrorController extends ResponseEntityExceptionHandler { 19 | 20 | private static final String DEFAULT_VALIDATION_FAILED_MESSAGE = "Validation failed"; 21 | 22 | @Override 23 | protected ResponseEntity handleMethodArgumentNotValid( 24 | MethodArgumentNotValidException ex, 25 | HttpHeaders headers, HttpStatus status, 26 | WebRequest request) { 27 | List errors = ex.getBindingResult() 28 | .getFieldErrors() 29 | .stream() 30 | .map(error -> error.getField() + ": " + error.getDefaultMessage()).collect( 31 | Collectors.toList()); 32 | 33 | ApiError apiError = new ApiError(DEFAULT_VALIDATION_FAILED_MESSAGE, errors); 34 | return handleExceptionInternal(ex, apiError, headers, HttpStatus.BAD_REQUEST, request); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/client/maps/Address.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.client.maps; 2 | 3 | /** 4 | * Declares a class to store an address, city, state and zip code. 5 | */ 6 | public class Address { 7 | 8 | private String address; 9 | private String city; 10 | private String state; 11 | private String zip; 12 | 13 | public Address() { 14 | } 15 | 16 | public String getAddress() { 17 | return address; 18 | } 19 | 20 | public void setAddress(String address) { 21 | this.address = address; 22 | } 23 | 24 | public String getCity() { 25 | return city; 26 | } 27 | 28 | public void setCity(String city) { 29 | this.city = city; 30 | } 31 | 32 | public String getState() { 33 | return state; 34 | } 35 | 36 | public void setState(String state) { 37 | this.state = state; 38 | } 39 | 40 | public String getZip() { 41 | return zip; 42 | } 43 | 44 | public void setZip(String zip) { 45 | this.zip = zip; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/client/maps/MapsClient.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.client.maps; 2 | 3 | import com.udacity.vehicles.domain.Location; 4 | import java.util.Objects; 5 | import org.modelmapper.ModelMapper; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.reactive.function.client.WebClient; 10 | 11 | /** 12 | * Implements a class to interface with the Maps Client for location data. 13 | */ 14 | @Component 15 | public class MapsClient { 16 | 17 | private static final Logger log = LoggerFactory.getLogger(MapsClient.class); 18 | 19 | private final WebClient client; 20 | private final ModelMapper mapper; 21 | 22 | public MapsClient(WebClient maps, 23 | ModelMapper mapper) { 24 | this.client = maps; 25 | this.mapper = mapper; 26 | } 27 | 28 | /** 29 | * Gets an address from the Maps client, given latitude and longitude. 30 | * @param location An object containing "lat" and "lon" of location 31 | * @return An updated location including street, city, state and zip, 32 | * or an exception message noting the Maps service is down 33 | */ 34 | public Location getAddress(Location location) { 35 | try { 36 | Address address = client 37 | .get() 38 | .uri(uriBuilder -> uriBuilder 39 | .path("/maps/") 40 | .queryParam("lat", location.getLat()) 41 | .queryParam("lon", location.getLon()) 42 | .build() 43 | ) 44 | .retrieve().bodyToMono(Address.class).block(); 45 | 46 | mapper.map(Objects.requireNonNull(address), location); 47 | 48 | return location; 49 | } catch (Exception e) { 50 | log.warn("Map service is down"); 51 | return location; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/client/prices/Price.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.client.prices; 2 | 3 | import java.math.BigDecimal; 4 | 5 | /** 6 | * Represents the price of a given vehicle, including currency. 7 | */ 8 | public class Price { 9 | 10 | private String currency; 11 | private BigDecimal price; 12 | private Long vehicleId; 13 | 14 | public Price() { 15 | } 16 | 17 | public String getCurrency() { 18 | return currency; 19 | } 20 | 21 | public void setCurrency(String currency) { 22 | this.currency = currency; 23 | } 24 | 25 | public BigDecimal getPrice() { 26 | return price; 27 | } 28 | 29 | public void setPrice(BigDecimal price) { 30 | this.price = price; 31 | } 32 | 33 | public Long getVehicleId() { 34 | return vehicleId; 35 | } 36 | 37 | public void setVehicleId(Long vehicleId) { 38 | this.vehicleId = vehicleId; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/client/prices/PriceClient.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.client.prices; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.reactive.function.client.WebClient; 7 | 8 | /** 9 | * Implements a class to interface with the Pricing Client for price data. 10 | */ 11 | @Component 12 | public class PriceClient { 13 | 14 | private static final Logger log = LoggerFactory.getLogger(PriceClient.class); 15 | 16 | private final WebClient client; 17 | 18 | public PriceClient(WebClient pricing) { 19 | this.client = pricing; 20 | } 21 | 22 | // In a real-world application we'll want to add some resilience 23 | // to this method with retries/CB/failover capabilities 24 | // We may also want to cache the results so we don't need to 25 | // do a request every time 26 | /** 27 | * Gets a vehicle price from the pricing client, given vehicle ID. 28 | * @param vehicleId ID number of the vehicle for which to get the price 29 | * @return Currency and price of the requested vehicle, 30 | * error message that the vehicle ID is invalid, or note that the 31 | * service is down. 32 | */ 33 | public String getPrice(Long vehicleId) { 34 | try { 35 | Price price = client 36 | .get() 37 | .uri(uriBuilder -> uriBuilder 38 | .path("services/price/") 39 | .queryParam("vehicleId", vehicleId) 40 | .build() 41 | ) 42 | .retrieve().bodyToMono(Price.class).block(); 43 | 44 | return String.format("%s %s", price.getCurrency(), price.getPrice()); 45 | 46 | } catch (Exception e) { 47 | log.error("Unexpected error retrieving price for vehicle {}", vehicleId, e); 48 | } 49 | return "(consult price)"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import springfox.documentation.builders.PathSelectors; 6 | import springfox.documentation.builders.RequestHandlerSelectors; 7 | import springfox.documentation.service.ApiInfo; 8 | import springfox.documentation.service.Contact; 9 | import springfox.documentation.spi.DocumentationType; 10 | import springfox.documentation.spring.web.plugins.Docket; 11 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 12 | 13 | import java.util.Collections; 14 | 15 | @Configuration 16 | @EnableSwagger2 17 | public class SwaggerConfig { 18 | 19 | @Bean 20 | public Docket api(){ 21 | return new Docket(DocumentationType.SWAGGER_2) 22 | .select() 23 | .apis(RequestHandlerSelectors.any()) 24 | .paths(PathSelectors.any()) 25 | .build() 26 | .apiInfo(apiInfo()); 27 | 28 | } 29 | 30 | private ApiInfo apiInfo(){ 31 | return new ApiInfo( 32 | "Vehicles API", 33 | "This API returns information of vehicles", 34 | "1.0", 35 | "http://wwww.udacity.com/tos", 36 | new Contact("Udacious Student", "www.udacity.com", "yoonsarah88@gmail.com" ), 37 | "License of API", "http://www.udacity.com/license", Collections.emptyList()); 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/domain/Condition.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.domain; 2 | 3 | /** 4 | * Available values for condition of a given car. 5 | */ 6 | public enum Condition { 7 | 8 | USED, 9 | NEW; 10 | } 11 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/domain/Location.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.domain; 2 | 3 | import javax.persistence.Embeddable; 4 | import javax.persistence.Transient; 5 | import javax.validation.constraints.NotNull; 6 | 7 | /** 8 | * Stores information about a given location. 9 | * Latitude and longitude must be provided, while other 10 | * location information must be gathered each time from 11 | * the maps API. 12 | */ 13 | @Embeddable 14 | public class Location { 15 | 16 | @NotNull 17 | private Double lat; 18 | 19 | @NotNull 20 | private Double lon; 21 | 22 | @Transient 23 | private String address; 24 | 25 | @Transient 26 | private String city; 27 | 28 | @Transient 29 | private String state; 30 | 31 | @Transient 32 | private String zip; 33 | 34 | public Location() { 35 | } 36 | 37 | public Location(Double lat, Double lon) { 38 | this.lat = lat; 39 | this.lon = lon; 40 | } 41 | 42 | public Double getLat() { 43 | return lat; 44 | } 45 | 46 | public Double getLon() { 47 | return lon; 48 | } 49 | 50 | public String getAddress() { 51 | return address; 52 | } 53 | 54 | public void setAddress(String address) { 55 | this.address = address; 56 | } 57 | 58 | public String getCity() { 59 | return city; 60 | } 61 | 62 | public void setCity(String city) { 63 | this.city = city; 64 | } 65 | 66 | public String getState() { 67 | return state; 68 | } 69 | 70 | public void setState(String state) { 71 | this.state = state; 72 | } 73 | 74 | public String getZip() { 75 | return zip; 76 | } 77 | 78 | public void setZip(String zip) { 79 | this.zip = zip; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/domain/car/Car.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.domain.car; 2 | 3 | import com.udacity.vehicles.domain.Condition; 4 | import com.udacity.vehicles.domain.Location; 5 | import java.time.LocalDateTime; 6 | import javax.persistence.Embedded; 7 | import javax.persistence.Entity; 8 | import javax.persistence.EntityListeners; 9 | import javax.persistence.EnumType; 10 | import javax.persistence.Enumerated; 11 | import javax.persistence.GeneratedValue; 12 | import javax.persistence.Id; 13 | import javax.persistence.Transient; 14 | import javax.validation.Valid; 15 | import javax.validation.constraints.NotNull; 16 | import org.springframework.data.annotation.CreatedDate; 17 | import org.springframework.data.annotation.LastModifiedDate; 18 | import org.springframework.data.jpa.domain.support.AuditingEntityListener; 19 | 20 | /** 21 | * Declares the Car class, related variables and methods. 22 | */ 23 | @Entity 24 | @EntityListeners(AuditingEntityListener.class) 25 | public class Car { 26 | 27 | @Id 28 | @GeneratedValue 29 | private Long id; 30 | 31 | @CreatedDate 32 | private LocalDateTime createdAt; 33 | 34 | @LastModifiedDate 35 | private LocalDateTime modifiedAt; 36 | 37 | @NotNull 38 | @Enumerated(EnumType.STRING) 39 | private Condition condition; 40 | 41 | @Valid 42 | @Embedded 43 | private Details details = new Details(); 44 | 45 | @Valid 46 | @Embedded 47 | private Location location = new Location(0d, 0d); 48 | 49 | @Transient 50 | private String price; 51 | 52 | public Long getId() { 53 | return id; 54 | } 55 | 56 | public void setId(Long id) { 57 | this.id = id; 58 | } 59 | 60 | public LocalDateTime getCreatedAt() { 61 | return createdAt; 62 | } 63 | 64 | public void setCreatedAt(LocalDateTime createdAt) { 65 | this.createdAt = createdAt; 66 | } 67 | 68 | public LocalDateTime getModifiedAt() { 69 | return modifiedAt; 70 | } 71 | 72 | public void setModifiedAt(LocalDateTime modifiedAt) { 73 | this.modifiedAt = modifiedAt; 74 | } 75 | 76 | public Condition getCondition() { 77 | return condition; 78 | } 79 | 80 | public void setCondition(Condition condition) { 81 | this.condition = condition; 82 | } 83 | 84 | public Details getDetails() { 85 | return details; 86 | } 87 | 88 | public void setDetails(Details details) { 89 | this.details = details; 90 | } 91 | 92 | public Location getLocation() { 93 | return location; 94 | } 95 | 96 | public void setLocation(Location location) { 97 | this.location = location; 98 | } 99 | 100 | public String getPrice() { 101 | return price; 102 | } 103 | 104 | public void setPrice(String price) { 105 | this.price = price; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/domain/car/CarRepository.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.domain.car; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public interface CarRepository extends JpaRepository { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/domain/manufacturer/Manufacturer.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.domain.manufacturer; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.Id; 5 | 6 | /** 7 | * Declares class to hold car manufacturer information. 8 | */ 9 | @Entity 10 | public class Manufacturer { 11 | 12 | @Id 13 | private Integer code; 14 | private String name; 15 | 16 | public Manufacturer() { } 17 | 18 | public Manufacturer(Integer code, String name) { 19 | this.code = code; 20 | this.name = name; 21 | } 22 | 23 | public Integer getCode() { 24 | return code; 25 | } 26 | 27 | public String getName() { 28 | return name; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/domain/manufacturer/ManufacturerRepository.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.domain.manufacturer; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public interface ManufacturerRepository extends JpaRepository { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/service/CarNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.service; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.web.bind.annotation.ResponseStatus; 5 | 6 | @ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Car not found") 7 | public class CarNotFoundException extends RuntimeException { 8 | 9 | public CarNotFoundException() { 10 | } 11 | 12 | public CarNotFoundException(String message) { 13 | super(message); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/java/com/udacity/vehicles/service/CarService.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles.service; 2 | 3 | import com.udacity.vehicles.client.maps.MapsClient; 4 | import com.udacity.vehicles.client.prices.PriceClient; 5 | import com.udacity.vehicles.domain.car.Car; 6 | import com.udacity.vehicles.domain.car.CarRepository; 7 | import java.util.List; 8 | import org.springframework.stereotype.Service; 9 | 10 | /** 11 | * Implements the car service create, read, update or delete 12 | * information about vehicles, as well as gather related 13 | * location and price data when desired. 14 | */ 15 | @Service 16 | public class CarService { 17 | 18 | private final CarRepository repository; 19 | private MapsClient mapsClient; 20 | private PriceClient priceClient; 21 | 22 | public CarService(CarRepository repository, MapsClient mapsClient, PriceClient priceClient) { 23 | 24 | this.repository = repository; 25 | this.mapsClient = mapsClient; 26 | this.priceClient = priceClient; 27 | 28 | } 29 | 30 | /** 31 | * Gathers a list of all vehicles 32 | * @return a list of all vehicles in the CarRepository 33 | */ 34 | public List list() { 35 | return repository.findAll(); 36 | } 37 | 38 | /** 39 | * Gets car information by ID (or throws exception if non-existent) 40 | * @param id the ID number of the car to gather information on 41 | * @return the requested car's information, including location and price 42 | */ 43 | public Car findById(Long id) { 44 | 45 | Car car = repository.findById(id).orElseThrow(CarNotFoundException::new); 46 | car.setPrice(priceClient.getPrice(id)); 47 | car.setLocation(mapsClient.getAddress(car.getLocation())); 48 | 49 | return car; 50 | } 51 | 52 | /** 53 | * Either creates or updates a vehicle, based on prior existence of car 54 | * @param car A car object, which can be either new or existing 55 | * @return the new/updated car is stored in the repository 56 | */ 57 | public Car save(Car car) { 58 | if (car.getId() != null) { 59 | return repository.findById(car.getId()) 60 | .map(carToBeUpdated -> { 61 | carToBeUpdated.setDetails(car.getDetails()); 62 | carToBeUpdated.setLocation(car.getLocation()); 63 | return repository.save(carToBeUpdated); 64 | }).orElseThrow(CarNotFoundException::new); 65 | } 66 | 67 | return repository.save(car); 68 | } 69 | 70 | /** 71 | * Deletes a given car by ID 72 | * @param id the ID number of the car to delete 73 | */ 74 | public void delete(Long id) { 75 | 76 | Car car = repository.findById(id).orElseThrow(CarNotFoundException::new); 77 | 78 | repository.delete(car); 79 | 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | pricing.endpoint=http://localhost:8082 2 | maps.endpoint=http://localhost:9191 3 | -------------------------------------------------------------------------------- /projects/vehiclesAPI/vehicles-api/src/test/java/com/udacity/vehicles/VehiclesApiApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.udacity.vehicles; 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 VehiclesApiApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------