Skip to content

Commit 6214f64

Browse files
committed
Add ReadMe
1 parent 2a50cf6 commit 6214f64

File tree

4 files changed

+167
-11
lines changed

4 files changed

+167
-11
lines changed

README.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Challenge with Java BE
2+
3+
This is a simple project with a challenge for Backend developers.
4+
5+
## In this project you will learn:
6+
7+
* Consuming API (Feign)
8+
* Creating API REST (Spring Web)
9+
* Create a database (Spring Data)
10+
* Create a CircuitBreak & RateLimiter (Resilience4J)
11+
* Different Roles & JWT (Spring Security)
12+
* JUnit, Mockito, MockMvc
13+
* H2/Postgres
14+
* Cache with Hazelcast
15+
* Swagger
16+
* Sonar
17+
* CI/CD
18+
* Docker
19+
* Kubernetes
20+
* Deploy in Cloud
21+
22+
## Tasks:
23+
24+
### LVL 1
25+
26+
**Goals:**
27+
* Create the project
28+
* Create the database using H2
29+
* Create the user entity, and Roles
30+
* Include JWT authentication
31+
* Create the login/registration/upgrade-permissions endpoints
32+
33+
**Expected time:** 16 | 8 | 4 hours
34+
35+
#### Create your project
36+
37+
- [ ] Create the database using [H2](https://www.h2database.com/html/main.html). You should include the user table, the user can have multiple roles.
38+
- [ ] Create an endpoint to create a user. (The user should have a username and a password, be careful when saving the user password, and the roles)
39+
- [ ] Create an endpoint to update the permission to this user to ADMIN and/or USER role. This API could be called just by the ADMIN user, see @Secured and Roles in Spring Security.
40+
41+
#### Create the authentication for your API
42+
43+
- [ ] Create the authentication using JWT
44+
- [ ] Create two roles ADMIN, USER
45+
- [ ] Create an endpoint to return the JWT (5 minutes of timeout), receive the username and password
46+
47+
* Book: REST API - Design Rulebook : Mark Masse: https://www.oreilly.com/library/view/rest-api-design/9781449317904/
48+
* Spring Data: https://www.baeldung.com/the-persistence-layer-with-spring-data-jpa
49+
* Spring REST - Full Tutorial: https://www.baeldung.com/rest-with-spring-series
50+
* Spring REST: https://spring.io/guides/tutorials/rest/
51+
* Spring Security: https://www.toptal.com/spring/spring-security-tutorial
52+
* Spring Security JWT: https://www.bezkoder.com/spring-boot-jwt-authentication/
53+
54+
### LVL 2
55+
56+
**Expected time:** 16 | 9 | 5 hours
57+
58+
#### Upgrade your API REST
59+
60+
- [ ] Create an endpoint to consume an API from IMDB (https://imdb-api.com/) and populate your database (you can use WebClient or Feign to consume the API). This API could be called just by the ADMIN user, see @Secured and Roles in Spring Security.
61+
- [ ] Create an endpoint to list all the movies.
62+
- [ ] Create an endpoint to include a movie to the user (favorite list)
63+
- [ ] Create an endpoint to exclude the movie from the favorite list
64+
- [ ] Each time the user includes the movie in the favorite list add one "star" to the movie
65+
- [ ] Create an endpoint to list the top 10 movies, the movies with more stars.
66+
- [ ] Create an endpoint to list the favorite movies per user.
67+
- [ ] Don't forget to include Swagger/OpenAPI, and the test.
68+
69+
#### Content to help:
70+
71+
* Spring Test: https://www.baeldung.com/integration-testing-in-spring
72+
* Open API: https://www.baeldung.com/spring-rest-openapi-documentation
73+
* WebClient: https://www.baeldung.com/spring-5-webclient
74+
* Feign: https://www.baeldung.com/intro-to-feign
75+
76+
----------
77+
78+
### LVL 3
79+
80+
**Expected time:** 18 | 11 | 7 hours
81+
82+
#### Include Hazelcast, design pattern, Resilience4J
83+
84+
- [ ] Include this rank top movies in the cache (Hazelcast), and get from it using RateLimiter (https://resilience4j.readme.io/docs/ratelimiter) as fallback.
85+
- [ ] Find another API to get Movies, and update the first endpoint to use the template method design pattern to be able to get the movies from both APIs. Use a CircuitBreak for that. If you have any problem with one API you should get it from the other API as a fallback. (You can try changing the API Key)
86+
- [ ] Create a new endpoint to send a random movie to the user.
87+
This endpoint should do this: find another user who likes the same movies as the current user and upload a random movie from that favorites list.
88+
If this condition does not exist, just send a random movie.
89+
90+
#### Content to help:
91+
92+
* Guide to Resilience4j: https://www.baeldung.com/resilience4j
93+
* RateLimiter: https://resilience4j.readme.io/docs/ratelimiter
94+
* Caching with Spring Boot and Hazelcast: https://hazelcast.com/blog/spring-boot/
95+
* Get Started with Hazelcast using Spring Boot: https://docs.hazelcast.com/tutorials/hazelcast-embedded-springboot
96+
* Template Method: https://refactoring.guru/design-patterns/template-method
97+
* Failover: https://medium.com/lydtech-consulting/failover-and-circuit-breaker-with-resilience4j-14a57a43c0da
98+
99+
----------
100+
101+
### LVL 4
102+
103+
**Expected time:** 21 | 14 | 8 hours
104+
105+
#### Part 1 - Docker, Kubernetes
106+
107+
- [ ] Run your application using Docker, create a docker file.
108+
- [ ] Create the files to deploy the application using kubernetes.
109+
- [ ] Include the probes from actuator in your deployment.yaml
110+
- [ ] Deploy your application in local environment using Kubernetes.
111+
112+
113+
**Expected time:** 27 | 17 | 7 hours
114+
115+
#### Part 2 - Deploy in the cloud, Openshift
116+
117+
- [ ] Include postgres to your production environment
118+
- [ ] Include all the yaml files that are required to deploy the hazelcast and postgres
119+
- [ ] Do the deployment into sandbox Openshift (https://developers.redhat.com/developer-sandbox)
120+
- [ ] Create a service and a route for your application to expose your application to internet.
121+
- [ ] Create a document with step-by-step on how to deploy the application in the Openshift
122+
123+
124+
#### Content to help:
125+
126+
* Spring Boot Actuator: https://www.baeldung.com/spring-boot-actuators
127+
* Spring Boot with Docker: https://spring.io/guides/gs/spring-boot-docker/
128+
* Hazelcast Config: https://docs.hazelcast.com/imdg/4.2/configuration/configuring-declaratively
129+
* Kubernetes Tutorial: https://medium.com/@javatechie/kubernetes-tutorial-run-deploy-spring-boot-application-in-k8s-cluster-using-yaml-configuration-3b079154d232
130+
* Postgres K8s: https://www.sumologic.com/blog/kubernetes-deploy-postgres/
131+
* Book: Modernizing Enterprise Java: https://developers.redhat.com/e-books/modernizing-enterprise-java
132+
133+
----------
134+
135+
### LVL 5
136+
137+
#### Pipeline, CI/CD, Sonar
138+
139+
- [ ] Include SonarCloud in your project, make sure the coverage is above 70% and you don't have a loud code smell.
140+
- [ ] Include a pipeline, you can use gitHub Actions, or Travis CI, use what you prefer. Your CI pipeline should include [build, test, sonar]
141+
- [ ] Include also CD in your pipeline, it should be able to deploy in the Cloud.
142+
143+
#### Content to help:
144+
145+
* SonarCloud Integration with SpringBoot-Maven: https://medium.com/@bethecodewithyou/sonarcloud-integration-with-springboot-maven-5820180ef764
146+
* How to build a CI/CD pipeline with GitHub Actions in four simple steps: https://github.blog/2022-02-02-build-ci-cd-pipeline-github-actions-four-steps/
147+
* The twelve-factor: https://12factor.net/
148+
* Travis CI: https://www.travis-ci.org/
149+
150+
151+

src/main/java/org/sid/jwtservice/JwtServiceApplication.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ CommandLineRunner start(AccountService accountService){
3939
accountService.addNewUser(new AppUser(null, "user3", "12345", new ArrayList<>()));
4040
accountService.addNewUser(new AppUser(null, "user2", "12345", new ArrayList<>()));
4141
accountService.addNewUser(new AppUser(null, "user4", "12345", new ArrayList<>()));
42+
accountService.addNewUser(new AppUser(null, "user5", "123456", new ArrayList<>()));
4243

4344
accountService.addRoleToUser("user1", "USER");
4445
accountService.addRoleToUser("admin", "USER");
@@ -49,6 +50,8 @@ CommandLineRunner start(AccountService accountService){
4950
accountService.addRoleToUser("user3", "PRODUCT_MANAGER");
5051
accountService.addRoleToUser("user4", "USER");
5152
accountService.addRoleToUser("user4", "BILLS_MANAGER");
53+
accountService.addRoleToUser("user5", "BILLS_MANAGER");
54+
5255
};
5356
}
5457

src/main/java/org/sid/jwtservice/securityp/web/AccountRestController.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@
55
import org.sid.jwtservice.securityp.entities.AppRole;
66
import org.sid.jwtservice.securityp.entities.AppUser;
77
import org.sid.jwtservice.securityp.service.AccountService;
8-
import org.springframework.web.bind.annotation.GetMapping;
9-
import org.springframework.web.bind.annotation.PostMapping;
10-
import org.springframework.web.bind.annotation.RequestBody;
11-
import org.springframework.web.bind.annotation.RestController;
8+
import org.springframework.web.bind.annotation.*;
129

1310
import java.util.List;
1411

1512
@RestController
13+
@RequestMapping(value = "/users")
1614
public class AccountRestController {
1715
private AccountService accountService;
1816

@@ -21,12 +19,12 @@ public AccountRestController(AccountService accountService) {
2119
this.accountService = accountService;
2220
}
2321

24-
@GetMapping(path="/users")
22+
@GetMapping
2523
public List<AppUser> appUser(){
2624
return accountService.listUsers();
2725
}
2826

29-
@PostMapping(path="/users")
27+
@PostMapping
3028
public AppUser saveUser(@RequestBody AppUser appUser){
3129
return accountService.addNewUser(appUser);
3230
}
@@ -42,8 +40,3 @@ public void addRoleToUser(@RequestBody RoleUserForm roleUserForm){
4240
}
4341
}
4442

45-
@Data
46-
class RoleUserForm{
47-
private String username;
48-
private String roleName;
49-
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.sid.jwtservice.securityp.web;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class RoleUserForm {
7+
private String username;
8+
private String roleName;
9+
}

0 commit comments

Comments
 (0)