diff --git a/eureka/persons-server/pom.xml b/eureka/persons-server/pom.xml
index b342d8e..0f0f141 100644
--- a/eureka/persons-server/pom.xml
+++ b/eureka/persons-server/pom.xml
@@ -70,6 +70,48 @@
org.projectlombok
lombok
+
+ org.springframework
+ spring-tx
+
+
+ org.springframework
+ spring-tx
+ 5.3.15
+
+
+ org.springframework.data
+ spring-data-jpa
+ 2.6.1
+
+
+ org.springframework.data
+ spring-data-commons
+ 2.6.1
+
+
+ org.hibernate.javax.persistence
+ hibernate-jpa-2.1-api
+ 2.2
+
+
+ org.hibernate
+ hibernate-core
+ 6.0.0.Alpha6
+
+
+ org.assertj
+ assertj-core
+
+
+ org.hibernate
+ hibernate-core
+ 5.2.12.Final
+
+
+ net.bytebuddy
+ byte-buddy
+
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..ba2f625 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,7 @@
package com.eureka.persons;
+import com.eureka.persons.base.AbstractEntity;
+import com.eureka.persons.ex.NotFoundException;
import com.eureka.persons.person.Person;
import com.eureka.persons.services.PersonService;
import org.springframework.http.HttpStatus;
@@ -7,8 +9,9 @@
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
-import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
+import java.util.Optional;
@RestController
@RequestMapping("/persons")
@@ -26,7 +29,10 @@ public PersonsController(PersonService personService) {
@ResponseStatus(HttpStatus.OK)
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public List list() {
- return new ArrayList<>();
+ List people = personService.findAll();
+ people.sort(Comparator.comparing(AbstractEntity::getId));
+
+ return people;
}
/**
@@ -36,6 +42,11 @@ public List list() {
@ResponseStatus(HttpStatus.CREATED)
@PostMapping
public void create(@RequestBody Person person, BindingResult result) {
+ if (result.hasErrors()) {
+ throw new PersonsException(HttpStatus.BAD_REQUEST, "Person could not be created!");
+ }
+
+ personService.save(person);
}
/**
@@ -48,7 +59,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 +73,16 @@ public Person show(@PathVariable Long id) {
@ResponseStatus(HttpStatus.NO_CONTENT)
@PutMapping("/{id}")
public void update(@RequestBody Person updatedPerson, @PathVariable Long id) {
+ Person person = show(id);
+
+ person.setUsername(updatedPerson.getUsername());
+ person.setFirstName(updatedPerson.getFirstName());
+ person.setLastName(updatedPerson.getLastName());
+ person.setPassword(updatedPerson.getPassword());
+ person.setHiringDate(updatedPerson.getHiringDate());
+ person.setNewPassword(updatedPerson.getNewPassword());
+
+ personService.save(person);
}
/**
@@ -73,5 +94,7 @@ public void update(@RequestBody Person updatedPerson, @PathVariable Long id) {
@ResponseStatus(HttpStatus.NO_CONTENT)
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id) {
+ Person person = show(id);
+ personService.delete(person);
}
}
\ 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/java/com/eureka/persons/base/AbstractEntity.java b/eureka/persons-server/src/main/java/com/eureka/persons/base/AbstractEntity.java
index 199103b..448a274 100644
--- a/eureka/persons-server/src/main/java/com/eureka/persons/base/AbstractEntity.java
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/base/AbstractEntity.java
@@ -1,17 +1,25 @@
package com.eureka.persons.base;
-import com.eureka.persons.util.DateProcessor;
-import com.fasterxml.jackson.annotation.JsonFormat;
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.Objects;
+import javax.persistence.Column;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Version;
+
+import org.springframework.format.annotation.DateTimeFormat;
+
+import com.eureka.persons.util.DateProcessor;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import lombok.Getter;
+import lombok.Setter;
+
@MappedSuperclass
@Getter
@Setter
@@ -24,6 +32,14 @@ public abstract class AbstractEntity implements Serializable {
@Column(updatable = false)
protected Long id;
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
@Version
protected int version;
diff --git a/eureka/persons-server/src/main/java/com/eureka/persons/person/Person.java b/eureka/persons-server/src/main/java/com/eureka/persons/person/Person.java
index 9064df8..b06b109 100644
--- a/eureka/persons-server/src/main/java/com/eureka/persons/person/Person.java
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/person/Person.java
@@ -23,7 +23,8 @@
@Setter
@NoArgsConstructor
public class Person extends AbstractEntity {
- interface BasicValidation{}
+ interface BasicValidation {
+ }
@NotNull(groups = BasicValidation.class)
@Size(min = 3, max = 30, groups = BasicValidation.class)
@@ -77,6 +78,54 @@ public String toString() {
return String.format("Person[username='%s', firstName='%s', lastName='%s', hiringDate='%s']\n",
username, firstName, lastName, hiringDate.toString());
+
+ }
+
+ public String getUsername() {
+ return username;
}
-}
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public LocalDateTime getHiringDate() {
+ return hiringDate;
+ }
+
+ public void setHiringDate(LocalDateTime hiringDate) {
+ this.hiringDate = hiringDate;
+ }
+
+ public String getNewPassword() {
+ return newPassword;
+ }
+
+ public void setNewPassword(String newPassword) {
+ this.newPassword = newPassword;
+ }
+}
\ No newline at end of file
diff --git a/eureka/persons-server/src/main/resources/persons-server.yml b/eureka/persons-server/src/main/resources/persons-server.yml
index b2b466d..ae83478 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:
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..40c14f3 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,5 +1,31 @@
server:
port: 8080
+ address: 0.0.0.0
+
+ 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/**
+
#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)
diff --git a/lab-6-api-gateway/service1/pom.xml b/lab-6-api-gateway/service1/pom.xml
index 478fe3f..22377d7 100644
--- a/lab-6-api-gateway/service1/pom.xml
+++ b/lab-6-api-gateway/service1/pom.xml
@@ -18,10 +18,10 @@
2021.0.1
-
+
org.springframework.boot
spring-boot-starter-actuator
@@ -30,24 +30,27 @@
org.springframework.boot
spring-boot-starter-web
-
+
+ org.springframework.cloud
+ spring-cloud-netflix-eureka-client
+
org.springframework.boot
spring-boot-starter-test
test
-
-
-
- org.springframework.cloud
- spring-cloud-dependencies
- ${spring-cloud.version}
- pom
- import
-
-
-
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
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..ae276e7 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,7 +2,9 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+@EnableEurekaClient
@SpringBootApplication
public class Service1Application {
diff --git a/lab-6-api-gateway/service1/src/main/java/com/example/service1/controller/Service1Controller.java b/lab-6-api-gateway/service1/src/main/java/com/example/service1/controller/Service1Controller.java
new file mode 100644
index 0000000..b93cf1f
--- /dev/null
+++ b/lab-6-api-gateway/service1/src/main/java/com/example/service1/controller/Service1Controller.java
@@ -0,0 +1,21 @@
+package com.example.service1.controller;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api")
+public class Service1Controller {
+
+ @ResponseStatus(HttpStatus.OK)
+ @GetMapping(value = "/greeting/{name}")
+ public String greeting(@PathVariable String name, @RequestHeader Map headers) {
+ System.out.println("Headers:");
+ for (Map.Entry header : headers.entrySet()) {
+ System.out.println(header);
+ }
+ return String.format("Hello, %s!", 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..7b37856 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,14 @@
server:
- port: 8081
\ No newline at end of file
+ port: 8081
+ address: 0.0.0.0
+
+ spring:
+ application:
+ name: service1
+
+ eureka:
+ client:
+ serviceUrl:
+ defaultZone: http://localhost:3000/eureka/
+ register-with-eureka: true
+ fetch-registry: true
\ 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..a3e7960 100644
--- a/lab-6-api-gateway/service2/pom.xml
+++ b/lab-6-api-gateway/service2/pom.xml
@@ -26,16 +26,32 @@
org.springframework.boot
spring-boot-starter-web
-
+
org.springframework.boot
spring-boot-starter-test
test
+
+ org.springframework.cloud
+ spring-cloud-netflix-eureka-client
+
+
+ org.hibernate
+ hibernate-core
+
+
+ org.projectlombok
+ lombok
+
+
+ org.projectlombok
+ lombok
+
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..b87df25 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,7 +2,9 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+@EnableEurekaClient
@SpringBootApplication
public class Service2Application {
diff --git a/lab-6-api-gateway/service2/src/main/java/com/example/service2/controller/Service2Controller.java b/lab-6-api-gateway/service2/src/main/java/com/example/service2/controller/Service2Controller.java
new file mode 100644
index 0000000..ea9bc8f
--- /dev/null
+++ b/lab-6-api-gateway/service2/src/main/java/com/example/service2/controller/Service2Controller.java
@@ -0,0 +1,34 @@
+package com.example.service2.controller;
+
+import com.example.service2.model.Product;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/product")
+public class Service2Controller {
+ private List products = new ArrayList();
+
+ @PostMapping()
+ @ResponseStatus(HttpStatus.OK)
+ public void addProduct(@RequestBody Product product, @RequestHeader Map headers) {
+ for (Map.Entry header : headers.entrySet()) {
+ System.out.println(header);
+ }
+ products.add(product);
+ }
+
+ @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
+ @ResponseStatus(HttpStatus.OK)
+ public List getProducts(@RequestHeader Map headers) {
+ for (Map.Entry header : headers.entrySet()) {
+ System.out.println(header);
+ }
+ return products;
+ }
+}
diff --git a/lab-6-api-gateway/service2/src/main/java/com/example/service2/model/Product.java b/lab-6-api-gateway/service2/src/main/java/com/example/service2/model/Product.java
new file mode 100644
index 0000000..c19f296
--- /dev/null
+++ b/lab-6-api-gateway/service2/src/main/java/com/example/service2/model/Product.java
@@ -0,0 +1,24 @@
+package com.example.service2.model;
+
+import com.sun.istack.NotNull;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+
+@Entity
+@Getter
+@Setter
+@NoArgsConstructor
+public class Product {
+
+ @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/resources/application.yml b/lab-6-api-gateway/service2/src/main/resources/application.yml
index 4772153..41d64e3 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
+ address: 0.0.0.0
+
+ spring:
+ application:
+ name: service2
+
+ eureka:
+ client:
+ serviceUrl:
+ defaultZone: http://localhost:3000/eureka/
+ register-with-eureka: true
+ fetch-registry: true
\ No newline at end of file
diff --git a/recipe/HELP.md b/recipe/HELP.md
new file mode 100644
index 0000000..e0690dd
--- /dev/null
+++ b/recipe/HELP.md
@@ -0,0 +1,9 @@
+# Getting Started
+
+### Reference Documentation
+For further reference, please consider the following sections:
+
+* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
+* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.6.5/maven-plugin/reference/html/)
+* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.6.5/maven-plugin/reference/html/#build-image)
+
diff --git a/recipe/target/classes/application.properties b/recipe/target/classes/application.properties
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/recipe/target/classes/application.properties
@@ -0,0 +1 @@
+
diff --git a/spring2/target/classes/application.properties b/spring2/target/classes/application.properties
new file mode 100644
index 0000000..a8d8dfc
--- /dev/null
+++ b/spring2/target/classes/application.properties
@@ -0,0 +1 @@
+car.model=Audi
\ No newline at end of file
diff --git a/spring2/target/classes/profiles.properties b/spring2/target/classes/profiles.properties
new file mode 100644
index 0000000..eedfad6
--- /dev/null
+++ b/spring2/target/classes/profiles.properties
@@ -0,0 +1 @@
+spring.profiles.active=DEV
\ No newline at end of file