일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 기록으로 실력을 쌓자
- CKA
- 정보처리기사 실기
- CloudWatch
- 정보처리기사실기 기출문제
- 오블완
- 티스토리챌린지
- Kubernetes
- 정보처리기사 실기 기출문제
- CKA 기출문제
- Java
- kotlin querydsl
- Linux
- Spring
- mysql 튜닝
- IntelliJ
- AI
- kotlin coroutine
- AWS EKS
- APM
- 코틀린 코루틴의 정석
- 공부
- Elasticsearch
- minikube
- aws
- kotlin
- kotlin spring
- PETERICA
- MySQL
- Pinpoint
- Today
- Total
피터의 개발이야기
[kotlin] Spring Data Elasticsearch 샘플코드 본문
ㅁ 들어가며
ㅇ Spring Data Elasticsearch를 Kotlin으로 예제 코드를 작성해보겠다.
ㅇ 이 글은 Kotlin과 Spring Boot를 사용하여 Elasticsearch에 데이터를 저장하고, JPA로 등록 조회 방법을 정리하였다.
ㅁ 관련 글
ㅇ [kotlin] Spring Data Elasticsearch 샘플코드
ㅇ [Elasticsearch] Elasticsearch + Kibana 설치하기 with Docker
ㅇ [Elasticsearch] Docker로 Elasticsearch 설치 및 테스트하기
ㅇ [Elasticsearch] Kibana Query Language 사용법 정리
ㅁ Elasticsearch API-KEY 생성
ㅇ Elasticsearch와 통신하기 위해서 api-key가 필요하다.
ㅇ kibana, Dev Tools에서 실행하였다.
POST /_security/api_key
{
"name": "spring_command",
"expiration": "999d",
"role_descriptors": {
"role-team-index-command": {
"cluster": ["all"],
"index": [
{
"names": ["*"],
"privileges": ["all"]
}
]
}
}
}
결과:
{
"id": "P26mDJEBPA0rStSZL1pD",
"name": "spring_command",
"expiration": 1808807703364,
"api_key": "Z_9Rv5N9SlelmGvFK7T8rw",
"encoded": "UDI2bURKRUJQQTByU3RTWkwxcEQ6Wl85UnY1TjlTbGVsbUd2Rks3VDhydw=="
}
ㅇ 실행한 스크립트
ㅇ 생성된 키는 Management에서 확인할 수 있다.
ㅁ 프로젝트 생성
ㅇ MySQL Driver, Spring Data JPA, Spring Data Elasticsearch, Spring Web을 추가하여 프로젝트 구성
ㅁ 의존성 추가
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-elasticsearch")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
runtimeOnly("com.mysql:mysql-connector-j")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
ㅁ Elasticsearch 연결 설정
spring:
application:
name: kotlin-elasticsearch
elasticsearch:
rest:
url: localhost:9200
api_key: Z_9Rv5N9SlelmGvFK7T8rw
username: elastic
password: Bcw_HDE8Nr2*RhmO6Cko
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/playground?characterEncoding=UTF-8
username: root
password: strong-password
ㅇ application.yml 파일에 Elasticsearch 연결 정보를 추가한다.
ㅇ username과 password는 Elasticsearch를 설치하였을 때에 자동생성되었던 것이다.
ㄴ이곳을 참조: [Elasticsearch] Elasticsearch + Kibana 설치하기 with Docker
@Configuration
@EnableElasticsearchRepositories
class ESconfig(
@Value("\${spring.elasticsearch.rest.url}") val uri: String,
@Value("\${spring.elasticsearch.rest.api_key}") val apiKey: String,
@Value("\${spring.elasticsearch.rest.username}") val username: String,
@Value("\${spring.elasticsearch.rest.password}") val password: String
): ElasticsearchConfiguration() {
override fun clientConfiguration(): ClientConfiguration {
val httpHeaders = HttpHeaders()
httpHeaders.add("Authorization", "Bearer $apiKey")
return ClientConfiguration.builder()
.connectedTo(uri)
.usingSsl()
.withDefaultHeaders(httpHeaders)
.withBasicAuth(username, password )
.build()
}
}
ㅇ ES의 연결을 설정한다.
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
ㅇ 위와 같은 SSL 인증서 문제가 발생하면, 이곳을 [Spring] SSL 접속시, PKIX path building failed 오류 해결방법 참조하면 된다.
ㅁ 엔티티 클래스 정의
import org.springframework.data.annotation.Id
import org.springframework.data.elasticsearch.annotations.Document
import org.springframework.data.elasticsearch.annotations.Field
import org.springframework.data.elasticsearch.annotations.FieldType
@Document(indexName = "products")
data class Product(
@Id
val id: String,
@Field(type = FieldType.Text, name = "name")
val name: String,
@Field(type = FieldType.Double, name = "price")
val price: Double
)
ㅇ Elasticsearch에 저장할 데이터 모델을 정의한다.
ㅁ Repository 인터페이스 생성
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository
interface ProductRepository : ElasticsearchRepository<Product, String> {
fun findByNameContaining(name: String): List<Product>
}
ㅇ Spring Data Elasticsearch를 사용하여 Repository 인터페이스를 생성한다.
ㅁ 서비스 클래스 구현
import org.springframework.stereotype.Service
@Service
class ProductService(private val productRepository: ProductRepository) {
fun saveProduct(product: Product): Product {
return productRepository.save(product)
}
fun findProductById(id: String): Product? {
return productRepository.findById(id).orElse(null)
}
fun searchProducts(name: String): List<Product> {
return productRepository.findByNameContaining(name)
}
}
ㅇ 데이터를 저장하고 조회하는 서비스 클래스를 구현한다.
ㅁ 컨트롤러 구현
import com.peterica.kotlinelasticsearch.Product
import com.peterica.kotlinelasticsearch.service.ProductService
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/products")
class ProductController(private val productService: ProductService) {
@GetMapping("/{id}")
fun getProduct(@PathVariable id: String): Product? {
return productService.findProductById(id)
}
@GetMapping("/search")
fun searchProducts(@RequestParam name: String): List<Product> {
return productService.searchProducts(name)
}
@PostMapping
fun createProduct(@RequestBody product: Product): Product {
return productService.saveProduct(product)
}
}
ㅇ REST API를 통해 데이터를 저장하고 조회할 수 있는 컨트롤러를 구현한다.
ㅁ Spring Data Elasticsearch Versions
Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch |
Spring Framework
|
2024 | 5.3.1 | 8.13.4 | 6.1.x |
2023.1 (Vaughan) | 5.2.x | 8.11.1 | 6.1.x |
2023.0 (Ullmann) | 5.1.x | 8.7.1 | 6.0.x |
2022.0 (Turing) | 5.0.x[1] | 8.5.3 | 6.0.x |
2021.2 (Raj) | 4.4.x[1] | 7.17.3 | 5.3.x |
2021.1 (Q) | 4.3.x[1] | 7.15.2 | 5.3.x |
2021.0 (Pascal) | 4.2.x[1] | 7.12.0 | 5.3.x |
2020.0 (Ockham) | 4.1.x[1] | 7.9.3 | 5.3.2 |
Neumann | 4.0.x[1] | 7.6.2 | 5.2.12 |
Moore | 3.2.x[1] | 6.8.12 | 5.2.12 |
Lovelace | 3.1.x[1] | 6.2.2 | 5.1.19 |
Kay | 3.0.x[1] | 5.5.0 | 5.0.13 |
Ingalls | 2.1.x[1] | 2.4.0 | 4.3.25 |
ㅇ Spring Data 릴리스 트레인에서 사용되는 Elasticsearch 및 Spring 버전과 그에 포함된 Spring Data Elasticsearch 버전을 보여준다.
ㅁ BootRun 테스트
ㅇ 정상 빌드 및 SpringBoot 정상 작동을 확인하였다.
ㅇ 이제부터는 테스트를 진행해 보자.
ㅁ TDD 코드 작성
package com.peterica.kotlinelasticsearch
import com.peterica.kotlinelasticsearch.repository.ProductRepository
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
@SpringBootTest
class KotlinElasticsearchApplicationTests {
@Autowired
private lateinit var productRepository: ProductRepository
@BeforeEach
fun setUp() {
productRepository.deleteAll()
}
@Test
fun `test save and find product`() {
val product = Product(id = "1", name = "Test Product", price = 10.0)
productRepository.save(product)
val foundProduct = productRepository.findById("1").orElse(null)
assertNotNull(foundProduct)
assertEquals("Test Product", foundProduct?.name)
assertEquals(10.0, foundProduct?.price)
}
@Test
fun `test find all products`() {
val product1 = Product(id = "1", name = "Product 1", price = 10.0)
val product2 = Product(id = "2", name = "Product 2", price = 20.0)
productRepository.saveAll(listOf(product1, product2))
val products = productRepository.findAll()
assertEquals(2, products.count())
}
}
ㅁ Kibana 데이터 생성
# 인덱스생성
PUT /products
출력:
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "products"
}
# 인덱스 삭제
DELETE /products
출력:
{
"acknowledged": true
}
ㅇ 인덱스를 생성 삭제할 수 있다.
# 생성
POST /products/_doc
{
"id": "1",
"name": "Laptop",
"price": 999.99
}
출력:
{
"_index": "products",
"_id": "VL24CpEBcfvwz7Sg77M4",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
ㅇ Kibana를 통한 조회
소스는 여기에 있음
ㅁ 함께 보면 좋은 사이트
ㅇ Elasticsearch에 Java Low Level REST Client를 통해 요청 보내기
ㅇ Spring Data Elasticsearch Versions
'Programming > Kotlin' 카테고리의 다른 글
[Kotlin] QueryDSL의 Q클래스 생성 과정에서 Entity 참조 오류 해결 (0) | 2024.08.15 |
---|---|
[Kotlin] Kotlin에서 all-open과 no-arg의 필요성 (0) | 2024.08.14 |
[Kotlin] Spring Boot Kotlin 프로젝트에 ktlint 설정하기 (0) | 2024.08.05 |
[Kotlin] Spring MVC, Circular view path 에러 (0) | 2024.08.04 |
[Kotlin] Spring Boot와 Kotlin으로 QueryDSL 페이징 처리하기 (0) | 2024.08.04 |