Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.springframework.security.web.SecurityFilterChain;

import uk.gov.hmcts.ccd.definition.store.elastic.endpoint.ElasticsearchIndexController;
import uk.gov.hmcts.ccd.definition.store.elastic.endpoint.ReindexTaskController;
import uk.gov.hmcts.ccd.definition.store.excel.endpoint.ImportController;
import uk.gov.hmcts.ccd.definition.store.security.JwtGrantedAuthoritiesConverter;
import uk.gov.hmcts.ccd.definition.store.security.filters.ExceptionHandlingFilter;
Expand Down Expand Up @@ -76,8 +77,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.csrf(csrf -> csrf.disable()) // NOSONAR - CSRF is disabled as per security requirements
.formLogin(fl -> fl.disable())
.logout(lg -> lg.disable())
.authorizeHttpRequests(ar ->
ar.requestMatchers(ImportController.URI_IMPORT, ElasticsearchIndexController.ELASTIC_INDEX_URI)
.authorizeHttpRequests(ar ->
ar.requestMatchers(ImportController.URI_IMPORT, ElasticsearchIndexController.ELASTIC_INDEX_URI,
ReindexTaskController.REINDEX_TASKS_URI)
.hasAuthority("ccd-import")
.anyRequest()
.authenticated()
Expand Down
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ allprojects {
testImplementation group: 'org.apache.groovy', name: 'groovy-xml', version: groovyVersion
testImplementation group: 'org.apache.groovy', name: 'groovy-json', version: groovyVersion
testImplementation group: 'com.github.hmcts', name: 'fortify-client', version: '1.4.10', classifier: 'all'

}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import uk.gov.hmcts.ccd.definition.store.repository.entity.FieldTypeListItemEntity;
import uk.gov.hmcts.ccd.definition.store.repository.entity.JurisdictionEntity;
import uk.gov.hmcts.ccd.definition.store.repository.entity.JurisdictionUiConfigEntity;
import uk.gov.hmcts.ccd.definition.store.repository.entity.ReindexEntity;
import uk.gov.hmcts.ccd.definition.store.repository.entity.RoleToAccessProfilesEntity;
import uk.gov.hmcts.ccd.definition.store.repository.entity.SearchAliasFieldEntity;
import uk.gov.hmcts.ccd.definition.store.repository.entity.SearchCasesResultFieldEntity;
Expand Down Expand Up @@ -65,6 +66,7 @@
import uk.gov.hmcts.ccd.definition.store.repository.model.FixedListItem;
import uk.gov.hmcts.ccd.definition.store.repository.model.Jurisdiction;
import uk.gov.hmcts.ccd.definition.store.repository.model.JurisdictionUiConfig;
import uk.gov.hmcts.ccd.definition.store.repository.model.ReindexTask;
import uk.gov.hmcts.ccd.definition.store.repository.model.RoleAssignment;
import uk.gov.hmcts.ccd.definition.store.repository.model.RoleToAccessProfiles;
import uk.gov.hmcts.ccd.definition.store.repository.model.SearchAliasField;
Expand Down Expand Up @@ -334,6 +336,8 @@ static List<CaseEventFieldComplex> map(List<? extends EventComplexTypeEntity> ev
@Mapping(source = "caseType.jurisdiction.name", target = "jurisdictionName")
AccessTypeField map(AccessTypeEntity accessTypeEntity);

ReindexTask map(ReindexEntity reindexEntity);

@Mapping(source = "caseType.reference", target = "id")
@Mapping(source = "roleToAccessProfilesEntity.roleName", target = "name")
RoleAssignment roleToAccessProfilesEntityToRoleAssignment(RoleToAccessProfilesEntity roleToAccessProfilesEntity);
Expand Down
3 changes: 3 additions & 0 deletions elastic-search-support/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ bootJar {

dependencies {

implementation group: 'org.mapstruct', name: 'mapstruct', version: '1.5.5.Final'
implementation project(':domain')
implementation project(':repository')
// need these for command line to pass in the gradle version,
Expand All @@ -25,6 +26,8 @@ dependencies {
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 @@ -10,6 +10,7 @@
import uk.gov.hmcts.ccd.definition.store.elastic.config.CcdElasticSearchProperties;
import uk.gov.hmcts.ccd.definition.store.elastic.exception.handler.ElasticsearchErrorHandler;
import uk.gov.hmcts.ccd.definition.store.elastic.mapping.CaseMappingGenerator;
import uk.gov.hmcts.ccd.definition.store.elastic.service.ReindexService;
import uk.gov.hmcts.ccd.definition.store.event.DefinitionImportedEvent;

@Service
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import uk.gov.hmcts.ccd.definition.store.elastic.exception.ElasticSearchInitialisationException;
import uk.gov.hmcts.ccd.definition.store.elastic.exception.handler.ElasticsearchErrorHandler;
import uk.gov.hmcts.ccd.definition.store.elastic.mapping.CaseMappingGenerator;
import uk.gov.hmcts.ccd.definition.store.elastic.service.ReindexService;
import uk.gov.hmcts.ccd.definition.store.event.DefinitionImportedEvent;
import uk.gov.hmcts.ccd.definition.store.repository.entity.CaseTypeEntity;

Expand All @@ -30,6 +31,7 @@ public abstract class ElasticDefinitionImportListener {

private final ReindexService reindexService;


public ElasticDefinitionImportListener(CcdElasticSearchProperties config, CaseMappingGenerator mappingGenerator,
ObjectFactory<HighLevelCCDElasticClient> clientFactory,
ElasticsearchErrorHandler elasticsearchErrorHandler,
Expand All @@ -51,8 +53,6 @@ public ElasticDefinitionImportListener(CcdElasticSearchProperties config, CaseMa
@Transactional
public void initialiseElasticSearch(DefinitionImportedEvent event) {
List<CaseTypeEntity> caseTypes = event.getContent();
boolean reindex = event.isReindex();

String caseMapping = null;
CaseTypeEntity currentCaseType = null;

Expand All @@ -65,7 +65,7 @@ public void initialiseElasticSearch(DefinitionImportedEvent event) {
String actualIndexName = baseIndexName + FIRST_INDEX_SUFFIX;
elasticClient.createIndex(actualIndexName, baseIndexName);
}
if (reindex) {
if (event.isReindex()) {
reindexService.asyncReindex(event, baseIndexName, caseType);
} else {
caseMapping = mappingGenerator.generateMapping(caseType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public String reindexIndex(String sourceIndex,
TaskInfo taskInfo = taskResponse.get().getTaskInfo();
if (!shouldWaitForMissingInfo(taskInfo, taskId, pollIntervalMs)) {
if (taskResponse.get().isCompleted()) {
if (handleCompletion(taskInfo, listener, destIndex)) {
if (handleCompletion(taskInfo, listener)) {
break;
}
} else {
Expand Down Expand Up @@ -111,22 +111,27 @@ private boolean shouldWaitForMissingInfo(TaskInfo taskInfo,
}

private boolean handleCompletion(TaskInfo taskInfo,
ReindexListener listener,
String destIndex) throws IOException {
ReindexListener listener) throws IOException {
Object statusObj = taskInfo.getStatus();
if (statusObj == null) {
listener.onFailure(new RuntimeException("Reindex process completed with unknown status"));
listener.onFailure(new RuntimeException(
String.format("Reindex process completed with unknown status (taskId=%s)", taskInfo.getTaskId())
));
return true;
}

JsonNode statusJson = toStatusJson(statusObj);
if (hasFailures(statusJson)) {
listener.onFailure(new RuntimeException("Reindex process failed: " + statusJson.path("failures")));
String failures = statusJson.path("failures").toString();
listener.onFailure(new RuntimeException(
String.format("Reindex process failed (taskId=%s): %s", taskInfo.getTaskId(), failures)
));
return true;
}

logProgress(destIndex, statusJson);
listener.onSuccess();
String response = mapper.writeValueAsString(taskInfo);
listener.onSuccess(response);
log.info("Reindex task completed successfully (taskId={}): {}", taskInfo.getTaskId(), response);
return true;
}

Expand All @@ -139,15 +144,6 @@ private boolean hasFailures(JsonNode statusJson) {
return statusJson.has("failures") && !statusJson.path("failures").isEmpty();
}

private void logProgress(String destIndex, JsonNode statusJson) {
int total = statusJson.path("total").asInt(0);
int created = statusJson.path("created").asInt(0);
int updated = statusJson.path("updated").asInt(0);
int batches = statusJson.path("batches").asInt(0);
log.info("Progress for index {}: total={}, created={}, updated={}, batches={}",
destIndex, total, created, updated, batches);
}

public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import uk.gov.hmcts.ccd.definition.store.elastic.config.CcdElasticSearchProperties;
import uk.gov.hmcts.ccd.definition.store.elastic.exception.handler.ElasticsearchErrorHandler;
import uk.gov.hmcts.ccd.definition.store.elastic.mapping.CaseMappingGenerator;
import uk.gov.hmcts.ccd.definition.store.elastic.service.ReindexService;
import uk.gov.hmcts.ccd.definition.store.event.DefinitionImportedEvent;

@Service
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package uk.gov.hmcts.ccd.definition.store.elastic.endpoint;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import uk.gov.hmcts.ccd.definition.store.elastic.service.ReindexService;
import uk.gov.hmcts.ccd.definition.store.repository.model.ReindexTask;

import java.util.List;

@RestController
@RequestMapping(ReindexTaskController.REINDEX_TASKS_URI)
@Api(value = ReindexTaskController.REINDEX_TASKS_URI)
public class ReindexTaskController {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add test cases to cover the end point responses using MockMvc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


public static final String REINDEX_TASKS_URI = "/elastic-support/reindex/tasks";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

        .authorizeHttpRequests(ar -> 
            ar.requestMatchers(ImportController.URI_IMPORT, ElasticsearchIndexController.ELASTIC_INDEX_URI)
            .hasAuthority("ccd-import")
            .anyRequest()
            .authenticated()
        )
        
        Add this end point in the SecurityConfiguration in above code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


private final ReindexService reindexService;

@Autowired
public ReindexTaskController(ReindexService reindexService) {
this.reindexService = reindexService;
}

@GetMapping
@ApiOperation(value = "Get all reindex tasks, optionally by case type",
response = ReindexTask.class,
responseContainer = "List")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successfully retrieved reindex tasks"),
@ApiResponse(code = 500, message = "Internal Server Error")
})
public ResponseEntity<List<ReindexTask>> getReindexTasksByCaseType(
@RequestParam(value = "caseType", required = false) String caseType
) {
List<ReindexTask> response = reindexService.getTasksByCaseType(caseType);
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public interface ReindexListener {

void onSuccess();
void onSuccess(String reindexResponse);

void onFailure(Exception ex);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package uk.gov.hmcts.ccd.definition.store.elastic.service;

import uk.gov.hmcts.ccd.definition.store.event.DefinitionImportedEvent;
import uk.gov.hmcts.ccd.definition.store.repository.entity.CaseTypeEntity;
import uk.gov.hmcts.ccd.definition.store.repository.entity.ReindexEntity;
import uk.gov.hmcts.ccd.definition.store.repository.model.ReindexTask;

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

public interface ReindexService {
void asyncReindex(DefinitionImportedEvent event, String baseIndexName, CaseTypeEntity caseType) throws IOException;

String incrementIndexNumber(String indexName);

List<ReindexTask> getAll();

List<ReindexTask> getTasksByCaseType(String caseType);

ReindexEntity saveEntity(Boolean deleteOldIndex, CaseTypeEntity caseType,
String newIndexName);

void updateEntity(String newIndexName, String response);

void updateEntity(String newIndexName, Exception exception);
}
Loading