SSL in JPA App
This commit is contained in:
parent
82dfba062c
commit
98bc9c336b
|
@ -0,0 +1,2 @@
|
||||||
|
CREATE USER 'test_user'@'%' IDENTIFIED BY 'Password2022' require X509;
|
||||||
|
GRANT ALL PRIVILEGES ON test_db.* TO 'test_user'@'%';
|
|
@ -0,0 +1,24 @@
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
mysql-service:
|
||||||
|
image: "mysql/mysql-server:8.0.30"
|
||||||
|
container_name: mysql-db
|
||||||
|
command: [ "mysqld",
|
||||||
|
"--require_secure_transport=ON",
|
||||||
|
"--ssl-ca=/etc/certs/root-ca.pem",
|
||||||
|
"--ssl-cert=/etc/certs/server-cert.pem",
|
||||||
|
"--ssl-key=/etc/certs/server-key.pem",
|
||||||
|
"--default_authentication_plugin=mysql_native_password",
|
||||||
|
"--general_log=ON" ]
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
volumes:
|
||||||
|
- type: bind
|
||||||
|
source: ./certs
|
||||||
|
target: /etc/certs/
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_HOST: "%"
|
||||||
|
MYSQL_ROOT_PASSWORD: "Password2022"
|
||||||
|
MYSQL_DATABASE: test_db
|
|
@ -0,0 +1,35 @@
|
||||||
|
mkdir certs
|
||||||
|
cd ./certs
|
||||||
|
|
||||||
|
# Generate new CA certificate ca.pem file.
|
||||||
|
openssl genrsa 2048 > root-ca-key.pem
|
||||||
|
|
||||||
|
openssl req -new -x509 -nodes -days 3600 \
|
||||||
|
-subj "/C=SE/ST=STOCKHOLM/L=Test/CN=fake-CA" \
|
||||||
|
-key root-ca-key.pem -out root-ca.pem
|
||||||
|
|
||||||
|
# Create the server-side certificates
|
||||||
|
openssl req -newkey rsa:2048 -days 3600 -nodes \
|
||||||
|
-subj "/C=SE/ST=STOCKHOLM/L=Test/CN=localhost" \
|
||||||
|
-keyout server-key.pem -out server-req.pem
|
||||||
|
openssl rsa -in server-key.pem -out server-key.pem
|
||||||
|
openssl x509 -req -in server-req.pem -days 3600 \
|
||||||
|
-CA root-ca.pem -CAkey root-ca-key.pem -set_serial 01 -out server-cert.pem
|
||||||
|
|
||||||
|
# Create the client-side certificates
|
||||||
|
openssl req -newkey rsa:2048 -days 3600 -nodes \
|
||||||
|
-subj "/C=SE/ST=STOCKHOLM/L=Test/CN=localhost" \
|
||||||
|
-keyout client-key.pem -out client-req.pem
|
||||||
|
openssl rsa -in client-key.pem -out client-key.pem
|
||||||
|
openssl x509 -req -in client-req.pem -days 3600 \
|
||||||
|
-CA root-ca.pem -CAkey root-ca-key.pem -set_serial 01 -out client-cert.pem
|
||||||
|
|
||||||
|
# Verify the certificates are correct
|
||||||
|
openssl verify -CAfile root-ca.pem server-cert.pem client-cert.pem
|
||||||
|
|
||||||
|
# Convert pem to jks file
|
||||||
|
keytool -importcert -alias MySQLCACert.jks -file root-ca.pem \
|
||||||
|
-keystore truststore.jks -storepass mypassword
|
||||||
|
|
||||||
|
openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -out certificate.p12 -name "certificate"
|
||||||
|
keytool -importkeystore -srckeystore certificate.p12 -srcstoretype pkcs12 -destkeystore cert.jks
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.baeldung.boot.jpa;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Employee implements Serializable {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
@Column(name = "id")
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@Column(name = "emp_name")
|
||||||
|
private String empName;
|
||||||
|
|
||||||
|
@Column(name = "job_title")
|
||||||
|
private String jobTitle;
|
||||||
|
|
||||||
|
@Column(name = "emp_doj")
|
||||||
|
private LocalDate empDoj;
|
||||||
|
|
||||||
|
@Column(name = "created_date")
|
||||||
|
private Date createdDate = new Date();
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmpName() {
|
||||||
|
return empName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmpName(String empName) {
|
||||||
|
this.empName = empName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJobTitle() {
|
||||||
|
return jobTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJobTitle(String jobTitle) {
|
||||||
|
this.jobTitle = jobTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getEmpDoj() {
|
||||||
|
return empDoj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmpDoj(LocalDate empDoj) {
|
||||||
|
this.empDoj = empDoj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreatedDate() {
|
||||||
|
return createdDate;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.boot.jpa;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class EmployeeController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmployeeRepository empRepository;
|
||||||
|
|
||||||
|
@GetMapping("/employee/{empId}")
|
||||||
|
public Employee get(@PathVariable(name = "empId") Integer empId) {
|
||||||
|
return empRepository.findById(empId).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/employee")
|
||||||
|
public Employee createUser(@RequestBody Employee employee) {
|
||||||
|
System.out.println(employee);
|
||||||
|
empRepository.save(employee);
|
||||||
|
return employee;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.baeldung.boot.jpa;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface EmployeeRepository extends JpaRepository<Employee, Serializable> {
|
||||||
|
}
|
|
@ -1,9 +1,8 @@
|
||||||
spring:
|
spring:
|
||||||
datasource:
|
profiles:
|
||||||
url: jdbc:mysql://localhost:3306/test?
|
active: "dev2"
|
||||||
username: root
|
main:
|
||||||
password:
|
banner-mode: "off"
|
||||||
|
|
||||||
jpa:
|
jpa:
|
||||||
hibernate:
|
hibernate:
|
||||||
ddl-auto: update
|
ddl-auto: update
|
||||||
|
@ -12,3 +11,25 @@ spring:
|
||||||
dialect: org.hibernate.dialect.MySQL8Dialect
|
dialect: org.hibernate.dialect.MySQL8Dialect
|
||||||
jdbc:
|
jdbc:
|
||||||
time_zone: UTC
|
time_zone: UTC
|
||||||
|
---
|
||||||
|
|
||||||
|
spring:
|
||||||
|
profiles: "dev1"
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://localhost:3306/test?
|
||||||
|
username: root
|
||||||
|
password:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
spring:
|
||||||
|
profiles: "dev2"
|
||||||
|
datasource:
|
||||||
|
url: >-
|
||||||
|
jdbc:mysql://localhost:3306/test_db?sslMode=VERIFY_IDENTITY&
|
||||||
|
trustCertificateKeyStoreUrl=file:/Users/saikatchakraborty/tutorials/persistence-modules/spring-boot-mysql/mysql-server/certs/truststore.jks&
|
||||||
|
trustCertificateKeyStorePassword=mypassword&
|
||||||
|
clientCertificateKeyStoreUrl=file:/Users/saikatchakraborty/tutorials/persistence-modules/spring-boot-mysql/mysql-server/certs/cert.jks&
|
||||||
|
clientCertificateKeyStorePassword=mypassword
|
||||||
|
username: test_user
|
||||||
|
password: Password2022
|
|
@ -0,0 +1,72 @@
|
||||||
|
package com.baeldung.boot.jpa;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@WebMvcTest(EmployeeController.class)
|
||||||
|
public class EmployeeControllerUnitTest {
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private EmployeeRepository employeeRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEmployeeId_whenGetEmployeeCalled_ThenReturnEmployee() throws Exception {
|
||||||
|
Employee employeeExpected = new Employee();
|
||||||
|
employeeExpected.setEmpName("Test Emp");
|
||||||
|
employeeExpected.setEmpDoj(LocalDate.now());
|
||||||
|
employeeExpected.setJobTitle("Manager");
|
||||||
|
|
||||||
|
Mockito.when(employeeRepository.findById(1234)).thenReturn(Optional.of(employeeExpected));
|
||||||
|
|
||||||
|
MvcResult result = mockMvc.perform(get("/employee/1234"))
|
||||||
|
.andExpect(status().isOk()).andReturn();
|
||||||
|
|
||||||
|
Employee employee = objectMapper.readValue(result.getResponse().getContentAsString(), Employee.class);
|
||||||
|
assertEquals(employeeExpected.getEmpName(), employee.getEmpName());
|
||||||
|
assertEquals(employeeExpected.getJobTitle(), employee.getJobTitle());
|
||||||
|
assertEquals(employeeExpected.getEmpDoj(), employee.getEmpDoj());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEmployee_whenCreateEmployeeCalled_ThenReturnEmployee() throws Exception {
|
||||||
|
Employee employeeExpected = new Employee();
|
||||||
|
employeeExpected.setEmpName("Test Emp");
|
||||||
|
employeeExpected.setEmpDoj(LocalDate.now());
|
||||||
|
employeeExpected.setJobTitle("Manager");
|
||||||
|
|
||||||
|
Mockito.when(employeeRepository.save(employeeExpected)).thenReturn(employeeExpected);
|
||||||
|
|
||||||
|
MvcResult result = mockMvc.perform(post("/employee")
|
||||||
|
.content(objectMapper.writeValueAsString(employeeExpected))
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andReturn();
|
||||||
|
|
||||||
|
Employee employee = objectMapper.readValue(result.getResponse().getContentAsString(), Employee.class);
|
||||||
|
assertEquals(employeeExpected.getEmpName(), employee.getEmpName());
|
||||||
|
assertEquals(employeeExpected.getJobTitle(), employee.getJobTitle());
|
||||||
|
assertEquals(employeeExpected.getEmpDoj(), employee.getEmpDoj());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue