Merge pull request #12746 from saikatcse03/master
Enable SSL in Spring Boot with MySQL
This commit is contained in:
commit
379537b930
|
@ -0,0 +1,7 @@
|
||||||
|
# Convert pem to jks file
|
||||||
|
mkdir certs
|
||||||
|
|
||||||
|
keytool -importcert -alias MySQLCACert.jks -file ./data/ca.pem \
|
||||||
|
-keystore ./certs/truststore.jks -storepass mypassword
|
||||||
|
openssl pkcs12 -export -in ./data/client-cert.pem -inkey ./data/client-key.pem -out ./certs/certificate.p12 -name "certificate"
|
||||||
|
keytool -importkeystore -srckeystore ./certs/certificate.p12 -srcstoretype pkcs12 -destkeystore ./certs/client-cert.jks
|
|
@ -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,21 @@
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
mysql-service:
|
||||||
|
image: "mysql/mysql-server:8.0.30"
|
||||||
|
container_name: mysql-db
|
||||||
|
command: [ "mysqld",
|
||||||
|
"--require_secure_transport=ON",
|
||||||
|
"--default_authentication_plugin=mysql_native_password",
|
||||||
|
"--general_log=ON" ]
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
volumes:
|
||||||
|
- type: bind
|
||||||
|
source: ./data
|
||||||
|
target: /var/lib/mysql
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_HOST: "%"
|
||||||
|
MYSQL_ROOT_PASSWORD: "Password2022"
|
||||||
|
MYSQL_DATABASE: test_db
|
|
@ -42,4 +42,21 @@
|
||||||
<mysql-connector-java.version>8.0.23</mysql-connector-java.version>
|
<mysql-connector-java.version>8.0.23</mysql-connector-java.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<version>2.1.5.RELEASE</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
|
@ -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,26 @@
|
||||||
|
package com.baeldung.boot.jpa;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.client.HttpClientErrorException;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class EmployeeController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmployeeRepository empRepository;
|
||||||
|
|
||||||
|
@GetMapping("/employee/{empId}")
|
||||||
|
public Employee get(@PathVariable(name = "empId") Integer empId) {
|
||||||
|
Optional<Employee> emp = empRepository.findById(empId);
|
||||||
|
return emp.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/employee")
|
||||||
|
public Employee createUser(@RequestBody Employee 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
|
||||||
|
@ -11,4 +10,26 @@ spring:
|
||||||
hibernate:
|
hibernate:
|
||||||
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_CA&
|
||||||
|
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/client-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.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.mockito.Mockito.when;
|
||||||
|
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");
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
export TRUSTSTORE=./mysql-server/certs/truststore.jks
|
||||||
|
export TRUSTSTORE_PASSWORD=mypassword
|
||||||
|
export KEYSTORE=./mysql-server/certs/client-cert.jks
|
||||||
|
export KEYSTORE_PASSWORD=mypassword
|
||||||
|
export SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/test_db?sslMode=VERIFY_CA
|
||||||
|
export SPRING_DATASOURCE_USERNAME=test_user
|
||||||
|
export SPRING_DATASOURCE_PASSWORD=Password2022
|
||||||
|
|
||||||
|
java -Djavax.net.ssl.keyStore=$KEYSTORE \
|
||||||
|
-Djavax.net.ssl.keyStorePassword=$KEYSTORE_PASSWORD \
|
||||||
|
-Djavax.net.ssl.trustStore=$TRUSTSTORE \
|
||||||
|
-Djavax.net.ssl.trustStorePassword=$TRUSTSTORE_PASSWORD \
|
||||||
|
-jar ./target/spring-boot-mysql-0.1.0.jar
|
Loading…
Reference in New Issue