Skip to content

Commit

Permalink
Merge pull request #61 from makevook/issue/60
Browse files Browse the repository at this point in the history
chore: meilisearch testcontainer 추가
  • Loading branch information
seungyeop-lee authored May 23, 2024
2 parents 4eae213 + 63c4a26 commit 71dcb5a
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 54 deletions.
38 changes: 2 additions & 36 deletions api/src/main/java/vook/server/api/devhelper/InitService.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

@Service
Expand All @@ -35,6 +34,7 @@ public class InitService {
private final UserRepository userRepository;
private final TermsRepository termsRepository;
private final DemoTermSearchService searchService;
private final TestTermsLoader testTermsLoader;

public void init() {
deleteAll();
Expand All @@ -43,7 +43,7 @@ public void init() {
termsRepository.save(Terms.of("개인정보 수집 이용 약관", loadContents("classpath:init/개인정보_수집_이용_약관.txt"), true));
termsRepository.save(Terms.of("마케팅 메일 수신 약관", loadContents("classpath:init/마케팅_메일_수신_약관.txt"), false));

List<DemoTerm> devTerms = getTerms("classpath:init/개발.tsv");
List<DemoTerm> devTerms = testTermsLoader.getTerms("classpath:init/개발.tsv");
demoTermRepository.saveAll(devTerms);

searchService.init();
Expand Down Expand Up @@ -76,38 +76,4 @@ private String loadContents(String location) {
throw new RuntimeException(e);
}
}

private List<DemoTerm> getTerms(String location) {
try {
// file로 바로 접근 할 경우, IDE에서는 접근 가능하나, jar로 패키징 후 실행 시에는 접근 불가능
// ref) https://velog.io/@haron/트러블슈팅-Spring-IDE-에서-되는데-배포하면-안-돼요
InputStream tsvFileInputStream = resourceLoader.getResource(location).getInputStream();
CsvReader tsvReader = new CsvReader("\t");
List<RawTerm> rawTerms = tsvReader.readValue(tsvFileInputStream, RawTerm.class);
return toTerms(rawTerms);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private static List<DemoTerm> toTerms(List<RawTerm> rawTerms) {
return rawTerms.stream()
.map(RawTerm::toTerm)
.toList();
}

public static class RawTerm {
private String term;
private String synonyms;
private String meaning;

public DemoTerm toTerm() {
DemoTerm term = DemoTerm.forCreateOf(this.term, this.meaning);
String[] synonymArray = this.synonyms.split("//n");
Arrays.stream(synonymArray)
.map(String::trim)
.forEach(term::addSynonym);
return term;
}
}
}
52 changes: 52 additions & 0 deletions api/src/main/java/vook/server/api/devhelper/TestTermsLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package vook.server.api.devhelper;

import lombok.RequiredArgsConstructor;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import vook.server.api.model.demo.DemoTerm;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

@Component
@RequiredArgsConstructor
public class TestTermsLoader {

private final ResourceLoader resourceLoader;

public List<DemoTerm> getTerms(String location) {
try {
// file로 바로 접근 할 경우, IDE에서는 접근 가능하나, jar로 패키징 후 실행 시에는 접근 불가능
// ref) https://velog.io/@haron/트러블슈팅-Spring-IDE-에서-되는데-배포하면-안-돼요
InputStream tsvFileInputStream = resourceLoader.getResource(location).getInputStream();
CsvReader tsvReader = new CsvReader("\t");
List<RawTerm> rawTerms = tsvReader.readValue(tsvFileInputStream, RawTerm.class);
return toTerms(rawTerms);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

static List<DemoTerm> toTerms(List<RawTerm> rawTerms) {
return rawTerms.stream()
.map(RawTerm::toTerm)
.toList();
}

static class RawTerm {
private String term;
private String synonyms;
private String meaning;

public DemoTerm toTerm() {
DemoTerm term = DemoTerm.forCreateOf(this.term, this.meaning);
String[] synonymArray = this.synonyms.split("//n");
Arrays.stream(synonymArray)
.map(String::trim)
.forEach(term::addSynonym);
return term;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.meilisearch.sdk.model.TypoTolerance;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import vook.server.api.model.demo.DemoTerm;
import vook.server.api.model.demo.DemoTermSynonym;
Expand All @@ -19,13 +18,17 @@
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class DemoTermSearchService extends MeilisearchService {

private static final String DEMO_TERMS_INDEX_UID = "demo-terms";

private final ObjectMapper objectMapper;

public DemoTermSearchService(MeilisearchProperties properties, ObjectMapper objectMapper) {
super(properties);
this.objectMapper = objectMapper;
}

public void clearAll() {
clearAll(DEMO_TERMS_INDEX_UID);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package vook.server.api.outbound.search;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Setter
@Getter
@Component
@ConfigurationProperties(prefix = "service.meilisearch")
public class MeilisearchProperties {
private String host;
private String apiKey;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,15 @@
import com.meilisearch.sdk.Index;
import com.meilisearch.sdk.model.IndexesQuery;
import com.meilisearch.sdk.model.Results;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Value;

import java.util.Arrays;

public abstract class MeilisearchService {

@Value("${service.meilisearch.host:}")
protected String host;
protected final Client client;

@Value("${service.meilisearch.apiKey:}")
protected String apiKey;

protected Client client;

@PostConstruct
public void postConstruct() {
this.client = new Client(new Config(host, apiKey));
protected MeilisearchService(MeilisearchProperties properties) {
this.client = new Client(new Config(properties.getHost(), properties.getApiKey()));
}

protected void clearAll(String uidPrefix) {
Expand Down
20 changes: 19 additions & 1 deletion api/src/test/java/vook/server/api/testhelper/ApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.testcontainers.containers.MariaDBContainer;
import vook.server.api.outbound.search.MeilisearchProperties;

import java.util.Map;
import java.util.TimeZone;
Expand All @@ -19,19 +22,34 @@ public abstract class ApiTest {
protected TestRestTemplate rest;

@ServiceConnection
protected static final MariaDBContainer mariaDBContainer = new MariaDBContainer<>("mariadb:10.11")
protected static final MariaDBContainer<?> mariaDBContainer = new MariaDBContainer<>("mariadb:10.11")
.withDatabaseName("example")
.withUsername("user")
.withPassword("userPw")
.withConfigurationOverride("db/conf")
.withTmpFs(Map.of("/var/lib/mysql", "rw"));

protected static final MeilisearchContainer meilisearchContainer = new MeilisearchContainer("getmeili/meilisearch:v1.8.0");

static {
mariaDBContainer.start();
meilisearchContainer.start();
}

@BeforeEach
void init() {
TimeZone.setDefault(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
}

@Configuration
public static class TestConfig {

@Bean
public MeilisearchProperties meilisearchProperties() {
MeilisearchProperties meilisearchProperties = new MeilisearchProperties();
meilisearchProperties.setHost(meilisearchContainer.getHostUrl());
meilisearchProperties.setApiKey(meilisearchContainer.getMasterKey());
return meilisearchProperties;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package vook.server.api.testhelper;

import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;

public class MeilisearchContainer extends GenericContainer<MeilisearchContainer> {

private static final String DEFAULT_IMAGE_NAME = "getmeili/meilisearch:latest";

public MeilisearchContainer() {
this(DEFAULT_IMAGE_NAME);
}

public MeilisearchContainer(String dockerImageName) {
this(DockerImageName.parse(dockerImageName));
}

public MeilisearchContainer(DockerImageName dockerImageName) {
super(dockerImageName);
this.addExposedPort(7700);
this.addEnv("MEILI_MASTER_KEY", "aMasterKey");
}

public String getMasterKey() {
return this.getEnvMap().get("MEILI_MASTER_KEY");
}

/**
* Meilisearch에 접속하기 위한 URL을 반환한다.
*/
public String getHostUrl() {
return "http://" + getHost() + ":" + getMappedPort(7700);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package vook.server.api.web.routes.demo;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import vook.server.api.app.demo.repo.DemoTermRepository;
import vook.server.api.devhelper.TestTermsLoader;
import vook.server.api.model.demo.DemoTerm;
import vook.server.api.outbound.search.DemoTermSearchService;
import vook.server.api.testhelper.ApiTest;
import vook.server.api.web.routes.demo.reqres.SearchTermRequest;
import vook.server.api.web.routes.demo.reqres.SearchTermResponse;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@Transactional
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class DemoWebServiceTest extends ApiTest {

@Autowired
private DemoWebService demoWebService;

@Autowired
private TestTermsLoader testTermsLoader;
@Autowired
private DemoTermRepository demoTermRepository;
@Autowired
private DemoTermSearchService demoTermSearchService;

@BeforeAll
void beforeAll() {
List<DemoTerm> terms = testTermsLoader.getTerms("classpath:init/개발.tsv");
demoTermRepository.saveAll(terms);
demoTermSearchService.init();
demoTermSearchService.addTerms(terms);
}

@AfterAll
void afterAll() {
demoTermSearchService.clearAll();
}

@Test
void searchTerm() {
SearchTermRequest searchTermRequest = new SearchTermRequest();
searchTermRequest.setQuery("하이브리드앱");
searchTermRequest.setWithFormat(false);
searchTermRequest.setHighlightPreTag("<em>");
searchTermRequest.setHighlightPostTag("</em>");

SearchTermResponse searchTermResponse = demoWebService.searchTerm(searchTermRequest);

assertThat(searchTermResponse).isNotNull();
assertThat(searchTermResponse.getQuery()).isEqualTo("하이브리드앱");
assertThat(searchTermResponse.getHits()).isNotEmpty();
}
}
3 changes: 0 additions & 3 deletions api/src/test/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ logging:
orm:
jdbc: TRACE
service:
meilisearch:
host: http://localhost:7700
apiKey: aSampleMasterKey
jwt:
secret: vmfhaltmskdlstkfkdgodyroqkfwkdba
oauth2:
Expand Down

0 comments on commit 71dcb5a

Please sign in to comment.