Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
764e68a
Add reindex entity
SammiChong Jul 17, 2025
8eae7a8
Add unit tests and metadata exception
SammiChong Jul 31, 2025
6c0017e
Add GET
SammiChong Aug 8, 2025
db33162
Add case_type
SammiChong Aug 8, 2025
c186109
Cleanup
SammiChong Aug 8, 2025
9e4eaa1
Add IT and clean up
SammiChong Aug 11, 2025
434db9c
Format error message
SammiChong Aug 11, 2025
0cb50c5
Revert testing
SammiChong Aug 11, 2025
46b8b3f
Cleanup
SammiChong Aug 11, 2025
8cecdf1
Merge branch 'master' into CME-239
SammiChong Aug 11, 2025
6d27919
Cleanup
SammiChong Aug 11, 2025
1b1835e
Add ActiveProfile to IT
SammiChong Aug 11, 2025
41708b4
Update ElasticsearchBaseTest.java
SammiChong Aug 11, 2025
b14b75b
Update ElasticsearchBaseTest.java
SammiChong Aug 12, 2025
36c9bb7
testing
SammiChong Aug 20, 2025
c9e1768
Add findByIndexName
SammiChong Aug 20, 2025
e3be5a6
Add ReindexPersistService
SammiChong Aug 20, 2025
aa1716a
Fix async transaction issue
SammiChong Aug 20, 2025
29a26fa
Clean up
SammiChong Aug 20, 2025
64d0e22
Replace overwrite with insert to DB
SammiChong Aug 22, 2025
2e585ef
Cleanup - rename and add tests
SammiChong Aug 22, 2025
d4aa313
Add reindex_response
SammiChong Aug 22, 2025
60fbf84
More cleanup
SammiChong Aug 29, 2025
3297c20
Merge branch 'master' into CME-239
SammiChong Aug 29, 2025
6ece42a
Add h2database
SammiChong Sep 2, 2025
3e773cd
Use testcontainers
SammiChong Sep 2, 2025
0d84d90
Add back ElasticsearchContainerInitializer
SammiChong Sep 2, 2025
1061029
Merge branch 'master' into CME-239
SammiChong Sep 3, 2025
6d68668
Return ReindexDTO instead of ReindexEntity
SammiChong Sep 3, 2025
c8bf2a9
Merge branch 'CME-239' of https://github.com/hmcts/ccd-definition-sto…
SammiChong Sep 3, 2025
b57eecb
Fix code smells
SammiChong Sep 3, 2025
d15f5d9
Revert !reindex
SammiChong Sep 3, 2025
3044cf3
Merge branch 'master' into CME-239
SammiChong Sep 8, 2025
a4aafd0
Remove null check
SammiChong Sep 8, 2025
453c3af
Address review comments
SammiChong Sep 10, 2025
5246cf8
Rename ReindexDTO
SammiChong Sep 11, 2025
aa5a82f
Merge branch 'master' into CME-239
SammiChong Sep 11, 2025
f2358dd
Merge branch 'master' into CME-239
SammiChong Sep 16, 2025
54b7265
Merge branch 'CME-238-patch' into CME-239
SammiChong Sep 30, 2025
4046b65
Cleanup, add tests
SammiChong Oct 1, 2025
956fa6b
Merge ReindexTaskService with ReindexService
SammiChong Oct 3, 2025
4ccb25b
Checkstyle
SammiChong Oct 3, 2025
35dbf88
Remove transactional
SammiChong Oct 6, 2025
3deab9b
Update ReindexServiceImpl.java
SammiChong Oct 6, 2025
20c2ffc
Merge branch 'CME-238-patch' into CME-239
SammiChong Oct 8, 2025
f7c1d3d
Fix tests, add reindexResponse
SammiChong Oct 8, 2025
576425f
Merge branch 'master' into CME-239
SammiChong Oct 8, 2025
283f295
Merge branch 'master' into CME-239
SammiChong Oct 8, 2025
82d0749
Merge branch 'CME-238-patch' into CME-239
kiran-yenigala-hmcts Oct 8, 2025
1a7d8bb
Clean import
SammiChong Oct 8, 2025
00e5241
Remove buildResponse, add logging
SammiChong Oct 28, 2025
73b2e5c
Remove reindex column
SammiChong Oct 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Cleanup
  • Loading branch information
SammiChong committed Aug 11, 2025
commit 6d27919d12baa77e46bf4b9de33ee54d0297290e
2 changes: 0 additions & 2 deletions elastic-search-support/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@ dependencies {
testImplementation project(path: ':domain', configuration: 'testOutput')
testImplementation project(":domain").sourceSets.main.output
testImplementation project(":repository").sourceSets.test.output

testImplementation group: 'org.skyscreamer', name: 'jsonassert', version: '1.5.3'
testImplementation group: 'org.testcontainers', name: 'elasticsearch', version: testcontainersVersion
testImplementation group: 'org.testcontainers', name: 'junit-jupiter', version: testcontainersVersion
testImplementation 'net.ttddyy:datasource-proxy:1.8'
testImplementation(project(":application"))

}

pitest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,17 @@ public void initialiseElasticSearch(DefinitionImportedEvent event) {

//prepare for db
metadata = new ReindexEntity();
metadata.setIndexName(caseTypeName);
metadata.setReindex(reindex);
metadata.setDeleteOldIndex(deleteOldIndex);
metadata.setCaseType(currentCaseType.getReference());
metadata.setJurisdiction(caseType.getJurisdiction().getReference());
metadata.setIndexName(caseTypeName);
metadata.setStartTime(LocalDateTime.now());
metadata.setStatus("STARTED");
metadata = reindexRepository.save(metadata);
if (metadata == null) {
throw new ElasticSearchInitialisationException(new IllegalStateException("Failed to persist reindex metadata"));
throw new ElasticSearchInitialisationException(
new IllegalStateException("Failed to persist reindex metadata"));
}

if (reindex) {
Expand Down Expand Up @@ -150,7 +151,7 @@ public void onResponse(BulkByScrollResponse bulkByScrollResponse) {
asyncElasticClient.removeIndex(oldIndex);
}

//for db
//set success status and end time for db
metadata.setStatus("SUCCESS");
metadata.setEndTime(LocalDateTime.now());
reindexRepository.save(metadata);
Expand All @@ -165,7 +166,7 @@ public void onResponse(BulkByScrollResponse bulkByScrollResponse) {
@Override
public void onFailure(Exception ex) {
try (elasticClient; HighLevelCCDElasticClient asyncElasticClient = clientFactory.getObject()) {
//for db
//set failure status and end time for db
reindexFailedPersist(metadata, ex);

//if failed delete new index, set old index writable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetMappingsRequest;
import org.elasticsearch.client.indices.GetMappingsResponse;
import org.elasticsearch.client.indices.PutMappingRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
Expand Down Expand Up @@ -94,6 +96,11 @@ public GetAliasesResponse getAlias(String alias) throws IOException {
return elasticClient.indices().getAlias(request, RequestOptions.DEFAULT);
}

public GetMappingsResponse getMapping(String indexName) throws IOException {
GetMappingsRequest request = new GetMappingsRequest().indices(indexName);
return elasticClient.indices().getMapping(request, RequestOptions.DEFAULT);
}

private Settings.Builder casesIndexSettings(String file) throws IOException {
try (InputStream inputStream = getClass().getResourceAsStream(file)) {
Settings.Builder settings = Settings.builder().loadFromStream(file,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
package uk.gov.hmcts.ccd.definition.store.elastic;

import org.elasticsearch.client.GetAliasesResponse;
import org.elasticsearch.cluster.metadata.AliasMetadata;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.ObjectFactory;
import uk.gov.hmcts.ccd.definition.store.elastic.client.HighLevelCCDElasticClient;
import uk.gov.hmcts.ccd.definition.store.elastic.config.CcdElasticSearchProperties;
import uk.gov.hmcts.ccd.definition.store.elastic.mapping.CaseMappingGenerator;
import uk.gov.hmcts.ccd.definition.store.event.DefinitionImportedEvent;
import uk.gov.hmcts.ccd.definition.store.repository.ReindexRepository;
import uk.gov.hmcts.ccd.definition.store.repository.entity.CaseTypeEntity;
import uk.gov.hmcts.ccd.definition.store.utils.CaseTypeBuilder;

import java.io.IOException;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.ObjectFactory;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

import static com.google.common.collect.Lists.newArrayList;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

Expand All @@ -40,6 +47,9 @@ class AsynchronousElasticDefinitionImportListenerTest {
@Mock
private CaseMappingGenerator caseMappingGenerator;

@Mock
private ReindexRepository reindexRepository;

private CaseTypeEntity caseA = new CaseTypeBuilder().withJurisdiction("jurA").withReference("caseTypeA").build();
private CaseTypeEntity caseB = new CaseTypeBuilder().withJurisdiction("jurB").withReference("caseTypeB").build();

Expand All @@ -54,6 +64,13 @@ void createsIndexIfNotExists() throws IOException {
when(config.getCasesIndexNameFormat()).thenReturn("%s");
when(ccdElasticClient.aliasExists(anyString())).thenReturn(false);

GetAliasesResponse aliasResponse = mock(GetAliasesResponse.class);
Map<String, Set<AliasMetadata>> aliasMap = Map.of("casetypea-000001",
Collections.singleton(AliasMetadata.builder("casetypea").build()));
when(aliasResponse.getAliases()).thenReturn(aliasMap);
when(ccdElasticClient.getAlias(anyString())).thenReturn(aliasResponse);
when(reindexRepository.save(any())).thenAnswer(invocation -> invocation.getArgument(0));

listener.onDefinitionImported(newEvent(caseA, caseB));

verify(ccdElasticClient).createIndex("casetypea-000001", "casetypea");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
package uk.gov.hmcts.ccd.definition.store.elastic;

import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.client.GetAliasesResponse;
import org.elasticsearch.cluster.metadata.AliasMetadata;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.rest.RestStatus;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.ObjectFactory;
import uk.gov.hmcts.ccd.definition.store.elastic.client.HighLevelCCDElasticClient;
import uk.gov.hmcts.ccd.definition.store.elastic.config.CcdElasticSearchProperties;
import uk.gov.hmcts.ccd.definition.store.elastic.exception.ElasticSearchInitialisationException;
Expand All @@ -18,21 +32,6 @@
import java.util.Map;
import java.util.Set;

import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.client.GetAliasesResponse;
import org.elasticsearch.cluster.metadata.AliasMetadata;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.rest.RestStatus;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.ObjectFactory;

import static com.google.common.collect.Lists.newArrayList;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
Expand Down Expand Up @@ -260,12 +259,13 @@ void deletesNewIndexWhenReindexingFails() throws IOException {
void savesMetadataOnSuccessfulReindex() throws IOException {
mockAliasResponse();

ArgumentCaptor<ReindexEntity> captor = ArgumentCaptor.forClass(ReindexEntity.class);
when(reindexRepository.save(any(ReindexEntity.class))).thenAnswer(invocation -> invocation.getArgument(0));
mockSuccessfulReindex();

listener.onDefinitionImported(newEvent(true, true, caseA));

ArgumentCaptor<ReindexEntity> captor = ArgumentCaptor.forClass(ReindexEntity.class);

//verify that the reindex metadata was saved twice, once before reindexing and once after
verify(reindexRepository, atLeast(2)).save(captor.capture());
List<ReindexEntity> metadata = captor.getAllValues();
Expand All @@ -284,7 +284,6 @@ void savesMetadataOnSuccessfulReindex() throws IOException {
void savesMetadataOnFailedReindex() throws IOException {
mockAliasResponse();

ArgumentCaptor<ReindexEntity> captor = ArgumentCaptor.forClass(ReindexEntity.class);
when(reindexRepository.save(any(ReindexEntity.class))).thenAnswer(invocation -> invocation.getArgument(0));
mockFailedReindex();

Expand All @@ -294,6 +293,8 @@ void savesMetadataOnFailedReindex() throws IOException {
listener.onDefinitionImported(event)
);

ArgumentCaptor<ReindexEntity> captor = ArgumentCaptor.forClass(ReindexEntity.class);

//verify that the reindex metadata was saved twice, once before reindexing and once after
verify(reindexRepository, atLeast(2)).save(captor.capture());
List<ReindexEntity> metadata = captor.getAllValues();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
import java.util.stream.Collectors;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = { ServletWebServerFactoryAutoConfiguration.class, ElasticsearchConfigurationIT.class, CaseDataAPIApplication.class })
classes = {ServletWebServerFactoryAutoConfiguration.class, ElasticsearchConfigurationIT.class,
CaseDataAPIApplication.class})
@ContextConfiguration(initializers = ElasticsearchContainerInitializer.class)
public abstract class ElasticsearchBaseTest implements TestUtils {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import uk.gov.hmcts.ccd.definition.store.elastic.exception.ElasticSearchInitialisationException;
import uk.gov.hmcts.ccd.definition.store.event.DefinitionImportedEvent;
import uk.gov.hmcts.ccd.definition.store.repository.ReindexRepository;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package uk.gov.hmcts.ccd.definition.store.elastic.integration;

import org.elasticsearch.client.indices.GetMappingsResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import uk.gov.hmcts.ccd.definition.store.elastic.ElasticDefinitionImportListener;
import uk.gov.hmcts.ccd.definition.store.elastic.ElasticsearchBaseTest;
import uk.gov.hmcts.ccd.definition.store.elastic.client.HighLevelCCDElasticClient;
Expand All @@ -16,18 +21,8 @@

import java.io.IOException;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.ApplicationEventPublisher;

import static com.google.common.collect.Lists.newArrayList;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.assertj.core.api.Assertions.assertThat;
import static uk.gov.hmcts.ccd.definition.store.utils.CaseFieldBuilder.newField;
import static uk.gov.hmcts.ccd.definition.store.utils.CaseFieldBuilder.newTextField;
import static uk.gov.hmcts.ccd.definition.store.utils.FieldTypeBuilder.newType;
Expand All @@ -47,15 +42,16 @@ class CaseMappingGenerationIT extends ElasticsearchBaseTest {
@Autowired
private CaseMappingGenerator mappingGenerator;

@MockBean
@Autowired
private HighLevelCCDElasticClient client;

@Mock
private ObjectFactory<HighLevelCCDElasticClient> clientObjectFactory;

@BeforeEach
void setUp() {
when(clientObjectFactory.getObject()).thenReturn(client);
try {
deleteElasticsearchIndices(WILDCARD);
} catch (Exception e) {
// Ignore any exceptions during index deletion, as it may not exist
}
}

@Test
Expand All @@ -64,8 +60,11 @@ void testListeningToDefinitionImportedEvent() throws IOException {

publisher.publishEvent(new DefinitionImportedEvent(newArrayList(caseType)));

verify(client).createIndex(anyString(), anyString());
verify(client).upsertMapping(anyString(), anyString());
String indexName = String.format(config.getCasesIndexNameFormat(), caseType.getReference().toLowerCase());
assertThat(client.aliasExists(indexName)).isTrue();

GetMappingsResponse mapping = client.getMapping(indexName);
assertThat(mapping).isNotNull();
}

@Test
Expand All @@ -74,8 +73,11 @@ void testListeningToDefinitionImportedEventWithDynamicLists() throws IOException

publisher.publishEvent(new DefinitionImportedEvent(newArrayList(caseType)));

verify(client).createIndex(anyString(), anyString());
verify(client).upsertMapping(anyString(), anyString());
String indexName = String.format(config.getCasesIndexNameFormat(), caseType.getReference().toLowerCase());
assertThat(client.aliasExists(indexName)).isTrue();

GetMappingsResponse mapping = client.getMapping(indexName);
assertThat(mapping).isNotNull();
}

private CaseTypeEntity createCaseType() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package uk.gov.hmcts.ccd.definition.store.repository.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import static javax.persistence.GenerationType.IDENTITY;
import static jakarta.persistence.GenerationType.IDENTITY;

@Table(name = "reindex")
@Entity
Expand Down