├── .elasticbeanstalk └── config.yml ├── .gitignore ├── Otherprojects ├── 01-spring-boot-hello-world-rest-api │ ├── pom.xml │ ├── readme.md │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── in28minutes │ │ │ │ └── rest │ │ │ │ └── webservices │ │ │ │ └── restfulwebservices │ │ │ │ ├── HelloWorldBean.java │ │ │ │ ├── HelloWorldController.java │ │ │ │ └── RestfulWebServicesApplication.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── in28minutes │ │ └── rest │ │ └── webservices │ │ └── restfulwebservices │ │ └── RestfulWebServicesApplicationTests.java ├── 02-spring-boot-todo-rest-api-h2 │ ├── pom.xml │ ├── readme.md │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── in28minutes │ │ │ │ └── rest │ │ │ │ └── webservices │ │ │ │ └── restfulwebservices │ │ │ │ ├── RestfulWebServicesApplication.java │ │ │ │ ├── helloworld │ │ │ │ ├── HelloWorldBean.java │ │ │ │ └── HelloWorldController.java │ │ │ │ └── todo │ │ │ │ ├── Todo.java │ │ │ │ ├── TodoHardcodedService.java │ │ │ │ ├── TodoJpaRepository.java │ │ │ │ ├── TodoJpaResource.java │ │ │ │ └── TodoResource.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── data.sql │ │ └── test │ │ └── java │ │ └── com │ │ └── in28minutes │ │ └── rest │ │ └── webservices │ │ └── restfulwebservices │ │ └── RestfulWebServicesApplicationTests.java ├── 03-spring-boot-web-application-h2 │ ├── pom.xml │ ├── readme.md │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── in28minutes │ │ │ │ └── springboot │ │ │ │ └── web │ │ │ │ ├── PropertyLogger.java │ │ │ │ ├── SpringBootFirstWebApplication.java │ │ │ │ ├── controller │ │ │ │ ├── ErrorController.java │ │ │ │ ├── LogoutController.java │ │ │ │ ├── TodoController.java │ │ │ │ └── WelcomeController.java │ │ │ │ ├── model │ │ │ │ └── Todo.java │ │ │ │ ├── security │ │ │ │ └── SecurityConfiguration.java │ │ │ │ └── service │ │ │ │ ├── TodoRepository.java │ │ │ │ └── TodoService.java │ │ ├── resources │ │ │ ├── application.properties │ │ │ └── data.sql │ │ └── webapp │ │ │ └── WEB-INF │ │ │ └── jsp │ │ │ ├── common │ │ │ ├── footer.jspf │ │ │ ├── header.jspf │ │ │ └── navigation.jspf │ │ │ ├── error.jsp │ │ │ ├── list-todos.jsp │ │ │ ├── todo.jsp │ │ │ └── welcome.jsp │ │ └── test │ │ └── java │ │ └── com │ │ └── in28minutes │ │ └── springboot │ │ └── web │ │ └── SpringBootFirstWebApplicationTests.java ├── 04-spring-boot-web-application-mysql │ ├── pom.xml │ ├── readme.md │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── in28minutes │ │ │ │ └── springboot │ │ │ │ └── web │ │ │ │ ├── PropertyLogger.java │ │ │ │ ├── SpringBootFirstWebApplication.java │ │ │ │ ├── controller │ │ │ │ ├── ErrorController.java │ │ │ │ ├── LogoutController.java │ │ │ │ ├── TodoController.java │ │ │ │ └── WelcomeController.java │ │ │ │ ├── model │ │ │ │ └── Todo.java │ │ │ │ ├── security │ │ │ │ └── SecurityConfiguration.java │ │ │ │ └── service │ │ │ │ ├── TodoRepository.java │ │ │ │ └── TodoService.java │ │ ├── resources │ │ │ └── application.properties │ │ └── webapp │ │ │ └── WEB-INF │ │ │ └── jsp │ │ │ ├── common │ │ │ ├── footer.jspf │ │ │ ├── header.jspf │ │ │ └── navigation.jspf │ │ │ ├── error.jsp │ │ │ ├── list-todos.jsp │ │ │ ├── todo.jsp │ │ │ └── welcome.jsp │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── in28minutes │ │ │ └── springboot │ │ │ └── web │ │ │ └── SpringBootFirstWebApplicationTests.java │ │ └── resources │ │ └── application.properties ├── 05-spring-boot-react-full-stack-h2 │ ├── frontend │ │ └── todo-app │ │ │ ├── build │ │ │ ├── asset-manifest.json │ │ │ ├── favicon.ico │ │ │ ├── index.html │ │ │ ├── manifest.json │ │ │ ├── precache-manifest.329107c39cdcab0d36989b26995e59f8.js │ │ │ ├── service-worker.js │ │ │ └── static │ │ │ │ ├── css │ │ │ │ ├── main.8537e868.chunk.css │ │ │ │ └── main.8537e868.chunk.css.map │ │ │ │ └── js │ │ │ │ ├── 2.3f64e426.chunk.js │ │ │ │ ├── 2.3f64e426.chunk.js.map │ │ │ │ ├── main.2304f8a7.chunk.js │ │ │ │ ├── main.2304f8a7.chunk.js.map │ │ │ │ ├── runtime~main.c5541365.js │ │ │ │ └── runtime~main.c5541365.js.map │ │ │ ├── package-lock.json │ │ │ ├── package.json │ │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── index.html │ │ │ └── manifest.json │ │ │ └── src │ │ │ ├── App.css │ │ │ ├── App.js │ │ │ ├── App.test.js │ │ │ ├── Constants.js │ │ │ ├── api │ │ │ └── todo │ │ │ │ ├── HelloWorldService.js │ │ │ │ └── TodoDataService.js │ │ │ ├── bootstrap.css │ │ │ ├── components │ │ │ ├── counter │ │ │ │ ├── Counter.css │ │ │ │ └── Counter.jsx │ │ │ ├── learning-examples │ │ │ │ ├── FirstComponent.jsx │ │ │ │ ├── SecondComponent.jsx │ │ │ │ └── ThirdComponent.jsx │ │ │ └── todo │ │ │ │ ├── AuthenticatedRoute.jsx │ │ │ │ ├── AuthenticationService.js │ │ │ │ ├── ErrorComponent.jsx │ │ │ │ ├── FooterComponent.jsx │ │ │ │ ├── HeaderComponent.jsx │ │ │ │ ├── ListTodosComponent.jsx │ │ │ │ ├── LoginComponent.jsx │ │ │ │ ├── LogoutComponent.jsx │ │ │ │ ├── TodoApp.jsx │ │ │ │ ├── TodoComponent.jsx │ │ │ │ └── WelcomeComponent.jsx │ │ │ ├── index.css │ │ │ ├── index.js │ │ │ ├── logo.svg │ │ │ └── serviceWorker.js │ ├── react_00_architecture.png │ ├── readme.md │ └── restful-web-services │ │ ├── pom.xml │ │ ├── readme.md │ │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── in28minutes │ │ │ │ └── rest │ │ │ │ ├── basic │ │ │ │ └── auth │ │ │ │ │ ├── AuthenticationBean.java │ │ │ │ │ ├── BasicAuthenticationController.java │ │ │ │ │ └── SpringSecurityConfigurationBasicAuth.java │ │ │ │ └── webservices │ │ │ │ └── restfulwebservices │ │ │ │ ├── RestfulWebServicesApplication.java │ │ │ │ ├── helloworld │ │ │ │ ├── HelloWorldBean.java │ │ │ │ └── HelloWorldController.java │ │ │ │ ├── jwt │ │ │ │ ├── JWTWebSecurityConfig.java │ │ │ │ ├── JwtInMemoryUserDetailsService.java │ │ │ │ ├── JwtTokenAuthorizationOncePerRequestFilter.java │ │ │ │ ├── JwtTokenUtil.java │ │ │ │ ├── JwtUnAuthorizedResponseAuthenticationEntryPoint.java │ │ │ │ ├── JwtUserDetails.java │ │ │ │ ├── JwtUserDetailsService.java │ │ │ │ ├── User.java │ │ │ │ ├── UserRepository.java │ │ │ │ └── resource │ │ │ │ │ ├── AuthenticationException.java │ │ │ │ │ ├── JwtAuthenticationRestController.java │ │ │ │ │ ├── JwtTokenRequest.java │ │ │ │ │ └── JwtTokenResponse.java │ │ │ │ └── todo │ │ │ │ ├── Todo.java │ │ │ │ ├── TodoHardcodedService.java │ │ │ │ ├── TodoJpaRepository.java │ │ │ │ ├── TodoJpaResource.java │ │ │ │ └── TodoResource.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── data.sql │ │ └── test │ │ └── java │ │ └── com │ │ └── in28minutes │ │ └── rest │ │ └── webservices │ │ └── restfulwebservices │ │ └── RestfulWebServicesApplicationTests.java ├── 06-todo-rest-api-h2-containerized │ ├── Dockerfile │ ├── Dockerrun.aws.json │ ├── pom.xml │ ├── readme.md │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── in28minutes │ │ │ │ └── rest │ │ │ │ └── webservices │ │ │ │ └── restfulwebservices │ │ │ │ ├── RestfulWebServicesApplication.java │ │ │ │ ├── helloworld │ │ │ │ ├── HelloWorldBean.java │ │ │ │ └── HelloWorldController.java │ │ │ │ └── todo │ │ │ │ ├── Todo.java │ │ │ │ ├── TodoHardcodedService.java │ │ │ │ └── TodoResource.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── in28minutes │ │ └── rest │ │ └── webservices │ │ └── restfulwebservices │ │ └── RestfulWebServicesApplicationTests.java └── 07-todo-rest-api-mysql-containerized │ ├── Dockerfile │ ├── Dockerrun.aws.json │ ├── pom.xml │ ├── readme.md │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── in28minutes │ │ │ └── rest │ │ │ └── webservices │ │ │ └── restfulwebservices │ │ │ ├── RestfulWebServicesApplication.java │ │ │ ├── helloworld │ │ │ ├── HelloWorldBean.java │ │ │ └── HelloWorldController.java │ │ │ └── todo │ │ │ ├── Todo.java │ │ │ ├── TodoHardcodedService.java │ │ │ └── TodoResource.java │ └── resources │ │ └── application.properties │ └── test │ ├── java │ └── com │ │ └── in28minutes │ │ └── rest │ │ └── webservices │ │ └── restfulwebservices │ │ └── RestfulWebServicesApplicationTests.java │ └── resources │ └── application.properties ├── buildspec.yml ├── cmd-line-test └── .gitignore ├── pom.xml ├── readme.md └── src ├── main ├── java │ └── com │ │ └── in28minutes │ │ └── rest │ │ └── webservices │ │ └── restfulwebservices │ │ ├── RestfulWebServicesApplication.java │ │ ├── helloworld │ │ ├── HelloWorldBean.java │ │ └── HelloWorldController.java │ │ └── todo │ │ ├── Todo.java │ │ ├── TodoHardcodedService.java │ │ ├── TodoJpaRepository.java │ │ ├── TodoJpaResource.java │ │ └── TodoResource.java └── resources │ ├── application.properties │ └── data.sql └── test └── java └── com └── in28minutes └── rest └── webservices └── restfulwebservices └── RestfulWebServicesApplicationTests.java /.elasticbeanstalk/config.yml: -------------------------------------------------------------------------------- 1 | global: 2 | profile: eb-cli 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /tmp 4 | /out-tsc 5 | 6 | # dependencies 7 | /node_modules 8 | 9 | # IDEs and editors 10 | /.idea 11 | .project 12 | .classpath 13 | .c9/ 14 | *.launch 15 | .settings/ 16 | *.sublime-workspace 17 | 18 | # IDE - VSCode 19 | .vscode/* 20 | !.vscode/settings.json 21 | !.vscode/tasks.json 22 | !.vscode/launch.json 23 | !.vscode/extensions.json 24 | 25 | # misc 26 | /.sass-cache 27 | /connect.lock 28 | /coverage 29 | /libpeerconnection.log 30 | npm-debug.log 31 | yarn-error.log 32 | testem.log 33 | /typings 34 | 35 | # System Files 36 | .DS_Store 37 | Thumbs.db 38 | 39 | # Compiled class file 40 | *.class 41 | 42 | # Log file 43 | *.log 44 | 45 | # BlueJ files 46 | *.ctxt 47 | 48 | # Mobile Tools for Java (J2ME) 49 | .mtj.tmp/ 50 | 51 | # Package Files # 52 | *.jar 53 | *.war 54 | *.ear 55 | *.tar.gz 56 | *.rar 57 | *.cmd 58 | *.classpath 59 | *.settings 60 | *.project 61 | *.mvn 62 | mvnw 63 | target 64 | *.DS_Store 65 | 66 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 67 | hs_err_pid* 68 | 69 | # Compiled class file 70 | *.class 71 | 72 | # Log file 73 | *.log 74 | 75 | # BlueJ files 76 | *.ctxt 77 | 78 | # Mobile Tools for Java (J2ME) 79 | .mtj.tmp/ 80 | 81 | # Package Files # 82 | *.jar 83 | *.war 84 | *.ear 85 | *.zip 86 | *.tar.gz 87 | *.rar 88 | *.cmd 89 | *.classpath 90 | *.settings 91 | *.project 92 | *.mvn 93 | mvnw 94 | target 95 | node_modules 96 | *.DS_Store 97 | 98 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 99 | hs_err_pid* 100 | bin -------------------------------------------------------------------------------- /Otherprojects/01-spring-boot-hello-world-rest-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.in28minutes.rest.webservices 8 | 01-spring-boot-hello-world-rest-api 9 | 0.0.1-SNAPSHOT 10 | jar 11 | Demo project for Spring Boot 12 | 13 | 14 | org.springframework.boot 15 | spring-boot-starter-parent 16 | 2.1.0.RELEASE 17 | 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 1.8 24 | 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-data-jpa 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-web 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-devtools 41 | runtime 42 | 43 | 44 | 45 | com.h2database 46 | h2 47 | runtime 48 | 49 | 50 | 51 | javax.xml.bind 52 | jaxb-api 53 | 2.3.0 54 | 55 | 56 | com.sun.xml.bind 57 | jaxb-impl 58 | 2.3.0 59 | 60 | 61 | org.glassfish.jaxb 62 | jaxb-runtime 63 | 2.3.0 64 | 65 | 66 | javax.activation 67 | activation 68 | 1.1.1 69 | 70 | 71 | 72 | org.springframework.boot 73 | spring-boot-starter-test 74 | test 75 | 76 | 77 | 78 | 79 | 80 | 81 | org.springframework.boot 82 | spring-boot-maven-plugin 83 | 84 | 85 | 86 | 87 | 88 | 89 | spring-snapshots 90 | Spring Snapshots 91 | https://repo.spring.io/snapshot 92 | 93 | true 94 | 95 | 96 | 97 | spring-milestones 98 | Spring Milestones 99 | https://repo.spring.io/milestone 100 | 101 | false 102 | 103 | 104 | 105 | 106 | 107 | 108 | spring-snapshots 109 | Spring Snapshots 110 | https://repo.spring.io/snapshot 111 | 112 | true 113 | 114 | 115 | 116 | spring-milestones 117 | Spring Milestones 118 | https://repo.spring.io/milestone 119 | 120 | false 121 | 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /Otherprojects/01-spring-boot-hello-world-rest-api/readme.md: -------------------------------------------------------------------------------- 1 | # Hello World Rest API running on port 5000 2 | 3 | Run com.in28minutes.rest.webservices.restfulwebservices.RestfulWebServicesApplication as a Java Application. 4 | 5 | - http://localhost:5000/hello-world 6 | 7 | ```txt 8 | Hello World 9 | ``` 10 | 11 | - http://localhost:5000/hello-world-bean 12 | 13 | ```json 14 | {"message":"Hello World - Changed"} 15 | ``` 16 | 17 | - http://localhost:5000/hello-world/path-variable/in28minutes 18 | 19 | ```json 20 | {"message":"Hello World, in28minutes"} 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /Otherprojects/01-spring-boot-hello-world-rest-api/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/HelloWorldBean.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 2 | 3 | public class HelloWorldBean { 4 | 5 | private String message; 6 | 7 | public HelloWorldBean(String message) { 8 | this.message = message; 9 | } 10 | 11 | public String getMessage() { 12 | return message; 13 | } 14 | 15 | public void setMessage(String message) { 16 | this.message = message; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return String.format("HelloWorldBean [message=%s]", message); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Otherprojects/01-spring-boot-hello-world-rest-api/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/HelloWorldController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.PathVariable; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | //Controller 8 | //AWS @CrossOrigin(origins="http://localhost:4200") 9 | @RestController 10 | public class HelloWorldController { 11 | 12 | @GetMapping(path = "/hello-world") 13 | public String helloWorld() { 14 | return "Hello World"; 15 | } 16 | 17 | @GetMapping(path = "/hello-world-bean") 18 | public HelloWorldBean helloWorldBean() { 19 | //throw new RuntimeException("Some Error has Happened! Contact Support at ***-***"); 20 | return new HelloWorldBean("Hello World - Changed"); 21 | } 22 | 23 | ///hello-world/path-variable/in28minutes 24 | @GetMapping(path = "/hello-world/path-variable/{name}") 25 | public HelloWorldBean helloWorldPathVariable(@PathVariable String name) { 26 | return new HelloWorldBean(String.format("Hello World, %s", name)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Otherprojects/01-spring-boot-hello-world-rest-api/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class RestfulWebServicesApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(RestfulWebServicesApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Otherprojects/01-spring-boot-hello-world-rest-api/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework = debug 2 | 3 | #AWS Elastic Beanstalk assumes that the application will listen on port 5000. 4 | server.port=5000 -------------------------------------------------------------------------------- /Otherprojects/01-spring-boot-hello-world-rest-api/src/test/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 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 RestfulWebServicesApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Otherprojects/02-spring-boot-todo-rest-api-h2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.in28minutes.rest.webservices 7 | 02-todo-rest-api-h2 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | Demo project for Spring Boot 12 | 13 | 14 | org.springframework.boot 15 | spring-boot-starter-parent 16 | 2.1.0.RELEASE 17 | 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 1.8 24 | 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-data-jpa 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-web 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-devtools 41 | runtime 42 | 43 | 44 | 45 | com.h2database 46 | h2 47 | runtime 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-test 53 | test 54 | 55 | 56 | 57 | 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-maven-plugin 62 | 63 | 64 | 65 | 66 | 67 | 68 | spring-snapshots 69 | Spring Snapshots 70 | https://repo.spring.io/snapshot 71 | 72 | true 73 | 74 | 75 | 76 | spring-milestones 77 | Spring Milestones 78 | https://repo.spring.io/milestone 79 | 80 | false 81 | 82 | 83 | 84 | 85 | 86 | 87 | spring-snapshots 88 | Spring Snapshots 89 | https://repo.spring.io/snapshot 90 | 91 | true 92 | 93 | 94 | 95 | spring-milestones 96 | Spring Milestones 97 | https://repo.spring.io/milestone 98 | 99 | false 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /Otherprojects/02-spring-boot-todo-rest-api-h2/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | @SpringBootApplication 10 | public class RestfulWebServicesApplication { 11 | 12 | // AWS 13 | @Bean 14 | public WebMvcConfigurer corsConfigurer() { 15 | return new WebMvcConfigurer() { 16 | @Override 17 | public void addCorsMappings(CorsRegistry registry) { 18 | registry.addMapping("/**").allowedMethods("*").allowedOrigins("*"); 19 | } 20 | }; 21 | } 22 | 23 | public static void main(String[] args) { 24 | SpringApplication.run(RestfulWebServicesApplication.class, args); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Otherprojects/02-spring-boot-todo-rest-api-h2/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/helloworld/HelloWorldBean.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.helloworld; 2 | 3 | public class HelloWorldBean { 4 | 5 | private String message; 6 | 7 | public HelloWorldBean(String message) { 8 | this.message = message; 9 | } 10 | 11 | public String getMessage() { 12 | return message; 13 | } 14 | 15 | public void setMessage(String message) { 16 | this.message = message; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return String.format("HelloWorldBean [message=%s]", message); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Otherprojects/02-spring-boot-todo-rest-api-h2/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/helloworld/HelloWorldController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.helloworld; 2 | 3 | import org.springframework.web.bind.annotation.CrossOrigin; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.PathVariable; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | //Controller 9 | @RestController 10 | @CrossOrigin(origins="http://localhost:4200") 11 | // 12 | public class HelloWorldController { 13 | 14 | @GetMapping(path = "/hello-world") 15 | public String helloWorld() { 16 | return "Hello World"; 17 | } 18 | 19 | @GetMapping(path = "/hello-world-bean") 20 | public HelloWorldBean helloWorldBean() { 21 | return new HelloWorldBean("Hello World"); 22 | } 23 | 24 | ///hello-world/path-variable/in28minutes 25 | @GetMapping(path = "/hello-world/path-variable/{name}") 26 | public HelloWorldBean helloWorldPathVariable(@PathVariable String name) { 27 | //throw new RuntimeException("Something went wrong"); 28 | return new HelloWorldBean(String.format("Hello World, %s", name)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Otherprojects/02-spring-boot-todo-rest-api-h2/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/Todo.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.Date; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.Id; 8 | 9 | @Entity 10 | public class Todo { 11 | @Id 12 | @GeneratedValue 13 | private Long id; 14 | private String username; 15 | private String description; 16 | private Date targetDate; 17 | private boolean isDone; 18 | 19 | public Todo() { 20 | 21 | } 22 | 23 | public Todo(long id, String username, String description, Date targetDate, boolean isDone) { 24 | super(); 25 | this.id = id; 26 | this.username = username; 27 | this.description = description; 28 | this.targetDate = targetDate; 29 | this.isDone = isDone; 30 | } 31 | 32 | public Long getId() { 33 | return id; 34 | } 35 | 36 | public void setId(Long id) { 37 | this.id = id; 38 | } 39 | 40 | public String getUsername() { 41 | return username; 42 | } 43 | 44 | public void setUsername(String username) { 45 | this.username = username; 46 | } 47 | 48 | public String getDescription() { 49 | return description; 50 | } 51 | 52 | public void setDescription(String description) { 53 | this.description = description; 54 | } 55 | 56 | public Date getTargetDate() { 57 | return targetDate; 58 | } 59 | 60 | public void setTargetDate(Date targetDate) { 61 | this.targetDate = targetDate; 62 | } 63 | 64 | public boolean isDone() { 65 | return isDone; 66 | } 67 | 68 | public void setDone(boolean isDone) { 69 | this.isDone = isDone; 70 | } 71 | 72 | @Override 73 | public int hashCode() { 74 | final int prime = 31; 75 | int result = 1; 76 | result = prime * result + (int) (id ^ (id >>> 32)); 77 | return result; 78 | } 79 | 80 | @Override 81 | public boolean equals(Object obj) { 82 | if (this == obj) 83 | return true; 84 | if (obj == null) 85 | return false; 86 | if (getClass() != obj.getClass()) 87 | return false; 88 | Todo other = (Todo) obj; 89 | if (id != other.id) 90 | return false; 91 | return true; 92 | } 93 | 94 | 95 | } -------------------------------------------------------------------------------- /Otherprojects/02-spring-boot-todo-rest-api-h2/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoHardcodedService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class TodoHardcodedService { 11 | 12 | private static List todos = new ArrayList<>(); 13 | private static long idCounter = 0; 14 | 15 | static { 16 | todos.add(new Todo(++idCounter, "in28minutes", "Learn to Dance 2", new Date(), false)); 17 | todos.add(new Todo(++idCounter, "in28minutes", "Learn about Microservices 2", new Date(), false)); 18 | todos.add(new Todo(++idCounter, "in28minutes", "Learn about Angular", new Date(), false)); 19 | } 20 | 21 | public List findAll() { 22 | return todos; 23 | } 24 | 25 | public Todo save(Todo todo) { 26 | if(todo.getId()==-1 || todo.getId()==0) { 27 | todo.setId(++idCounter); 28 | todos.add(todo); 29 | } else { 30 | deleteById(todo.getId()); 31 | todos.add(todo); 32 | } 33 | return todo; 34 | } 35 | 36 | public Todo deleteById(long id) { 37 | Todo todo = findById(id); 38 | 39 | if (todo == null) 40 | return null; 41 | 42 | if (todos.remove(todo)) { 43 | return todo; 44 | } 45 | 46 | return null; 47 | } 48 | 49 | public Todo findById(long id) { 50 | for (Todo todo : todos) { 51 | if (todo.getId() == id) { 52 | return todo; 53 | } 54 | } 55 | 56 | return null; 57 | } 58 | } -------------------------------------------------------------------------------- /Otherprojects/02-spring-boot-todo-rest-api-h2/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoJpaRepository.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | @Repository 9 | public interface TodoJpaRepository extends JpaRepository{ 10 | List findByUsername(String username); 11 | } -------------------------------------------------------------------------------- /Otherprojects/02-spring-boot-todo-rest-api-h2/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoJpaResource.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.net.URI; 4 | import java.util.List; 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.DeleteMapping; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.PutMapping; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.RestController; 16 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 17 | 18 | //@CrossOrigin(origins="http://localhost:4200") Replace with global config 19 | @RestController 20 | public class TodoJpaResource { 21 | 22 | @Autowired 23 | private TodoJpaRepository todoJpaRepository; 24 | 25 | 26 | @GetMapping("/jpa/users/{username}/todos") 27 | public List getAllTodos(@PathVariable String username){ 28 | return todoJpaRepository.findByUsername(username); 29 | //return todoService.findAll(); 30 | } 31 | 32 | @GetMapping("/jpa/users/{username}/todos/{id}") 33 | public Todo getTodo(@PathVariable String username, @PathVariable long id){ 34 | return todoJpaRepository.findById(id).get(); 35 | //return todoService.findById(id); 36 | } 37 | 38 | // DELETE /users/{username}/todos/{id} 39 | @DeleteMapping("/jpa/users/{username}/todos/{id}") 40 | public ResponseEntity deleteTodo( 41 | @PathVariable String username, @PathVariable long id) { 42 | 43 | todoJpaRepository.deleteById(id); 44 | 45 | return ResponseEntity.noContent().build(); 46 | } 47 | 48 | 49 | //Edit/Update a Todo 50 | //PUT /users/{user_name}/todos/{todo_id} 51 | @PutMapping("/jpa/users/{username}/todos/{id}") 52 | public ResponseEntity updateTodo( 53 | @PathVariable String username, 54 | @PathVariable long id, @RequestBody Todo todo){ 55 | 56 | todo.setUsername(username); 57 | 58 | Todo todoUpdated = todoJpaRepository.save(todo); 59 | 60 | return new ResponseEntity(todo, HttpStatus.OK); 61 | } 62 | 63 | @PostMapping("/jpa/users/{username}/todos") 64 | public ResponseEntity createTodo( 65 | @PathVariable String username, @RequestBody Todo todo){ 66 | 67 | todo.setUsername(username); 68 | 69 | Todo createdTodo = todoJpaRepository.save(todo); 70 | 71 | //Location 72 | //Get current resource url 73 | ///{id} 74 | URI uri = ServletUriComponentsBuilder.fromCurrentRequest() 75 | .path("/{id}").buildAndExpand(createdTodo.getId()).toUri(); 76 | 77 | return ResponseEntity.created(uri).build(); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /Otherprojects/02-spring-boot-todo-rest-api-h2/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoResource.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.net.URI; 4 | import java.util.List; 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.DeleteMapping; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.PutMapping; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.RestController; 16 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 17 | 18 | //@CrossOrigin(origins = "http://localhost:4200") Replace with global config 19 | @RestController 20 | public class TodoResource { 21 | 22 | @Autowired 23 | private TodoHardcodedService todoService; 24 | 25 | @GetMapping("/users/{username}/todos") 26 | public List getAllTodos(@PathVariable String username) { 27 | // Thread.sleep(3000); 28 | return todoService.findAll(); 29 | } 30 | 31 | @GetMapping("/users/{username}/todos/{id}") 32 | public Todo getTodo(@PathVariable String username, @PathVariable long id) { 33 | // Thread.sleep(3000); 34 | return todoService.findById(id); 35 | } 36 | 37 | 38 | // DELETE /users/{username}/todos/{id} 39 | @DeleteMapping("/users/{username}/todos/{id}") 40 | public ResponseEntity deleteTodo(@PathVariable String username, @PathVariable long id) { 41 | 42 | Todo todo = todoService.deleteById(id); 43 | 44 | if (todo != null) { 45 | return ResponseEntity.noContent().build(); 46 | } 47 | 48 | return ResponseEntity.notFound().build(); 49 | } 50 | 51 | //Edit/Update a Todo 52 | //PUT /users/{user_name}/todos/{todo_id} 53 | @PutMapping("/users/{username}/todos/{id}") 54 | public ResponseEntity updateTodo( 55 | @PathVariable String username, 56 | @PathVariable long id, @RequestBody Todo todo){ 57 | 58 | Todo todoUpdated = todoService.save(todo); 59 | 60 | return new ResponseEntity(todo, HttpStatus.OK); 61 | } 62 | 63 | @PostMapping("/users/{username}/todos") 64 | public ResponseEntity updateTodo( 65 | @PathVariable String username, @RequestBody Todo todo){ 66 | 67 | Todo createdTodo = todoService.save(todo); 68 | 69 | //Location 70 | //Get current resource url 71 | ///{id} 72 | URI uri = ServletUriComponentsBuilder.fromCurrentRequest() 73 | .path("/{id}").buildAndExpand(createdTodo.getId()).toUri(); 74 | 75 | return ResponseEntity.created(uri).build(); 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /Otherprojects/02-spring-boot-todo-rest-api-h2/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.jpa.show-sql=true 2 | spring.h2.console.enabled=true 3 | 4 | logging.level.org.springframework = info 5 | server.port=5000 -------------------------------------------------------------------------------- /Otherprojects/02-spring-boot-todo-rest-api-h2/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | insert into todo(id, username,description,target_date,is_done) 2 | values(10001, 'in28minutes', 'Learn JPA', sysdate(), false); 3 | 4 | insert into todo(id, username,description,target_date,is_done) 5 | values(10002, 'in28minutes', 'Learn Data JPA', sysdate(), false); 6 | 7 | insert into todo(id, username,description,target_date,is_done) 8 | values(10003, 'in28minutes', 'Learn Microservices', sysdate(), false); -------------------------------------------------------------------------------- /Otherprojects/02-spring-boot-todo-rest-api-h2/src/test/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 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 RestfulWebServicesApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.in28minutes.springboot.web 8 | 03-spring-boot-web-application-h2 9 | 0.0.1-SNAPSHOT 10 | war 11 | 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.1.0.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-data-jpa 36 | 37 | 38 | 39 | com.h2database 40 | h2 41 | runtime 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-security 47 | 48 | 49 | 50 | javax.servlet 51 | jstl 52 | 53 | 54 | 55 | org.webjars 56 | bootstrap 57 | 3.3.6 58 | 59 | 60 | 61 | org.webjars 62 | bootstrap-datepicker 63 | 1.0.1 64 | 65 | 66 | 67 | org.webjars 68 | jquery 69 | 1.9.1 70 | 71 | 72 | 73 | org.apache.tomcat.embed 74 | tomcat-embed-jasper 75 | provided 76 | 77 | 78 | 79 | 80 | org.springframework.boot 81 | spring-boot-starter-tomcat 82 | provided 83 | 84 | 85 | 86 | org.springframework.boot 87 | spring-boot-devtools 88 | runtime 89 | 90 | 91 | 92 | org.springframework.boot 93 | spring-boot-starter-test 94 | test 95 | 96 | 97 | 98 | 99 | 100 | 101 | org.springframework.boot 102 | spring-boot-maven-plugin 103 | 104 | 105 | 106 | 107 | 108 | 109 | spring-milestones 110 | Spring Milestones 111 | https://repo.spring.io/milestones 112 | 113 | 114 | 115 | 116 | 117 | spring-milestones 118 | Spring Milestones 119 | https://repo.spring.io/milestones 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/readme.md: -------------------------------------------------------------------------------- 1 | # Todo Web Application using Spring Boot and H2 In memory database 2 | 3 | Run com.in28minutes.springboot.web.SpringBootFirstWebApplication as a Java Application. 4 | 5 | Runs on default port of Spring Boot - 8080 6 | 7 | ## Can be run as a Jar or a WAR 8 | 9 | `mvn clean install` generate a war which can deployed to your favorite web server. 10 | 11 | We will deploy to Cloud as a WAR 12 | 13 | ## Web Application 14 | 15 | - http://localhost:8080/login with in28minutes/dummy as credentials 16 | - You can add, delete and update your todos 17 | - Spring Security is used to secure the application 18 | - `com.in28minutes.springboot.web.security.SecurityConfiguration` contains the in memory security credential configuration. 19 | 20 | ## H2 Console 21 | 22 | - http://localhost:8080/h2-console 23 | - Use `jdbc:h2:mem:testdb` as JDBC URL 24 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/java/com/in28minutes/springboot/web/PropertyLogger.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web; 2 | 3 | import java.util.Arrays; 4 | import java.util.stream.StreamSupport; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.context.event.ContextRefreshedEvent; 9 | import org.springframework.context.event.EventListener; 10 | import org.springframework.core.env.AbstractEnvironment; 11 | import org.springframework.core.env.EnumerablePropertySource; 12 | import org.springframework.core.env.Environment; 13 | import org.springframework.core.env.MutablePropertySources; 14 | import org.springframework.stereotype.Component; 15 | 16 | @Component 17 | public class PropertyLogger { 18 | 19 | private static final Logger LOGGER = LoggerFactory.getLogger(PropertyLogger.class); 20 | 21 | @EventListener 22 | public void handleContextRefresh(ContextRefreshedEvent event) { 23 | final Environment env = event.getApplicationContext().getEnvironment(); 24 | LOGGER.info("====== Environment and configuration ======"); 25 | LOGGER.info("Active profiles: {}", Arrays.toString(env.getActiveProfiles())); 26 | final MutablePropertySources sources = ((AbstractEnvironment) env).getPropertySources(); 27 | StreamSupport.stream(sources.spliterator(), false).filter(ps -> ps instanceof EnumerablePropertySource) 28 | .map(ps -> ((EnumerablePropertySource) ps).getPropertyNames()).flatMap(Arrays::stream).distinct() 29 | .filter(prop -> !(prop.contains("credentials") || prop.contains("password"))) 30 | .forEach(prop -> LOGGER.info("{}: {}", prop, env.getProperty(prop))); 31 | LOGGER.info("==========================================="); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/java/com/in28minutes/springboot/web/SpringBootFirstWebApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.boot.builder.SpringApplicationBuilder; 9 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 10 | import org.springframework.context.annotation.ComponentScan; 11 | import org.springframework.core.env.Environment; 12 | 13 | @SpringBootApplication 14 | @ComponentScan("com.in28minutes.springboot.web") 15 | public class SpringBootFirstWebApplication extends SpringBootServletInitializer { // AWS 16 | 17 | @Autowired 18 | private Environment env; 19 | 20 | @Override // AWS 21 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 22 | return application.sources(SpringBootFirstWebApplication.class); 23 | } 24 | 25 | public static void main(String[] args) { 26 | 27 | Map env = System.getenv(); 28 | 29 | env.forEach((k, v) -> System.out.println(k + ":" + v)); 30 | 31 | SpringApplication.run(SpringBootFirstWebApplication.class, args); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/java/com/in28minutes/springboot/web/controller/ErrorController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.servlet.ModelAndView; 9 | 10 | @Controller("error") 11 | public class ErrorController { 12 | 13 | @ExceptionHandler(Exception.class) 14 | public ModelAndView handleException 15 | (HttpServletRequest request, Exception ex){ 16 | ModelAndView mv = new ModelAndView(); 17 | 18 | mv.addObject("exception", ex.getLocalizedMessage()); 19 | mv.addObject("url", request.getRequestURL()); 20 | 21 | mv.setViewName("error"); 22 | return mv; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/java/com/in28minutes/springboot/web/controller/LogoutController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | import org.springframework.security.core.Authentication; 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | import org.springframework.security.core.userdetails.UserDetails; 9 | import org.springframework.security.web.authentication.logout.LogoutHandler; 10 | import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.ui.ModelMap; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RequestMethod; 15 | 16 | @Controller 17 | public class LogoutController { 18 | 19 | @RequestMapping(value = "/logout", method = RequestMethod.GET) 20 | public String logout(HttpServletRequest request, 21 | HttpServletResponse response) { 22 | 23 | Authentication authentication = SecurityContextHolder.getContext() 24 | .getAuthentication(); 25 | 26 | if (authentication != null) { 27 | new SecurityContextLogoutHandler().logout(request, response, 28 | authentication); 29 | } 30 | 31 | return "redirect:/"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/java/com/in28minutes/springboot/web/controller/TodoController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | import javax.validation.Valid; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.beans.propertyeditors.CustomDateEditor; 10 | import org.springframework.security.core.context.SecurityContextHolder; 11 | import org.springframework.security.core.userdetails.UserDetails; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.ui.ModelMap; 14 | import org.springframework.validation.BindingResult; 15 | import org.springframework.web.bind.WebDataBinder; 16 | import org.springframework.web.bind.annotation.InitBinder; 17 | import org.springframework.web.bind.annotation.RequestMapping; 18 | import org.springframework.web.bind.annotation.RequestMethod; 19 | import org.springframework.web.bind.annotation.RequestParam; 20 | 21 | import com.in28minutes.springboot.web.model.Todo; 22 | import com.in28minutes.springboot.web.service.TodoRepository; 23 | 24 | @Controller 25 | public class TodoController { 26 | 27 | @Autowired 28 | TodoRepository repository; 29 | 30 | @InitBinder 31 | public void initBinder(WebDataBinder binder) { 32 | // Date - dd/MM/yyyy 33 | SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); 34 | binder.registerCustomEditor(Date.class, new CustomDateEditor( 35 | dateFormat, false)); 36 | } 37 | 38 | @RequestMapping(value = "/list-todos", method = RequestMethod.GET) 39 | public String showTodos(ModelMap model) { 40 | String name = getLoggedInUserName(model); 41 | model.put("todos", repository.findByUser(name)); 42 | //model.put("todos", service.retrieveTodos(name)); 43 | return "list-todos"; 44 | } 45 | 46 | private String getLoggedInUserName(ModelMap model) { 47 | Object principal = SecurityContextHolder.getContext() 48 | .getAuthentication().getPrincipal(); 49 | 50 | if (principal instanceof UserDetails) { 51 | return ((UserDetails) principal).getUsername(); 52 | } 53 | 54 | return principal.toString(); 55 | } 56 | 57 | @RequestMapping(value = "/add-todo", method = RequestMethod.GET) 58 | public String showAddTodoPage(ModelMap model) { 59 | model.addAttribute("todo", new Todo(0, getLoggedInUserName(model), 60 | "Default Desc", new Date(), false)); 61 | return "todo"; 62 | } 63 | 64 | @RequestMapping(value = "/delete-todo", method = RequestMethod.GET) 65 | public String deleteTodo(@RequestParam int id) { 66 | 67 | //if(id==1) 68 | //throw new RuntimeException("Something went wrong"); 69 | repository.deleteById(id); 70 | //service.deleteTodo(id); 71 | return "redirect:/list-todos"; 72 | } 73 | 74 | @RequestMapping(value = "/update-todo", method = RequestMethod.GET) 75 | public String showUpdateTodoPage(@RequestParam int id, ModelMap model) { 76 | Todo todo = repository.findById(id).get(); 77 | //Todo todo = service.retrieveTodo(id); 78 | model.put("todo", todo); 79 | return "todo"; 80 | } 81 | 82 | @RequestMapping(value = "/update-todo", method = RequestMethod.POST) 83 | public String updateTodo(ModelMap model, @Valid Todo todo, 84 | BindingResult result) { 85 | 86 | if (result.hasErrors()) { 87 | return "todo"; 88 | } 89 | 90 | todo.setUser(getLoggedInUserName(model)); 91 | 92 | repository.save(todo); 93 | //service.updateTodo(todo); 94 | 95 | return "redirect:/list-todos"; 96 | } 97 | 98 | @RequestMapping(value = "/add-todo", method = RequestMethod.POST) 99 | public String addTodo(ModelMap model, @Valid Todo todo, BindingResult result) { 100 | 101 | if (result.hasErrors()) { 102 | return "todo"; 103 | } 104 | 105 | todo.setUser(getLoggedInUserName(model)); 106 | repository.save(todo); 107 | /*service.addTodo(getLoggedInUserName(model), todo.getDesc(), todo.getTargetDate(), 108 | false);*/ 109 | return "redirect:/list-todos"; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/java/com/in28minutes/springboot/web/controller/WelcomeController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import org.springframework.security.core.context.SecurityContextHolder; 4 | import org.springframework.security.core.userdetails.UserDetails; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.ModelMap; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | 10 | @Controller 11 | public class WelcomeController { 12 | 13 | @RequestMapping(value = "/", method = RequestMethod.GET) 14 | public String showWelcomePage(ModelMap model) { 15 | model.put("name", getLoggedinUserName()); 16 | return "welcome"; 17 | } 18 | 19 | private String getLoggedinUserName() { 20 | Object principal = SecurityContextHolder.getContext() 21 | .getAuthentication().getPrincipal(); 22 | 23 | if (principal instanceof UserDetails) { 24 | return ((UserDetails) principal).getUsername(); 25 | } 26 | 27 | return principal.toString(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/java/com/in28minutes/springboot/web/model/Todo.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.model; 2 | 3 | import java.util.Date; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.Id; 8 | import javax.validation.constraints.Size; 9 | 10 | @Entity 11 | public class Todo { 12 | 13 | @Id 14 | @GeneratedValue 15 | private int id; 16 | 17 | private String user; 18 | 19 | @Size(min=10, message="Enter at least 10 Characters...") 20 | private String desc; 21 | 22 | private Date targetDate; 23 | private boolean isDone; 24 | 25 | public Todo() { 26 | super(); 27 | } 28 | 29 | public Todo(int id, String user, String desc, Date targetDate, 30 | boolean isDone) { 31 | super(); 32 | this.id = id; 33 | this.user = user; 34 | this.desc = desc; 35 | this.targetDate = targetDate; 36 | this.isDone = isDone; 37 | } 38 | 39 | public int getId() { 40 | return id; 41 | } 42 | 43 | public void setId(int id) { 44 | this.id = id; 45 | } 46 | 47 | public String getUser() { 48 | return user; 49 | } 50 | 51 | public void setUser(String user) { 52 | this.user = user; 53 | } 54 | 55 | public String getDesc() { 56 | return desc; 57 | } 58 | 59 | public void setDesc(String desc) { 60 | this.desc = desc; 61 | } 62 | 63 | public Date getTargetDate() { 64 | return targetDate; 65 | } 66 | 67 | public void setTargetDate(Date targetDate) { 68 | this.targetDate = targetDate; 69 | } 70 | 71 | public boolean isDone() { 72 | return isDone; 73 | } 74 | 75 | public void setDone(boolean isDone) { 76 | this.isDone = isDone; 77 | } 78 | 79 | @Override 80 | public int hashCode() { 81 | final int prime = 31; 82 | int result = 1; 83 | result = prime * result + id; 84 | return result; 85 | } 86 | 87 | @Override 88 | public boolean equals(Object obj) { 89 | if (this == obj) { 90 | return true; 91 | } 92 | if (obj == null) { 93 | return false; 94 | } 95 | if (getClass() != obj.getClass()) { 96 | return false; 97 | } 98 | Todo other = (Todo) obj; 99 | if (id != other.id) { 100 | return false; 101 | } 102 | return true; 103 | } 104 | 105 | @Override 106 | public String toString() { 107 | return String.format( 108 | "Todo [id=%s, user=%s, desc=%s, targetDate=%s, isDone=%s]", id, 109 | user, desc, targetDate, isDone); 110 | } 111 | 112 | } -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/java/com/in28minutes/springboot/web/security/SecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.security; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 8 | 9 | @Configuration 10 | public class SecurityConfiguration extends WebSecurityConfigurerAdapter{ 11 | //Create User - in28Minutes/dummy 12 | @Autowired 13 | public void configureGlobalSecurity(AuthenticationManagerBuilder auth) 14 | throws Exception { 15 | auth.inMemoryAuthentication().withUser("in28minutes").password("{noop}dummy") 16 | .roles("USER", "ADMIN"); 17 | } 18 | 19 | @Override 20 | protected void configure(HttpSecurity http) throws Exception { 21 | http.authorizeRequests().antMatchers("/login", "/h2-console/**").permitAll() 22 | .antMatchers("/", "/*todo*/**").access("hasRole('USER')").and() 23 | .formLogin(); 24 | 25 | http.csrf().disable(); 26 | http.headers().frameOptions().disable(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/java/com/in28minutes/springboot/web/service/TodoRepository.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.service; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import com.in28minutes.springboot.web.model.Todo; 8 | 9 | public interface TodoRepository extends JpaRepository{ 10 | List findByUser(String user); 11 | 12 | //service.retrieveTodos(name) 13 | 14 | //service.deleteTodo(id); 15 | //service.retrieveTodo(id) 16 | //service.updateTodo(todo) 17 | //service.addTodo(getLoggedInUserName(model), todo.getDesc(), todo.getTargetDate(),false); 18 | } 19 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/java/com/in28minutes/springboot/web/service/TodoService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.service; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | 8 | import org.springframework.stereotype.Service; 9 | 10 | import com.in28minutes.springboot.web.model.Todo; 11 | 12 | @Service 13 | public class TodoService { 14 | private static List todos = new ArrayList(); 15 | private static int todoCount = 3; 16 | 17 | static { 18 | todos.add(new Todo(1, "in28minutes", "Learn Spring MVC", new Date(), 19 | false)); 20 | todos.add(new Todo(2, "in28minutes", "Learn Struts", new Date(), false)); 21 | todos.add(new Todo(3, "in28minutes", "Learn Hibernate", new Date(), 22 | false)); 23 | } 24 | 25 | public List retrieveTodos(String user) { 26 | List filteredTodos = new ArrayList(); 27 | for (Todo todo : todos) { 28 | if (todo.getUser().equalsIgnoreCase(user)) { 29 | filteredTodos.add(todo); 30 | } 31 | } 32 | return filteredTodos; 33 | } 34 | 35 | public Todo retrieveTodo(int id) { 36 | for (Todo todo : todos) { 37 | if (todo.getId()==id) { 38 | return todo; 39 | } 40 | } 41 | return null; 42 | } 43 | 44 | public void updateTodo(Todo todo){ 45 | todos.remove(todo); 46 | todos.add(todo); 47 | } 48 | 49 | public void addTodo(String name, String desc, Date targetDate, 50 | boolean isDone) { 51 | todos.add(new Todo(++todoCount, name, desc, targetDate, isDone)); 52 | } 53 | 54 | public void deleteTodo(int id) { 55 | Iterator iterator = todos.iterator(); 56 | while (iterator.hasNext()) { 57 | Todo todo = iterator.next(); 58 | if (todo.getId() == id) { 59 | iterator.remove(); 60 | } 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.mvc.view.prefix=/WEB-INF/jsp/ 2 | spring.mvc.view.suffix=.jsp 3 | logging.level.org.springframework.web=INFO 4 | 5 | spring.jpa.show-sql=true 6 | spring.h2.console.enabled=true 7 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | insert into TODO 2 | values(10001, 'Learn Spring Boot', false, sysdate(), 'in28minutes'); 3 | insert into TODO 4 | values(10002, 'Learn Angular JS', false, sysdate(), 'in28minutes'); 5 | insert into TODO 6 | values(10003, 'Learn to Dance', false, sysdate(), 'in28minutes'); 7 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/webapp/WEB-INF/jsp/common/footer.jspf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/webapp/WEB-INF/jsp/common/header.jspf: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 2 | <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> 3 | <%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> 4 | 5 | 6 | 7 | 8 | First Web Application 9 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/webapp/WEB-INF/jsp/common/navigation.jspf: -------------------------------------------------------------------------------- 1 | 2 | 16 | -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/webapp/WEB-INF/jsp/error.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf"%> 2 | <%@ include file="common/navigation.jspf"%> 3 |
4 | An exception occurred! Please contact Support! 5 |
6 | <%@ include file="common/footer.jspf"%> -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/webapp/WEB-INF/jsp/list-todos.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf" %> 2 | <%@ include file="common/navigation.jspf" %> 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 26 | 27 | 28 | 29 |
Your todos are
DescriptionTarget DateIs it Done?
${todo.desc}${todo.done}UpdateDelete
30 |
31 | Add a Todo 32 |
33 |
34 | <%@ include file="common/footer.jspf" %> -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/webapp/WEB-INF/jsp/todo.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf" %> 2 | <%@ include file="common/navigation.jspf" %> 3 |
4 | 5 | 6 |
7 | Description 8 | 10 | 11 |
12 | 13 |
14 | Target Date 15 | 17 | 18 |
19 | 20 | 21 |
22 |
23 | <%@ include file="common/footer.jspf" %> -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/main/webapp/WEB-INF/jsp/welcome.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf"%> 2 | <%@ include file="common/navigation.jspf"%> 3 |
4 | Welcome ${name}!! Click here to manage your 5 | todo's. 6 |
7 | <%@ include file="common/footer.jspf"%> -------------------------------------------------------------------------------- /Otherprojects/03-spring-boot-web-application-h2/src/test/java/com/in28minutes/springboot/web/SpringBootFirstWebApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web; 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 SpringBootFirstWebApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.in28minutes.springboot.web 8 | 04-spring-boot-web-application-mysql 9 | 0.0.1-SNAPSHOT 10 | war 11 | 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.1.0.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-data-jpa 36 | 37 | 38 | 39 | 40 | com.h2database 41 | h2 42 | test 43 | 44 | 45 | 46 | 47 | 48 | mysql 49 | mysql-connector-java 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-starter-security 55 | 56 | 57 | 58 | javax.servlet 59 | jstl 60 | 61 | 62 | 63 | org.webjars 64 | bootstrap 65 | 3.3.6 66 | 67 | 68 | 69 | org.webjars 70 | bootstrap-datepicker 71 | 1.0.1 72 | 73 | 74 | 75 | org.webjars 76 | jquery 77 | 1.9.1 78 | 79 | 80 | 81 | org.apache.tomcat.embed 82 | tomcat-embed-jasper 83 | provided 84 | 85 | 86 | 87 | 88 | org.springframework.boot 89 | spring-boot-starter-tomcat 90 | provided 91 | 92 | 93 | 94 | org.springframework.boot 95 | spring-boot-devtools 96 | runtime 97 | 98 | 99 | 100 | org.springframework.boot 101 | spring-boot-starter-test 102 | test 103 | 104 | 105 | 106 | 107 | 108 | 109 | org.springframework.boot 110 | spring-boot-maven-plugin 111 | 112 | 113 | 114 | 115 | 116 | 117 | spring-milestones 118 | Spring Milestones 119 | https://repo.spring.io/milestones 120 | 121 | 122 | 123 | 124 | 125 | spring-milestones 126 | Spring Milestones 127 | https://repo.spring.io/milestones 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/readme.md: -------------------------------------------------------------------------------- 1 | # Todo Web Application using Spring Boot and MySQL as Database 2 | 3 | Run com.in28minutes.springboot.web.SpringBootFirstWebApplication as a Java Application. 4 | 5 | Runs on default port of Spring Boot - 8080 6 | 7 | Application uses h2 database to run the tests. 8 | 9 | ## Can be run as a Jar or a WAR 10 | 11 | `mvn clean install` generate a war which can deployed to your favorite web server. 12 | 13 | We will deploy to Cloud as a WAR 14 | 15 | ## Web Application 16 | 17 | - http://localhost:8080/login with in28minutes/dummy as credentials 18 | - You can add, delete and update your todos 19 | - Spring Security is used to secure the application 20 | - `com.in28minutes.springboot.web.security.SecurityConfiguration` contains the in memory security credential configuration. 21 | 22 | ## My SQL 23 | 24 | Refer to the configuration in `application.properties` to configure and launch your mysql database 25 | 26 | ``` 27 | spring.datasource.url=jdbc:mysql://${RDS_HOSTNAME:localhost}:${RDS_PORT:3306}/${RDS_DB_NAME:todos} 28 | spring.datasource.username=${RDS_USERNAME:todos-user} 29 | spring.datasource.password=${RDS_PASSWORD:dummytodos} 30 | 31 | ``` 32 | 33 | ### Launching MySQL using Docker 34 | 35 | ``` 36 | docker run --detach --env MYSQL_ROOT_PASSWORD=dummypassword --env MYSQL_USER=todos-user --env MYSQL_PASSWORD=dummytodos --env MYSQL_DATABASE=todos --name mysql --publish 3306:3306 mysql:5.7 37 | ``` 38 | 39 | ### Create Todo Table for Production 40 | 41 | ``` 42 | create table hibernate_sequence (next_val bigint) engine=InnoDB 43 | insert into hibernate_sequence values ( 1 ) 44 | create table todo (id integer not null, description varchar(255), is_done bit not null, target_date datetime(6), user varchar(255), primary key (id)) engine=InnoDB 45 | 46 | ``` 47 | 48 | ### My SQL Shell Client 49 | 50 | Install on mac using `brew install caskroom/cask/mysql-shell`. 51 | 52 | 53 | ``` 54 | Rangas-MacBook-Air:aws-projects rangakaranam$ mysqlsh 55 | MySQL Shell 8.0.15 56 | Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. 57 | Oracle is a registered trademark of Oracle Corporation and/or its affiliates. 58 | Other names may be trademarks of their respective owners. 59 | 60 | Type '\help' or '\?' for help; '\quit' to exit. 61 | 62 | MySQL JS > \connect todos-user@localhost:3306 63 | Creating a session to 'todos-user@localhost:3306' 64 | Please provide the password for 'todos-user@localhost:3306': 65 | Save password for 'todos-user@localhost:3306'? [Y]es/[N]o/Ne[v]er (default No): v 66 | Fetching schema names for autocompletion... Press ^C to stop. 67 | Your MySQL connection id is 37 68 | Server version: 5.7.26 MySQL Community Server (GPL) 69 | No default schema selected; type \use to set one. 70 | 71 | MySQL localhost:3306 ssl JS > \sql 72 | Switching to SQL mode... Commands end with ; 73 | 74 | MySQL localhost:3306 ssl SQL > use todos 75 | Default schema set to `todos`. 76 | Fetching table and column names from `todos` for auto-completion... Press ^C to stop. 77 | 78 | MySQL localhost:3306 ssl todos SQL > select * from todo ; 79 | +----+--------------+---------+----------------------------+-------------+ 80 | | id | description | is_done | target_date | user | 81 | +----+--------------+---------+----------------------------+-------------+ 82 | | 1 | Default Desc | 0 | 2019-06-26 18:30:00.000000 | in28minutes | 83 | +----+--------------+---------+----------------------------+-------------+ 84 | 1 row in set (0.0032 sec) 85 | 86 | ``` -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/java/com/in28minutes/springboot/web/PropertyLogger.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web; 2 | 3 | import java.util.Arrays; 4 | import java.util.stream.StreamSupport; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.context.event.ContextRefreshedEvent; 9 | import org.springframework.context.event.EventListener; 10 | import org.springframework.core.env.AbstractEnvironment; 11 | import org.springframework.core.env.EnumerablePropertySource; 12 | import org.springframework.core.env.Environment; 13 | import org.springframework.core.env.MutablePropertySources; 14 | import org.springframework.stereotype.Component; 15 | 16 | //@Component 17 | public class PropertyLogger { 18 | 19 | private static final Logger LOGGER = LoggerFactory.getLogger(PropertyLogger.class); 20 | 21 | @EventListener 22 | public void handleContextRefresh(ContextRefreshedEvent event) { 23 | final Environment env = event.getApplicationContext().getEnvironment(); 24 | LOGGER.info("====== Environment and configuration ======"); 25 | LOGGER.info("Active profiles: {}", Arrays.toString(env.getActiveProfiles())); 26 | final MutablePropertySources sources = ((AbstractEnvironment) env).getPropertySources(); 27 | StreamSupport.stream(sources.spliterator(), false).filter(ps -> ps instanceof EnumerablePropertySource) 28 | .map(ps -> ((EnumerablePropertySource) ps).getPropertyNames()).flatMap(Arrays::stream).distinct() 29 | .filter(prop -> !(prop.contains("credentials") || prop.contains("password"))) 30 | .forEach(prop -> LOGGER.info("{}: {}", prop, env.getProperty(prop))); 31 | LOGGER.info("==========================================="); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/java/com/in28minutes/springboot/web/SpringBootFirstWebApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.boot.builder.SpringApplicationBuilder; 9 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 10 | import org.springframework.context.annotation.ComponentScan; 11 | import org.springframework.core.env.Environment; 12 | 13 | @SpringBootApplication 14 | @ComponentScan("com.in28minutes.springboot.web") 15 | public class SpringBootFirstWebApplication extends SpringBootServletInitializer { // AWS 16 | 17 | @Autowired 18 | private Environment env; 19 | 20 | @Override // AWS 21 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 22 | return application.sources(SpringBootFirstWebApplication.class); 23 | } 24 | 25 | public static void main(String[] args) { 26 | 27 | Map env = System.getenv(); 28 | 29 | env.forEach((k, v) -> System.out.println(k + ":" + v)); 30 | 31 | SpringApplication.run(SpringBootFirstWebApplication.class, args); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/java/com/in28minutes/springboot/web/controller/ErrorController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.servlet.ModelAndView; 9 | 10 | @Controller("error") 11 | public class ErrorController { 12 | 13 | @ExceptionHandler(Exception.class) 14 | public ModelAndView handleException 15 | (HttpServletRequest request, Exception ex){ 16 | ModelAndView mv = new ModelAndView(); 17 | 18 | mv.addObject("exception", ex.getLocalizedMessage()); 19 | mv.addObject("url", request.getRequestURL()); 20 | 21 | mv.setViewName("error"); 22 | return mv; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/java/com/in28minutes/springboot/web/controller/LogoutController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | import org.springframework.security.core.Authentication; 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | import org.springframework.security.core.userdetails.UserDetails; 9 | import org.springframework.security.web.authentication.logout.LogoutHandler; 10 | import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.ui.ModelMap; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RequestMethod; 15 | 16 | @Controller 17 | public class LogoutController { 18 | 19 | @RequestMapping(value = "/logout", method = RequestMethod.GET) 20 | public String logout(HttpServletRequest request, 21 | HttpServletResponse response) { 22 | 23 | Authentication authentication = SecurityContextHolder.getContext() 24 | .getAuthentication(); 25 | 26 | if (authentication != null) { 27 | new SecurityContextLogoutHandler().logout(request, response, 28 | authentication); 29 | } 30 | 31 | return "redirect:/"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/java/com/in28minutes/springboot/web/controller/TodoController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | import javax.validation.Valid; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.beans.propertyeditors.CustomDateEditor; 10 | import org.springframework.security.core.context.SecurityContextHolder; 11 | import org.springframework.security.core.userdetails.UserDetails; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.ui.ModelMap; 14 | import org.springframework.validation.BindingResult; 15 | import org.springframework.web.bind.WebDataBinder; 16 | import org.springframework.web.bind.annotation.InitBinder; 17 | import org.springframework.web.bind.annotation.RequestMapping; 18 | import org.springframework.web.bind.annotation.RequestMethod; 19 | import org.springframework.web.bind.annotation.RequestParam; 20 | 21 | import com.in28minutes.springboot.web.model.Todo; 22 | import com.in28minutes.springboot.web.service.TodoRepository; 23 | 24 | @Controller 25 | public class TodoController { 26 | 27 | @Autowired 28 | TodoRepository repository; 29 | 30 | @InitBinder 31 | public void initBinder(WebDataBinder binder) { 32 | // Date - dd/MM/yyyy 33 | SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); 34 | binder.registerCustomEditor(Date.class, new CustomDateEditor( 35 | dateFormat, false)); 36 | } 37 | 38 | @RequestMapping(value = "/list-todos", method = RequestMethod.GET) 39 | public String showTodos(ModelMap model) { 40 | String name = getLoggedInUserName(model); 41 | model.put("todos", repository.findByUser(name)); 42 | //model.put("todos", service.retrieveTodos(name)); 43 | return "list-todos"; 44 | } 45 | 46 | private String getLoggedInUserName(ModelMap model) { 47 | Object principal = SecurityContextHolder.getContext() 48 | .getAuthentication().getPrincipal(); 49 | 50 | if (principal instanceof UserDetails) { 51 | return ((UserDetails) principal).getUsername(); 52 | } 53 | 54 | return principal.toString(); 55 | } 56 | 57 | @RequestMapping(value = "/add-todo", method = RequestMethod.GET) 58 | public String showAddTodoPage(ModelMap model) { 59 | model.addAttribute("todo", new Todo(0, getLoggedInUserName(model), 60 | "Default Desc", new Date(), false)); 61 | return "todo"; 62 | } 63 | 64 | @RequestMapping(value = "/delete-todo", method = RequestMethod.GET) 65 | public String deleteTodo(@RequestParam int id) { 66 | 67 | //if(id==1) 68 | //throw new RuntimeException("Something went wrong"); 69 | repository.deleteById(id); 70 | //service.deleteTodo(id); 71 | return "redirect:/list-todos"; 72 | } 73 | 74 | @RequestMapping(value = "/update-todo", method = RequestMethod.GET) 75 | public String showUpdateTodoPage(@RequestParam int id, ModelMap model) { 76 | Todo todo = repository.findById(id).get(); 77 | //Todo todo = service.retrieveTodo(id); 78 | model.put("todo", todo); 79 | return "todo"; 80 | } 81 | 82 | @RequestMapping(value = "/update-todo", method = RequestMethod.POST) 83 | public String updateTodo(ModelMap model, @Valid Todo todo, 84 | BindingResult result) { 85 | 86 | if (result.hasErrors()) { 87 | return "todo"; 88 | } 89 | 90 | todo.setUser(getLoggedInUserName(model)); 91 | 92 | repository.save(todo); 93 | //service.updateTodo(todo); 94 | 95 | return "redirect:/list-todos"; 96 | } 97 | 98 | @RequestMapping(value = "/add-todo", method = RequestMethod.POST) 99 | public String addTodo(ModelMap model, @Valid Todo todo, BindingResult result) { 100 | 101 | if (result.hasErrors()) { 102 | return "todo"; 103 | } 104 | 105 | todo.setUser(getLoggedInUserName(model)); 106 | repository.save(todo); 107 | /*service.addTodo(getLoggedInUserName(model), todo.getDesc(), todo.getTargetDate(), 108 | false);*/ 109 | return "redirect:/list-todos"; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/java/com/in28minutes/springboot/web/controller/WelcomeController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.controller; 2 | 3 | import org.springframework.security.core.context.SecurityContextHolder; 4 | import org.springframework.security.core.userdetails.UserDetails; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.ModelMap; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | 10 | @Controller 11 | public class WelcomeController { 12 | 13 | @RequestMapping(value = "/", method = RequestMethod.GET) 14 | public String showWelcomePage(ModelMap model) { 15 | model.put("name", getLoggedinUserName()); 16 | return "welcome"; 17 | } 18 | 19 | private String getLoggedinUserName() { 20 | Object principal = SecurityContextHolder.getContext() 21 | .getAuthentication().getPrincipal(); 22 | 23 | if (principal instanceof UserDetails) { 24 | return ((UserDetails) principal).getUsername(); 25 | } 26 | 27 | return principal.toString(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/java/com/in28minutes/springboot/web/model/Todo.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.model; 2 | 3 | import java.util.Date; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.Id; 9 | import javax.validation.constraints.Size; 10 | 11 | @Entity 12 | public class Todo { 13 | 14 | @Id 15 | @GeneratedValue 16 | private int id; 17 | 18 | private String user; 19 | 20 | 21 | //AWS MYSQL 22 | @Size(min=10, message="Enter at least 10 Characters...") 23 | @Column(name="description") 24 | private String desc; 25 | 26 | private Date targetDate; 27 | private boolean isDone; 28 | 29 | public Todo() { 30 | super(); 31 | } 32 | 33 | public Todo(int id, String user, String desc, Date targetDate, 34 | boolean isDone) { 35 | super(); 36 | this.id = id; 37 | this.user = user; 38 | this.desc = desc; 39 | this.targetDate = targetDate; 40 | this.isDone = isDone; 41 | } 42 | 43 | public int getId() { 44 | return id; 45 | } 46 | 47 | public void setId(int id) { 48 | this.id = id; 49 | } 50 | 51 | public String getUser() { 52 | return user; 53 | } 54 | 55 | public void setUser(String user) { 56 | this.user = user; 57 | } 58 | 59 | public String getDesc() { 60 | return desc; 61 | } 62 | 63 | public void setDesc(String desc) { 64 | this.desc = desc; 65 | } 66 | 67 | public Date getTargetDate() { 68 | return targetDate; 69 | } 70 | 71 | public void setTargetDate(Date targetDate) { 72 | this.targetDate = targetDate; 73 | } 74 | 75 | public boolean isDone() { 76 | return isDone; 77 | } 78 | 79 | public void setDone(boolean isDone) { 80 | this.isDone = isDone; 81 | } 82 | 83 | @Override 84 | public int hashCode() { 85 | final int prime = 31; 86 | int result = 1; 87 | result = prime * result + id; 88 | return result; 89 | } 90 | 91 | @Override 92 | public boolean equals(Object obj) { 93 | if (this == obj) { 94 | return true; 95 | } 96 | if (obj == null) { 97 | return false; 98 | } 99 | if (getClass() != obj.getClass()) { 100 | return false; 101 | } 102 | Todo other = (Todo) obj; 103 | if (id != other.id) { 104 | return false; 105 | } 106 | return true; 107 | } 108 | 109 | @Override 110 | public String toString() { 111 | return String.format( 112 | "Todo [id=%s, user=%s, desc=%s, targetDate=%s, isDone=%s]", id, 113 | user, desc, targetDate, isDone); 114 | } 115 | 116 | } -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/java/com/in28minutes/springboot/web/security/SecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.security; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 8 | 9 | @Configuration 10 | public class SecurityConfiguration extends WebSecurityConfigurerAdapter{ 11 | //Create User - in28Minutes/dummy 12 | @Autowired 13 | public void configureGlobalSecurity(AuthenticationManagerBuilder auth) 14 | throws Exception { 15 | auth.inMemoryAuthentication().withUser("in28minutes").password("{noop}dummy") 16 | .roles("USER", "ADMIN"); 17 | } 18 | 19 | @Override 20 | protected void configure(HttpSecurity http) throws Exception { 21 | http.authorizeRequests().antMatchers("/login", "/h2-console/**").permitAll() 22 | .antMatchers("/", "/*todo*/**").access("hasRole('USER')").and() 23 | .formLogin(); 24 | 25 | http.csrf().disable(); 26 | http.headers().frameOptions().disable(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/java/com/in28minutes/springboot/web/service/TodoRepository.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.service; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import com.in28minutes.springboot.web.model.Todo; 8 | 9 | public interface TodoRepository extends JpaRepository{ 10 | List findByUser(String user); 11 | 12 | //service.retrieveTodos(name) 13 | 14 | //service.deleteTodo(id); 15 | //service.retrieveTodo(id) 16 | //service.updateTodo(todo) 17 | //service.addTodo(getLoggedInUserName(model), todo.getDesc(), todo.getTargetDate(),false); 18 | } 19 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/java/com/in28minutes/springboot/web/service/TodoService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web.service; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | 8 | import org.springframework.stereotype.Service; 9 | 10 | import com.in28minutes.springboot.web.model.Todo; 11 | 12 | @Service 13 | public class TodoService { 14 | private static List todos = new ArrayList(); 15 | private static int todoCount = 3; 16 | 17 | static { 18 | todos.add(new Todo(1, "in28minutes", "Learn Spring MVC", new Date(), 19 | false)); 20 | todos.add(new Todo(2, "in28minutes", "Learn Struts", new Date(), false)); 21 | todos.add(new Todo(3, "in28minutes", "Learn Hibernate", new Date(), 22 | false)); 23 | } 24 | 25 | public List retrieveTodos(String user) { 26 | List filteredTodos = new ArrayList(); 27 | for (Todo todo : todos) { 28 | if (todo.getUser().equalsIgnoreCase(user)) { 29 | filteredTodos.add(todo); 30 | } 31 | } 32 | return filteredTodos; 33 | } 34 | 35 | public Todo retrieveTodo(int id) { 36 | for (Todo todo : todos) { 37 | if (todo.getId()==id) { 38 | return todo; 39 | } 40 | } 41 | return null; 42 | } 43 | 44 | public void updateTodo(Todo todo){ 45 | todos.remove(todo); 46 | todos.add(todo); 47 | } 48 | 49 | public void addTodo(String name, String desc, Date targetDate, 50 | boolean isDone) { 51 | todos.add(new Todo(++todoCount, name, desc, targetDate, isDone)); 52 | } 53 | 54 | public void deleteTodo(int id) { 55 | Iterator iterator = todos.iterator(); 56 | while (iterator.hasNext()) { 57 | Todo todo = iterator.next(); 58 | if (todo.getId() == id) { 59 | iterator.remove(); 60 | } 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.mvc.view.prefix=/WEB-INF/jsp/ 2 | spring.mvc.view.suffix=.jsp 3 | logging.level.org.springframework.web=INFO 4 | 5 | spring.jpa.show-sql=true 6 | spring.h2.console.enabled=true 7 | 8 | #AWS 9 | spring.jpa.hibernate.ddl-auto=update 10 | spring.datasource.url=jdbc:mysql://${RDS_HOSTNAME:localhost}:${RDS_PORT:3306}/${RDS_DB_NAME:todos} 11 | spring.datasource.username=${RDS_USERNAME:todos-user} 12 | spring.datasource.password=${RDS_PASSWORD:dummytodos} 13 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/webapp/WEB-INF/jsp/common/footer.jspf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/webapp/WEB-INF/jsp/common/header.jspf: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 2 | <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> 3 | <%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> 4 | 5 | 6 | 7 | 8 | First Web Application 9 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/webapp/WEB-INF/jsp/common/navigation.jspf: -------------------------------------------------------------------------------- 1 | 2 | 16 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/webapp/WEB-INF/jsp/error.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf"%> 2 | <%@ include file="common/navigation.jspf"%> 3 |
4 | An exception occurred! Please contact Support! 5 |
6 | <%@ include file="common/footer.jspf"%> -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/webapp/WEB-INF/jsp/list-todos.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf" %> 2 | <%@ include file="common/navigation.jspf" %> 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 26 | 27 | 28 | 29 |
Your todos are
DescriptionTarget DateIs it Done?
${todo.desc}${todo.done}UpdateDelete
30 |
31 | Add a Todo 32 |
33 |
34 | <%@ include file="common/footer.jspf" %> -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/webapp/WEB-INF/jsp/todo.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf" %> 2 | <%@ include file="common/navigation.jspf" %> 3 |
4 | 5 | 6 |
7 | Description 8 | 10 | 11 |
12 | 13 |
14 | Target Date 15 | 17 | 18 |
19 | 20 | 21 |
22 |
23 | <%@ include file="common/footer.jspf" %> -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/main/webapp/WEB-INF/jsp/welcome.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="common/header.jspf"%> 2 | <%@ include file="common/navigation.jspf"%> 3 |
4 | Welcome ${name}!! Click here to manage your 5 | todo's. 6 |
7 | <%@ include file="common/footer.jspf"%> -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/test/java/com/in28minutes/springboot/web/SpringBootFirstWebApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.springboot.web; 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 SpringBootFirstWebApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Otherprojects/04-spring-boot-web-application-mysql/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | #AWS 2 | spring.jpa.hibernate.ddl-auto=create-drop 3 | spring.datasource.driver-class-name=org.h2.Driver 4 | spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1 5 | spring.datasource.username=sa 6 | spring.datasource.password=sa 7 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/build/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "main.css": "/static/css/main.8537e868.chunk.css", 3 | "main.js": "/static/js/main.2304f8a7.chunk.js", 4 | "main.js.map": "/static/js/main.2304f8a7.chunk.js.map", 5 | "runtime~main.js": "/static/js/runtime~main.c5541365.js", 6 | "runtime~main.js.map": "/static/js/runtime~main.c5541365.js.map", 7 | "static/js/2.3f64e426.chunk.js": "/static/js/2.3f64e426.chunk.js", 8 | "static/js/2.3f64e426.chunk.js.map": "/static/js/2.3f64e426.chunk.js.map", 9 | "index.html": "/index.html", 10 | "precache-manifest.329107c39cdcab0d36989b26995e59f8.js": "/precache-manifest.329107c39cdcab0d36989b26995e59f8.js", 11 | "service-worker.js": "/service-worker.js", 12 | "static/css/main.8537e868.chunk.css.map": "/static/css/main.8537e868.chunk.css.map" 13 | } -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/build/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/spring-boot-rest-api-playground/eec79b82d22c4a17529dc16bdc1092f3e8e1889e/Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/build/favicon.ico -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/build/index.html: -------------------------------------------------------------------------------- 1 | My Todo Application
-------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/build/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/build/precache-manifest.329107c39cdcab0d36989b26995e59f8.js: -------------------------------------------------------------------------------- 1 | self.__precacheManifest = [ 2 | { 3 | "revision": "fdfcfda2d9b1bf31db52", 4 | "url": "/static/js/runtime~main.c5541365.js" 5 | }, 6 | { 7 | "revision": "ad01e75089b5af171d3c", 8 | "url": "/static/js/main.2304f8a7.chunk.js" 9 | }, 10 | { 11 | "revision": "3be61595d9a1137a984f", 12 | "url": "/static/js/2.3f64e426.chunk.js" 13 | }, 14 | { 15 | "revision": "ad01e75089b5af171d3c", 16 | "url": "/static/css/main.8537e868.chunk.css" 17 | }, 18 | { 19 | "revision": "160732c51defb4fead56a9198b42e6dd", 20 | "url": "/index.html" 21 | } 22 | ]; -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/build/service-worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to your Workbox-powered service worker! 3 | * 4 | * You'll need to register this file in your web app and you should 5 | * disable HTTP caching for this file too. 6 | * See https://goo.gl/nhQhGp 7 | * 8 | * The rest of the code is auto-generated. Please don't update this file 9 | * directly; instead, make changes to your Workbox build configuration 10 | * and re-run your build process. 11 | * See https://goo.gl/2aRDsh 12 | */ 13 | 14 | importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.6.3/workbox-sw.js"); 15 | 16 | importScripts( 17 | "/precache-manifest.329107c39cdcab0d36989b26995e59f8.js" 18 | ); 19 | 20 | workbox.clientsClaim(); 21 | 22 | /** 23 | * The workboxSW.precacheAndRoute() method efficiently caches and responds to 24 | * requests for URLs in the manifest. 25 | * See https://goo.gl/S9QRab 26 | */ 27 | self.__precacheManifest = [].concat(self.__precacheManifest || []); 28 | workbox.precaching.suppressWarnings(); 29 | workbox.precaching.precacheAndRoute(self.__precacheManifest, {}); 30 | 31 | workbox.routing.registerNavigationRoute("/index.html", { 32 | 33 | blacklist: [/^\/_/,/\/[^\/]+\.[^\/]+$/], 34 | }); 35 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/build/static/css/main.8537e868.chunk.css: -------------------------------------------------------------------------------- 1 | @import url(https://unpkg.com/bootstrap@4.1.0/dist/css/bootstrap.min.css);body{margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}.footer{position:absolute;bottom:0;width:100%;height:40px;background-color:#222}.App{text-align:center}.App-logo{-webkit-animation:App-logo-spin 20s linear infinite;animation:App-logo-spin 20s linear infinite;height:40vmin;pointer-events:none}.App-header{background-color:#282c34;min-height:100vh;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;font-size:calc(10px + 2vmin);color:#fff}.App-link{color:#61dafb}@-webkit-keyframes App-logo-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes App-logo-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}} 2 | /*# sourceMappingURL=main.8537e868.chunk.css.map */ -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/build/static/css/main.8537e868.chunk.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["main.8537e868.chunk.css","/Ranga/001.Notes/00.CoursePreparations/Cloud-AWS-GCP-AZURE-PREPARATION/JUNE-2019/aws-projects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/index.css","/Ranga/001.Notes/00.CoursePreparations/Cloud-AWS-GCP-AZURE-PREPARATION/JUNE-2019/aws-projects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/App.css"],"names":[],"mappings":"AAAA,yEAAyE,CCAzE,KACE,QAAA,CACA,SAAA,CACA,mIDGY,CCAZ,kCAAA,CACA,iCDEF,CCCA,KACE,uEDGF,CEdA,QACE,iBAAA,CACA,QAAA,CACA,UAAA,CACA,WAAA,CACA,qBFiBF,CEdA,KACE,iBFiBF,CEdA,UACE,mDAAA,CAAA,2CAAA,CACA,aAAA,CACA,mBFkBF,CEfA,YACE,wBAAA,CACA,gBAAA,CACA,oBAAA,CAAA,YAAA,CACA,6BAAA,CAAA,qBAAA,CACA,0BAAA,CAAA,kBAAA,CACA,8BAAA,CAAA,sBAAA,CACA,4BAAA,CACA,UFsBF,CEnBA,UACE,aFsBF,CEnBA,iCACE,GACE,8BAAA,CAAA,sBFuBF,CErBA,GACE,+BAAA,CAAA,uBFwBF,CACF,CE9BA,yBACE,GACE,8BAAA,CAAA,sBFkCF,CEhCA,GACE,+BAAA,CAAA,uBFmCF,CACF","file":"main.8537e868.chunk.css","sourcesContent":["@import url(https://unpkg.com/bootstrap@4.1.0/dist/css/bootstrap.min.css);\nbody {\n margin: 0;\n padding: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\",\n \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\",\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n monospace;\n}\n\n.footer {\n position: absolute;\n bottom: 0;\n width: 100%;\n height: 40px;\n background-color: #222222;\n}\n\n.App {\n text-align: center;\n}\n\n.App-logo {\n -webkit-animation: App-logo-spin infinite 20s linear;\n animation: App-logo-spin infinite 20s linear;\n height: 40vmin;\n pointer-events: none;\n}\n\n.App-header {\n background-color: #282c34;\n min-height: 100vh;\n display: -webkit-flex;\n display: flex;\n -webkit-flex-direction: column;\n flex-direction: column;\n -webkit-align-items: center;\n align-items: center;\n -webkit-justify-content: center;\n justify-content: center;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App-link {\n color: #61dafb;\n}\n\n@-webkit-keyframes App-logo-spin {\n from {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n@keyframes App-logo-spin {\n from {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n\n","body {\n margin: 0;\n padding: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\",\n \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\",\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n monospace;\n}\n",".footer {\n position: absolute;\n bottom: 0;\n width: 100%;\n height: 40px;\n background-color: #222222;\n}\n\n.App {\n text-align: center;\n}\n\n.App-logo {\n animation: App-logo-spin infinite 20s linear;\n height: 40vmin;\n pointer-events: none;\n}\n\n.App-header {\n background-color: #282c34;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App-link {\n color: #61dafb;\n}\n\n@keyframes App-logo-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n"]} -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/build/static/js/runtime~main.c5541365.js: -------------------------------------------------------------------------------- 1 | !function(e){function r(r){for(var n,f,i=r[0],l=r[1],a=r[2],c=0,s=[];c0.2%", 25 | "not dead", 26 | "not ie <= 11", 27 | "not op_mini all" 28 | ] 29 | } -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/spring-boot-rest-api-playground/eec79b82d22c4a17529dc16bdc1092f3e8e1889e/Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/public/favicon.ico -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 15 | 16 | 25 | My Todo Application 26 | 27 | 28 | 29 |
30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/App.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | position: absolute; 3 | bottom: 0; 4 | width: 100%; 5 | height: 40px; 6 | background-color: #222222; 7 | } 8 | 9 | .App { 10 | text-align: center; 11 | } 12 | 13 | .App-logo { 14 | animation: App-logo-spin infinite 20s linear; 15 | height: 40vmin; 16 | pointer-events: none; 17 | } 18 | 19 | .App-header { 20 | background-color: #282c34; 21 | min-height: 100vh; 22 | display: flex; 23 | flex-direction: column; 24 | align-items: center; 25 | justify-content: center; 26 | font-size: calc(10px + 2vmin); 27 | color: white; 28 | } 29 | 30 | .App-link { 31 | color: #61dafb; 32 | } 33 | 34 | @keyframes App-logo-spin { 35 | from { 36 | transform: rotate(0deg); 37 | } 38 | to { 39 | transform: rotate(360deg); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | //import FirstComponent from './components/learning-examples/FirstComponent' 3 | //import SecondComponent from './components/learning-examples/SecondComponent' 4 | //import ThirdComponent from './components/learning-examples/ThirdComponent' 5 | //import Counter from './components/counter/Counter' 6 | import TodoApp from './components/todo/TodoApp' 7 | import './App.css'; 8 | import './bootstrap.css'; 9 | 10 | class App extends Component { 11 | render() { 12 | return ( 13 |
14 | {/**/} 15 | 16 |
17 | ); 18 | } 19 | } 20 | 21 | // class LearningComponents extends Component { 22 | // render() { 23 | // return ( 24 | //
25 | // My Hello World 26 | // 27 | // 28 | // 29 | //
30 | // ); 31 | // } 32 | // } 33 | 34 | export default App; -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/Constants.js: -------------------------------------------------------------------------------- 1 | /* For Best Practices https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables*/ 2 | //export const API_URL = 'http://localhost:5000' 3 | export const API_URL = 'http://restfulwebservices-env.uhpev7xzpb.us-east-1.elasticbeanstalk.com' 4 | export const JPA_API_URL = `${API_URL}/jpa` -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/api/todo/HelloWorldService.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { API_URL } from '../../Constants' 3 | 4 | class HelloWorldService { 5 | 6 | executeHelloWorldService() { 7 | //console.log('executed service') 8 | return axios.get(`${API_URL}/hello-world`); 9 | } 10 | 11 | executeHelloWorldBeanService() { 12 | //console.log('executed service') 13 | return axios.get(`${API_URL}/hello-world-bean`); 14 | } 15 | 16 | executeHelloWorldPathVariableService(name) { 17 | //console.log('executed service') 18 | // let username = 'in28minutes' 19 | // let password = 'dummy' 20 | 21 | // let basicAuthHeader = 'Basic ' + window.btoa(username + ":" + password) 22 | 23 | return axios.get(`${API_URL}/hello-world/path-variable/${name}` 24 | // , 25 | // { 26 | // headers : { 27 | // authorization: basicAuthHeader 28 | // } 29 | // } 30 | ); 31 | } 32 | 33 | } 34 | 35 | export default new HelloWorldService() -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/api/todo/TodoDataService.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { JPA_API_URL } from '../../Constants' 3 | 4 | class TodoDataService { 5 | 6 | retrieveAllTodos(name) { 7 | //console.log('executed service') 8 | return axios.get(`${JPA_API_URL}/users/${name}/todos`); 9 | } 10 | 11 | retrieveTodo(name, id) { 12 | //console.log('executed service') 13 | return axios.get(`${JPA_API_URL}/users/${name}/todos/${id}`); 14 | } 15 | 16 | deleteTodo(name, id) { 17 | //console.log('executed service') 18 | return axios.delete(`${JPA_API_URL}/users/${name}/todos/${id}`); 19 | } 20 | 21 | updateTodo(name, id, todo) { 22 | //console.log('executed service') 23 | return axios.put(`${JPA_API_URL}/users/${name}/todos/${id}`, todo); 24 | } 25 | 26 | createTodo(name, todo) { 27 | //console.log('executed service') 28 | return axios.post(`${JPA_API_URL}/users/${name}/todos/`, todo); 29 | } 30 | 31 | } 32 | 33 | export default new TodoDataService() -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/bootstrap.css: -------------------------------------------------------------------------------- 1 | @import url(https://unpkg.com/bootstrap@4.1.0/dist/css/bootstrap.min.css) -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/counter/Counter.css: -------------------------------------------------------------------------------- 1 | /* 2 | button { 3 | background-color: green; 4 | font-size : 16px; 5 | padding : 15px 30px; 6 | color : white; 7 | width : 100px; 8 | } 9 | 10 | .count { 11 | font-size : 50px; 12 | padding : 15px 30px; 13 | } 14 | 15 | .reset { 16 | background-color: red; 17 | width : 200px; 18 | } 19 | 20 | body { 21 | padding : 15px 30px; 22 | } 23 | */ -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/counter/Counter.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import PropTypes from 'prop-types' 3 | import './Counter.css' 4 | 5 | class Counter extends Component { 6 | 7 | constructor() { 8 | 9 | super(); //Error 1 10 | 11 | this.state = { 12 | counter: 0 13 | } 14 | 15 | this.increment = this.increment.bind(this); 16 | this.decrement = this.decrement.bind(this); 17 | this.reset = this.reset.bind(this); 18 | } 19 | 20 | render() { 21 | return ( 22 |
23 | 24 | 25 | 26 | {this.state.counter} 27 |
28 |
29 | ); 30 | } 31 | 32 | reset() { 33 | this.setState({ counter: 0 }); 34 | } 35 | 36 | increment(by) { 37 | //console.log(`increment from child - ${by}`) 38 | this.setState( 39 | (prevState) => { 40 | return { counter: prevState.counter + by } 41 | } 42 | ); 43 | } 44 | 45 | decrement(by) { 46 | //console.log(`increment from child - ${by}`) 47 | this.setState( 48 | (prevState) => { 49 | return { counter: prevState.counter - by } 50 | } 51 | ); 52 | } 53 | 54 | } 55 | 56 | class CounterButton extends Component { 57 | //Define the initial state in a constructor 58 | //state => counter 0 59 | //constructor() { 60 | // super(); //Error 1 61 | 62 | // this.state = { 63 | // counter : 0 64 | // } 65 | 66 | // this.increment = this.increment.bind(this); 67 | // this.decrement = this.decrement.bind(this); 68 | //} 69 | 70 | render() { 71 | //render = () => { 72 | //const style = {fontSize : "50px", padding : "15px 30px"}; 73 | return ( 74 |
75 | 76 | 77 | {/*{this.state.counter}*/} 79 |
80 | ) 81 | } 82 | 83 | // increment() { //Update state - counter++ 84 | // //console.log('increment'); 85 | // //this.state.counter++; //Bad Practice 86 | // this.setState({ 87 | // counter: this.state.counter + this.props.by 88 | // }); 89 | 90 | // this.props.incrementMethod(this.props.by); 91 | // } 92 | 93 | // decrement () { 94 | // this.setState({ 95 | // counter: this.state.counter - this.props.by 96 | // }); 97 | 98 | // this.props.decrementMethod(this.props.by); 99 | // } 100 | } 101 | 102 | CounterButton.defaultProps = { 103 | by: 1 104 | } 105 | 106 | CounterButton.propTypes = { 107 | by: PropTypes.number 108 | } 109 | 110 | export default Counter -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/learning-examples/FirstComponent.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | //Class Component 4 | class FirstComponent extends Component { 5 | render() { 6 | return ( 7 |
8 | FirstComponent 9 |
10 | ) 11 | } 12 | } 13 | 14 | export default FirstComponent -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/learning-examples/SecondComponent.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | class SecondComponent extends Component { 4 | render() { 5 | return ( 6 |
7 | Second Component 8 |
9 | ) 10 | } 11 | } 12 | 13 | export default SecondComponent -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/learning-examples/ThirdComponent.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | function ThirdComponent() { 4 | return ( 5 |
6 | Third Component 7 |
8 | ) 9 | } 10 | 11 | export default ThirdComponent -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/todo/AuthenticatedRoute.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Route, Redirect } from 'react-router-dom' 3 | import AuthenticationService from './AuthenticationService.js' 4 | 5 | class AuthenticatedRoute extends Component { 6 | render() { 7 | if (AuthenticationService.isUserLoggedIn()) { 8 | return 9 | } else { 10 | return 11 | } 12 | 13 | } 14 | } 15 | 16 | export default AuthenticatedRoute -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/todo/AuthenticationService.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { API_URL } from '../../Constants' 3 | 4 | export const USER_NAME_SESSION_ATTRIBUTE_NAME = 'authenticatedUser' 5 | 6 | class AuthenticationService { 7 | 8 | executeBasicAuthenticationService(username, password) { 9 | return axios.get(`${API_URL}/basicauth`, 10 | { headers: { authorization: this.createBasicAuthToken(username, password) } }) 11 | } 12 | 13 | executeJwtAuthenticationService(username, password) { 14 | return axios.post(`${API_URL}/authenticate`, { 15 | username, 16 | password 17 | }) 18 | } 19 | 20 | createBasicAuthToken(username, password) { 21 | return 'Basic ' + window.btoa(username + ":" + password) 22 | } 23 | 24 | registerSuccessfulLogin(username, password) { 25 | //let basicAuthHeader = 'Basic ' + window.btoa(username + ":" + password) 26 | //console.log('registerSuccessfulLogin') 27 | sessionStorage.setItem(USER_NAME_SESSION_ATTRIBUTE_NAME, username) 28 | this.setupAxiosInterceptors(this.createBasicAuthToken(username, password)) 29 | } 30 | 31 | registerSuccessfulLoginForJwt(username, token) { 32 | sessionStorage.setItem(USER_NAME_SESSION_ATTRIBUTE_NAME, username) 33 | this.setupAxiosInterceptors(this.createJWTToken(token)) 34 | } 35 | 36 | createJWTToken(token) { 37 | return 'Bearer ' + token 38 | } 39 | 40 | 41 | logout() { 42 | sessionStorage.removeItem(USER_NAME_SESSION_ATTRIBUTE_NAME); 43 | } 44 | 45 | isUserLoggedIn() { 46 | let user = sessionStorage.getItem(USER_NAME_SESSION_ATTRIBUTE_NAME) 47 | if (user === null) return false 48 | return true 49 | } 50 | 51 | getLoggedInUserName() { 52 | let user = sessionStorage.getItem(USER_NAME_SESSION_ATTRIBUTE_NAME) 53 | if (user === null) return '' 54 | return user 55 | } 56 | 57 | setupAxiosInterceptors(token) { 58 | 59 | axios.interceptors.request.use( 60 | (config) => { 61 | if (this.isUserLoggedIn()) { 62 | config.headers.authorization = token 63 | } 64 | return config 65 | } 66 | ) 67 | } 68 | } 69 | 70 | export default new AuthenticationService() -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/todo/ErrorComponent.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | function ErrorComponent() { 4 | return
An Error Occurred. I don't know what to do! Contact support at abcd-efgh-ijkl
5 | } 6 | 7 | export default ErrorComponent -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/todo/FooterComponent.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | class FooterComponent extends Component { 4 | render() { 5 | return ( 6 |
7 | All Rights Reserved 2018 @in28minutes 8 |
9 | ) 10 | } 11 | } 12 | 13 | export default FooterComponent -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/todo/HeaderComponent.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Link } from 'react-router-dom' 3 | import AuthenticationService from './AuthenticationService.js' 4 | 5 | 6 | class HeaderComponent extends Component { 7 | render() { 8 | const isUserLoggedIn = AuthenticationService.isUserLoggedIn(); 9 | //console.log(isUserLoggedIn); 10 | 11 | return ( 12 |
13 | 24 |
25 | ) 26 | } 27 | } 28 | 29 | export default HeaderComponent -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/todo/LogoutComponent.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | class LogoutComponent extends Component { 4 | render() { 5 | return ( 6 | <> 7 |

You are logged out

8 |
9 | Thank You for Using Our Application. 10 |
11 | 12 | ) 13 | } 14 | } 15 | 16 | export default LogoutComponent -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/todo/TodoApp.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react' 2 | import {BrowserRouter as Router, Route, Switch} from 'react-router-dom' 3 | import AuthenticatedRoute from './AuthenticatedRoute.jsx' 4 | import LoginComponent from './LoginComponent.jsx' 5 | import ListTodosComponent from './ListTodosComponent.jsx' 6 | import ErrorComponent from './ErrorComponent.jsx' 7 | import HeaderComponent from './HeaderComponent.jsx' 8 | import FooterComponent from './FooterComponent.jsx' 9 | import LogoutComponent from './LogoutComponent.jsx' 10 | import WelcomeComponent from './WelcomeComponent.jsx' 11 | import TodoComponent from './TodoComponent.jsx' 12 | 13 | class TodoApp extends Component { 14 | render() { 15 | return ( 16 |
17 | 18 | <> 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | {/* 34 | */} 35 |
36 | ) 37 | } 38 | } 39 | 40 | export default TodoApp -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/components/todo/WelcomeComponent.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Link } from 'react-router-dom' 3 | import HelloWorldService from '../../api/todo/HelloWorldService.js' 4 | 5 | class WelcomeComponent extends Component { 6 | 7 | constructor(props) { 8 | super(props) 9 | this.retrieveWelcomeMessage = this.retrieveWelcomeMessage.bind(this) 10 | this.state = { 11 | welcomeMessage: '' 12 | } 13 | this.handleSuccessfulResponse = this.handleSuccessfulResponse.bind(this) 14 | this.handleError = this.handleError.bind(this) 15 | } 16 | 17 | render() { 18 | return ( 19 | <> 20 |

Welcome!

21 |
22 | Welcome {this.props.match.params.name}. 23 | You can manage your todos here. 24 |
25 |
26 | Click here to get a customized welcome message. 27 | 29 |
30 |
31 | {this.state.welcomeMessage} 32 |
33 | 34 | 35 | ) 36 | } 37 | 38 | retrieveWelcomeMessage() { 39 | // HelloWorldService.executeHelloWorldService() 40 | // .then( response => this.handleSuccessfulResponse(response) ) 41 | 42 | // HelloWorldService.executeHelloWorldBeanService() 43 | // .then( response => this.handleSuccessfulResponse(response) ) 44 | 45 | HelloWorldService.executeHelloWorldPathVariableService(this.props.match.params.name) 46 | .then(response => this.handleSuccessfulResponse(response)) 47 | .catch(error => this.handleError(error)) 48 | } 49 | 50 | handleSuccessfulResponse(response) { 51 | console.log(response) 52 | this.setState({ welcomeMessage: response.data.message }) 53 | } 54 | 55 | handleError(error) { 56 | 57 | console.log(error.response) 58 | 59 | let errorMessage = ''; 60 | 61 | if (error.message) 62 | errorMessage += error.message 63 | 64 | if (error.response && error.response.data) { 65 | errorMessage += error.response.data.message 66 | } 67 | 68 | this.setState({ welcomeMessage: errorMessage }) 69 | } 70 | 71 | } 72 | 73 | 74 | export default WelcomeComponent -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 5 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: https://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/frontend/todo-app/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/react_00_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/spring-boot-rest-api-playground/eec79b82d22c4a17529dc16bdc1092f3e8e1889e/Otherprojects/05-spring-boot-react-full-stack-h2/react_00_architecture.png -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.in28minutes.rest.webservices 7 | 05-restful-web-services-full-stack-bankend 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | restful-web-services 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.1.0.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-data-jpa 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-web 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-security 42 | 43 | 44 | 45 | io.jsonwebtoken 46 | jjwt 47 | 0.9.1 48 | 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-devtools 54 | runtime 55 | 56 | 57 | 58 | com.h2database 59 | h2 60 | runtime 61 | 62 | 63 | 64 | org.springframework.boot 65 | spring-boot-starter-test 66 | test 67 | 68 | 69 | 70 | 71 | 72 | 73 | org.springframework.boot 74 | spring-boot-maven-plugin 75 | 76 | 77 | 78 | 79 | 80 | 81 | spring-snapshots 82 | Spring Snapshots 83 | https://repo.spring.io/snapshot 84 | 85 | true 86 | 87 | 88 | 89 | spring-milestones 90 | Spring Milestones 91 | https://repo.spring.io/milestone 92 | 93 | false 94 | 95 | 96 | 97 | 98 | 99 | 100 | spring-snapshots 101 | Spring Snapshots 102 | https://repo.spring.io/snapshot 103 | 104 | true 105 | 106 | 107 | 108 | spring-milestones 109 | Spring Milestones 110 | https://repo.spring.io/milestone 111 | 112 | false 113 | 114 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/in28minutes/spring-boot-rest-api-playground/eec79b82d22c4a17529dc16bdc1092f3e8e1889e/Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/readme.md -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/basic/auth/AuthenticationBean.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.basic.auth; 2 | public class AuthenticationBean { 3 | 4 | private String message; 5 | 6 | public AuthenticationBean(String message) { 7 | this.message = message; 8 | } 9 | 10 | public String getMessage() { 11 | return message; 12 | } 13 | 14 | public void setMessage(String message) { 15 | this.message = message; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return String.format("HelloWorldBean [message=%s]", message); 21 | } 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/basic/auth/BasicAuthenticationController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.basic.auth; 2 | import org.springframework.web.bind.annotation.GetMapping; 3 | import org.springframework.web.bind.annotation.RestController; 4 | 5 | //Controller 6 | //@CrossOrigin(origins="http://localhost:4200")Replace with global config 7 | @RestController 8 | public class BasicAuthenticationController { 9 | 10 | @GetMapping(path = "/basicauth") 11 | public AuthenticationBean helloWorldBean() { 12 | //throw new RuntimeException("Some Error has Happened! Contact Support at ***-***"); 13 | return new AuthenticationBean("You are authenticated"); 14 | } 15 | } -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/basic/auth/SpringSecurityConfigurationBasicAuth.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.basic.auth; 2 | import org.springframework.context.annotation.Configuration; 3 | import org.springframework.http.HttpMethod; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 6 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 7 | 8 | @Configuration 9 | @EnableWebSecurity 10 | public class SpringSecurityConfigurationBasicAuth extends WebSecurityConfigurerAdapter{ 11 | 12 | @Override 13 | protected void configure(HttpSecurity http) throws Exception { 14 | http 15 | .csrf().disable() 16 | .authorizeRequests() 17 | .antMatchers(HttpMethod.OPTIONS,"/**").permitAll() 18 | .anyRequest().authenticated() 19 | .and() 20 | //.formLogin().and() 21 | .httpBasic(); 22 | } 23 | } -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | @SpringBootApplication 10 | public class RestfulWebServicesApplication { 11 | 12 | // AWS 13 | @Bean 14 | public WebMvcConfigurer corsConfigurer() { 15 | return new WebMvcConfigurer() { 16 | @Override 17 | public void addCorsMappings(CorsRegistry registry) { 18 | registry.addMapping("/**").allowedMethods("*").allowedOrigins("*"); 19 | } 20 | }; 21 | } 22 | 23 | public static void main(String[] args) { 24 | SpringApplication.run(RestfulWebServicesApplication.class, args); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/helloworld/HelloWorldBean.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.helloworld; 2 | 3 | public class HelloWorldBean { 4 | 5 | private String message; 6 | 7 | public HelloWorldBean(String message) { 8 | this.message = message; 9 | } 10 | 11 | public String getMessage() { 12 | return message; 13 | } 14 | 15 | public void setMessage(String message) { 16 | this.message = message; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return String.format("HelloWorldBean [message=%s]", message); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/helloworld/HelloWorldController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.helloworld; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.PathVariable; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | //Controller 8 | @RestController 9 | //@CrossOrigin(origins="http://localhost:4200")Replace with global config 10 | // 11 | public class HelloWorldController { 12 | 13 | @GetMapping(path = "/hello-world") 14 | public String helloWorld() { 15 | return "Hello World"; 16 | } 17 | 18 | @GetMapping(path = "/hello-world-bean") 19 | public HelloWorldBean helloWorldBean() { 20 | return new HelloWorldBean("Hello World"); 21 | } 22 | 23 | ///hello-world/path-variable/in28minutes 24 | @GetMapping(path = "/hello-world/path-variable/{name}") 25 | public HelloWorldBean helloWorldPathVariable(@PathVariable String name) { 26 | //throw new RuntimeException("Something went wrong"); 27 | return new HelloWorldBean(String.format("Hello World, %s", name)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/jwt/JwtInMemoryUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.jwt; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Optional; 6 | 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 | 11 | 12 | //This is not used! 13 | //@Service 14 | public class JwtInMemoryUserDetailsService implements UserDetailsService { 15 | 16 | static List inMemoryUserList = new ArrayList<>(); 17 | 18 | static { 19 | inMemoryUserList.add(new JwtUserDetails(1L, "in28minutes", 20 | "$2a$10$3zHzb.Npv1hfZbLEU5qsdOju/tk2je6W6PnNnY.c1ujWPcZh4PL6e", "ROLE_USER_2")); 21 | } 22 | 23 | @Override 24 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 25 | Optional findFirst = inMemoryUserList.stream() 26 | .filter(user -> user.getUsername().equals(username)).findFirst(); 27 | 28 | if (!findFirst.isPresent()) { 29 | throw new UsernameNotFoundException(String.format("USER_NOT_FOUND '%s'.", username)); 30 | } 31 | 32 | return findFirst.get(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/jwt/JwtTokenAuthorizationOncePerRequestFilter.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.jwt; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.FilterChain; 6 | import javax.servlet.ServletException; 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.beans.factory.annotation.Value; 14 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 15 | import org.springframework.security.core.context.SecurityContextHolder; 16 | import org.springframework.security.core.userdetails.UserDetails; 17 | import org.springframework.security.core.userdetails.UserDetailsService; 18 | import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; 19 | import org.springframework.stereotype.Component; 20 | import org.springframework.web.filter.OncePerRequestFilter; 21 | 22 | import io.jsonwebtoken.ExpiredJwtException; 23 | 24 | @Component 25 | public class JwtTokenAuthorizationOncePerRequestFilter extends OncePerRequestFilter { 26 | 27 | private final Logger logger = LoggerFactory.getLogger(this.getClass()); 28 | 29 | @Autowired 30 | private UserDetailsService jwtInMemoryUserDetailsService; 31 | 32 | @Autowired 33 | private JwtTokenUtil jwtTokenUtil; 34 | 35 | @Value("${jwt.http.request.header}") 36 | private String tokenHeader; 37 | 38 | @Override 39 | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { 40 | logger.debug("Authentication Request For '{}'", request.getRequestURL()); 41 | 42 | final String requestTokenHeader = request.getHeader(this.tokenHeader); 43 | 44 | String username = null; 45 | String jwtToken = null; 46 | if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) { 47 | jwtToken = requestTokenHeader.substring(7); 48 | try { 49 | username = jwtTokenUtil.getUsernameFromToken(jwtToken); 50 | } catch (IllegalArgumentException e) { 51 | logger.error("JWT_TOKEN_UNABLE_TO_GET_USERNAME", e); 52 | } catch (ExpiredJwtException e) { 53 | logger.warn("JWT_TOKEN_EXPIRED", e); 54 | } 55 | } else { 56 | logger.warn("JWT_TOKEN_DOES_NOT_START_WITH_BEARER_STRING"); 57 | } 58 | 59 | logger.debug("JWT_TOKEN_USERNAME_VALUE '{}'", username); 60 | if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { 61 | 62 | UserDetails userDetails = this.jwtInMemoryUserDetailsService.loadUserByUsername(username); 63 | 64 | if (jwtTokenUtil.validateToken(jwtToken, userDetails)) { 65 | UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); 66 | usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); 67 | SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); 68 | } 69 | } 70 | 71 | chain.doFilter(request, response); 72 | } 73 | } 74 | 75 | 76 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/jwt/JwtTokenUtil.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.jwt; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.function.Function; 8 | 9 | import org.springframework.beans.factory.annotation.Value; 10 | import org.springframework.security.core.userdetails.UserDetails; 11 | import org.springframework.stereotype.Component; 12 | 13 | import io.jsonwebtoken.Claims; 14 | import io.jsonwebtoken.Clock; 15 | import io.jsonwebtoken.Jwts; 16 | import io.jsonwebtoken.SignatureAlgorithm; 17 | import io.jsonwebtoken.impl.DefaultClock; 18 | 19 | @Component 20 | public class JwtTokenUtil implements Serializable { 21 | 22 | static final String CLAIM_KEY_USERNAME = "sub"; 23 | static final String CLAIM_KEY_CREATED = "iat"; 24 | private static final long serialVersionUID = -3301605591108950415L; 25 | private Clock clock = DefaultClock.INSTANCE; 26 | 27 | @Value("${jwt.signing.key.secret}") 28 | private String secret; 29 | 30 | @Value("${jwt.token.expiration.in.seconds}") 31 | private Long expiration; 32 | 33 | public String getUsernameFromToken(String token) { 34 | return getClaimFromToken(token, Claims::getSubject); 35 | } 36 | 37 | public Date getIssuedAtDateFromToken(String token) { 38 | return getClaimFromToken(token, Claims::getIssuedAt); 39 | } 40 | 41 | public Date getExpirationDateFromToken(String token) { 42 | return getClaimFromToken(token, Claims::getExpiration); 43 | } 44 | 45 | public T getClaimFromToken(String token, Function claimsResolver) { 46 | final Claims claims = getAllClaimsFromToken(token); 47 | return claimsResolver.apply(claims); 48 | } 49 | 50 | private Claims getAllClaimsFromToken(String token) { 51 | return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); 52 | } 53 | 54 | private Boolean isTokenExpired(String token) { 55 | final Date expiration = getExpirationDateFromToken(token); 56 | return expiration.before(clock.now()); 57 | } 58 | 59 | private Boolean ignoreTokenExpiration(String token) { 60 | // here you specify tokens, for that the expiration is ignored 61 | return false; 62 | } 63 | 64 | public String generateToken(UserDetails userDetails) { 65 | Map claims = new HashMap<>(); 66 | return doGenerateToken(claims, userDetails.getUsername()); 67 | } 68 | 69 | private String doGenerateToken(Map claims, String subject) { 70 | final Date createdDate = clock.now(); 71 | final Date expirationDate = calculateExpirationDate(createdDate); 72 | 73 | return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(createdDate) 74 | .setExpiration(expirationDate).signWith(SignatureAlgorithm.HS512, secret).compact(); 75 | } 76 | 77 | public Boolean canTokenBeRefreshed(String token) { 78 | return (!isTokenExpired(token) || ignoreTokenExpiration(token)); 79 | } 80 | 81 | public String refreshToken(String token) { 82 | final Date createdDate = clock.now(); 83 | final Date expirationDate = calculateExpirationDate(createdDate); 84 | 85 | final Claims claims = getAllClaimsFromToken(token); 86 | claims.setIssuedAt(createdDate); 87 | claims.setExpiration(expirationDate); 88 | 89 | return Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact(); 90 | } 91 | 92 | public Boolean validateToken(String token, UserDetails userDetails) { 93 | JwtUserDetails user = (JwtUserDetails) userDetails; 94 | final String username = getUsernameFromToken(token); 95 | return (username.equals(user.getUsername()) && !isTokenExpired(token)); 96 | } 97 | 98 | private Date calculateExpirationDate(Date createdDate) { 99 | return new Date(createdDate.getTime() + expiration * 1000); 100 | } 101 | } 102 | 103 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/jwt/JwtUnAuthorizedResponseAuthenticationEntryPoint.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.jwt; 2 | 3 | import java.io.IOException; 4 | import java.io.Serializable; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | import org.springframework.security.core.AuthenticationException; 10 | import org.springframework.security.web.AuthenticationEntryPoint; 11 | import org.springframework.stereotype.Component; 12 | 13 | @Component 14 | public class JwtUnAuthorizedResponseAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable { 15 | 16 | private static final long serialVersionUID = -8970718410437077606L; 17 | 18 | @Override 19 | public void commence(HttpServletRequest request, HttpServletResponse response, 20 | AuthenticationException authException) throws IOException { 21 | response.sendError(HttpServletResponse.SC_UNAUTHORIZED, 22 | "You would need to provide the Jwt Token to Access This resource"); 23 | } 24 | } -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/jwt/JwtUserDetails.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.jwt; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | import org.springframework.security.core.GrantedAuthority; 8 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 9 | import org.springframework.security.core.userdetails.UserDetails; 10 | 11 | import com.fasterxml.jackson.annotation.JsonIgnore; 12 | 13 | public class JwtUserDetails implements UserDetails { 14 | 15 | private static final long serialVersionUID = 5155720064139820502L; 16 | 17 | private final Long id; 18 | private final String username; 19 | private final String password; 20 | private final Collection authorities; 21 | 22 | public JwtUserDetails(Long id, String username, String password, String role) { 23 | this.id = id; 24 | this.username = username; 25 | this.password = password; 26 | 27 | List authorities = new ArrayList(); 28 | authorities.add(new SimpleGrantedAuthority(role)); 29 | 30 | this.authorities = authorities; 31 | } 32 | 33 | @JsonIgnore 34 | public Long getId() { 35 | return id; 36 | } 37 | 38 | @Override 39 | public String getUsername() { 40 | return username; 41 | } 42 | 43 | @JsonIgnore 44 | @Override 45 | public boolean isAccountNonExpired() { 46 | return true; 47 | } 48 | 49 | @JsonIgnore 50 | @Override 51 | public boolean isAccountNonLocked() { 52 | return true; 53 | } 54 | 55 | @JsonIgnore 56 | @Override 57 | public boolean isCredentialsNonExpired() { 58 | return true; 59 | } 60 | 61 | @JsonIgnore 62 | @Override 63 | public String getPassword() { 64 | return password; 65 | } 66 | 67 | @Override 68 | public Collection getAuthorities() { 69 | return authorities; 70 | } 71 | 72 | @Override 73 | public boolean isEnabled() { 74 | return true; 75 | } 76 | 77 | } 78 | 79 | 80 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/jwt/JwtUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.jwt; 2 | import java.util.ArrayList; 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 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 | @Service 13 | public class JwtUserDetailsService implements UserDetailsService { 14 | 15 | @Autowired 16 | private UserRepository userRepository; 17 | 18 | @Override 19 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 20 | User user = userRepository.findByUsername(username); 21 | 22 | if (user == null) { 23 | throw new UsernameNotFoundException(String.format("USER_NOT_FOUND '%s'.", username)); 24 | } else { 25 | return create(user); 26 | } 27 | } 28 | 29 | public static JwtUserDetails create(User user) { 30 | return new JwtUserDetails(user.getId(), user.getUsername(), user.getPassword(), user.getRole()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/jwt/User.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.jwt; 2 | import javax.persistence.Column; 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import javax.persistence.SequenceGenerator; 8 | import javax.persistence.Table; 9 | import javax.validation.constraints.NotNull; 10 | import javax.validation.constraints.Size; 11 | 12 | @Entity 13 | @Table(name = "USER") 14 | public class User { 15 | 16 | @Id 17 | @Column(name = "ID") 18 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq") 19 | @SequenceGenerator(name = "user_seq", sequenceName = "user_seq", allocationSize = 1) 20 | private Long id; 21 | 22 | @Column(name = "USERNAME", length = 50, unique = true) 23 | @NotNull 24 | @Size(min = 4, max = 50) 25 | private String username; 26 | 27 | @Column(name = "PASSWORD", length = 100) 28 | @Size(min = 4, max = 100) 29 | @NotNull 30 | private String password; 31 | 32 | @Column(name = "ROLE", length = 100) 33 | @Size(min = 4, max = 100) 34 | @NotNull 35 | private String role; 36 | 37 | public Long getId() { 38 | return id; 39 | } 40 | 41 | public void setId(Long id) { 42 | this.id = id; 43 | } 44 | 45 | public String getUsername() { 46 | return username; 47 | } 48 | 49 | public void setUsername(String username) { 50 | this.username = username; 51 | } 52 | 53 | public String getPassword() { 54 | return password; 55 | } 56 | 57 | public void setPassword(String password) { 58 | this.password = password; 59 | } 60 | 61 | public String getRole() { 62 | return role; 63 | } 64 | 65 | public void setRole(String role) { 66 | this.role = role; 67 | } 68 | 69 | 70 | } -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/jwt/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.jwt; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | 5 | public interface UserRepository extends JpaRepository { 6 | User findByUsername(String username); 7 | } 8 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/jwt/resource/AuthenticationException.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.jwt.resource; 2 | public class AuthenticationException extends RuntimeException { 3 | public AuthenticationException(String message, Throwable cause) { 4 | super(message, cause); 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/jwt/resource/JwtTokenRequest.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.jwt.resource; 2 | 3 | import java.io.Serializable; 4 | 5 | public class JwtTokenRequest implements Serializable { 6 | 7 | private static final long serialVersionUID = -5616176897013108345L; 8 | 9 | private String username; 10 | private String password; 11 | 12 | public JwtTokenRequest() { 13 | super(); 14 | } 15 | 16 | public JwtTokenRequest(String username, String password) { 17 | this.setUsername(username); 18 | this.setPassword(password); 19 | } 20 | 21 | public String getUsername() { 22 | return this.username; 23 | } 24 | 25 | public void setUsername(String username) { 26 | this.username = username; 27 | } 28 | 29 | public String getPassword() { 30 | return this.password; 31 | } 32 | 33 | public void setPassword(String password) { 34 | this.password = password; 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/jwt/resource/JwtTokenResponse.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.jwt.resource; 2 | 3 | import java.io.Serializable; 4 | 5 | public class JwtTokenResponse implements Serializable { 6 | 7 | private static final long serialVersionUID = 8317676219297719109L; 8 | 9 | private final String token; 10 | 11 | public JwtTokenResponse(String token) { 12 | this.token = token; 13 | } 14 | 15 | public String getToken() { 16 | return this.token; 17 | } 18 | } -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/Todo.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.Date; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.Id; 8 | 9 | @Entity 10 | public class Todo { 11 | @Id 12 | @GeneratedValue 13 | private Long id; 14 | private String username; 15 | private String description; 16 | private Date targetDate; 17 | private boolean isDone; 18 | 19 | public Todo() { 20 | 21 | } 22 | 23 | public Todo(long id, String username, String description, Date targetDate, boolean isDone) { 24 | super(); 25 | this.id = id; 26 | this.username = username; 27 | this.description = description; 28 | this.targetDate = targetDate; 29 | this.isDone = isDone; 30 | } 31 | 32 | public Long getId() { 33 | return id; 34 | } 35 | 36 | public void setId(Long id) { 37 | this.id = id; 38 | } 39 | 40 | public String getUsername() { 41 | return username; 42 | } 43 | 44 | public void setUsername(String username) { 45 | this.username = username; 46 | } 47 | 48 | public String getDescription() { 49 | return description; 50 | } 51 | 52 | public void setDescription(String description) { 53 | this.description = description; 54 | } 55 | 56 | public Date getTargetDate() { 57 | return targetDate; 58 | } 59 | 60 | public void setTargetDate(Date targetDate) { 61 | this.targetDate = targetDate; 62 | } 63 | 64 | public boolean isDone() { 65 | return isDone; 66 | } 67 | 68 | public void setDone(boolean isDone) { 69 | this.isDone = isDone; 70 | } 71 | 72 | @Override 73 | public int hashCode() { 74 | final int prime = 31; 75 | int result = 1; 76 | result = prime * result + (int) (id ^ (id >>> 32)); 77 | return result; 78 | } 79 | 80 | @Override 81 | public boolean equals(Object obj) { 82 | if (this == obj) 83 | return true; 84 | if (obj == null) 85 | return false; 86 | if (getClass() != obj.getClass()) 87 | return false; 88 | Todo other = (Todo) obj; 89 | if (id != other.id) 90 | return false; 91 | return true; 92 | } 93 | 94 | 95 | } -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoHardcodedService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class TodoHardcodedService { 11 | 12 | private static List todos = new ArrayList<>(); 13 | private static long idCounter = 0; 14 | 15 | static { 16 | todos.add(new Todo(++idCounter, "in28minutes", "Learn to Dance 2", new Date(), false)); 17 | todos.add(new Todo(++idCounter, "in28minutes", "Learn about Microservices 2", new Date(), false)); 18 | todos.add(new Todo(++idCounter, "in28minutes", "Learn about Angular", new Date(), false)); 19 | } 20 | 21 | public List findAll() { 22 | return todos; 23 | } 24 | 25 | public Todo save(Todo todo) { 26 | if(todo.getId()==-1 || todo.getId()==0) { 27 | todo.setId(++idCounter); 28 | todos.add(todo); 29 | } else { 30 | deleteById(todo.getId()); 31 | todos.add(todo); 32 | } 33 | return todo; 34 | } 35 | 36 | public Todo deleteById(long id) { 37 | Todo todo = findById(id); 38 | 39 | if (todo == null) 40 | return null; 41 | 42 | if (todos.remove(todo)) { 43 | return todo; 44 | } 45 | 46 | return null; 47 | } 48 | 49 | public Todo findById(long id) { 50 | for (Todo todo : todos) { 51 | if (todo.getId() == id) { 52 | return todo; 53 | } 54 | } 55 | 56 | return null; 57 | } 58 | } -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoJpaRepository.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | @Repository 9 | public interface TodoJpaRepository extends JpaRepository{ 10 | List findByUsername(String username); 11 | } -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoJpaResource.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.net.URI; 4 | import java.util.List; 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.DeleteMapping; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.PutMapping; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.RestController; 16 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 17 | 18 | //@CrossOrigin(origins="http://localhost:4200") Replace with global config 19 | @RestController 20 | public class TodoJpaResource { 21 | 22 | @Autowired 23 | private TodoJpaRepository todoJpaRepository; 24 | 25 | 26 | @GetMapping("/jpa/users/{username}/todos") 27 | public List getAllTodos(@PathVariable String username){ 28 | return todoJpaRepository.findByUsername(username); 29 | //return todoService.findAll(); 30 | } 31 | 32 | @GetMapping("/jpa/users/{username}/todos/{id}") 33 | public Todo getTodo(@PathVariable String username, @PathVariable long id){ 34 | return todoJpaRepository.findById(id).get(); 35 | //return todoService.findById(id); 36 | } 37 | 38 | // DELETE /users/{username}/todos/{id} 39 | @DeleteMapping("/jpa/users/{username}/todos/{id}") 40 | public ResponseEntity deleteTodo( 41 | @PathVariable String username, @PathVariable long id) { 42 | 43 | todoJpaRepository.deleteById(id); 44 | 45 | return ResponseEntity.noContent().build(); 46 | } 47 | 48 | 49 | //Edit/Update a Todo 50 | //PUT /users/{user_name}/todos/{todo_id} 51 | @PutMapping("/jpa/users/{username}/todos/{id}") 52 | public ResponseEntity updateTodo( 53 | @PathVariable String username, 54 | @PathVariable long id, @RequestBody Todo todo){ 55 | 56 | todo.setUsername(username); 57 | 58 | Todo todoUpdated = todoJpaRepository.save(todo); 59 | 60 | return new ResponseEntity(todo, HttpStatus.OK); 61 | } 62 | 63 | @PostMapping("/jpa/users/{username}/todos") 64 | public ResponseEntity createTodo( 65 | @PathVariable String username, @RequestBody Todo todo){ 66 | 67 | todo.setUsername(username); 68 | 69 | Todo createdTodo = todoJpaRepository.save(todo); 70 | 71 | //Location 72 | //Get current resource url 73 | ///{id} 74 | URI uri = ServletUriComponentsBuilder.fromCurrentRequest() 75 | .path("/{id}").buildAndExpand(createdTodo.getId()).toUri(); 76 | 77 | return ResponseEntity.created(uri).build(); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoResource.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.net.URI; 4 | import java.util.List; 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.DeleteMapping; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.PutMapping; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.RestController; 16 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 17 | 18 | //@CrossOrigin(origins = "http://localhost:4200") Replace with global config 19 | @RestController 20 | public class TodoResource { 21 | 22 | @Autowired 23 | private TodoHardcodedService todoService; 24 | 25 | @GetMapping("/users/{username}/todos") 26 | public List getAllTodos(@PathVariable String username) { 27 | // Thread.sleep(3000); 28 | return todoService.findAll(); 29 | } 30 | 31 | @GetMapping("/users/{username}/todos/{id}") 32 | public Todo getTodo(@PathVariable String username, @PathVariable long id) { 33 | // Thread.sleep(3000); 34 | return todoService.findById(id); 35 | } 36 | 37 | 38 | // DELETE /users/{username}/todos/{id} 39 | @DeleteMapping("/users/{username}/todos/{id}") 40 | public ResponseEntity deleteTodo(@PathVariable String username, @PathVariable long id) { 41 | 42 | Todo todo = todoService.deleteById(id); 43 | 44 | if (todo != null) { 45 | return ResponseEntity.noContent().build(); 46 | } 47 | 48 | return ResponseEntity.notFound().build(); 49 | } 50 | 51 | //Edit/Update a Todo 52 | //PUT /users/{user_name}/todos/{todo_id} 53 | @PutMapping("/users/{username}/todos/{id}") 54 | public ResponseEntity updateTodo( 55 | @PathVariable String username, 56 | @PathVariable long id, @RequestBody Todo todo){ 57 | 58 | Todo todoUpdated = todoService.save(todo); 59 | 60 | return new ResponseEntity(todo, HttpStatus.OK); 61 | } 62 | 63 | @PostMapping("/users/{username}/todos") 64 | public ResponseEntity updateTodo( 65 | @PathVariable String username, @RequestBody Todo todo){ 66 | 67 | Todo createdTodo = todoService.save(todo); 68 | 69 | //Location 70 | //Get current resource url 71 | ///{id} 72 | URI uri = ServletUriComponentsBuilder.fromCurrentRequest() 73 | .path("/{id}").buildAndExpand(createdTodo.getId()).toUri(); 74 | 75 | return ResponseEntity.created(uri).build(); 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework = info 2 | 3 | #spring.security.user.name=in28minutes 4 | #spring.security.user.password=dummy 5 | 6 | jwt.signing.key.secret=mySecret 7 | jwt.get.token.uri=/authenticate 8 | jwt.refresh.token.uri=/refresh 9 | jwt.http.request.header=Authorization 10 | jwt.token.expiration.in.seconds=604800 11 | 12 | spring.jpa.show-sql=true 13 | spring.h2.console.enabled=true 14 | 15 | #AWS 16 | server.port = 5000 -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | /*https://www.browserling.com/tools/bcrypt Use Rounds 10*/ 2 | 3 | /*in28minutes/dummy*/ 4 | INSERT INTO USER (ID, USERNAME, PASSWORD, ROLE) 5 | VALUES (1, 'in28minutes', '$2a$10$3zHzb.Npv1hfZbLEU5qsdOju/tk2je6W6PnNnY.c1ujWPcZh4PL6e','ROLE_USER'); 6 | 7 | /*in28minutes2/mypassword*/ 8 | INSERT INTO USER (ID, USERNAME, PASSWORD, ROLE) 9 | VALUES (2, 'in28minutes2', '$2a$10$i9AckmxMkb4yKtLCdxeQheCm2pXWB3qZ2G189/Ph/DUci1DvLO.Rq','ROLE_USER'); 10 | 11 | 12 | 13 | 14 | insert into todo(id, username,description,target_date,is_done) 15 | values(10001, 'in28minutes', 'Learn JPA', sysdate(), false); 16 | 17 | insert into todo(id, username,description,target_date,is_done) 18 | values(10002, 'in28minutes', 'Learn Data JPA', sysdate(), false); 19 | 20 | insert into todo(id, username,description,target_date,is_done) 21 | values(10003, 'in28minutes', 'Learn Microservices', sysdate(), false); -------------------------------------------------------------------------------- /Otherprojects/05-spring-boot-react-full-stack-h2/restful-web-services/src/test/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 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 RestfulWebServicesApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Otherprojects/06-todo-rest-api-h2-containerized/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | VOLUME /tmp 3 | EXPOSE 5000 4 | ADD target/*.jar app.jar 5 | ENV JAVA_OPTS="" 6 | ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ] -------------------------------------------------------------------------------- /Otherprojects/06-todo-rest-api-h2-containerized/Dockerrun.aws.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSEBDockerrunVersion": "1", 3 | "Image": { 4 | "Name": "rangakaranam/06-todo-rest-api-containerized:0.0.1-SNAPSHOT", 5 | "Update": "true" 6 | }, 7 | "Ports": [ 8 | { 9 | "ContainerPort": "5000" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /Otherprojects/06-todo-rest-api-h2-containerized/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.in28minutes.rest.webservices 8 | 06-todo-rest-api-h2-containerized 9 | 0.0.1-SNAPSHOT 10 | jar 11 | 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.1.0.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-data-jpa 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-web 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-devtools 42 | runtime 43 | 44 | 45 | 46 | com.h2database 47 | h2 48 | runtime 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-starter-test 54 | test 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-maven-plugin 63 | 64 | 65 | 66 | 67 | com.spotify 68 | dockerfile-maven-plugin 69 | 1.4.9 70 | 71 | 72 | default 73 | 74 | build 75 | 76 | 77 | 78 | 79 | 80 | rangakaranam/${project.artifactId} 81 | ${project.version} 82 | 83 | ${project.build.finalName}.jar 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | spring-snapshots 93 | Spring Snapshots 94 | https://repo.spring.io/snapshot 95 | 96 | true 97 | 98 | 99 | 100 | spring-milestones 101 | Spring Milestones 102 | https://repo.spring.io/milestone 103 | 104 | false 105 | 106 | 107 | 108 | 109 | 110 | 111 | spring-snapshots 112 | Spring Snapshots 113 | https://repo.spring.io/snapshot 114 | 115 | true 116 | 117 | 118 | 119 | spring-milestones 120 | Spring Milestones 121 | https://repo.spring.io/milestone 122 | 123 | false 124 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /Otherprojects/06-todo-rest-api-h2-containerized/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class RestfulWebServicesApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(RestfulWebServicesApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Otherprojects/06-todo-rest-api-h2-containerized/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/helloworld/HelloWorldBean.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.helloworld; 2 | 3 | public class HelloWorldBean { 4 | 5 | private String message; 6 | 7 | public HelloWorldBean(String message) { 8 | this.message = message; 9 | } 10 | 11 | public String getMessage() { 12 | return message; 13 | } 14 | 15 | public void setMessage(String message) { 16 | this.message = message; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return String.format("HelloWorldBean [message=%s]", message); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Otherprojects/06-todo-rest-api-h2-containerized/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/helloworld/HelloWorldController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.helloworld; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.PathVariable; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | //Controller 8 | @RestController 9 | // 10 | public class HelloWorldController { 11 | 12 | @GetMapping(path = "/hello-world") 13 | public String helloWorld() { 14 | return "Hello World"; 15 | } 16 | 17 | @GetMapping(path = "/hello-world-bean") 18 | public HelloWorldBean helloWorldBean() { 19 | return new HelloWorldBean("Hello World"); 20 | } 21 | 22 | ///hello-world/path-variable/in28minutes 23 | @GetMapping(path = "/hello-world/path-variable/{name}") 24 | public HelloWorldBean helloWorldPathVariable(@PathVariable String name) { 25 | //throw new RuntimeException("Something went wrong"); 26 | return new HelloWorldBean(String.format("Hello World, %s", name)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Otherprojects/06-todo-rest-api-h2-containerized/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/Todo.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.Date; 4 | 5 | public class Todo { 6 | private long id; 7 | private String username; 8 | private String description; 9 | private Date targetDate; 10 | private boolean isDone; 11 | 12 | public Todo() { 13 | 14 | } 15 | 16 | public Todo(long id, String username, String description, Date targetDate, boolean isDone) { 17 | super(); 18 | this.id = id; 19 | this.username = username; 20 | this.description = description; 21 | this.targetDate = targetDate; 22 | this.isDone = isDone; 23 | } 24 | 25 | public long getId() { 26 | return id; 27 | } 28 | 29 | public void setId(long id) { 30 | this.id = id; 31 | } 32 | 33 | public String getUsername() { 34 | return username; 35 | } 36 | 37 | public void setUsername(String username) { 38 | this.username = username; 39 | } 40 | 41 | public String getDescription() { 42 | return description; 43 | } 44 | 45 | public void setDescription(String description) { 46 | this.description = description; 47 | } 48 | 49 | public Date getTargetDate() { 50 | return targetDate; 51 | } 52 | 53 | public void setTargetDate(Date targetDate) { 54 | this.targetDate = targetDate; 55 | } 56 | 57 | public boolean isDone() { 58 | return isDone; 59 | } 60 | 61 | public void setDone(boolean isDone) { 62 | this.isDone = isDone; 63 | } 64 | 65 | @Override 66 | public int hashCode() { 67 | final int prime = 31; 68 | int result = 1; 69 | result = prime * result + (int) (id ^ (id >>> 32)); 70 | return result; 71 | } 72 | 73 | @Override 74 | public boolean equals(Object obj) { 75 | if (this == obj) 76 | return true; 77 | if (obj == null) 78 | return false; 79 | if (getClass() != obj.getClass()) 80 | return false; 81 | Todo other = (Todo) obj; 82 | if (id != other.id) 83 | return false; 84 | return true; 85 | } 86 | 87 | 88 | } -------------------------------------------------------------------------------- /Otherprojects/06-todo-rest-api-h2-containerized/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoHardcodedService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class TodoHardcodedService { 11 | 12 | private static List todos = new ArrayList<>(); 13 | private static int idCounter = 0; 14 | 15 | static { 16 | todos.add(new Todo(++idCounter, "in28minutes", "Learn to Dance 2", new Date(), false)); 17 | todos.add(new Todo(++idCounter, "in28minutes", "Learn about Microservices 2", new Date(), false)); 18 | todos.add(new Todo(++idCounter, "in28minutes", "Learn about Angular", new Date(), false)); 19 | } 20 | 21 | public List findAll() { 22 | return todos; 23 | } 24 | 25 | public Todo save(Todo todo) { 26 | if(todo.getId()==-1 || todo.getId()==0) { 27 | todo.setId(++idCounter); 28 | todos.add(todo); 29 | } else { 30 | deleteById(todo.getId()); 31 | todos.add(todo); 32 | } 33 | return todo; 34 | } 35 | 36 | public Todo deleteById(long id) { 37 | Todo todo = findById(id); 38 | 39 | if (todo == null) 40 | return null; 41 | 42 | if (todos.remove(todo)) { 43 | return todo; 44 | } 45 | 46 | return null; 47 | } 48 | 49 | public Todo findById(long id) { 50 | for (Todo todo : todos) { 51 | if (todo.getId() == id) { 52 | return todo; 53 | } 54 | } 55 | 56 | return null; 57 | } 58 | } -------------------------------------------------------------------------------- /Otherprojects/06-todo-rest-api-h2-containerized/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoResource.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.net.URI; 4 | import java.util.List; 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.DeleteMapping; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.PutMapping; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.RestController; 16 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 17 | 18 | @RestController 19 | public class TodoResource { 20 | 21 | @Autowired 22 | private TodoHardcodedService todoService; 23 | 24 | @GetMapping("/users/{username}/todos") 25 | public List getAllTodos(@PathVariable String username) { 26 | // Thread.sleep(3000); 27 | return todoService.findAll(); 28 | } 29 | 30 | @GetMapping("/users/{username}/todos/{id}") 31 | public Todo getTodo(@PathVariable String username, @PathVariable long id) { 32 | // Thread.sleep(3000); 33 | return todoService.findById(id); 34 | } 35 | 36 | 37 | // DELETE /users/{username}/todos/{id} 38 | @DeleteMapping("/users/{username}/todos/{id}") 39 | public ResponseEntity deleteTodo(@PathVariable String username, @PathVariable long id) { 40 | 41 | Todo todo = todoService.deleteById(id); 42 | 43 | if (todo != null) { 44 | return ResponseEntity.noContent().build(); 45 | } 46 | 47 | return ResponseEntity.notFound().build(); 48 | } 49 | 50 | //Edit/Update a Todo 51 | //PUT /users/{user_name}/todos/{todo_id} 52 | @PutMapping("/users/{username}/todos/{id}") 53 | public ResponseEntity updateTodo( 54 | @PathVariable String username, 55 | @PathVariable long id, @RequestBody Todo todo){ 56 | 57 | Todo todoUpdated = todoService.save(todo); 58 | 59 | return new ResponseEntity(todo, HttpStatus.OK); 60 | } 61 | 62 | @PostMapping("/users/{username}/todos") 63 | public ResponseEntity updateTodo( 64 | @PathVariable String username, @RequestBody Todo todo){ 65 | 66 | Todo createdTodo = todoService.save(todo); 67 | 68 | //Location 69 | //Get current resource url 70 | ///{id} 71 | URI uri = ServletUriComponentsBuilder.fromCurrentRequest() 72 | .path("/{id}").buildAndExpand(createdTodo.getId()).toUri(); 73 | 74 | return ResponseEntity.created(uri).build(); 75 | } 76 | 77 | } -------------------------------------------------------------------------------- /Otherprojects/06-todo-rest-api-h2-containerized/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework = info 2 | server.port=5000 -------------------------------------------------------------------------------- /Otherprojects/06-todo-rest-api-h2-containerized/src/test/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 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 RestfulWebServicesApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Otherprojects/07-todo-rest-api-mysql-containerized/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | VOLUME /tmp 3 | EXPOSE 5000 4 | ADD target/*.jar app.jar 5 | ENV JAVA_OPTS="" 6 | ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ] -------------------------------------------------------------------------------- /Otherprojects/07-todo-rest-api-mysql-containerized/Dockerrun.aws.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSEBDockerrunVersion": 2, 3 | "containerDefinitions": [ 4 | { 5 | "name": "mysql", 6 | "image": "mysql:5.7", 7 | "environment": [ 8 | { 9 | "name": "MYSQL_ROOT_PASSWORD", 10 | "value": "dummypassword" 11 | }, 12 | { 13 | "name": "MYSQL_USER", 14 | "value": "todos-user" 15 | }, 16 | { 17 | "name": "MYSQL_PASSWORD", 18 | "value": "dummytodos" 19 | }, 20 | { 21 | "name": "MYSQL_DATABASE", 22 | "value": "todos" 23 | } 24 | ], 25 | "essential": true, 26 | "memory": 256, 27 | "portMappings": [ 28 | { 29 | "hostPort": 3306, 30 | "containerPort": 3306 31 | } 32 | ] 33 | }, 34 | { 35 | "name": "todo-rest-api", 36 | "image": "rangakaranam/07-todo-rest-api-mysql-containerized:0.0.1-SNAPSHOT", 37 | "essential": true, 38 | "memory": 256, 39 | "portMappings": [ 40 | { 41 | "hostPort": 5000, 42 | "containerPort": 5000 43 | } 44 | ], 45 | "links": [ 46 | "mysql" 47 | ] 48 | } 49 | ] 50 | } -------------------------------------------------------------------------------- /Otherprojects/07-todo-rest-api-mysql-containerized/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class RestfulWebServicesApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(RestfulWebServicesApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Otherprojects/07-todo-rest-api-mysql-containerized/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/helloworld/HelloWorldBean.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.helloworld; 2 | 3 | public class HelloWorldBean { 4 | 5 | private String message; 6 | 7 | public HelloWorldBean(String message) { 8 | this.message = message; 9 | } 10 | 11 | public String getMessage() { 12 | return message; 13 | } 14 | 15 | public void setMessage(String message) { 16 | this.message = message; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return String.format("HelloWorldBean [message=%s]", message); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Otherprojects/07-todo-rest-api-mysql-containerized/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/helloworld/HelloWorldController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.helloworld; 2 | 3 | import org.springframework.web.bind.annotation.CrossOrigin; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.PathVariable; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | @RestController 9 | public class HelloWorldController { 10 | 11 | @GetMapping(path = "/hello-world") 12 | public String helloWorld() { 13 | return "Hello World"; 14 | } 15 | 16 | @GetMapping(path = "/hello-world-bean") 17 | public HelloWorldBean helloWorldBean() { 18 | return new HelloWorldBean("Hello World"); 19 | } 20 | 21 | ///hello-world/path-variable/in28minutes 22 | @GetMapping(path = "/hello-world/path-variable/{name}") 23 | public HelloWorldBean helloWorldPathVariable(@PathVariable String name) { 24 | //throw new RuntimeException("Something went wrong"); 25 | return new HelloWorldBean(String.format("Hello World, %s", name)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Otherprojects/07-todo-rest-api-mysql-containerized/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/Todo.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.Date; 4 | 5 | public class Todo { 6 | private long id; 7 | private String username; 8 | private String description; 9 | private Date targetDate; 10 | private boolean isDone; 11 | 12 | public Todo() { 13 | 14 | } 15 | 16 | public Todo(long id, String username, String description, Date targetDate, boolean isDone) { 17 | super(); 18 | this.id = id; 19 | this.username = username; 20 | this.description = description; 21 | this.targetDate = targetDate; 22 | this.isDone = isDone; 23 | } 24 | 25 | public long getId() { 26 | return id; 27 | } 28 | 29 | public void setId(long id) { 30 | this.id = id; 31 | } 32 | 33 | public String getUsername() { 34 | return username; 35 | } 36 | 37 | public void setUsername(String username) { 38 | this.username = username; 39 | } 40 | 41 | public String getDescription() { 42 | return description; 43 | } 44 | 45 | public void setDescription(String description) { 46 | this.description = description; 47 | } 48 | 49 | public Date getTargetDate() { 50 | return targetDate; 51 | } 52 | 53 | public void setTargetDate(Date targetDate) { 54 | this.targetDate = targetDate; 55 | } 56 | 57 | public boolean isDone() { 58 | return isDone; 59 | } 60 | 61 | public void setDone(boolean isDone) { 62 | this.isDone = isDone; 63 | } 64 | 65 | @Override 66 | public int hashCode() { 67 | final int prime = 31; 68 | int result = 1; 69 | result = prime * result + (int) (id ^ (id >>> 32)); 70 | return result; 71 | } 72 | 73 | @Override 74 | public boolean equals(Object obj) { 75 | if (this == obj) 76 | return true; 77 | if (obj == null) 78 | return false; 79 | if (getClass() != obj.getClass()) 80 | return false; 81 | Todo other = (Todo) obj; 82 | if (id != other.id) 83 | return false; 84 | return true; 85 | } 86 | 87 | 88 | } -------------------------------------------------------------------------------- /Otherprojects/07-todo-rest-api-mysql-containerized/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoHardcodedService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class TodoHardcodedService { 11 | 12 | private static List todos = new ArrayList<>(); 13 | private static int idCounter = 0; 14 | 15 | static { 16 | todos.add(new Todo(++idCounter, "in28minutes", "Learn to Dance 2", new Date(), false)); 17 | todos.add(new Todo(++idCounter, "in28minutes", "Learn about Microservices 2", new Date(), false)); 18 | todos.add(new Todo(++idCounter, "in28minutes", "Learn about Angular", new Date(), false)); 19 | } 20 | 21 | public List findAll() { 22 | return todos; 23 | } 24 | 25 | public Todo save(Todo todo) { 26 | if(todo.getId()==-1 || todo.getId()==0) { 27 | todo.setId(++idCounter); 28 | todos.add(todo); 29 | } else { 30 | deleteById(todo.getId()); 31 | todos.add(todo); 32 | } 33 | return todo; 34 | } 35 | 36 | public Todo deleteById(long id) { 37 | Todo todo = findById(id); 38 | 39 | if (todo == null) 40 | return null; 41 | 42 | if (todos.remove(todo)) { 43 | return todo; 44 | } 45 | 46 | return null; 47 | } 48 | 49 | public Todo findById(long id) { 50 | for (Todo todo : todos) { 51 | if (todo.getId() == id) { 52 | return todo; 53 | } 54 | } 55 | 56 | return null; 57 | } 58 | } -------------------------------------------------------------------------------- /Otherprojects/07-todo-rest-api-mysql-containerized/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoResource.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.net.URI; 4 | import java.util.List; 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.DeleteMapping; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.PutMapping; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.RestController; 16 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 17 | 18 | @RestController 19 | public class TodoResource { 20 | 21 | @Autowired 22 | private TodoHardcodedService todoService; 23 | 24 | @GetMapping("/users/{username}/todos") 25 | public List getAllTodos(@PathVariable String username) { 26 | // Thread.sleep(3000); 27 | return todoService.findAll(); 28 | } 29 | 30 | @GetMapping("/users/{username}/todos/{id}") 31 | public Todo getTodo(@PathVariable String username, @PathVariable long id) { 32 | // Thread.sleep(3000); 33 | return todoService.findById(id); 34 | } 35 | 36 | 37 | // DELETE /users/{username}/todos/{id} 38 | @DeleteMapping("/users/{username}/todos/{id}") 39 | public ResponseEntity deleteTodo(@PathVariable String username, @PathVariable long id) { 40 | 41 | Todo todo = todoService.deleteById(id); 42 | 43 | if (todo != null) { 44 | return ResponseEntity.noContent().build(); 45 | } 46 | 47 | return ResponseEntity.notFound().build(); 48 | } 49 | 50 | //Edit/Update a Todo 51 | //PUT /users/{user_name}/todos/{todo_id} 52 | @PutMapping("/users/{username}/todos/{id}") 53 | public ResponseEntity updateTodo( 54 | @PathVariable String username, 55 | @PathVariable long id, @RequestBody Todo todo){ 56 | 57 | Todo todoUpdated = todoService.save(todo); 58 | 59 | return new ResponseEntity(todo, HttpStatus.OK); 60 | } 61 | 62 | @PostMapping("/users/{username}/todos") 63 | public ResponseEntity updateTodo( 64 | @PathVariable String username, @RequestBody Todo todo){ 65 | 66 | Todo createdTodo = todoService.save(todo); 67 | 68 | //Location 69 | //Get current resource url 70 | ///{id} 71 | URI uri = ServletUriComponentsBuilder.fromCurrentRequest() 72 | .path("/{id}").buildAndExpand(createdTodo.getId()).toUri(); 73 | 74 | return ResponseEntity.created(uri).build(); 75 | } 76 | 77 | } -------------------------------------------------------------------------------- /Otherprojects/07-todo-rest-api-mysql-containerized/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework = info 2 | server.port=5000 3 | 4 | #AWS 5 | spring.jpa.hibernate.ddl-auto=update 6 | spring.datasource.url=jdbc:mysql://${RDS_HOSTNAME:mysql}:${RDS_PORT:3306}/${RDS_DB_NAME:todos} 7 | spring.datasource.username=${RDS_USERNAME:todos-user} 8 | spring.datasource.password=${RDS_PASSWORD:dummytodos} 9 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect -------------------------------------------------------------------------------- /Otherprojects/07-todo-rest-api-mysql-containerized/src/test/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 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 RestfulWebServicesApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Otherprojects/07-todo-rest-api-mysql-containerized/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | #AWS 2 | spring.jpa.hibernate.ddl-auto=create-drop 3 | spring.datasource.driver-class-name=org.h2.Driver 4 | spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1 5 | spring.datasource.username=sa 6 | spring.datasource.password=sa 7 | -------------------------------------------------------------------------------- /buildspec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | artifacts: 3 | files: 4 | - target/spring-boot-rest-api-playground-h2-0.0.1-SNAPSHOT.jar 5 | phases: 6 | build: 7 | commands: 8 | - "mvn package" 9 | - "echo \"build stage started\"" 10 | install: 11 | pre_build: 12 | commands: 13 | - "echo \"pre_build stage started\"" 14 | runtime-versions: 15 | java: openjdk8 16 | post_build: 17 | commands: 18 | - "echo \"post_build stage started\"" 19 | version: 0.2 20 | -------------------------------------------------------------------------------- /cmd-line-test/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Elastic Beanstalk Files 3 | .elasticbeanstalk/* 4 | !.elasticbeanstalk/*.cfg.yml 5 | !.elasticbeanstalk/*.global.yml 6 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.in28minutes.rest.webservices 7 | spring-boot-rest-api-playground-h2 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | Demo project for Spring Boot 12 | 13 | 14 | org.springframework.boot 15 | spring-boot-starter-parent 16 | 2.1.0.RELEASE 17 | 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 1.8 24 | 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-data-jpa 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-web 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-devtools 41 | runtime 42 | 43 | 44 | 45 | com.h2database 46 | h2 47 | runtime 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-test 53 | test 54 | 55 | 56 | 57 | 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-maven-plugin 62 | 63 | 64 | 65 | 66 | 67 | 68 | spring-snapshots 69 | Spring Snapshots 70 | https://repo.spring.io/snapshot 71 | 72 | true 73 | 74 | 75 | 76 | spring-milestones 77 | Spring Milestones 78 | https://repo.spring.io/milestone 79 | 80 | false 81 | 82 | 83 | 84 | 85 | 86 | 87 | spring-snapshots 88 | Spring Snapshots 89 | https://repo.spring.io/snapshot 90 | 91 | true 92 | 93 | 94 | 95 | spring-milestones 96 | Spring Milestones 97 | https://repo.spring.io/milestone 98 | 99 | false 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplication.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | @SpringBootApplication 10 | public class RestfulWebServicesApplication { 11 | 12 | // AWS 13 | @Bean 14 | public WebMvcConfigurer corsConfigurer() { 15 | return new WebMvcConfigurer() { 16 | @Override 17 | public void addCorsMappings(CorsRegistry registry) { 18 | registry.addMapping("/**").allowedMethods("*").allowedOrigins("*"); 19 | } 20 | }; 21 | } 22 | 23 | public static void main(String[] args) { 24 | SpringApplication.run(RestfulWebServicesApplication.class, args); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/helloworld/HelloWorldBean.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.helloworld; 2 | 3 | public class HelloWorldBean { 4 | 5 | private String message; 6 | 7 | public HelloWorldBean(String message) { 8 | this.message = message; 9 | } 10 | 11 | public String getMessage() { 12 | return message; 13 | } 14 | 15 | public void setMessage(String message) { 16 | this.message = message; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return String.format("HelloWorldBean [message=%s]", message); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/helloworld/HelloWorldController.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.helloworld; 2 | 3 | import org.springframework.web.bind.annotation.CrossOrigin; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.PathVariable; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | //Controller 9 | @RestController 10 | @CrossOrigin(origins="http://localhost:4200") 11 | // 12 | public class HelloWorldController { 13 | 14 | @GetMapping(path = "/hello-world") 15 | public String helloWorld() { 16 | return "Hello World"; 17 | } 18 | 19 | @GetMapping(path = "/hello-world-bean") 20 | public HelloWorldBean helloWorldBean() { 21 | return new HelloWorldBean("Hello World - Changed"); 22 | } 23 | 24 | ///hello-world/path-variable/in28minutes 25 | @GetMapping(path = "/hello-world/path-variable/{name}") 26 | public HelloWorldBean helloWorldPathVariable(@PathVariable String name) { 27 | //throw new RuntimeException("Something went wrong"); 28 | return new HelloWorldBean(String.format("Hello World, %s", name)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/Todo.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.Date; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.Id; 8 | 9 | @Entity 10 | public class Todo { 11 | @Id 12 | @GeneratedValue 13 | private Long id; 14 | private String username; 15 | private String description; 16 | private Date targetDate; 17 | private boolean isDone; 18 | 19 | public Todo() { 20 | 21 | } 22 | 23 | public Todo(long id, String username, String description, Date targetDate, boolean isDone) { 24 | super(); 25 | this.id = id; 26 | this.username = username; 27 | this.description = description; 28 | this.targetDate = targetDate; 29 | this.isDone = isDone; 30 | } 31 | 32 | public Long getId() { 33 | return id; 34 | } 35 | 36 | public void setId(Long id) { 37 | this.id = id; 38 | } 39 | 40 | public String getUsername() { 41 | return username; 42 | } 43 | 44 | public void setUsername(String username) { 45 | this.username = username; 46 | } 47 | 48 | public String getDescription() { 49 | return description; 50 | } 51 | 52 | public void setDescription(String description) { 53 | this.description = description; 54 | } 55 | 56 | public Date getTargetDate() { 57 | return targetDate; 58 | } 59 | 60 | public void setTargetDate(Date targetDate) { 61 | this.targetDate = targetDate; 62 | } 63 | 64 | public boolean isDone() { 65 | return isDone; 66 | } 67 | 68 | public void setDone(boolean isDone) { 69 | this.isDone = isDone; 70 | } 71 | 72 | @Override 73 | public int hashCode() { 74 | final int prime = 31; 75 | int result = 1; 76 | result = prime * result + (int) (id ^ (id >>> 32)); 77 | return result; 78 | } 79 | 80 | @Override 81 | public boolean equals(Object obj) { 82 | if (this == obj) 83 | return true; 84 | if (obj == null) 85 | return false; 86 | if (getClass() != obj.getClass()) 87 | return false; 88 | Todo other = (Todo) obj; 89 | if (id != other.id) 90 | return false; 91 | return true; 92 | } 93 | 94 | 95 | } -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoHardcodedService.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class TodoHardcodedService { 11 | 12 | private static List todos = new ArrayList<>(); 13 | private static long idCounter = 0; 14 | 15 | static { 16 | todos.add(new Todo(++idCounter, "in28minutes", "Learn to Dance 2", new Date(), false)); 17 | todos.add(new Todo(++idCounter, "in28minutes", "Learn about Microservices 2", new Date(), false)); 18 | todos.add(new Todo(++idCounter, "in28minutes", "Learn about Angular", new Date(), false)); 19 | } 20 | 21 | public List findAll() { 22 | return todos; 23 | } 24 | 25 | public Todo save(Todo todo) { 26 | if(todo.getId()==-1 || todo.getId()==0) { 27 | todo.setId(++idCounter); 28 | todos.add(todo); 29 | } else { 30 | deleteById(todo.getId()); 31 | todos.add(todo); 32 | } 33 | return todo; 34 | } 35 | 36 | public Todo deleteById(long id) { 37 | Todo todo = findById(id); 38 | 39 | if (todo == null) 40 | return null; 41 | 42 | if (todos.remove(todo)) { 43 | return todo; 44 | } 45 | 46 | return null; 47 | } 48 | 49 | public Todo findById(long id) { 50 | for (Todo todo : todos) { 51 | if (todo.getId() == id) { 52 | return todo; 53 | } 54 | } 55 | 56 | return null; 57 | } 58 | } -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoJpaRepository.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | @Repository 9 | public interface TodoJpaRepository extends JpaRepository{ 10 | List findByUsername(String username); 11 | } -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoJpaResource.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.net.URI; 4 | import java.util.List; 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.DeleteMapping; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.PutMapping; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.RestController; 16 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 17 | 18 | //@CrossOrigin(origins="http://localhost:4200") Replace with global config 19 | @RestController 20 | public class TodoJpaResource { 21 | 22 | @Autowired 23 | private TodoJpaRepository todoJpaRepository; 24 | 25 | 26 | @GetMapping("/jpa/users/{username}/todos") 27 | public List getAllTodos(@PathVariable String username){ 28 | return todoJpaRepository.findByUsername(username); 29 | //return todoService.findAll(); 30 | } 31 | 32 | @GetMapping("/jpa/users/{username}/todos/{id}") 33 | public Todo getTodo(@PathVariable String username, @PathVariable long id){ 34 | return todoJpaRepository.findById(id).get(); 35 | //return todoService.findById(id); 36 | } 37 | 38 | // DELETE /users/{username}/todos/{id} 39 | @DeleteMapping("/jpa/users/{username}/todos/{id}") 40 | public ResponseEntity deleteTodo( 41 | @PathVariable String username, @PathVariable long id) { 42 | 43 | todoJpaRepository.deleteById(id); 44 | 45 | return ResponseEntity.noContent().build(); 46 | } 47 | 48 | 49 | //Edit/Update a Todo 50 | //PUT /users/{user_name}/todos/{todo_id} 51 | @PutMapping("/jpa/users/{username}/todos/{id}") 52 | public ResponseEntity updateTodo( 53 | @PathVariable String username, 54 | @PathVariable long id, @RequestBody Todo todo){ 55 | 56 | todo.setUsername(username); 57 | 58 | Todo todoUpdated = todoJpaRepository.save(todo); 59 | 60 | return new ResponseEntity(todo, HttpStatus.OK); 61 | } 62 | 63 | @PostMapping("/jpa/users/{username}/todos") 64 | public ResponseEntity createTodo( 65 | @PathVariable String username, @RequestBody Todo todo){ 66 | 67 | todo.setUsername(username); 68 | 69 | Todo createdTodo = todoJpaRepository.save(todo); 70 | 71 | //Location 72 | //Get current resource url 73 | ///{id} 74 | URI uri = ServletUriComponentsBuilder.fromCurrentRequest() 75 | .path("/{id}").buildAndExpand(createdTodo.getId()).toUri(); 76 | 77 | return ResponseEntity.created(uri).build(); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/todo/TodoResource.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices.todo; 2 | 3 | import java.net.URI; 4 | import java.util.List; 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.DeleteMapping; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.PutMapping; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.RestController; 16 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 17 | 18 | //@CrossOrigin(origins = "http://localhost:4200") Replace with global config 19 | @RestController 20 | public class TodoResource { 21 | 22 | @Autowired 23 | private TodoHardcodedService todoService; 24 | 25 | @GetMapping("/users/{username}/todos") 26 | public List getAllTodos(@PathVariable String username) { 27 | // Thread.sleep(3000); 28 | return todoService.findAll(); 29 | } 30 | 31 | @GetMapping("/users/{username}/todos/{id}") 32 | public Todo getTodo(@PathVariable String username, @PathVariable long id) { 33 | // Thread.sleep(3000); 34 | return todoService.findById(id); 35 | } 36 | 37 | 38 | // DELETE /users/{username}/todos/{id} 39 | @DeleteMapping("/users/{username}/todos/{id}") 40 | public ResponseEntity deleteTodo(@PathVariable String username, @PathVariable long id) { 41 | 42 | Todo todo = todoService.deleteById(id); 43 | 44 | if (todo != null) { 45 | return ResponseEntity.noContent().build(); 46 | } 47 | 48 | return ResponseEntity.notFound().build(); 49 | } 50 | 51 | //Edit/Update a Todo 52 | //PUT /users/{user_name}/todos/{todo_id} 53 | @PutMapping("/users/{username}/todos/{id}") 54 | public ResponseEntity updateTodo( 55 | @PathVariable String username, 56 | @PathVariable long id, @RequestBody Todo todo){ 57 | 58 | Todo todoUpdated = todoService.save(todo); 59 | 60 | return new ResponseEntity(todo, HttpStatus.OK); 61 | } 62 | 63 | @PostMapping("/users/{username}/todos") 64 | public ResponseEntity updateTodo( 65 | @PathVariable String username, @RequestBody Todo todo){ 66 | 67 | Todo createdTodo = todoService.save(todo); 68 | 69 | //Location 70 | //Get current resource url 71 | ///{id} 72 | URI uri = ServletUriComponentsBuilder.fromCurrentRequest() 73 | .path("/{id}").buildAndExpand(createdTodo.getId()).toUri(); 74 | 75 | return ResponseEntity.created(uri).build(); 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.jpa.show-sql=true 2 | spring.h2.console.enabled=true 3 | 4 | logging.level.org.springframework = info 5 | server.port=5000 -------------------------------------------------------------------------------- /src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | insert into todo(id, username,description,target_date,is_done) 2 | values(10001, 'in28minutes', 'Learn JPA', sysdate(), false); 3 | 4 | insert into todo(id, username,description,target_date,is_done) 5 | values(10002, 'in28minutes', 'Learn Data JPA', sysdate(), false); 6 | 7 | insert into todo(id, username,description,target_date,is_done) 8 | values(10003, 'in28minutes', 'Learn Microservices', sysdate(), false); -------------------------------------------------------------------------------- /src/test/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.in28minutes.rest.webservices.restfulwebservices; 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 RestfulWebServicesApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------