diff --git a/eureka/.gitignore b/eureka/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/eureka/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/eureka/discovery-server/.gitignore b/eureka/discovery-server/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/eureka/discovery-server/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/eureka/discovery-server/pom.xml b/eureka/discovery-server/pom.xml
new file mode 100644
index 0000000..d9e9e18
--- /dev/null
+++ b/eureka/discovery-server/pom.xml
@@ -0,0 +1,57 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.4
+
+
+ com.example
+ discovery-server
+ 0.0.1-SNAPSHOT
+ discovery-server
+ discovery-server
+
+ 11
+ 2021.0.1
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-eureka-client
+
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-eureka-server
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
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
new file mode 100644
index 0000000..15d783c
--- /dev/null
+++ b/eureka/discovery-server/src/main/java/com/example/discovery/DiscoveryServer.java
@@ -0,0 +1,25 @@
+package com.example.discovery;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import java.io.IOException;
+
+@SpringBootApplication
+public class DiscoveryServer {
+
+ private static Logger logger = LoggerFactory.getLogger(DiscoveryServer.class);
+
+ public static void main(String... args) throws IOException {
+ // Look for configuration in discovery-server.properties or discovery-server.yml
+ System.setProperty("spring.config.name", "discovery-server");
+
+ var ctx = SpringApplication.run(DiscoveryServer.class, args);
+ assert (ctx != null);
+ logger.info("Started ...");
+ System.in.read();
+ ctx.close();
+ }
+}
diff --git a/eureka/discovery-server/src/main/resources/discovery-server.yml b/eureka/discovery-server/src/main/resources/discovery-server.yml
new file mode 100644
index 0000000..b55b43b
--- /dev/null
+++ b/eureka/discovery-server/src/main/resources/discovery-server.yml
@@ -0,0 +1,13 @@
+spring:
+ application:
+ name: discovery-service
+# Configure this Discovery Server
+#TODO here you add configurations for server
+
+logging:
+ pattern:
+ console: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
+ level:
+ root: INFO
+ org.springframework: DEBUG
+ com.apress.cems: DEBUG
diff --git a/eureka/discovery-server/src/test/java/com/example/discoveryserver/DiscoveryServerApplicationTests.java b/eureka/discovery-server/src/test/java/com/example/discoveryserver/DiscoveryServerApplicationTests.java
new file mode 100644
index 0000000..f102053
--- /dev/null
+++ b/eureka/discovery-server/src/test/java/com/example/discoveryserver/DiscoveryServerApplicationTests.java
@@ -0,0 +1,13 @@
+package com.example.discoveryserver;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class DiscoveryServerApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/eureka/persons-server/.gitignore b/eureka/persons-server/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/eureka/persons-server/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/eureka/persons-server/pom.xml b/eureka/persons-server/pom.xml
new file mode 100644
index 0000000..b342d8e
--- /dev/null
+++ b/eureka/persons-server/pom.xml
@@ -0,0 +1,96 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.4
+
+
+ com.example
+ persons-server
+ 0.0.1-SNAPSHOT
+ persons-server
+ persons-server
+
+ 11
+ 2021.0.1
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-eureka-client
+
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-eureka-server
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ com.h2database
+ h2
+ 2.1.210
+ runtime
+
+
+ com.sun.jersey.contribs
+ jersey-apache-client4
+ 1.19.4
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.13.1
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.13.1
+
+
+ javax.validation
+ validation-api
+ 2.0.1.Final
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/eureka/persons-server/src/main/java/com/eureka/persons/PersonRepo.java b/eureka/persons-server/src/main/java/com/eureka/persons/PersonRepo.java
new file mode 100644
index 0000000..5e7b169
--- /dev/null
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/PersonRepo.java
@@ -0,0 +1,36 @@
+package com.eureka.persons;
+
+import com.eureka.persons.person.Person;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
+
+@Repository
+public interface PersonRepo extends JpaRepository {
+
+ @Query("select p from Person p where p.username like %?1%")
+ Optional findByUsername(String username);
+
+ @Query("select p from Person p where p.username like %?1%")
+ List findByUsernameLike(String username);
+
+ @Query("select p from Person p where p.firstName=:fn")
+ List findByFirstName(@Param("fn") String firstName);
+
+ @Query("select p from Person p where p.firstName like %?1%")
+ List findByFirstNameLike(String firstName);
+
+ @Query("select p from Person p where p.lastName=:ln")
+ List findByLastName(@Param("ln") String lastName);
+
+ @Query("select p from Person p where p.lastName like %?1%")
+ List findByLastNameLike(String lastName);
+
+ @Query("select p from Person p where p.hiringDate=:hd")
+ List findByHiringDate(@Param("hd") LocalDateTime date);
+}
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
new file mode 100644
index 0000000..ff4acb5
--- /dev/null
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/PersonsController.java
@@ -0,0 +1,77 @@
+package com.eureka.persons;
+
+import com.eureka.persons.person.Person;
+import com.eureka.persons.services.PersonService;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("/persons")
+public class PersonsController {
+ private PersonService personService;
+
+ public PersonsController(PersonService personService) {
+ this.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<>();
+ }
+
+ /**
+ * Handles requests to create a person.
+ */
+ //TODO save a person to the db or throw PersonsException
+ @ResponseStatus(HttpStatus.CREATED)
+ @PostMapping
+ public void create(@RequestBody Person person, BindingResult result) {
+ }
+
+ /**
+ * Returns the {@code Person} instance with id {@code id}
+ *
+ * @param id
+ * @return
+ */
+ //TODO find a person by id or throw NotFoundException
+ @ResponseStatus(HttpStatus.OK)
+ @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
+ public Person show(@PathVariable Long id) {
+ return new Person();
+ }
+
+ /**
+ * Updates the {@code Person} instance with id {@code id}
+ *
+ * @param updatedPerson
+ * @param id
+ * @return
+ */
+ //TODO update an existing person if found else throw NotFoundException
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ @PutMapping("/{id}")
+ public void update(@RequestBody Person updatedPerson, @PathVariable Long id) {
+ }
+
+ /**
+ * Delete the {@code Person} instance with id {@code id}
+ *
+ * @param id
+ */
+ //TODO delete a person
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ @DeleteMapping("/{id}")
+ public void delete(@PathVariable Long id) {
+ }
+}
\ No newline at end of file
diff --git a/eureka/persons-server/src/main/java/com/eureka/persons/PersonsException.java b/eureka/persons-server/src/main/java/com/eureka/persons/PersonsException.java
new file mode 100644
index 0000000..781c4f6
--- /dev/null
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/PersonsException.java
@@ -0,0 +1,17 @@
+package com.eureka.persons;
+
+import org.springframework.http.HttpStatus;
+
+public class PersonsException extends RuntimeException{
+ private HttpStatus status;
+
+ public PersonsException(HttpStatus status, String message) {
+ super(message);
+ this.status = status;
+ }
+
+ public PersonsException(HttpStatus status, Throwable cause) {
+ super(cause);
+ this.status = status;
+ }
+}
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
new file mode 100644
index 0000000..f2098ae
--- /dev/null
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/PersonsServer.java
@@ -0,0 +1,27 @@
+package com.eureka.persons;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+
+import java.io.IOException;
+
+@EntityScan(basePackages = "com.eureka.persons")
+@SpringBootApplication
+public class PersonsServer {
+
+ private static Logger logger = LoggerFactory.getLogger(PersonsServer.class);
+
+ public static void main(String... args) throws IOException {
+ // Look for configuration in persons-server.properties or persons-server.yml
+ System.setProperty("spring.config.name", "persons-server");
+
+ var ctx = SpringApplication.run(PersonsServer.class, args);
+ assert (ctx != null);
+ logger.info("Started ...");
+ System.in.read();
+ ctx.close();
+ }
+}
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
new file mode 100644
index 0000000..199103b
--- /dev/null
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/base/AbstractEntity.java
@@ -0,0 +1,70 @@
+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;
+
+@MappedSuperclass
+@Getter
+@Setter
+public abstract class AbstractEntity implements Serializable {
+
+ public static Comparator COMPARATOR_BY_ID = Comparator.comparing(AbstractEntity::getId);
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ @Column(updatable = false)
+ protected Long id;
+
+ @Version
+ protected int version;
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DateProcessor.DATE_FORMAT)
+ @Column(name = "created_at", nullable = false)
+ @DateTimeFormat(pattern = DateProcessor.DATE_FORMAT)
+ protected LocalDateTime createdAt;
+
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DateProcessor.DATE_FORMAT)
+ @Column(name = "modified_at", nullable = false)
+ @DateTimeFormat(pattern = DateProcessor.DATE_FORMAT)
+ protected LocalDateTime modifiedAt;
+
+ /**
+ * This constructor is required by JPA. All subclasses of this class will inherit this constructor.
+ */
+ protected AbstractEntity() {
+ createdAt = LocalDateTime.now();
+ modifiedAt = LocalDateTime.now();
+ }
+
+ // IDE generated methods
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ var that = (AbstractEntity) o;
+ if (!Objects.equals(id, that.id)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return id != null ? id.hashCode() : 0;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("AbstractEntity[id='%d%n', createdAt='%s', modifiedAt='%s', version='%d%n']",
+ id, DateProcessor.toString(createdAt), DateProcessor.toString(modifiedAt), version);
+ }
+}
diff --git a/eureka/persons-server/src/main/java/com/eureka/persons/ex/NotFoundException.java b/eureka/persons-server/src/main/java/com/eureka/persons/ex/NotFoundException.java
new file mode 100644
index 0000000..094ecec
--- /dev/null
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/ex/NotFoundException.java
@@ -0,0 +1,7 @@
+package com.eureka.persons.ex;
+
+public class NotFoundException extends RuntimeException {
+ public NotFoundException(Class cls, Long id) {
+ super(cls.getSimpleName() + " with id: " + id + " does not exist!");
+ }
+}
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
new file mode 100644
index 0000000..9064df8
--- /dev/null
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/person/Person.java
@@ -0,0 +1,82 @@
+package com.eureka.persons.person;
+
+import com.eureka.persons.base.AbstractEntity;
+import com.eureka.persons.util.DateProcessor;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Transient;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.time.LocalDateTime;
+import java.util.Objects;
+
+@Entity
+@Getter
+@Setter
+@NoArgsConstructor
+public class Person extends AbstractEntity {
+ interface BasicValidation{}
+
+ @NotNull(groups = BasicValidation.class)
+ @Size(min = 3, max = 30, groups = BasicValidation.class)
+ @Column(nullable = false, unique = true)
+ private String username;
+
+ @NotNull(groups = BasicValidation.class)
+ @Size(min = 3, max = 30, groups = BasicValidation.class)
+ @Column(nullable = false)
+ private String firstName;
+
+ @NotNull(groups = BasicValidation.class)
+ @Size(min = 3, max = 30, groups = BasicValidation.class)
+ @Column(nullable = false)
+ private String lastName;
+
+ @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
+ @NotNull
+ @Size(min = 4, max = 50)
+ @Column(nullable = false)
+ private String password;
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DateProcessor.DATE_FORMAT)
+ @NotNull(groups = BasicValidation.class)
+ @Column(nullable = false)
+ @DateTimeFormat(pattern = DateProcessor.DATE_FORMAT)
+ private LocalDateTime hiringDate;
+
+ @JsonIgnore
+ @Transient
+ private String newPassword;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ var person = (Person) o;
+ if (!Objects.equals(id, person.id)) return false;
+ return Objects.equals(firstName, person.firstName) &&
+ Objects.equals(lastName, person.lastName) &&
+ Objects.equals(hiringDate.toLocalDate(), person.hiringDate.toLocalDate());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), firstName, lastName, hiringDate.toLocalDate());
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Person[username='%s', firstName='%s', lastName='%s', hiringDate='%s']\n",
+ username, firstName, lastName, hiringDate.toString());
+
+ }
+
+}
diff --git a/eureka/persons-server/src/main/java/com/eureka/persons/services/Initializer.java b/eureka/persons-server/src/main/java/com/eureka/persons/services/Initializer.java
new file mode 100644
index 0000000..22024a4
--- /dev/null
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/services/Initializer.java
@@ -0,0 +1,65 @@
+package com.eureka.persons.services;
+
+import com.eureka.persons.person.Person;
+import com.eureka.persons.util.DateProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.PostConstruct;
+
+@Service
+@Transactional
+public class Initializer {
+ private Logger logger = LoggerFactory.getLogger(Initializer.class);
+
+ private PersonService personService;
+
+ public Initializer(PersonService personService) {
+ this.personService = personService;
+ }
+
+ @PostConstruct
+ public void init() {
+ logger.info(" -->> Starting database initialization...");
+ if (personService.findAll().isEmpty()) {
+ createPersons();
+ }
+ logger.info(" -->> Database initialization finished.");
+ }
+
+ private void createPersons() {
+ Person person = new Person();
+ person.setUsername("sherlock.holmes");
+ person.setFirstName("Sherlock");
+ person.setLastName("Holmes");
+ person.setPassword("dudu");
+ person.setHiringDate(DateProcessor.toDate("1983-08-15 00:23"));
+ personService.save(person);
+
+ person = new Person();
+ person.setUsername("jackson.brodie");
+ person.setFirstName("Jackson");
+ person.setLastName("Brodie");
+ person.setPassword("bagy");
+ person.setHiringDate(DateProcessor.toDate("1983-06-22 00:23"));
+ personService.save(person);
+
+ person = new Person();
+ person.setUsername("nancy.drew");
+ person.setFirstName("Nancy");
+ person.setLastName("Drew");
+ person.setPassword("dada45");
+ person.setHiringDate(DateProcessor.toDate("1990-05-21 00:23"));
+ personService.save(person);
+
+ person = new Person();
+ person.setUsername("irene.adler");
+ person.setFirstName("Irene");
+ person.setLastName("Adler");
+ person.setPassword("xxxyy");
+ person.setHiringDate(DateProcessor.toDate("1987-03-11 00:23"));
+ personService.save(person);
+ }
+}
\ No newline at end of file
diff --git a/eureka/persons-server/src/main/java/com/eureka/persons/services/PersonService.java b/eureka/persons-server/src/main/java/com/eureka/persons/services/PersonService.java
new file mode 100644
index 0000000..0f86a73
--- /dev/null
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/services/PersonService.java
@@ -0,0 +1,16 @@
+package com.eureka.persons.services;
+
+import com.eureka.persons.person.Person;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface PersonService {
+ List findAll();
+
+ Optional findById(Long id);
+
+ Person save(Person person);
+
+ void delete(Person person);
+}
\ No newline at end of file
diff --git a/eureka/persons-server/src/main/java/com/eureka/persons/services/PersonServiceImpl.java b/eureka/persons-server/src/main/java/com/eureka/persons/services/PersonServiceImpl.java
new file mode 100644
index 0000000..f1c2fec
--- /dev/null
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/services/PersonServiceImpl.java
@@ -0,0 +1,42 @@
+package com.eureka.persons.services;
+
+import com.eureka.persons.PersonRepo;
+import com.eureka.persons.person.Person;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Optional;
+
+@Service
+@Transactional
+public class PersonServiceImpl implements PersonService {
+ private PersonRepo personRepo;
+
+ public PersonServiceImpl(PersonRepo personRepo) {
+ this.personRepo = personRepo;
+ }
+
+ @Override
+ public List findAll() {
+ return personRepo.findAll();
+ }
+
+ @Override
+ public Optional findById(Long id) {
+ return personRepo.findById(id);
+ }
+
+
+ @Override
+ public Person save(Person person) {
+ personRepo.save(person);
+ return person;
+ }
+
+ @Override
+ public void delete(Person person) {
+ personRepo.delete(person);
+ }
+}
+
diff --git a/eureka/persons-server/src/main/java/com/eureka/persons/util/DateProcessor.java b/eureka/persons-server/src/main/java/com/eureka/persons/util/DateProcessor.java
new file mode 100644
index 0000000..0d2f624
--- /dev/null
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/util/DateProcessor.java
@@ -0,0 +1,17 @@
+package com.eureka.persons.util;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+public class DateProcessor {
+ public static final String DATE_FORMAT= "yyyy-MM-dd HH:mm";
+ private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
+
+ public static LocalDateTime toDate(final String date) {
+ return LocalDateTime.parse(date, formatter);
+ }
+
+ public static String toString(final LocalDateTime date){
+ return date.format(formatter);
+ }
+}
diff --git a/eureka/persons-server/src/main/java/com/eureka/persons/util/NumberGenerator.java b/eureka/persons-server/src/main/java/com/eureka/persons/util/NumberGenerator.java
new file mode 100644
index 0000000..92b1c40
--- /dev/null
+++ b/eureka/persons-server/src/main/java/com/eureka/persons/util/NumberGenerator.java
@@ -0,0 +1,18 @@
+package com.eureka.persons.util;
+
+import java.util.Random;
+
+public final class NumberGenerator {
+ private static final Random RAND = new Random();
+ private static final String UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ private static final String DIGITS = "0123456789";
+
+ private static Character randomCharacter() {
+ final var all = UPPER.concat(UPPER.toLowerCase()).concat(DIGITS);
+ return all.charAt(RAND.nextInt(all.length() - 1));
+ }
+
+ private NumberGenerator() {
+ // prevent initialization fo this class
+ }
+}
diff --git a/eureka/persons-server/src/main/resources/banner.txt b/eureka/persons-server/src/main/resources/banner.txt
new file mode 100644
index 0000000..be21922
--- /dev/null
+++ b/eureka/persons-server/src/main/resources/banner.txt
@@ -0,0 +1,7 @@
+__________ _________ .__
+\______ \ ___________ __________ ____ ______ / _____/ ______________ _|__| ____ ____
+ | ___// __ \_ __ \/ ___/ _ \ / \ / ___/ \_____ \_/ __ \_ __ \ \/ / |/ ___\/ __ \
+ | | \ ___/| | \/\___ ( <_> ) | \\___ \ / \ ___/| | \/\ /| \ \__\ ___/
+ |____| \___ >__| /____ >____/|___| /____ > /_______ /\___ >__| \_/ |__|\___ >___ >
+ \/ \/ \/ \/ \/ \/ \/ \/
+ :: Spring Boot :: (v2.2.4.RELEASE)
diff --git a/eureka/persons-server/src/main/resources/persons-server.yml b/eureka/persons-server/src/main/resources/persons-server.yml
new file mode 100644
index 0000000..b2b466d
--- /dev/null
+++ b/eureka/persons-server/src/main/resources/persons-server.yml
@@ -0,0 +1,41 @@
+spring:
+ application:
+ name: persons-service # Service registers under this name
+ datasource:
+ driver-class-name: org.h2.Driver
+ jdbc-url: jdbc:h2:mem:personsdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
+ username: sa
+ password: password
+ maximum-pool-size: 5
+ connection-test-query: "SELECT 1"
+ pool-name: cemsPool
+ connection-timeout: 60000
+ jpa:
+ generate-ddl: true
+ hibernate:
+ ddl-auto: create-drop
+ database-platform: org.hibernate.dialect.H2Dialect
+ h2:
+ console:
+ enabled: true
+# HTTP Server
+server:
+ port: 4001 # HTTP (Tomcat) port
+ address: 0.0.0.0
+
+# Discovery Server Access
+#TODO here you add configurations for eureka client
+
+info:
+ app:
+ name: persons-server
+ description: Spring Cloud Application Managing Person Instances
+ version: 1.0-SNAPSHOT
+
+logging:
+ pattern:
+ console: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
+ level:
+ root: INFO
+ org.springframework: DEBUG
+ com.apress.cems: DEBUG
diff --git a/eureka/persons-server/src/test/java/com/example/personsserver/PersonsServerApplicationTests.java b/eureka/persons-server/src/test/java/com/example/personsserver/PersonsServerApplicationTests.java
new file mode 100644
index 0000000..2fd298e
--- /dev/null
+++ b/eureka/persons-server/src/test/java/com/example/personsserver/PersonsServerApplicationTests.java
@@ -0,0 +1,17 @@
+package com.example.personsserver;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class PersonsServerApplicationTests {
+
+ //TODO configure discovery-server to be the Eureka's server (on port 3000) and persons-server to be the client server (on port 4001)
+ // hint1: you need to add some configurations in resources -> .yml files
+ // After you start your server and your client you need to create the endpoints from PersonsController, you have more details there
+ // Use postman to test the endpoints. Create a new collection and add all 5 endpoints inside of it.
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/eureka/pom.xml b/eureka/pom.xml
new file mode 100644
index 0000000..3a7d06f
--- /dev/null
+++ b/eureka/pom.xml
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.4
+
+
+ com.example
+ eureka
+ 0.0.1-SNAPSHOT
+ eureka
+ eureka
+
+ 11
+ 2021.0.1
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-eureka-client
+
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-eureka-server
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/eureka/src/main/java/com/example/eureka/EurekaApplication.java b/eureka/src/main/java/com/example/eureka/EurekaApplication.java
new file mode 100644
index 0000000..20c67a9
--- /dev/null
+++ b/eureka/src/main/java/com/example/eureka/EurekaApplication.java
@@ -0,0 +1,13 @@
+package com.example.eureka;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class EurekaApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(EurekaApplication.class, args);
+ }
+
+}
diff --git a/eureka/src/main/resources/application.properties b/eureka/src/main/resources/application.properties
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/eureka/src/main/resources/application.properties
@@ -0,0 +1 @@
+
diff --git a/eureka/src/test/java/com/example/eureka/EurekaApplicationTests.java b/eureka/src/test/java/com/example/eureka/EurekaApplicationTests.java
new file mode 100644
index 0000000..1415105
--- /dev/null
+++ b/eureka/src/test/java/com/example/eureka/EurekaApplicationTests.java
@@ -0,0 +1,13 @@
+package com.example.eureka;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class EurekaApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 487bfbd..4500e55 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,9 +21,17 @@
java8
rest-service
+ spring1
+ spring2
+ eureka
+
+ org.springframework
+ spring-context
+ 5.3.15
+
org.junit.jupiter
junit-jupiter-engine
diff --git a/spring1/.gitignore b/spring1/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/spring1/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/spring1/pom.xml b/spring1/pom.xml
new file mode 100644
index 0000000..55666da
--- /dev/null
+++ b/spring1/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.3
+
+
+ com.example
+ spring1
+ 0.0.1-SNAPSHOT
+ spring1
+ spring1
+
+ 1.8
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.data
+ spring-data-jpa
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 10
+ 10
+
+
+
+
+
+
diff --git a/spring1/src/main/java/com/unitbv/Spring1Application.java b/spring1/src/main/java/com/unitbv/Spring1Application.java
new file mode 100644
index 0000000..2d9a6da
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/Spring1Application.java
@@ -0,0 +1,13 @@
+package com.unitbv;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Spring1Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Spring1Application.class, args);
+ }
+
+}
diff --git a/spring1/src/main/java/com/unitbv/autowiring/AutowiredCfg.java b/spring1/src/main/java/com/unitbv/autowiring/AutowiredCfg.java
new file mode 100644
index 0000000..db8f32e
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/autowiring/AutowiredCfg.java
@@ -0,0 +1,9 @@
+package com.unitbv.autowiring;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan(basePackages = {"com.unitbv.autowiring"})
+public class AutowiredCfg {
+}
diff --git a/spring1/src/main/java/com/unitbv/autowiring/service/FormatServiceConstructorInjection.java b/spring1/src/main/java/com/unitbv/autowiring/service/FormatServiceConstructorInjection.java
new file mode 100644
index 0000000..526880d
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/autowiring/service/FormatServiceConstructorInjection.java
@@ -0,0 +1,14 @@
+package com.unitbv.autowiring.service;
+
+import com.unitbv.autowiring.util.FormatUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class FormatServiceConstructorInjection {
+ private final FormatUtil formatUtil;
+
+ public void checkFormatted() {
+ System.out.println(this.formatUtil.formatted(true));
+ }
+}
diff --git a/spring1/src/main/java/com/unitbv/autowiring/service/FormatServiceFieldInjection.java b/spring1/src/main/java/com/unitbv/autowiring/service/FormatServiceFieldInjection.java
new file mode 100644
index 0000000..8873634
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/autowiring/service/FormatServiceFieldInjection.java
@@ -0,0 +1,14 @@
+package com.unitbv.autowiring.service;
+
+import com.unitbv.autowiring.util.FormatUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class FormatServiceFieldInjection {
+ public FormatUtil formatUtil;
+
+ public void checkFormatted() {
+ System.out.println(this.formatUtil.formatted(true));
+ }
+}
diff --git a/spring1/src/main/java/com/unitbv/autowiring/service/FormatServiceSetterInjection.java b/spring1/src/main/java/com/unitbv/autowiring/service/FormatServiceSetterInjection.java
new file mode 100644
index 0000000..f2ec37e
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/autowiring/service/FormatServiceSetterInjection.java
@@ -0,0 +1,14 @@
+package com.unitbv.autowiring.service;
+
+import com.unitbv.autowiring.util.FormatUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class FormatServiceSetterInjection {
+ private FormatUtil formatUtil;
+
+ public void checkFormatted() {
+ System.out.println(this.formatUtil.formatted(true));
+ }
+}
diff --git a/spring1/src/main/java/com/unitbv/autowiring/util/FormatUtil.java b/spring1/src/main/java/com/unitbv/autowiring/util/FormatUtil.java
new file mode 100644
index 0000000..39025aa
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/autowiring/util/FormatUtil.java
@@ -0,0 +1,13 @@
+package com.unitbv.autowiring.util;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class FormatUtil {
+ public String formatted(boolean isFormatted) {
+ if (isFormatted) {
+ return "Everything was formatted.";
+ }
+ return "Couldn't format";
+ }
+}
diff --git a/spring1/src/main/java/com/unitbv/beans/Book.java b/spring1/src/main/java/com/unitbv/beans/Book.java
new file mode 100644
index 0000000..3429ac6
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/beans/Book.java
@@ -0,0 +1,11 @@
+package com.unitbv.beans;
+
+public class Book implements Item {
+
+ private String title;
+
+ @Override
+ public String getTitle() {
+ return title;
+ }
+}
diff --git a/spring1/src/main/java/com/unitbv/beans/Human.java b/spring1/src/main/java/com/unitbv/beans/Human.java
new file mode 100644
index 0000000..5bbd304
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/beans/Human.java
@@ -0,0 +1,6 @@
+package com.unitbv.beans;
+
+public interface Human {
+
+ Item getItem();
+}
diff --git a/spring1/src/main/java/com/unitbv/beans/HumanAppCfg.java b/spring1/src/main/java/com/unitbv/beans/HumanAppCfg.java
new file mode 100644
index 0000000..a38cf2b
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/beans/HumanAppCfg.java
@@ -0,0 +1,9 @@
+package com.unitbv.beans;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan(basePackages = {"com.unitbv.beans"} )
+public class HumanAppCfg {
+}
diff --git a/spring1/src/main/java/com/unitbv/beans/Item.java b/spring1/src/main/java/com/unitbv/beans/Item.java
new file mode 100644
index 0000000..a06892b
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/beans/Item.java
@@ -0,0 +1,5 @@
+package com.unitbv.beans;
+
+public interface Item {
+ String getTitle();
+}
diff --git a/spring1/src/main/java/com/unitbv/beans/Person.java b/spring1/src/main/java/com/unitbv/beans/Person.java
new file mode 100644
index 0000000..3a851d0
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/beans/Person.java
@@ -0,0 +1,11 @@
+package com.unitbv.beans;
+
+public class Person implements Human {
+
+ private Item item;
+
+ @Override
+ public Item getItem() {
+ return item;
+ }
+}
diff --git a/spring1/src/main/java/com/unitbv/beansnaming/DependantBean.java b/spring1/src/main/java/com/unitbv/beansnaming/DependantBean.java
new file mode 100644
index 0000000..b47f156
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/beansnaming/DependantBean.java
@@ -0,0 +1,4 @@
+package com.unitbv.beansnaming;
+
+public interface DependantBean {
+}
diff --git a/spring1/src/main/java/com/unitbv/beansnaming/DependantBeanImpl.java b/spring1/src/main/java/com/unitbv/beansnaming/DependantBeanImpl.java
new file mode 100644
index 0000000..ff79055
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/beansnaming/DependantBeanImpl.java
@@ -0,0 +1,10 @@
+package com.unitbv.beansnaming;
+
+
+public class DependantBeanImpl implements DependantBean {
+ private SimpleBean simpleBean;
+
+ public DependantBeanImpl(SimpleBean simpleBean) {
+ this.simpleBean = simpleBean;
+ }
+}
diff --git a/spring1/src/main/java/com/unitbv/beansnaming/SimpleBean.java b/spring1/src/main/java/com/unitbv/beansnaming/SimpleBean.java
new file mode 100644
index 0000000..d4b2076
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/beansnaming/SimpleBean.java
@@ -0,0 +1,4 @@
+package com.unitbv.beansnaming;
+
+public interface SimpleBean {
+}
diff --git a/spring1/src/main/java/com/unitbv/beansnaming/SimpleBeanImpl.java b/spring1/src/main/java/com/unitbv/beansnaming/SimpleBeanImpl.java
new file mode 100644
index 0000000..c83ca34
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/beansnaming/SimpleBeanImpl.java
@@ -0,0 +1,19 @@
+package com.unitbv.beansnaming;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+//TODO test what will happen when you add a stereotype annotation
+public class SimpleBeanImpl implements SimpleBean {
+
+ public SimpleBeanImpl() {
+ Logger logger = LoggerFactory.getLogger(SimpleBeanImpl.class);
+ logger.info("[SimpleBeanImpl instantiation]");
+ }
+
+ @Override
+ public String toString() {
+ return "SimpleBeanImpl{ code: " + hashCode() + "}";
+ }
+
+}
diff --git a/spring1/src/main/java/com/unitbv/beansnaming/SimpleDependantCfg.java b/spring1/src/main/java/com/unitbv/beansnaming/SimpleDependantCfg.java
new file mode 100644
index 0000000..0d57764
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/beansnaming/SimpleDependantCfg.java
@@ -0,0 +1,21 @@
+package com.unitbv.beansnaming;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan(basePackages = {"com.unitbv.beansnaming"})
+public class SimpleDependantCfg {
+
+ private final Logger logger = LoggerFactory.getLogger(SimpleDependantCfg.class);
+
+ SimpleBean simpleBean() {
+ return new SimpleBeanImpl();
+ }
+
+ DependantBean dependantBean() {
+ return new DependantBeanImpl(simpleBean());
+ }
+}
diff --git a/spring1/src/main/java/com/unitbv/lifecycle/DepBean.java b/spring1/src/main/java/com/unitbv/lifecycle/DepBean.java
new file mode 100644
index 0000000..808134f
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/lifecycle/DepBean.java
@@ -0,0 +1,7 @@
+package com.unitbv.lifecycle;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class DepBean {
+}
diff --git a/spring1/src/main/java/com/unitbv/lifecycle/FunBean.java b/spring1/src/main/java/com/unitbv/lifecycle/FunBean.java
new file mode 100644
index 0000000..3cb72a8
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/lifecycle/FunBean.java
@@ -0,0 +1,16 @@
+package com.unitbv.lifecycle;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+public class FunBean {
+ private Logger logger = LoggerFactory.getLogger(FunBean.class);
+
+ private DepBean depBean;
+}
diff --git a/spring1/src/main/java/com/unitbv/lifecycle/FunBeanCfg.java b/spring1/src/main/java/com/unitbv/lifecycle/FunBeanCfg.java
new file mode 100644
index 0000000..55796b2
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/lifecycle/FunBeanCfg.java
@@ -0,0 +1,14 @@
+package com.unitbv.lifecycle;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+@ComponentScan(basePackages = {"com.unitbv.lifecycle"})
+public class FunBeanCfg {
+
+ FunBean funBean() {
+ return new FunBean();
+ }
+}
diff --git a/spring1/src/main/java/com/unitbv/stereotype/StereotypeCfg.java b/spring1/src/main/java/com/unitbv/stereotype/StereotypeCfg.java
new file mode 100644
index 0000000..cb4586e
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/stereotype/StereotypeCfg.java
@@ -0,0 +1,9 @@
+package com.unitbv.stereotype;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan(basePackages = "com.unitbv")
+public class StereotypeCfg {
+}
diff --git a/spring1/src/main/java/com/unitbv/stereotype/controller/UserController.java b/spring1/src/main/java/com/unitbv/stereotype/controller/UserController.java
new file mode 100644
index 0000000..797feeb
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/stereotype/controller/UserController.java
@@ -0,0 +1,4 @@
+package com.unitbv.stereotype.controller;
+
+public class UserController {
+}
diff --git a/spring1/src/main/java/com/unitbv/stereotype/model/User.java b/spring1/src/main/java/com/unitbv/stereotype/model/User.java
new file mode 100644
index 0000000..e7b6094
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/stereotype/model/User.java
@@ -0,0 +1,6 @@
+package com.unitbv.stereotype.model;
+
+public class User {
+ private Integer id;
+ private String name;
+}
diff --git a/spring1/src/main/java/com/unitbv/stereotype/repository/UserRepository.java b/spring1/src/main/java/com/unitbv/stereotype/repository/UserRepository.java
new file mode 100644
index 0000000..01ea991
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/stereotype/repository/UserRepository.java
@@ -0,0 +1,7 @@
+package com.unitbv.stereotype.repository;
+
+import com.unitbv.stereotype.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface UserRepository extends JpaRepository {
+}
diff --git a/spring1/src/main/java/com/unitbv/stereotype/repository/impl/UserRepositoryImpl.java b/spring1/src/main/java/com/unitbv/stereotype/repository/impl/UserRepositoryImpl.java
new file mode 100644
index 0000000..9081e1e
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/stereotype/repository/impl/UserRepositoryImpl.java
@@ -0,0 +1,160 @@
+package com.unitbv.stereotype.repository.impl;
+
+import com.unitbv.stereotype.model.User;
+import com.unitbv.stereotype.repository.UserRepository;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.repository.query.FluentQuery;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+
+public class UserRepositoryImpl implements UserRepository {
+ @Override
+ public List findAll() {
+ return null;
+ }
+
+ @Override
+ public List findAll(Sort sort) {
+ return null;
+ }
+
+ @Override
+ public Page findAll(Pageable pageable) {
+ return null;
+ }
+
+ @Override
+ public List findAllById(Iterable users) {
+ return null;
+ }
+
+ @Override
+ public long count() {
+ return 0;
+ }
+
+ @Override
+ public void deleteById(User user) {
+
+ }
+
+ @Override
+ public void delete(Integer entity) {
+
+ }
+
+ @Override
+ public void deleteAllById(Iterable extends User> users) {
+
+ }
+
+ @Override
+ public void deleteAll(Iterable extends Integer> entities) {
+
+ }
+
+ @Override
+ public void deleteAll() {
+
+ }
+
+ @Override
+ public S save(S entity) {
+ return null;
+ }
+
+ @Override
+ public List saveAll(Iterable entities) {
+ return null;
+ }
+
+ @Override
+ public Optional findById(User user) {
+ return Optional.empty();
+ }
+
+ @Override
+ public boolean existsById(User user) {
+ return false;
+ }
+
+ @Override
+ public void flush() {
+
+ }
+
+ @Override
+ public S saveAndFlush(S entity) {
+ return null;
+ }
+
+ @Override
+ public List saveAllAndFlush(Iterable entities) {
+ return null;
+ }
+
+ @Override
+ public void deleteAllInBatch(Iterable entities) {
+
+ }
+
+ @Override
+ public void deleteAllByIdInBatch(Iterable users) {
+
+ }
+
+ @Override
+ public void deleteAllInBatch() {
+
+ }
+
+ @Override
+ public Integer getOne(User user) {
+ return null;
+ }
+
+ @Override
+ public Integer getById(User user) {
+ return null;
+ }
+
+ @Override
+ public Optional findOne(Example example) {
+ return Optional.empty();
+ }
+
+ @Override
+ public List findAll(Example example) {
+ return null;
+ }
+
+ @Override
+ public List findAll(Example example, Sort sort) {
+ return null;
+ }
+
+ @Override
+ public Page findAll(Example example, Pageable pageable) {
+ return null;
+ }
+
+ @Override
+ public long count(Example example) {
+ return 0;
+ }
+
+ @Override
+ public boolean exists(Example example) {
+ return false;
+ }
+
+ @Override
+ public R findBy(Example example, Function, R> queryFunction) {
+ return null;
+ }
+}
diff --git a/spring1/src/main/java/com/unitbv/stereotype/service/UserService.java b/spring1/src/main/java/com/unitbv/stereotype/service/UserService.java
new file mode 100644
index 0000000..3b9ad34
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/stereotype/service/UserService.java
@@ -0,0 +1,4 @@
+package com.unitbv.stereotype.service;
+
+public interface UserService {
+}
diff --git a/spring1/src/main/java/com/unitbv/stereotype/service/impl/UserServiceImpl.java b/spring1/src/main/java/com/unitbv/stereotype/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..afc9967
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/stereotype/service/impl/UserServiceImpl.java
@@ -0,0 +1,6 @@
+package com.unitbv.stereotype.service.impl;
+
+import com.unitbv.stereotype.service.UserService;
+
+public class UserServiceImpl implements UserService {
+}
diff --git a/spring1/src/main/java/com/unitbv/stereotype/util/UserUtil.java b/spring1/src/main/java/com/unitbv/stereotype/util/UserUtil.java
new file mode 100644
index 0000000..1f440a4
--- /dev/null
+++ b/spring1/src/main/java/com/unitbv/stereotype/util/UserUtil.java
@@ -0,0 +1,4 @@
+package com.unitbv.stereotype.util;
+
+public class UserUtil {
+}
diff --git a/spring1/src/main/resources/application.properties b/spring1/src/main/resources/application.properties
new file mode 100644
index 0000000..b2ff11b
--- /dev/null
+++ b/spring1/src/main/resources/application.properties
@@ -0,0 +1 @@
+book.title="Dummy title"
\ No newline at end of file
diff --git a/spring1/src/test/java/com/unitbv/Spring1ApplicationTests.java b/spring1/src/test/java/com/unitbv/Spring1ApplicationTests.java
new file mode 100644
index 0000000..8307489
--- /dev/null
+++ b/spring1/src/test/java/com/unitbv/Spring1ApplicationTests.java
@@ -0,0 +1,13 @@
+package com.unitbv;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class Spring1ApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/spring1/src/test/java/com/unitbv/autowiring/AutowiredCfgTest.java b/spring1/src/test/java/com/unitbv/autowiring/AutowiredCfgTest.java
new file mode 100644
index 0000000..7e2b6d0
--- /dev/null
+++ b/spring1/src/test/java/com/unitbv/autowiring/AutowiredCfgTest.java
@@ -0,0 +1,39 @@
+package com.unitbv.autowiring;
+
+import com.unitbv.autowiring.service.FormatServiceConstructorInjection;
+import com.unitbv.autowiring.service.FormatServiceFieldInjection;
+import com.unitbv.autowiring.service.FormatServiceSetterInjection;
+import com.unitbv.autowiring.util.FormatUtil;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class AutowiredCfgTest {
+ //TODO use constructor injection, setter injection and field injection to add dependency in FormatServices classes
+
+ @Test
+ void checkFormattedTestAutowireConstructorInjection() {
+ FormatUtil formatUtil = new FormatUtil();
+ FormatServiceConstructorInjection formatServiceConstructorInjection = new FormatServiceConstructorInjection(formatUtil);
+ formatServiceConstructorInjection.checkFormatted();
+ }
+
+ @Test
+ void checkFormattedTestAutowireSetterInjection() {
+ FormatUtil formatUtil = new FormatUtil();
+ FormatServiceSetterInjection formatServiceSetterInjection = new FormatServiceSetterInjection();
+ formatServiceSetterInjection.setFormatUtil(formatUtil);
+ formatServiceSetterInjection.checkFormatted();
+ }
+
+ @Test
+ void checkFormattedTestAutowireFieldInjection() {
+ ConfigurableApplicationContext ctx =
+ new AnnotationConfigApplicationContext(AutowiredCfg.class);
+ FormatServiceFieldInjection formatServiceFieldInjection = ctx.getBean(FormatServiceFieldInjection.class);
+ assertNotNull(formatServiceFieldInjection);
+ formatServiceFieldInjection.checkFormatted();
+ }
+}
diff --git a/spring1/src/test/java/com/unitbv/beans/HumanAppCfgTest.java b/spring1/src/test/java/com/unitbv/beans/HumanAppCfgTest.java
new file mode 100644
index 0000000..45d1a77
--- /dev/null
+++ b/spring1/src/test/java/com/unitbv/beans/HumanAppCfgTest.java
@@ -0,0 +1,53 @@
+/*
+Freeware License, some rights reserved
+
+Copyright (c) 2019 Iuliana Cosmina
+
+Permission is hereby granted, free of charge, to anyone obtaining a copy
+of this software and associated documentation files (the "Software"),
+to work with the Software within the limits of freeware distribution and fair use.
+This includes the rights to use, copy, and modify the Software for personal use.
+Users are also allowed and encouraged to submit corrections and modifications
+to the Software for the benefit of other users.
+
+It is not allowed to reuse, modify, or redistribute the Software for
+commercial use in any way, or for a user's educational materials such as books
+or blog articles without prior permission from the copyright holder.
+
+The above copyright notice and this permission notice need to be included
+in all copies or substantial portions of the software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+package com.unitbv.beans;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class HumanAppCfgTest {
+
+ //TODO make Book.class and Person.class to be recognized as beans by Spring and inject their values
+ // through constructors in order to make them compile
+ //title from Book class should be populated with a value that comes from application.properties file
+ @Test
+ void testHumanAndItem() {
+ ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(HumanAppCfg.class);
+
+ Human humanBean = ctx.getBean(Human.class);
+
+ assertNotNull(humanBean);
+ assertNotNull(humanBean.getItem());
+ assertNotNull(humanBean.getItem().getTitle());
+
+ ctx.close();
+ }
+}
diff --git a/spring1/src/test/java/com/unitbv/beansnaming/SimpleDependantCfgTest.java b/spring1/src/test/java/com/unitbv/beansnaming/SimpleDependantCfgTest.java
new file mode 100644
index 0000000..74fe6b5
--- /dev/null
+++ b/spring1/src/test/java/com/unitbv/beansnaming/SimpleDependantCfgTest.java
@@ -0,0 +1,65 @@
+package com.unitbv.beansnaming;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class SimpleDependantCfgTest {
+
+ @Test
+ void testBeanNamingDefaultName() {
+ //TODO create definitions for SimpleBean and DependantBean and log some messages
+ ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(SimpleDependantCfg.class);
+
+ SimpleBean simpleBean = ctx.getBean("simpleBean", SimpleBean.class);
+ DependantBean dependantBean = ctx.getBean("dependantBean", DependantBean.class);
+
+ assertNotNull(simpleBean);
+ assertNotNull(dependantBean);
+
+ ctx.close();
+ }
+
+ @Test
+ void testBeanNamingSingleCustomName() {
+ //TODO define a name for your beans
+ ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(SimpleDependantCfg.class);
+
+ SimpleBean customSimpleBean = ctx.getBean("customSimpleBean", SimpleBean.class);
+ DependantBean customDependantBean = ctx.getBean("customDependantBean", DependantBean.class);
+
+ assertNotNull(customSimpleBean);
+ assertNotNull(customDependantBean);
+
+ // no bean named 'simpleBean' and 'dependantBean'
+ assertThrows(NoSuchBeanDefinitionException.class, () -> ctx.getBean("simpleBean", SimpleBean.class));
+ assertThrows(NoSuchBeanDefinitionException.class, () -> ctx.getBean("dependantBean", DependantBean.class));
+
+ ctx.close();
+ }
+
+ @Test
+ void testBeanNamingMultipleCustomName() {
+ //TODO define multiple names for the same bean
+ ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(SimpleDependantCfg.class);
+
+ SimpleBean customSimpleBean1 = ctx.getBean("customSimpleBean1", SimpleBean.class);
+ SimpleBean customSimpleBean2 = ctx.getBean("customSimpleBean2", SimpleBean.class);
+
+ DependantBean customDependantBean1 = ctx.getBean("customDependantBean1", DependantBean.class);
+ DependantBean customDependantBean2 = ctx.getBean("customDependantBean2", DependantBean.class);
+
+ assertNotNull(customSimpleBean1);
+ assertNotNull(customSimpleBean2);
+ assertEquals(customDependantBean1, customDependantBean2);
+
+ assertNotNull(customDependantBean1);
+ assertNotNull(customDependantBean2);
+ assertEquals(customDependantBean1, customDependantBean2);
+
+ ctx.close();
+ }
+}
diff --git a/spring1/src/test/java/com/unitbv/lifecycle/FunBeanCfgTest.java b/spring1/src/test/java/com/unitbv/lifecycle/FunBeanCfgTest.java
new file mode 100644
index 0000000..b84d821
--- /dev/null
+++ b/spring1/src/test/java/com/unitbv/lifecycle/FunBeanCfgTest.java
@@ -0,0 +1,23 @@
+package com.unitbv.lifecycle;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class FunBeanCfgTest {
+
+ @Test
+ void testBeanLifecycle() {
+ //TODO configure all lifecycle methods for FunBean and log messages just to be clear in each order are the methods called.
+ // hint 1: Use setter to inject a value for DepBean
+ // hint 2: @Bean has 2 values called initMethod and destroyMethod
+ // hint 3: you need to implement InitializingBean, DisposableBean
+ // hint 4: there should be 8 logged messages
+ var ctx = new AnnotationConfigApplicationContext(FunBeanCfg.class);
+ ctx.registerShutdownHook();
+
+ FunBean funBean = ctx.getBean(FunBean.class);
+ assertNotNull(funBean);
+ }
+}
diff --git a/spring1/src/test/java/com/unitbv/stereotype/StereotypeCfgTest.java b/spring1/src/test/java/com/unitbv/stereotype/StereotypeCfgTest.java
new file mode 100644
index 0000000..df519f3
--- /dev/null
+++ b/spring1/src/test/java/com/unitbv/stereotype/StereotypeCfgTest.java
@@ -0,0 +1,35 @@
+package com.unitbv.stereotype;
+
+import com.unitbv.stereotype.controller.UserController;
+import com.unitbv.stereotype.repository.UserRepository;
+import com.unitbv.stereotype.repository.impl.UserRepositoryImpl;
+import com.unitbv.stereotype.service.UserService;
+import com.unitbv.stereotype.service.impl.UserServiceImpl;
+import com.unitbv.stereotype.util.UserUtil;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class StereotypeCfgTest {
+
+ //TODO add stereotype annotations in order to instantiate the beans. Use more specific annotations where you can
+ // Hint 1: there are 4 stereotype annotations
+ // Hint 2: pay attention to the configuration of StereotypeCfg.class
+ @Test
+ void testStereotypeAnnotations() {
+ var ctx = new AnnotationConfigApplicationContext(StereotypeCfg.class);
+ ctx.registerShutdownHook();
+
+ UserController userControllerBean = ctx.getBean(UserController.class);
+ UserService userServiceBean = ctx.getBean(UserServiceImpl.class);
+ UserRepository userRepositoryBean = ctx.getBean(UserRepositoryImpl.class);
+ UserUtil userUtilBean = ctx.getBean(UserUtil.class);
+
+ assertNotNull(userControllerBean);
+ assertNotNull(userServiceBean);
+ assertNotNull(userRepositoryBean);
+ assertNotNull(userUtilBean);
+
+ }
+}
diff --git a/spring2/pom.xml b/spring2/pom.xml
new file mode 100644
index 0000000..5e0f131
--- /dev/null
+++ b/spring2/pom.xml
@@ -0,0 +1,84 @@
+
+
+ 4.0.0
+
+ programare-cloud-java
+ com.unitbv
+ 1.0-SNAPSHOT
+
+
+ com.unitbv
+ spring2
+ 1.0-SNAPSHOT
+
+ spring2
+
+ http://www.example.com
+
+
+ UTF-8
+ 1.7
+ 1.7
+
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.springframework
+ spring-test
+ 5.3.16
+ test
+
+
+
+
+
+
+
+
+ maven-clean-plugin
+ 3.1.0
+
+
+
+ maven-resources-plugin
+ 3.0.2
+
+
+ maven-compiler-plugin
+ 3.8.0
+
+
+ maven-surefire-plugin
+ 2.22.1
+
+
+ maven-jar-plugin
+ 3.0.2
+
+
+ maven-install-plugin
+ 2.5.2
+
+
+ maven-deploy-plugin
+ 2.8.2
+
+
+
+ maven-site-plugin
+ 3.7.1
+
+
+ maven-project-info-reports-plugin
+ 3.0.0
+
+
+
+
+
diff --git a/spring2/src/main/java/com/unitbv/dependsOn/AppConfig.java b/spring2/src/main/java/com/unitbv/dependsOn/AppConfig.java
new file mode 100644
index 0000000..66592a2
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/dependsOn/AppConfig.java
@@ -0,0 +1,8 @@
+package com.unitbv.dependsOn;
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AppConfig {
+
+}
diff --git a/spring2/src/main/java/com/unitbv/dependsOn/BeanA.java b/spring2/src/main/java/com/unitbv/dependsOn/BeanA.java
new file mode 100644
index 0000000..a419e37
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/dependsOn/BeanA.java
@@ -0,0 +1,4 @@
+package com.unitbv.dependsOn;
+
+public class BeanA {
+}
diff --git a/spring2/src/main/java/com/unitbv/dependsOn/BeanB.java b/spring2/src/main/java/com/unitbv/dependsOn/BeanB.java
new file mode 100644
index 0000000..e98848b
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/dependsOn/BeanB.java
@@ -0,0 +1,5 @@
+package com.unitbv.dependsOn;
+
+public class BeanB {
+
+}
diff --git a/spring2/src/main/java/com/unitbv/dependsOn/BeanC.java b/spring2/src/main/java/com/unitbv/dependsOn/BeanC.java
new file mode 100644
index 0000000..4e3275d
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/dependsOn/BeanC.java
@@ -0,0 +1,4 @@
+package com.unitbv.dependsOn;
+
+public class BeanC {
+}
diff --git a/spring2/src/main/java/com/unitbv/events/configuration/AppConfig.java b/spring2/src/main/java/com/unitbv/events/configuration/AppConfig.java
new file mode 100644
index 0000000..9773c64
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/events/configuration/AppConfig.java
@@ -0,0 +1,7 @@
+package com.unitbv.events.configuration;
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AppConfig {
+}
diff --git a/spring2/src/main/java/com/unitbv/events/event/CarForRentEvent.java b/spring2/src/main/java/com/unitbv/events/event/CarForRentEvent.java
new file mode 100644
index 0000000..fb00378
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/events/event/CarForRentEvent.java
@@ -0,0 +1,9 @@
+package com.unitbv.events.event;
+
+import org.springframework.context.ApplicationEvent;
+
+public class CarForRentEvent extends ApplicationEvent {
+ public CarForRentEvent(Object source) {
+ super(source);
+ }
+}
diff --git a/spring2/src/main/java/com/unitbv/events/model/Car.java b/spring2/src/main/java/com/unitbv/events/model/Car.java
new file mode 100644
index 0000000..142056e
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/events/model/Car.java
@@ -0,0 +1,9 @@
+package com.unitbv.events.model;
+
+public class Car {
+ private final String model;
+
+ public Car(String model) {
+ this.model = model;
+ }
+}
diff --git a/spring2/src/main/java/com/unitbv/events/service/CarService.java b/spring2/src/main/java/com/unitbv/events/service/CarService.java
new file mode 100644
index 0000000..1558f1a
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/events/service/CarService.java
@@ -0,0 +1,22 @@
+package com.unitbv.events.service;
+
+import com.unitbv.events.event.CarForRentEvent;
+import com.unitbv.events.model.Car;
+import lombok.Getter;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+@Getter
+public class CarService {
+ private final List availableCars;
+
+ public CarService() {
+ this.availableCars = new ArrayList<>();
+ }
+
+ public void addCarForRent(CarForRentEvent carForRentEvent) {
+ }
+}
diff --git a/spring2/src/main/java/com/unitbv/events/service/PersonService.java b/spring2/src/main/java/com/unitbv/events/service/PersonService.java
new file mode 100644
index 0000000..f4df14a
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/events/service/PersonService.java
@@ -0,0 +1,20 @@
+package com.unitbv.events.service;
+
+import com.unitbv.events.model.Car;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Service;
+
+@Service
+public class PersonService {
+
+ private final ApplicationEventPublisher eventPublisher;
+
+ public PersonService(ApplicationEventPublisher eventPublisher) {
+ this.eventPublisher = eventPublisher;
+ }
+
+ public void rentCar(String model) {
+ final Car car = new Car(model);
+ //create a new event and publish car on event
+ }
+}
diff --git a/spring2/src/main/java/com/unitbv/multipleConfigs/BeanA.java b/spring2/src/main/java/com/unitbv/multipleConfigs/BeanA.java
new file mode 100644
index 0000000..53bfd3b
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/multipleConfigs/BeanA.java
@@ -0,0 +1,5 @@
+package com.unitbv.multipleConfigs;
+
+public class BeanA {
+
+}
diff --git a/spring2/src/main/java/com/unitbv/multipleConfigs/BeanB.java b/spring2/src/main/java/com/unitbv/multipleConfigs/BeanB.java
new file mode 100644
index 0000000..d7943be
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/multipleConfigs/BeanB.java
@@ -0,0 +1,5 @@
+package com.unitbv.multipleConfigs;
+
+public class BeanB {
+
+}
diff --git a/spring2/src/main/java/com/unitbv/multipleConfigs/ConfigA.java b/spring2/src/main/java/com/unitbv/multipleConfigs/ConfigA.java
new file mode 100644
index 0000000..091de81
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/multipleConfigs/ConfigA.java
@@ -0,0 +1,7 @@
+package com.unitbv.multipleConfigs;
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class ConfigA {
+}
diff --git a/spring2/src/main/java/com/unitbv/multipleConfigs/ConfigB.java b/spring2/src/main/java/com/unitbv/multipleConfigs/ConfigB.java
new file mode 100644
index 0000000..e60ff4e
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/multipleConfigs/ConfigB.java
@@ -0,0 +1,8 @@
+package com.unitbv.multipleConfigs;
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class ConfigB {
+
+}
diff --git a/spring2/src/main/java/com/unitbv/multipleConfigs/appConfig/AppConfig.java b/spring2/src/main/java/com/unitbv/multipleConfigs/appConfig/AppConfig.java
new file mode 100644
index 0000000..654bacb
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/multipleConfigs/appConfig/AppConfig.java
@@ -0,0 +1,10 @@
+package com.unitbv.multipleConfigs.appConfig;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan(basePackages = "com.unitbv.multipleConfigs.appConfig")
+public class AppConfig {
+
+}
diff --git a/spring2/src/main/java/com/unitbv/profiles/automatically/AppConfig.java b/spring2/src/main/java/com/unitbv/profiles/automatically/AppConfig.java
new file mode 100644
index 0000000..39e36ff
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/profiles/automatically/AppConfig.java
@@ -0,0 +1,9 @@
+package com.unitbv.profiles.automatically;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan
+public class AppConfig {
+}
diff --git a/spring2/src/main/java/com/unitbv/profiles/automatically/DataSourceConfig.java b/spring2/src/main/java/com/unitbv/profiles/automatically/DataSourceConfig.java
new file mode 100644
index 0000000..5fc4502
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/profiles/automatically/DataSourceConfig.java
@@ -0,0 +1,5 @@
+package com.unitbv.profiles.automatically;
+
+public interface DataSourceConfig {
+ void setup();
+}
diff --git a/spring2/src/main/java/com/unitbv/profiles/automatically/DevDataSourceConfig.java b/spring2/src/main/java/com/unitbv/profiles/automatically/DevDataSourceConfig.java
new file mode 100644
index 0000000..a456519
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/profiles/automatically/DevDataSourceConfig.java
@@ -0,0 +1,11 @@
+package com.unitbv.profiles.automatically;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class DevDataSourceConfig implements DataSourceConfig {
+ @Override
+ public void setup() {
+ System.out.println("Setting up datasource for DEV environment. ");
+ }
+}
diff --git a/spring2/src/main/java/com/unitbv/profiles/automatically/ProdDataSourceConfig.java b/spring2/src/main/java/com/unitbv/profiles/automatically/ProdDataSourceConfig.java
new file mode 100644
index 0000000..8280304
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/profiles/automatically/ProdDataSourceConfig.java
@@ -0,0 +1,11 @@
+package com.unitbv.profiles.automatically;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class ProdDataSourceConfig implements DataSourceConfig {
+ @Override
+ public void setup() {
+ System.out.println("Setting up datasource for PROD environment. ");
+ }
+}
diff --git a/spring2/src/main/java/com/unitbv/profiles/programatically/AppConfig.java b/spring2/src/main/java/com/unitbv/profiles/programatically/AppConfig.java
new file mode 100644
index 0000000..a2fac53
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/profiles/programatically/AppConfig.java
@@ -0,0 +1,7 @@
+package com.unitbv.profiles.programatically;
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AppConfig {
+}
diff --git a/spring2/src/main/java/com/unitbv/profiles/programatically/DataSourceConfig.java b/spring2/src/main/java/com/unitbv/profiles/programatically/DataSourceConfig.java
new file mode 100644
index 0000000..898f677
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/profiles/programatically/DataSourceConfig.java
@@ -0,0 +1,5 @@
+package com.unitbv.profiles.programatically;
+
+public interface DataSourceConfig {
+ public void setup();
+}
diff --git a/spring2/src/main/java/com/unitbv/profiles/programatically/DevDataSourceConfig.java b/spring2/src/main/java/com/unitbv/profiles/programatically/DevDataSourceConfig.java
new file mode 100644
index 0000000..bdc7c93
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/profiles/programatically/DevDataSourceConfig.java
@@ -0,0 +1,8 @@
+package com.unitbv.profiles.programatically;
+
+public class DevDataSourceConfig implements DataSourceConfig {
+ @Override
+ public void setup() {
+
+ }
+}
diff --git a/spring2/src/main/java/com/unitbv/profiles/programatically/ProdDataSourceConfig.java b/spring2/src/main/java/com/unitbv/profiles/programatically/ProdDataSourceConfig.java
new file mode 100644
index 0000000..3433fe5
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/profiles/programatically/ProdDataSourceConfig.java
@@ -0,0 +1,8 @@
+package com.unitbv.profiles.programatically;
+
+public class ProdDataSourceConfig implements DataSourceConfig {
+ @Override
+ public void setup() {
+
+ }
+}
diff --git a/spring2/src/main/java/com/unitbv/profiles/stereotype/AppConfig.java b/spring2/src/main/java/com/unitbv/profiles/stereotype/AppConfig.java
new file mode 100644
index 0000000..da8e65d
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/profiles/stereotype/AppConfig.java
@@ -0,0 +1,10 @@
+package com.unitbv.profiles.stereotype;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+
+@Configuration
+@ComponentScan
+public class AppConfig {
+}
diff --git a/spring2/src/main/java/com/unitbv/profiles/stereotype/DataSourceConfig.java b/spring2/src/main/java/com/unitbv/profiles/stereotype/DataSourceConfig.java
new file mode 100644
index 0000000..c620bf5
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/profiles/stereotype/DataSourceConfig.java
@@ -0,0 +1,5 @@
+package com.unitbv.profiles.stereotype;
+
+public interface DataSourceConfig {
+ public void setup();
+}
diff --git a/spring2/src/main/java/com/unitbv/profiles/stereotype/DevDataSourceConfig.java b/spring2/src/main/java/com/unitbv/profiles/stereotype/DevDataSourceConfig.java
new file mode 100644
index 0000000..bc28c29
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/profiles/stereotype/DevDataSourceConfig.java
@@ -0,0 +1,8 @@
+package com.unitbv.profiles.stereotype;
+
+public class DevDataSourceConfig implements DataSourceConfig {
+ @Override
+ public void setup() {
+
+ }
+}
diff --git a/spring2/src/main/java/com/unitbv/profiles/stereotype/ProdDataSourceConfig.java b/spring2/src/main/java/com/unitbv/profiles/stereotype/ProdDataSourceConfig.java
new file mode 100644
index 0000000..0ceec4b
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/profiles/stereotype/ProdDataSourceConfig.java
@@ -0,0 +1,8 @@
+package com.unitbv.profiles.stereotype;
+
+public class ProdDataSourceConfig implements DataSourceConfig {
+ @Override
+ public void setup() {
+
+ }
+}
diff --git a/spring2/src/main/java/com/unitbv/properties/config/AppConfig.java b/spring2/src/main/java/com/unitbv/properties/config/AppConfig.java
new file mode 100644
index 0000000..df09351
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/properties/config/AppConfig.java
@@ -0,0 +1,11 @@
+package com.unitbv.properties.config;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@RequiredArgsConstructor
+public class AppConfig {
+ private String model;
+
+}
diff --git a/spring2/src/main/java/com/unitbv/properties/config/Car.java b/spring2/src/main/java/com/unitbv/properties/config/Car.java
new file mode 100644
index 0000000..0539481
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/properties/config/Car.java
@@ -0,0 +1,12 @@
+package com.unitbv.properties.config;
+
+import lombok.Getter;
+
+@Getter
+public class Car {
+ private String model;
+
+ public Car(String model) {
+ this.model = model;
+ }
+}
diff --git a/spring2/src/main/java/com/unitbv/properties/programatically/AppConfig.java b/spring2/src/main/java/com/unitbv/properties/programatically/AppConfig.java
new file mode 100644
index 0000000..b04c92c
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/properties/programatically/AppConfig.java
@@ -0,0 +1,5 @@
+package com.unitbv.properties.programatically;
+
+public class AppConfig {
+ private String model;
+}
diff --git a/spring2/src/main/java/com/unitbv/properties/programatically/Car.java b/spring2/src/main/java/com/unitbv/properties/programatically/Car.java
new file mode 100644
index 0000000..0a11aad
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/properties/programatically/Car.java
@@ -0,0 +1,10 @@
+package com.unitbv.properties.programatically;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@Getter
+@RequiredArgsConstructor
+public class Car {
+ private final String model;
+}
diff --git a/spring2/src/main/java/com/unitbv/properties/stereotype/AppConfig.java b/spring2/src/main/java/com/unitbv/properties/stereotype/AppConfig.java
new file mode 100644
index 0000000..54d3141
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/properties/stereotype/AppConfig.java
@@ -0,0 +1,11 @@
+package com.unitbv.properties.stereotype;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@RequiredArgsConstructor
+@ComponentScan
+public class AppConfig {
+}
diff --git a/spring2/src/main/java/com/unitbv/properties/stereotype/Car.java b/spring2/src/main/java/com/unitbv/properties/stereotype/Car.java
new file mode 100644
index 0000000..ca34c6a
--- /dev/null
+++ b/spring2/src/main/java/com/unitbv/properties/stereotype/Car.java
@@ -0,0 +1,9 @@
+package com.unitbv.properties.stereotype;
+
+import lombok.Getter;
+
+@Getter
+public class Car {
+ private String model;
+
+}
\ No newline at end of file
diff --git a/spring2/src/main/resources/application.properties b/spring2/src/main/resources/application.properties
new file mode 100644
index 0000000..e69de29
diff --git a/spring2/src/main/resources/profiles.properties b/spring2/src/main/resources/profiles.properties
new file mode 100644
index 0000000..e69de29
diff --git a/spring2/src/test/java/com/unitbv/dependsOn/DependsOnTest.java b/spring2/src/test/java/com/unitbv/dependsOn/DependsOnTest.java
new file mode 100644
index 0000000..eddf941
--- /dev/null
+++ b/spring2/src/test/java/com/unitbv/dependsOn/DependsOnTest.java
@@ -0,0 +1,27 @@
+package com.unitbv.dependsOn;
+
+
+import org.junit.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class DependsOnTest {
+ // TODO: create 3 beans: BeanA, BeanB and BeanC and make them depending on each other like:
+ // BeanA depends on BeanB and BeanB depends on BeanC
+ // use configuration class to declare beans
+ @Test
+ public void test() {
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
+
+ BeanA beanA = context.getBean("beanA", BeanA.class);
+ BeanB beanB = context.getBean("beanB", BeanB.class);
+ BeanC beanC = context.getBean("beanC", BeanC.class);
+
+ assertNotNull(beanA);
+ assertNotNull(beanB);
+ assertNotNull(beanC);
+ context.close();
+
+ }
+}
diff --git a/spring2/src/test/java/com/unitbv/events/SpringEventsTest.java b/spring2/src/test/java/com/unitbv/events/SpringEventsTest.java
new file mode 100644
index 0000000..0bdff53
--- /dev/null
+++ b/spring2/src/test/java/com/unitbv/events/SpringEventsTest.java
@@ -0,0 +1,25 @@
+package com.unitbv.events;
+
+import com.unitbv.events.configuration.AppConfig;
+import com.unitbv.events.service.CarService;
+import com.unitbv.events.service.PersonService;
+import org.junit.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class SpringEventsTest {
+
+ // Publish an event on PersonService that will be consumed in CarService
+ @Test
+ public void test() {
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
+
+ final PersonService personService = context.getBean(PersonService.class);
+ personService.rentCar("Audi");
+
+ final CarService carService = context.getBean(CarService.class);
+
+ assertEquals(carService.getAvailableCars().size(), 1);
+
+ }
+}
diff --git a/spring2/src/test/java/com/unitbv/multipleConfigs/MultipleConfigsTest.java b/spring2/src/test/java/com/unitbv/multipleConfigs/MultipleConfigsTest.java
new file mode 100644
index 0000000..25f29f6
--- /dev/null
+++ b/spring2/src/test/java/com/unitbv/multipleConfigs/MultipleConfigsTest.java
@@ -0,0 +1,25 @@
+package com.unitbv.multipleConfigs;
+
+
+import com.unitbv.multipleConfigs.appConfig.AppConfig;
+import org.junit.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class MultipleConfigsTest {
+ // TODO: create 2 classes: BeanA, BeanB and declare them as beans in 2 config class; use both of them in AppConfig class
+ @Test
+ public void test() {
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
+
+ BeanA beanA = context.getBean("beanA", BeanA.class);
+ BeanB beanB = context.getBean("beanB", BeanB.class);
+
+ assertNotNull(beanA);
+ assertNotNull(beanB);
+
+ context.close();
+
+ }
+}
diff --git a/spring2/src/test/java/com/unitbv/profiles/automatically/ProfilesTest.java b/spring2/src/test/java/com/unitbv/profiles/automatically/ProfilesTest.java
new file mode 100644
index 0000000..73123c0
--- /dev/null
+++ b/spring2/src/test/java/com/unitbv/profiles/automatically/ProfilesTest.java
@@ -0,0 +1,27 @@
+package com.unitbv.profiles.automatically;
+
+import org.junit.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+
+@ExtendWith(SpringExtension.class)
+@ContextConfiguration(classes = AppConfig.class)
+@RunWith(SpringRunner.class)
+public class ProfilesTest {
+
+ @Autowired
+ DataSourceConfig dataSourceConfig;
+
+ // set dev as active profile in profile.properties file; use this file in AppConfig;
+ @Test
+ public void test() {
+ assertInstanceOf(DevDataSourceConfig.class, dataSourceConfig);
+
+ }
+}
diff --git a/spring2/src/test/java/com/unitbv/profiles/programatically/ProfilesTest.java b/spring2/src/test/java/com/unitbv/profiles/programatically/ProfilesTest.java
new file mode 100644
index 0000000..a38c787
--- /dev/null
+++ b/spring2/src/test/java/com/unitbv/profiles/programatically/ProfilesTest.java
@@ -0,0 +1,39 @@
+package com.unitbv.profiles.programatically;
+
+
+import org.junit.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+
+//TODO: define 3 beans in AppConfig, one for each profile: dev, default, prod
+public class ProfilesTest {
+ @Test
+ public void devProfile() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.getEnvironment().setActiveProfiles("dev");
+ ctx.register(AppConfig.class);
+ ctx.refresh();
+ assertInstanceOf(DevDataSourceConfig.class, ctx.getBean(DataSourceConfig.class));
+ }
+
+ @Test
+ public void prodProfile() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.getEnvironment().setActiveProfiles("prod");
+ ctx.register(AppConfig.class);
+ ctx.refresh();
+
+ assertInstanceOf(ProdDataSourceConfig.class, ctx.getBean(DataSourceConfig.class));
+ }
+
+ @Test
+ public void defaultProfile() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.register(AppConfig.class);
+ ctx.refresh();
+
+ assertInstanceOf(DevDataSourceConfig.class, ctx.getBean(DataSourceConfig.class));
+ }
+
+}
diff --git a/spring2/src/test/java/com/unitbv/profiles/stereotype/ProfilesTest.java b/spring2/src/test/java/com/unitbv/profiles/stereotype/ProfilesTest.java
new file mode 100644
index 0000000..0296057
--- /dev/null
+++ b/spring2/src/test/java/com/unitbv/profiles/stereotype/ProfilesTest.java
@@ -0,0 +1,42 @@
+package com.unitbv.profiles.stereotype;
+
+import com.unitbv.profiles.programatically.AppConfig;
+import com.unitbv.profiles.programatically.DataSourceConfig;
+import com.unitbv.profiles.programatically.DevDataSourceConfig;
+import com.unitbv.profiles.programatically.ProdDataSourceConfig;
+import org.junit.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+
+//TODO define DevDataSourceConfig and ProdDataSourceConfig as beans and set profiles: dev and default for DevDataSourceConfig and prod for ProdDataSourceConfig
+public class ProfilesTest {
+ @Test
+ public void devProfile() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.getEnvironment().setActiveProfiles("dev");
+ ctx.register(com.unitbv.profiles.programatically.AppConfig.class);
+ ctx.refresh();
+ assertInstanceOf(DevDataSourceConfig.class, ctx.getBean(DataSourceConfig.class));
+ }
+
+ @Test
+ public void prodProfile() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.getEnvironment().setActiveProfiles("prod");
+ ctx.register(com.unitbv.profiles.programatically.AppConfig.class);
+ ctx.refresh();
+
+ assertInstanceOf(ProdDataSourceConfig.class, ctx.getBean(com.unitbv.profiles.programatically.DataSourceConfig.class));
+ }
+
+ @Test
+ public void defaultProfile() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.register(AppConfig.class);
+ ctx.refresh();
+
+ assertInstanceOf(DevDataSourceConfig.class, ctx.getBean(DataSourceConfig.class));
+ }
+
+}
diff --git a/spring2/src/test/java/com/unitbv/properties/config/PropertiesConfigTest.java b/spring2/src/test/java/com/unitbv/properties/config/PropertiesConfigTest.java
new file mode 100644
index 0000000..666cbc0
--- /dev/null
+++ b/spring2/src/test/java/com/unitbv/properties/config/PropertiesConfigTest.java
@@ -0,0 +1,17 @@
+package com.unitbv.properties.config;
+
+import org.junit.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class PropertiesConfigTest {
+ // Declare Car as bean in AppConfig; read model value from application.properties file
+ @Test
+ public void test() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
+ final Car car = ctx.getBean(Car.class);
+ assertEquals(car.getModel(), "Audi");
+
+ }
+}
diff --git a/spring2/src/test/java/com/unitbv/properties/programatically/PropertiesProgramTest.java b/spring2/src/test/java/com/unitbv/properties/programatically/PropertiesProgramTest.java
new file mode 100644
index 0000000..7003dc2
--- /dev/null
+++ b/spring2/src/test/java/com/unitbv/properties/programatically/PropertiesProgramTest.java
@@ -0,0 +1,19 @@
+package com.unitbv.properties.programatically;
+
+import org.junit.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class PropertiesProgramTest {
+ //TODO: define Car bean and PropertySourcesPlaceholderConfigurer bean in App config and read model value from application.properties file using PropertySourcesPlaceholderConfigurer; DO NOT USE PropertySource annotation
+ @Test
+ public void test() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
+
+ final Car car = ctx.getBean(Car.class);
+
+ assertEquals(car.getModel(), "Audi");
+
+ }
+}
diff --git a/spring2/src/test/java/com/unitbv/properties/stereotype/PropertiesStereotypeTest.java b/spring2/src/test/java/com/unitbv/properties/stereotype/PropertiesStereotypeTest.java
new file mode 100644
index 0000000..244c6f2
--- /dev/null
+++ b/spring2/src/test/java/com/unitbv/properties/stereotype/PropertiesStereotypeTest.java
@@ -0,0 +1,18 @@
+package com.unitbv.properties.stereotype;
+
+
+import org.junit.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class PropertiesStereotypeTest {
+ //TODO: define Car as a bean and read model directly in Car.class
+ @Test
+ public void test() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
+ final Car car = ctx.getBean(Car.class);
+ assertEquals(car.getModel(), "Audi");
+
+ }
+}