Skip to content

Commit 3c8eaf5

Browse files
Add endpoint to recreate the index
Now free from manual `curl` commands!
1 parent 7b19a1a commit 3c8eaf5

File tree

3 files changed

+103
-3
lines changed

3 files changed

+103
-3
lines changed

src/main/java/org/gridsuite/directory/server/SupervisionController.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,19 @@
1212
import io.swagger.v3.oas.annotations.tags.Tag;
1313
import org.gridsuite.directory.server.dto.ElementAttributes;
1414
import org.gridsuite.directory.server.services.SupervisionService;
15+
import org.springframework.http.MediaType;
1516
import org.springframework.http.ResponseEntity;
1617
import org.springframework.web.bind.annotation.*;
1718

1819
import java.util.List;
20+
import java.util.Optional;
1921
import java.util.UUID;
2022

2123
/**
2224
* @author Kevin Le Saulnier <kevin.lesaulnier at rte-france.com>
2325
*/
2426
@RestController
25-
@RequestMapping(value = "/" + DirectoryApi.API_VERSION + "/supervision")
27+
@RequestMapping(value = "/" + DirectoryApi.API_VERSION + "/supervision", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
2628
@Tag(name = "directory-server - Supervision")
2729
public class SupervisionController {
2830
private final SupervisionService service;
@@ -47,4 +49,17 @@ public ResponseEntity<Void> deleteElements(@RequestParam("ids") List<UUID> eleme
4749
service.deleteElementsByIds(elementsUuid);
4850
return ResponseEntity.ok().build();
4951
}
52+
53+
@PostMapping(value = "/elements/recreate-index", produces = MediaType.TEXT_PLAIN_VALUE)
54+
@Operation(summary = "Recreate the index then reindex data")
55+
@ApiResponse(responseCode = "200", description = "Success of the index recreation & reindexing of elements")
56+
@ApiResponse(responseCode = "500", description = "An error happen while recreating the index.\nAn manual intervention is needing as no details of the error is available.")
57+
public ResponseEntity<Optional<String>> deleteElements() {
58+
if (service.recreateIndexDirectoryElementInfos()) {
59+
return ResponseEntity.ok().build();
60+
} else {
61+
return ResponseEntity.internalServerError().contentType(MediaType.TEXT_PLAIN)
62+
.body(Optional.of("An error happen while re-creating the index. As no details is available an manual intervention is required."));
63+
}
64+
}
5065
}

src/main/java/org/gridsuite/directory/server/services/SupervisionService.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package org.gridsuite.directory.server.services;
22

3+
import lombok.extern.slf4j.Slf4j;
34
import org.gridsuite.directory.server.dto.ElementAttributes;
5+
import org.gridsuite.directory.server.dto.elasticsearch.DirectoryElementInfos;
46
import org.gridsuite.directory.server.repository.DirectoryElementEntity;
57
import org.gridsuite.directory.server.repository.DirectoryElementRepository;
8+
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
9+
import org.springframework.data.elasticsearch.core.IndexOperations;
610
import org.springframework.stereotype.Service;
711

812
import java.util.List;
@@ -11,13 +15,17 @@
1115
import static org.gridsuite.directory.server.dto.ElementAttributes.toElementAttributes;
1216

1317
@Service
18+
@Slf4j
1419
public class SupervisionService {
1520
private final DirectoryElementRepository directoryElementRepository;
1621
private final DirectoryRepositoryService repositoryService;
22+
private final ElasticsearchTemplate esTemplate;
1723

18-
public SupervisionService(DirectoryRepositoryService repositoryService, DirectoryElementRepository directoryElementRepository) {
24+
public SupervisionService(DirectoryRepositoryService repositoryService, DirectoryElementRepository directoryElementRepository,
25+
ElasticsearchTemplate elasticsearchTemplate) {
1926
this.repositoryService = repositoryService;
2027
this.directoryElementRepository = directoryElementRepository;
28+
this.esTemplate = elasticsearchTemplate;
2129
}
2230

2331
public List<ElementAttributes> getStashedElementsAttributes() {
@@ -35,4 +43,28 @@ public void deleteElementsByIds(List<UUID> uuids) {
3543
public List<DirectoryElementEntity> getStashedElements() {
3644
return directoryElementRepository.findAllByStashed(true);
3745
}
46+
47+
public boolean recreateIndexDirectoryElementInfos() {
48+
final IndexOperations idxDirectoryElementInfos = esTemplate.indexOps(DirectoryElementInfos.class);
49+
final String idxDirectoryElementInfosName = idxDirectoryElementInfos.getIndexCoordinates().getIndexName();
50+
log.warn("Recreating ElasticSearch index {}", idxDirectoryElementInfosName);
51+
if (idxDirectoryElementInfos.exists()) {
52+
log.info("Index {} found, delete it.", idxDirectoryElementInfosName);
53+
if (idxDirectoryElementInfos.delete()) {
54+
log.info("Successfully delete index {}", idxDirectoryElementInfosName);
55+
} else {
56+
log.error("A problem seems to happen when deleting index {}...", idxDirectoryElementInfosName);
57+
return false;
58+
}
59+
}
60+
if (idxDirectoryElementInfos.createWithMapping()) {
61+
log.info("Index {} successfully recreated!", idxDirectoryElementInfosName);
62+
} else {
63+
log.info("An error happen while re-creating index {}...", idxDirectoryElementInfosName);
64+
return false;
65+
}
66+
log.info("Re-indexing all elements of {}", idxDirectoryElementInfosName);
67+
repositoryService.reindexAllElements();
68+
return true;
69+
}
3870
}

src/test/java/org/gridsuite/directory/server/SupervisionTest.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,30 @@
66
*/
77
package org.gridsuite.directory.server;
88

9+
import org.gridsuite.directory.server.dto.elasticsearch.DirectoryElementInfos;
910
import org.gridsuite.directory.server.elasticsearch.DirectoryElementInfosRepository;
1011
import org.gridsuite.directory.server.repository.DirectoryElementEntity;
1112
import org.gridsuite.directory.server.repository.DirectoryElementRepository;
13+
import org.gridsuite.directory.server.services.DirectoryRepositoryService;
1214
import org.gridsuite.directory.server.services.SupervisionService;
1315
import org.gridsuite.directory.server.utils.elasticsearch.DisableElasticsearch;
1416
import org.junit.jupiter.api.AfterEach;
1517
import org.junit.jupiter.api.Test;
18+
import org.junit.jupiter.params.ParameterizedTest;
19+
import org.junit.jupiter.params.provider.CsvSource;
1620
import org.springframework.beans.factory.annotation.Autowired;
1721
import org.springframework.boot.test.context.SpringBootTest;
1822
import org.springframework.boot.test.mock.mockito.MockBean;
23+
import org.springframework.boot.test.mock.mockito.SpyBean;
24+
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
25+
import org.springframework.data.elasticsearch.core.IndexOperations;
26+
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
1927

2028
import java.time.Instant;
2129
import java.util.List;
2230
import java.util.UUID;
2331

32+
import static org.assertj.core.api.Assertions.*;
2433
import static org.junit.jupiter.api.Assertions.assertEquals;
2534
import static org.mockito.Mockito.*;
2635

@@ -39,6 +48,12 @@ class SupervisionTest {
3948
@MockBean
4049
DirectoryElementInfosRepository directoryElementInfosRepository;
4150

51+
@SpyBean
52+
DirectoryRepositoryService repositoryService;
53+
54+
@MockBean(name = "elasticsearchOperations")
55+
ElasticsearchTemplate elasticsearchTemplate;
56+
4257
List<DirectoryElementEntity> expectedElements = List.of(
4358
new DirectoryElementEntity(UUID.randomUUID(), UUID.randomUUID(), "dir1", "DIRECTORY", "user1", null, Instant.now(), Instant.now(), "user1", true, Instant.now()),
4459
new DirectoryElementEntity(UUID.randomUUID(), UUID.randomUUID(), "filter1", "FILTER", "user1", null, Instant.now(), Instant.now(), "user1", true, Instant.now()),
@@ -57,14 +72,52 @@ void testGetStashedElements() {
5772
void testDeleteElements() {
5873
List<UUID> uuidsToDelete = List.of(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID());
5974
supervisionService.deleteElementsByIds(uuidsToDelete);
60-
75+
verify(repositoryService).deleteElements(uuidsToDelete);
6176
verify(directoryElementRepository, times(1)).deleteAllById(uuidsToDelete);
6277
verify(directoryElementInfosRepository, times(1)).deleteAllById(uuidsToDelete);
6378
}
6479

80+
@ParameterizedTest
81+
@CsvSource(nullValues = { "null" }, value = {
82+
"false, null, true, true", //not existant, juste recreate
83+
"false, null, false, false", //not existant, error while creating
84+
"true, true, true, true", //delete + create + reindex OK
85+
"true, true, false, false", //delete, but error while creating
86+
"true, false, null, false" //exist, but error while deleting
87+
})
88+
void testReindexElements(final boolean exists, final Boolean delete, final Boolean create, final boolean result) {
89+
final IndexOperations idxOps = mock(IndexOperations.class);
90+
when(elasticsearchTemplate.indexOps(any(Class.class))).thenReturn(idxOps);
91+
when(idxOps.getIndexCoordinates()).thenReturn(IndexCoordinates.of("test-mock-index")); //for logs
92+
when(idxOps.exists()).thenReturn(exists);
93+
if (delete != null) {
94+
when(idxOps.delete()).thenReturn(delete);
95+
}
96+
if (create != null) {
97+
when(idxOps.createWithMapping()).thenReturn(create);
98+
}
99+
doNothing().when(repositoryService).reindexAllElements(); //intercept call
100+
assertThat(supervisionService.recreateIndexDirectoryElementInfos()).as("service call result").isEqualTo(result);
101+
verify(elasticsearchTemplate).indexOps(DirectoryElementInfos.class);
102+
verify(idxOps, atLeastOnce()).getIndexCoordinates();
103+
verify(idxOps).exists();
104+
if (delete != null) {
105+
verify(idxOps).delete();
106+
}
107+
if (create != null) {
108+
verify(idxOps).createWithMapping();
109+
}
110+
if (create == Boolean.TRUE) {
111+
verify(repositoryService).reindexAllElements();
112+
}
113+
verifyNoMoreInteractions(idxOps);
114+
}
115+
65116
@AfterEach
66117
public void verifyNoMoreInteractionsMocks() {
67118
verifyNoMoreInteractions(directoryElementRepository);
68119
verifyNoMoreInteractions(directoryElementInfosRepository);
120+
verifyNoMoreInteractions(repositoryService);
121+
verifyNoMoreInteractions(elasticsearchTemplate);
69122
}
70123
}

0 commit comments

Comments
 (0)