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