이 글에서는 Springboot에 Couchbase를 연동하는 방법에 대해 알아보겠습니다.

Couchbase는 docker로 올리고, Springboot에서 JSON 로그를 couchbase에 insert, select하는 간단한 예제를 소개합니다.

 

전체 소스는 깃헙을 참고하시기 바랍니다.

 

 

01. 개발 환경 셋팅

1) 프로젝트 구조

 

2) build.gradle

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    
    /* couchbase */
    compile group: 'org.springframework.data', name: 'spring-data-couchbase', version: '4.0.3.RELEASE'
    
    /* lombok */
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

 

3) Couchbase 컨테이너 실행

Couchbase 컨테이너는 공식 이미지를 사용하며, 문서에 실행 방법에 대한 설명이 잘나와 있으므로 참고하시길 바랍니다.

Docker가 설치되어 있지 않다면 이글을 참고해주세요!

# docker run -d --name db -p 8091-8094:8091-8094 -p 11210:11210 couchbase:community-6.5.0

여기서는 cummunity-6.5.0 이미지를 다운받아 실행했지만, 다른 버전으로 진행해도 상관없을겁니다.

컨테이너를 실행했으면 http://localhost:8091/ui/index.html에 접근하여 클러스터를 설정해줍니다.

이 글에서 설정한 클러스터 정보는 다음과 같습니다.

  • Cluster Name : exam
  • Create Admin Username : victolee
  • Create Password : 123456

설정을 마치고 아래의 대시보드로 진입했으면 끝입니다.

 

 

02. 구현하기

1) CouchbaseConfig.java

import org.springframework.context.annotation.Configuration;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;

@Configuration
@EnableCouchbaseRepositories(basePackages={"com.victolee.couchbaseexam"})
public class CouchbaseConfig extends AbstractCouchbaseConfiguration {
    @Override
    public String getConnectionString() {
        return "couchbase://127.0.0.1";
    }

    @Override
    public String getBucketName() {
        return "sample_bucket";
    }

    @Override
    public String getUserName() {
        return "victolee";
    }

    @Override
    public String getPassword() {
        return "123456";
    }
}

Couchbase 서버에 접속하기 위한 connection 설정을 합니다.

  • getConnectionString()
    • Couchbase 서버 url을 명시하면 됩니다.
    • 여기서는 local에 컨테이너를 띄운 것이므로 127.0.0.1을 작성했습니다.
  • getBuckectName()
    • 접근할 버킷명을 작성합니다.
  • getUserName()
    • Couchbase 클러스터 생성시 기입했던 Admin Username을 작성합니다.
  • getPassword()
    • Couchbase 클러스터 생성시 기입했던 Admin Password를 작성합니다.

❗❗ 주의

해당 파일은 DB에 커넥션하는 설정 파일이므로 공개된 저장소에 저장되지 않도록 .gitignore를 해주시는것이 좋습니다.

 

 

2) MessageLogController.java

import com.victolee.couchbaseexam.dto.MessageLogDto;
import com.victolee.couchbaseexam.service.MessageLogService;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@AllArgsConstructor
@RequestMapping(value = "/log")
public class MessageLogController {
    private final MessageLogService messageLogService;

    @GetMapping
    public List<Map<String, Object>> getLogList(String startDate, String endDate) {
        List<MessageLogDto> messageLogDtos = messageLogService.getLogList(LocalDateTime.parse(startDate), LocalDateTime.parse(endDate));

        List<Map<String, Object>> messageLogList = new ArrayList<>();
        for (MessageLogDto mailLogDto : messageLogDtos) {
            Map<String, Object> result = new HashMap<>();
            result.put("sender", mailLogDto.getSender());
            result.put("receiver", mailLogDto.getReceiver());
            result.put("content", mailLogDto.getContent());
            result.put("date", mailLogDto.getDate());
            messageLogList.add(result);
        }

        return messageLogList;
    }

    @PostMapping
    public String setLog(MessageLogDto messageLogDto) {
        messageLogService.setLog(messageLogDto);

        return "success";
    }
}

 

컨트롤러를 작성합니다.

  • getLostList()
    • 파라미터인 두 일시 사이에 존재하는 로그 리스트를 조회하는 API
  • setLog()
    • 로그를 기록하는 API

 

 

3) MessageLogDocument.java

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.couchbase.core.mapping.Document;
import org.springframework.data.couchbase.core.mapping.Field;
import org.springframework.data.couchbase.core.mapping.id.GeneratedValue;
import org.springframework.data.couchbase.core.mapping.id.GenerationStrategy;

@Builder
@Data
@AllArgsConstructor
@Document
public class MessageLogDocument {
    @Id
    @GeneratedValue(strategy = GenerationStrategy.UNIQUE)
    final String id;

    @Field
    String sender;

    @Field
    String receiver;

    @Field
    String content;

    @Field
    @CreatedDate
    String date;
}

실제 DB 컬럼과 일치하는 domain을 작성합니다.

 

4) MessageLogDto.java

import lombok.*;

import java.time.LocalDateTime;

@Builder
@Getter
@Setter
@ToString
@AllArgsConstructor
public class MessageLogDto {
    private String id;
    private String sender;
    private String receiver;
    private String content;
    private LocalDateTime date;
}

데이터 전달용 dto를 작성합니다.

 

5) MessageLogService.java

import com.victolee.couchbaseexam.domain.document.MessageLogDocument;
import com.victolee.couchbaseexam.domain.repository.MessageLogRepository;
import com.victolee.couchbaseexam.dto.MessageLogDto;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@AllArgsConstructor
public class MessageLogService {
    private final MessageLogRepository messageLogRepository;

    /**
     * get log
     */
    public List<MessageLogDto> getLogList(LocalDateTime startDateTime, LocalDateTime endDateTime) {
        List<MessageLogDto> messageLogDtos = new ArrayList<>();
        List<MessageLogDocument> messageLogDocuments = messageLogRepository.findAllByDateBetween(startDateTime, endDateTime);

        for (MessageLogDocument messageLogDocument : messageLogDocuments) {
            messageLogDtos.add(this.convertDocumentToDto(messageLogDocument));
        }

        return messageLogDtos;
    }

    /**
     * add log
     */
    public void setLog(MessageLogDto messageLogDto) {
        messageLogRepository.save(this.createLogDocument(messageLogDto));
    }

    /**
     * convert Dto to Document
     */
    private MessageLogDocument createLogDocument(MessageLogDto messageLogDto) {
        return MessageLogDocument.builder()
                .content(messageLogDto.getContent())
                .sender(messageLogDto.getSender())
                .receiver(messageLogDto.getReceiver())
                .date(LocalDateTime.now())
                .build();
    }

    /**
     * convert Document to Dto
     */
    private MessageLogDto convertDocumentToDto(MessageLogDocument messageLogDocument) {
        return MessageLogDto.builder()
                .sender(messageLogDocument.getSender())
                .receiver(messageLogDocument.getReceiver())
                .content(messageLogDocument.getContent())
                .date(messageLogDocument.getDate())
                .build();
    }
}

로그 리스트를 조회하고, 추가하는 비즈로직을 작성합니다.

 

6) MessageLogRepository.java

import com.victolee.couchbaseexam.domain.document.MessageLogDocument;
import org.springframework.data.repository.CrudRepository;

import java.time.LocalDateTime;
import java.util.List;

public interface MessageLogRepository extends CrudRepository<MessageLogDocument, String> {
    List<MessageLogDocument> findAllByDateBetween(LocalDateTime startDateTime, LocalDateTime endDateTime);
}

 

다른 Spring Data에서 사용하는 것처럼 couchbase도 CrudRepository 인터페이스를 상속받아서 사용합니다.

findAllByDateBetween는 API 파라미터 두 날짜 사이에 기록된 로그를 조회하기 위해 추가한 메서드입니다.

 

 

 

03. 테스트

1) Couchbase 어드민 셋팅

우선 테스트하기에 앞서, Couchbase dashboard의 Buckets탭에서 버킷을 생성합니다.

버킷명은 CouchbaseConfig에서 작성한 것과 동일하게 sample_bucket으로 생성해줍니다.

 

다음으로 Query 탭에서 인덱스를 추가합니다.

CREATE PRIMARY INDEX ON sample_bucket;

 

2) 메시지 등록

이제 postman으로 API를 호출하여, 메시지를 작성해보겠습니다.

 

메시지는 Couchbase 어드민의 Documents 탭에서 확인할 수 있습니다.

날짜 조회가 정상적으로 수행되는지 확인하기 위해 시간 간격을 조금 두고 메시지를 여러개 등록해두면 좋습니다.

 

 

3) 메시지 검색

다음으로 로그 리스트를 조회해보도록 하겠습니다.

 

2020-11-29 기준으로 조회해보면 다음과 같이 총 2개의 리스트가 출력이 됩니다.

 

시간을 수정해서 API를 조회해도 정상적으로 조회되는것을 확인할수 있습니다.

 

 

이상으로 Springboot에서 Couchbase를 연동하고 간단한 테스트를 해보았습니다.

 

참고 자료

  • docs.spring.io/spring-data/couchbase/docs/current/reference/html/#reference