diff --git a/eureka/discovery-server/src/main/java/com/example/discovery/DiscoveryServer.java b/eureka/discovery-server/src/main/java/com/example/discovery/DiscoveryServer.java index 15d783c..8a91eb8 100644 --- a/eureka/discovery-server/src/main/java/com/example/discovery/DiscoveryServer.java +++ b/eureka/discovery-server/src/main/java/com/example/discovery/DiscoveryServer.java @@ -4,10 +4,12 @@ import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; import java.io.IOException; @SpringBootApplication +@EnableEurekaServer public class DiscoveryServer { private static Logger logger = LoggerFactory.getLogger(DiscoveryServer.class); diff --git a/eureka/discovery-server/src/main/resources/discovery-server.yml b/eureka/discovery-server/src/main/resources/discovery-server.yml index b55b43b..048af49 100644 --- a/eureka/discovery-server/src/main/resources/discovery-server.yml +++ b/eureka/discovery-server/src/main/resources/discovery-server.yml @@ -11,3 +11,11 @@ logging: root: INFO org.springframework: DEBUG com.apress.cems: DEBUG + +server: + port: 3000 + +eureka: + client: + register-with-eureka: false + fetch-registry: false \ No newline at end of file diff --git a/eureka/persons-server/src/main/java/com/eureka/persons/PersonsController.java b/eureka/persons-server/src/main/java/com/eureka/persons/PersonsController.java index ff4acb5..576fc69 100644 --- a/eureka/persons-server/src/main/java/com/eureka/persons/PersonsController.java +++ b/eureka/persons-server/src/main/java/com/eureka/persons/PersonsController.java @@ -1,5 +1,6 @@ package com.eureka.persons; +import com.eureka.persons.ex.NotFoundException; import com.eureka.persons.person.Person; import com.eureka.persons.services.PersonService; import org.springframework.http.HttpStatus; @@ -8,6 +9,7 @@ import org.springframework.web.bind.annotation.*; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; @RestController @@ -22,11 +24,18 @@ public PersonsController(PersonService personService) { /** * Handles requests to list all persons. */ - //TODO find all persons using the functions already implemented and sort them by id @ResponseStatus(HttpStatus.OK) @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) public List list() { - return new ArrayList<>(); + List persons = personService.findAll(); + persons.sort(new Comparator() { + @Override + public int compare(Person person1, Person person2) { + return person1.getId().compareTo(person2.getId()); + } + }); + + return persons; } /** @@ -34,8 +43,12 @@ public List list() { */ //TODO save a person to the db or throw PersonsException @ResponseStatus(HttpStatus.CREATED) - @PostMapping + @PostMapping(value = "/create") public void create(@RequestBody Person person, BindingResult result) { + if(!result.hasErrors()) + personService.save(person); + else + throw new PersonsException(HttpStatus.BAD_REQUEST, "It can't add a new person!"); } /** @@ -48,7 +61,7 @@ public void create(@RequestBody Person person, BindingResult result) { @ResponseStatus(HttpStatus.OK) @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE) public Person show(@PathVariable Long id) { - return new Person(); + return personService.findById(id).orElseThrow(()->new NotFoundException(Person.class,id)); } /** @@ -62,6 +75,15 @@ public Person show(@PathVariable Long id) { @ResponseStatus(HttpStatus.NO_CONTENT) @PutMapping("/{id}") public void update(@RequestBody Person updatedPerson, @PathVariable Long id) { + Person resultPerson = personService.findById(id).orElseThrow(()->new NotFoundException(Person.class,id)); + resultPerson.setFirstName(updatedPerson.getFirstName()); + resultPerson.setLastName(updatedPerson.getLastName()); + resultPerson.setUsername(updatedPerson.getUsername()); + resultPerson.setPassword(updatedPerson.getPassword()); + resultPerson.setHiringDate(updatedPerson.getHiringDate()); + resultPerson.setNewPassword(updatedPerson.getNewPassword()); + + personService.save(resultPerson); } /** @@ -73,5 +95,6 @@ public void update(@RequestBody Person updatedPerson, @PathVariable Long id) { @ResponseStatus(HttpStatus.NO_CONTENT) @DeleteMapping("/{id}") public void delete(@PathVariable Long id) { + personService.delete(personService.findById(id).orElseThrow(()->new NotFoundException(Person.class,id))); } } \ No newline at end of file diff --git a/eureka/persons-server/src/main/java/com/eureka/persons/PersonsServer.java b/eureka/persons-server/src/main/java/com/eureka/persons/PersonsServer.java index f2098ae..c23be15 100644 --- a/eureka/persons-server/src/main/java/com/eureka/persons/PersonsServer.java +++ b/eureka/persons-server/src/main/java/com/eureka/persons/PersonsServer.java @@ -5,11 +5,13 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import java.io.IOException; @EntityScan(basePackages = "com.eureka.persons") @SpringBootApplication +@EnableEurekaClient public class PersonsServer { private static Logger logger = LoggerFactory.getLogger(PersonsServer.class); diff --git a/eureka/persons-server/src/main/resources/persons-server.yml b/eureka/persons-server/src/main/resources/persons-server.yml index b2b466d..6aa9c3b 100644 --- a/eureka/persons-server/src/main/resources/persons-server.yml +++ b/eureka/persons-server/src/main/resources/persons-server.yml @@ -25,6 +25,11 @@ server: # Discovery Server Access #TODO here you add configurations for eureka client +eureka: + client: + serviceUrl: + defaultZone: http://localhost:3000/eureka/ + fetchRegistry: true info: app: @@ -38,4 +43,4 @@ logging: level: root: INFO org.springframework: DEBUG - com.apress.cems: DEBUG + com.apress.cems: DEBUG \ No newline at end of file diff --git a/eureka/src/test/java/com/example/eureka/EurekaApplicationTests.java b/eureka/src/test/java/com/example/eureka/EurekaApplicationTests.java index 1415105..98bd7a3 100644 --- a/eureka/src/test/java/com/example/eureka/EurekaApplicationTests.java +++ b/eureka/src/test/java/com/example/eureka/EurekaApplicationTests.java @@ -5,9 +5,9 @@ @SpringBootTest class EurekaApplicationTests { - - @Test - void contextLoads() { - } +// +// @Test +// void contextLoads() { +// } } diff --git a/lab-6-api-gateway/api-gateway-project/pom.xml b/lab-6-api-gateway/api-gateway-project/pom.xml index 871ce8d..32dd4c0 100644 --- a/lab-6-api-gateway/api-gateway-project/pom.xml +++ b/lab-6-api-gateway/api-gateway-project/pom.xml @@ -43,6 +43,10 @@ reactor-test test + + org.springframework.cloud + spring-cloud-netflix-eureka-server + diff --git a/lab-6-api-gateway/api-gateway-project/src/main/java/com/example/apigatewayproject/ApiGatewayProjectApplication.java b/lab-6-api-gateway/api-gateway-project/src/main/java/com/example/apigatewayproject/ApiGatewayProjectApplication.java index e0f6114..708791f 100644 --- a/lab-6-api-gateway/api-gateway-project/src/main/java/com/example/apigatewayproject/ApiGatewayProjectApplication.java +++ b/lab-6-api-gateway/api-gateway-project/src/main/java/com/example/apigatewayproject/ApiGatewayProjectApplication.java @@ -2,8 +2,11 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication +@EnableEurekaClient public class ApiGatewayProjectApplication { public static void main(String[] args) { diff --git a/lab-6-api-gateway/api-gateway-project/src/main/resources/application.yml b/lab-6-api-gateway/api-gateway-project/src/main/resources/application.yml index aaad35d..116b756 100644 --- a/lab-6-api-gateway/api-gateway-project/src/main/resources/application.yml +++ b/lab-6-api-gateway/api-gateway-project/src/main/resources/application.yml @@ -1,6 +1,29 @@ -server: - port: 8080 #TODO use eureka to discover the URL for the service1 and service2 #TODO configure spring cloud gateway to route the request to downstream services (service1 and service2) based on the paths(/api/greeting, /product) #TODO for greeting endpoint add a route to accept requests to /greeting but before calling service1 it must append api before the greeting path (HINT: rewrite path filter) -#and method types (GET,POST) \ No newline at end of file +#and method types (GET,POST) + +server: + port: 8080 +eureka: + client: + serviceUrl: + defaultZone: http://localhost:3000/eureka/ + register-with-eureka: true + fetch-registry: true +spring: + application: + name: gateway + main: + web-application-type: reactive + cloud: + gateway: + routes: + - id: service1 + uri: http://localhost:8081 + predicates: + - Path=/api/greeting/** + - id: service2 + uri: http://localhost:8082 + predicates: + - Path=/product/** \ No newline at end of file diff --git a/lab-6-api-gateway/pom.xml b/lab-6-api-gateway/pom.xml index aa491ab..12a9b1b 100644 --- a/lab-6-api-gateway/pom.xml +++ b/lab-6-api-gateway/pom.xml @@ -33,6 +33,18 @@ spring-boot-starter-test test + + org.springframework.cloud + spring-cloud-netflix-eureka-client + 3.1.1 + compile + + + org.springframework.cloud + spring-cloud-netflix-eureka-server + 3.1.1 + compile + diff --git a/lab-6-api-gateway/service1/pom.xml b/lab-6-api-gateway/service1/pom.xml index 478fe3f..0f2b7bc 100644 --- a/lab-6-api-gateway/service1/pom.xml +++ b/lab-6-api-gateway/service1/pom.xml @@ -18,10 +18,11 @@ 2021.0.1 - + org.springframework.boot spring-boot-starter-actuator @@ -36,6 +37,18 @@ spring-boot-starter-test test + + org.springframework + spring-web + + + org.springframework.cloud + spring-cloud-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-netflix-eureka-server + diff --git a/lab-6-api-gateway/service1/src/main/java/com/example/service1/Service1Application.java b/lab-6-api-gateway/service1/src/main/java/com/example/service1/Service1Application.java index 27128b5..6bc4e45 100644 --- a/lab-6-api-gateway/service1/src/main/java/com/example/service1/Service1Application.java +++ b/lab-6-api-gateway/service1/src/main/java/com/example/service1/Service1Application.java @@ -2,8 +2,13 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; @SpringBootApplication +@EnableEurekaClient public class Service1Application { public static void main(String[] args) { diff --git a/lab-6-api-gateway/service1/src/main/java/com/example/service1/Service1Controller.java b/lab-6-api-gateway/service1/src/main/java/com/example/service1/Service1Controller.java new file mode 100644 index 0000000..fdd995e --- /dev/null +++ b/lab-6-api-gateway/service1/src/main/java/com/example/service1/Service1Controller.java @@ -0,0 +1,19 @@ +package com.example.service1; + +import com.netflix.discovery.DiscoveryClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +public class Service1Controller { + + @GetMapping("/greeting/{name}") + public String greeting(@PathVariable String name) { + System.out.println(name); + return "Hello " + name + "!"; + } +} diff --git a/lab-6-api-gateway/service1/src/main/resources/application.yml b/lab-6-api-gateway/service1/src/main/resources/application.yml index 54b155f..9b6c410 100644 --- a/lab-6-api-gateway/service1/src/main/resources/application.yml +++ b/lab-6-api-gateway/service1/src/main/resources/application.yml @@ -1,2 +1,12 @@ server: - port: 8081 \ No newline at end of file + port: 8081 +spring: + application: + name: service1 + +eureka: + client: + serviceUrl: + defaultZone: http://localhost:3000/eureka/ + register-with-eureka: false + fetch-registry: false \ No newline at end of file diff --git a/lab-6-api-gateway/service2/pom.xml b/lab-6-api-gateway/service2/pom.xml index be06918..696b0df 100644 --- a/lab-6-api-gateway/service2/pom.xml +++ b/lab-6-api-gateway/service2/pom.xml @@ -22,20 +22,50 @@ org.springframework.boot spring-boot-starter-actuator + + org.springframework.boot + spring-boot-starter-tomcat + org.springframework.boot spring-boot-starter-web - + org.springframework.boot spring-boot-starter-test test + + com.netflix.eureka + eureka-client + + + jakarta.persistence + jakarta.persistence-api + + + org.jetbrains + annotations + RELEASE + compile + + + org.projectlombok + lombok + + + org.springframework.cloud + spring-cloud-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-netflix-eureka-server + diff --git a/lab-6-api-gateway/service2/src/main/java/com/example/service2/Product.java b/lab-6-api-gateway/service2/src/main/java/com/example/service2/Product.java new file mode 100644 index 0000000..574c698 --- /dev/null +++ b/lab-6-api-gateway/service2/src/main/java/com/example/service2/Product.java @@ -0,0 +1,28 @@ +package com.example.service2; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.jetbrains.annotations.NotNull; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +@Getter +@Setter +@NoArgsConstructor +public class Product { + @Id + @Column(name = "id", nullable = false) + private Long id; + + @NotNull + @Column(nullable = false, unique = true) + private String name; + + @NotNull + @Column(nullable = false, unique = true) + private int quantity; +} \ No newline at end of file diff --git a/lab-6-api-gateway/service2/src/main/java/com/example/service2/Service2Application.java b/lab-6-api-gateway/service2/src/main/java/com/example/service2/Service2Application.java index 3c2fbd2..e3aacbe 100644 --- a/lab-6-api-gateway/service2/src/main/java/com/example/service2/Service2Application.java +++ b/lab-6-api-gateway/service2/src/main/java/com/example/service2/Service2Application.java @@ -2,8 +2,11 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication +@EnableEurekaClient public class Service2Application { public static void main(String[] args) { diff --git a/lab-6-api-gateway/service2/src/main/java/com/example/service2/Service2Controller.java b/lab-6-api-gateway/service2/src/main/java/com/example/service2/Service2Controller.java new file mode 100644 index 0000000..9c25278 --- /dev/null +++ b/lab-6-api-gateway/service2/src/main/java/com/example/service2/Service2Controller.java @@ -0,0 +1,31 @@ +package com.example.service2; + +import com.netflix.discovery.DiscoveryClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.List; + +@RestController +@RequestMapping("/product") +public class Service2Controller { + + private List products = new ArrayList(); + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping() + public void greeting(@RequestBody Product product, BindingResult result) { + if(result.hasErrors()) + throw new RuntimeException("Product Exception"); + products.add(product); + } + + @GetMapping() + public List greeting() { + return products; + } +} diff --git a/lab-6-api-gateway/service2/src/main/resources/application.yml b/lab-6-api-gateway/service2/src/main/resources/application.yml index 4772153..a4c36b2 100644 --- a/lab-6-api-gateway/service2/src/main/resources/application.yml +++ b/lab-6-api-gateway/service2/src/main/resources/application.yml @@ -1,3 +1,14 @@ - server: - port: 8082 \ No newline at end of file + port: 8082 +spring: + application: + name: service2 + main: + allow-bean-definition-overriding: true + +eureka: + client: + serviceUrl: + defaultZone: http://localhost:3000/eureka/ + register-with-eureka: false + fetch-registry: false \ No newline at end of file diff --git a/lab-6-api-gateway/src/main/java/com/example/lab6apigateway/Lab6ApiGatewayApplication.java b/lab-6-api-gateway/src/main/java/com/example/lab6apigateway/Lab6ApiGatewayApplication.java index eb83cff..6ede37c 100644 --- a/lab-6-api-gateway/src/main/java/com/example/lab6apigateway/Lab6ApiGatewayApplication.java +++ b/lab-6-api-gateway/src/main/java/com/example/lab6apigateway/Lab6ApiGatewayApplication.java @@ -2,8 +2,11 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication +@EnableEurekaServer public class Lab6ApiGatewayApplication { public static void main(String[] args) { diff --git a/lab-6-api-gateway/src/main/resources/application.properties b/lab-6-api-gateway/src/main/resources/application.properties deleted file mode 100644 index 8b13789..0000000 --- a/lab-6-api-gateway/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ - diff --git a/lab-6-api-gateway/src/main/resources/application.yml b/lab-6-api-gateway/src/main/resources/application.yml new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml index 1ccc714..485c42f 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,7 @@ java8 rest-service eureka + spring1 lab-6-api-gateway