diff --git a/pom.xml b/pom.xml
index 17fd7ad..1691ec0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,11 +1,11 @@
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.springframework.boot
spring-boot-starter-parent
- 2.1.3.RELEASE
+ 2.7.7
com.zoomcare
@@ -23,6 +23,10 @@
org.springframework.boot
spring-boot-starter-actuator
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
org.springframework.boot
spring-boot-starter-data-jdbc
@@ -31,19 +35,22 @@
org.springframework.boot
spring-boot-starter-web
-
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
org.flywaydb
flyway-core
runtime
-
com.h2database
h2
runtime
-
org.springframework.boot
spring-boot-starter-test
@@ -60,4 +67,4 @@
-
+
\ No newline at end of file
diff --git a/src/main/java/com/zoomcare/candidatechallenge/controller/CrudController.java b/src/main/java/com/zoomcare/candidatechallenge/controller/CrudController.java
new file mode 100644
index 0000000..e43d554
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/controller/CrudController.java
@@ -0,0 +1,109 @@
+package com.zoomcare.candidatechallenge.controller;
+
+import com.zoomcare.candidatechallenge.entity.Employee;
+import com.zoomcare.candidatechallenge.entity.Property;
+import com.zoomcare.candidatechallenge.exception.EmployeeNotFoundException;
+import com.zoomcare.candidatechallenge.exception.PropertyNotFoundException;
+import com.zoomcare.candidatechallenge.repository.EmployeeRepository;
+import com.zoomcare.candidatechallenge.repository.PropertiesRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@RestController
+public class CrudController {
+ // , ;
+
+ @Autowired
+ private EmployeeRepository employeeRepository;
+
+ @Autowired
+ private PropertiesRepository propertiesRepository;
+
+ // Employee
+ @PostMapping("/api/employees")
+ public ResponseEntity createEmployee(@RequestBody Employee employee) {
+
+ Employee _employee = employeeRepository.save(new Employee(employee.getSupervisor_id()));
+
+ return new ResponseEntity<>(_employee, HttpStatus.CREATED);
+ }
+
+ @GetMapping("/api/employees")
+ public ResponseEntity> getAllEmployees() {
+ List lemployees = new ArrayList();
+ employeeRepository.findAll().forEach(lemployees::add);
+
+ if (lemployees.isEmpty()) {
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+ }
+
+ return new ResponseEntity<>(lemployees, HttpStatus.OK);
+ }
+
+ @GetMapping("/api/employees/{id}")
+ public ResponseEntity getEmployeeById(@PathVariable("id") long id) {
+
+ Optional employee = employeeRepository.findById(id);
+
+ if(!employee.isPresent()) {
+ throw new EmployeeNotFoundException("Book with Id = " + id + " not found");
+ }
+
+ return new ResponseEntity(employee.get(), HttpStatus.OK);
+ }
+
+ @PutMapping("/api/employees/{id}")
+ public ResponseEntity updateEmployee(@PathVariable("id") long id, @RequestBody Employee employee) {
+
+ Optional _employee = employeeRepository.findById(id);
+
+ if(!_employee.isPresent()) {
+ throw new EmployeeNotFoundException("Employee with Id = " + id + " not found.");
+ }
+
+ _employee.get().setSupervisor_id(employee.getSupervisor_id());
+
+ return new ResponseEntity<>(employeeRepository.save(_employee.get()), HttpStatus.OK);
+ }
+
+ @DeleteMapping("/api/books/{id}")
+ public ResponseEntity deleteEmployee(@PathVariable("id") long id) {
+
+ Optional employee = employeeRepository.findById(id);
+
+ if(!employee.isPresent()) {
+ throw new EmployeeNotFoundException("Employee id = " + id + " not found.");
+ }
+
+ employeeRepository.deleteById(id);
+
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+ }
+
+ //Properties
+ @PostMapping("/api/employees/{employeeId}/properties")
+ public ResponseEntity createProperty(@PathVariable(value = "employeeId") Long employeeId, @RequestBody Property properties) {
+
+ Property _properties = employeeRepository.findById(employeeId).map(emp -> { // Ojo con el map
+ properties.setEmployee(emp);
+ return propertiesRepository.save(properties);
+ }).orElseThrow(() -> new EmployeeNotFoundException("Not found Book with id = " + employeeId));
+
+ return new ResponseEntity<>(_properties, HttpStatus.CREATED);
+ }
+
+ @GetMapping("/api/properties/{id}")
+ public ResponseEntity getPropertiesById(@PathVariable(value = "id") Long id) {
+
+ Property _properties = propertiesRepository.findById(id)
+ .orElseThrow(() -> new PropertyNotFoundException("Property not found with id = " + id));
+
+ return new ResponseEntity<>(_properties, HttpStatus.OK);
+ }
+}
diff --git a/src/main/java/com/zoomcare/candidatechallenge/entity/Employee.java b/src/main/java/com/zoomcare/candidatechallenge/entity/Employee.java
new file mode 100644
index 0000000..944ad71
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/entity/Employee.java
@@ -0,0 +1,42 @@
+package com.zoomcare.candidatechallenge.entity;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "employee")
+public class Employee {
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "employee_generator")
+ private Long id;
+ private Long supervisor_id;
+
+ public Employee() {}
+
+ public Employee(Long supervisor_id) {
+ this.supervisor_id = supervisor_id;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getSupervisor_id() {
+ return supervisor_id;
+ }
+
+ public void setSupervisor_id(Long supervisor_id) {
+ this.supervisor_id = supervisor_id;
+ }
+
+ @Override
+ public String toString() {
+ return "Employee{" +
+ "id=" + id +
+ ", supervisor_id=" + supervisor_id +
+ '}';
+ }
+}
diff --git a/src/main/java/com/zoomcare/candidatechallenge/entity/Property.java b/src/main/java/com/zoomcare/candidatechallenge/entity/Property.java
new file mode 100644
index 0000000..ddbf822
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/entity/Property.java
@@ -0,0 +1,58 @@
+package com.zoomcare.candidatechallenge.entity;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "property")
+public class Property {
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "properties_generator")
+ private Long property_id;
+
+ @ManyToOne(fetch = FetchType.LAZY, optional = false)
+ @JoinColumn(name = "employee_id", nullable = false)
+ @OnDelete(action = OnDeleteAction.CASCADE)
+ @JsonIgnore
+ private Employee employee;
+
+ private String mykey;
+ private String myvalue;
+
+ public Property() {}
+
+ public Long getProperty_id() {
+ return property_id;
+ }
+
+ public void setProperty_id(Long property_id) {
+ this.property_id = property_id;
+ }
+
+ public String getMykey() {
+ return mykey;
+ }
+
+ public void setMykey(String mykey) {
+ this.mykey = mykey;
+ }
+
+ public String getMyvalue() {
+ return myvalue;
+ }
+
+ public void setMyvalue(String myvalue) {
+ this.myvalue = myvalue;
+ }
+
+ public Employee getEmployee() {
+ return employee;
+ }
+
+ public void setEmployee(Employee employee) {
+ this.employee = employee;
+ }
+}
diff --git a/src/main/java/com/zoomcare/candidatechallenge/exception/EmployeeNotFoundException.java b/src/main/java/com/zoomcare/candidatechallenge/exception/EmployeeNotFoundException.java
new file mode 100644
index 0000000..bc137d0
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/exception/EmployeeNotFoundException.java
@@ -0,0 +1,11 @@
+package com.zoomcare.candidatechallenge.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.NOT_FOUND)
+public class EmployeeNotFoundException extends RuntimeException {
+ public EmployeeNotFoundException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/main/java/com/zoomcare/candidatechallenge/exception/PropertyNotFoundException.java b/src/main/java/com/zoomcare/candidatechallenge/exception/PropertyNotFoundException.java
new file mode 100644
index 0000000..a89db12
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/exception/PropertyNotFoundException.java
@@ -0,0 +1,11 @@
+package com.zoomcare.candidatechallenge.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.NOT_FOUND)
+public class PropertyNotFoundException extends RuntimeException {
+ public PropertyNotFoundException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/main/java/com/zoomcare/candidatechallenge/repository/EmployeeRepository.java b/src/main/java/com/zoomcare/candidatechallenge/repository/EmployeeRepository.java
new file mode 100644
index 0000000..0c1caeb
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/repository/EmployeeRepository.java
@@ -0,0 +1,10 @@
+package com.zoomcare.candidatechallenge.repository;
+
+import com.zoomcare.candidatechallenge.entity.Employee;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface EmployeeRepository extends JpaRepository {
+
+}
diff --git a/src/main/java/com/zoomcare/candidatechallenge/repository/PropertiesRepository.java b/src/main/java/com/zoomcare/candidatechallenge/repository/PropertiesRepository.java
new file mode 100644
index 0000000..e560571
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/repository/PropertiesRepository.java
@@ -0,0 +1,16 @@
+package com.zoomcare.candidatechallenge.repository;
+
+import com.zoomcare.candidatechallenge.entity.Property;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+@Repository
+public interface PropertiesRepository extends JpaRepository {
+ List findByEmployeeId(Long id);
+
+ @Transactional
+ void deleteByEmployeeId(long id);
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000..8c24bd2
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+spring.datasource.url=jdbc:h2:mem:testdb
+spring.data.jpa.repositories.bootstrap-mode=default
+spring.jpa.show-sql=true
+spring.h2.console.enabled=true
\ No newline at end of file
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
deleted file mode 100644
index 4408d17..0000000
--- a/src/main/resources/application.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-spring:
- h2:
- console:
- enabled: true
-management:
- endpoints:
- web:
- exposure:
- include: "*"
- endpoint:
- health:
- show-details: always
\ No newline at end of file
diff --git a/src/main/resources/db/migration/V1__init.sql b/src/main/resources/db/migration/V1__init.sql
deleted file mode 100644
index 47eb795..0000000
--- a/src/main/resources/db/migration/V1__init.sql
+++ /dev/null
@@ -1,14 +0,0 @@
-create table employee (
- id bigint(20) not null auto_increment,
- supervisor_id bigint(20),
- primary key (id),
- foreign key (supervisor_id) references employee(id)
-);
-
-create table property (
- employee_id bigint(20) not null,
- key varchar(256),
- value varchar(256),
- primary key (employee_id, key),
- foreign key (employee_id) references employee(id)
-);
\ No newline at end of file
diff --git a/src/main/resources/db/migration/V2__initial_data_structures.sql b/src/main/resources/db/migration/V2__initial_data_structures.sql
deleted file mode 100644
index a7a0745..0000000
--- a/src/main/resources/db/migration/V2__initial_data_structures.sql
+++ /dev/null
@@ -1,39 +0,0 @@
-insert into employee values ();
-select @ceo := scope_identity();
-insert into property (employee_id, key, value) values (@ceo, 'title', 'CEO');
-
-insert into employee (supervisor_id) values (@ceo);
-select @vpsales := scope_identity();
-insert into property (employee_id, key, value) values (@vpsales, 'title', 'Vice President of Sales');
-
-insert into employee(supervisor_id) values (@vpsales);
-select @nasales := scope_identity();
-insert into property (employee_id, key, value) values (@nasales, 'title', 'Regional Director of Sales');
-insert into property (employee_id, key, value) values (@nasales, 'region', 'North America');
-
-insert into employee(supervisor_id) values (@nasales);
-select @salesrep1 := scope_identity();
-insert into property (employee_id, key, value) values (@salesrep1, 'title', 'Sales Representative');
-
-insert into employee(supervisor_id) values (@vpsales);
-select @eusales := scope_identity();
-insert into property (employee_id, key, value) values (@eusales, 'title', 'Regional Director of Sales');
-insert into property (employee_id, key, value) values (@eusales, 'region', 'Europe');
-
-insert into employee (supervisor_id) values (@ceo);
-select @vpp := scope_identity();
-insert into property (employee_id, key, value) values (@vpp, 'title', 'Vice President of People');
-
-insert into employee (supervisor_id) values (@ceo);
-select @vpm := scope_identity();
-insert into property (employee_id, key, value) values (@vpm, 'title', 'Vice President of Marketing');
-
-insert into employee(supervisor_id) values (@vpm);
-select @namarketing := scope_identity();
-insert into property (employee_id, key, value) values (@namarketing, 'title', 'Regional Director of Marketing');
-insert into property (employee_id, key, value) values (@namarketing, 'region', 'North America');
-
-insert into employee(supervisor_id) values (@vpm);
-select @eumarketing := scope_identity();
-insert into property (employee_id, key, value) values (@eumarketing, 'title', 'Regional Director of Marketing');
-insert into property (employee_id, key, value) values (@eumarketing, 'region', 'Europe');
\ No newline at end of file