-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
disable auto case indexation #39
Changes from 17 commits
49f5a76
eb50035
3faccb1
397d9c4
4fb0ead
dff6051
f8761fa
82643ee
eab35af
66fafa8
571a851
4abc90c
d787751
51bbe76
11f42d1
809b620
cb26803
5524154
9f80c67
d4f5b02
08a7a2d
e821fe6
0f911ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -152,9 +152,10 @@ public ResponseEntity<Boolean> exists(@PathVariable("caseUuid") UUID caseUuid) { | |
@Operation(summary = "import a case") | ||
@SuppressWarnings("javasecurity:S5145") | ||
public ResponseEntity<UUID> importCase(@RequestParam("file") MultipartFile file, | ||
@RequestParam(value = "withExpiration", required = false, defaultValue = "false") boolean withExpiration) { | ||
@RequestParam(value = "withExpiration", required = false, defaultValue = "false") boolean withExpiration, | ||
@RequestParam(value = "indexed", required = false, defaultValue = "false") boolean indexed) { | ||
LOGGER.debug("importCase request received with file = {}", file.getName()); | ||
UUID caseUuid = caseService.importCase(file, withExpiration); | ||
UUID caseUuid = caseService.importCase(file, withExpiration, indexed); | ||
return ResponseEntity.ok().body(caseUuid); | ||
} | ||
|
||
|
@@ -165,9 +166,10 @@ public ResponseEntity<UUID> importCase(@RequestParam("file") MultipartFile file, | |
@ApiResponse(responseCode = "500", description = "An error occurred during the case file duplication")}) | ||
public ResponseEntity<UUID> duplicateCase( | ||
@RequestParam("duplicateFrom") UUID caseId, | ||
@RequestParam(value = "withExpiration", required = false, defaultValue = "false") boolean withExpiration) { | ||
@RequestParam(value = "withExpiration", required = false, defaultValue = "false") boolean withExpiration, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove paramter There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
@RequestParam(value = "indexed", required = false, defaultValue = "false") boolean indexed) { | ||
LOGGER.debug("duplicateCase request received with parameter sourceCaseUuid = {}", caseId); | ||
UUID newCaseUuid = caseService.duplicateCase(caseId, withExpiration); | ||
UUID newCaseUuid = caseService.duplicateCase(caseId, withExpiration, indexed); | ||
return ResponseEntity.ok().body(newCaseUuid); | ||
} | ||
|
||
|
@@ -182,6 +184,17 @@ public ResponseEntity<Void> disableCaseExpiration(@PathVariable("caseUuid") UUID | |
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@PutMapping(value = "/cases/{caseUuid}/indexation") | ||
jamal-khey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
@Operation(summary = "enable automatic indexation of the case") | ||
@ApiResponses(value = { | ||
@ApiResponse(responseCode = "200", description = "The case index has been changed"), | ||
@ApiResponse(responseCode = "404", description = "Source case not found")}) | ||
public ResponseEntity<Void> enableCaseIndexation(@PathVariable("caseUuid") UUID caseUuid, @RequestParam("indexed") boolean indexed) { | ||
LOGGER.debug("enableIndexation request received for caseUuid = {}", caseUuid); | ||
caseService.enableCaseIndexation(caseUuid, indexed); | ||
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@DeleteMapping(value = "/cases/{caseUuid}") | ||
@Operation(summary = "delete a case") | ||
public ResponseEntity<Void> deleteCase(@PathVariable("caseUuid") UUID caseUuid) { | ||
|
@@ -206,14 +219,6 @@ public ResponseEntity<List<CaseInfos>> searchCases(@RequestParam(value = "q") St | |
return ResponseEntity.ok().body(cases); | ||
} | ||
|
||
@PostMapping(value = "/cases/reindex-all") | ||
@Operation(summary = "reindex all cases") | ||
public ResponseEntity<Void> reindexAllCases() { | ||
LOGGER.debug("reindex all cases request received"); | ||
caseService.reindexAllCases(); | ||
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@GetMapping(value = "/cases/metadata") | ||
@Operation(summary = "Get cases Metadata") | ||
public ResponseEntity<List<CaseInfos>> getMetadata(@RequestParam("ids") List<UUID> ids) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
|
||
import com.powsybl.caseserver.dto.CaseInfos; | ||
import com.powsybl.caseserver.dto.ExportCaseInfos; | ||
import com.powsybl.caseserver.elasticsearch.CaseInfosRepository; | ||
import com.powsybl.caseserver.elasticsearch.CaseInfosService; | ||
import com.powsybl.caseserver.parsers.FileNameInfos; | ||
import com.powsybl.caseserver.parsers.FileNameParser; | ||
|
@@ -46,14 +47,7 @@ | |
import java.nio.file.StandardCopyOption; | ||
import java.time.Instant; | ||
import java.time.temporal.ChronoUnit; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.Optional; | ||
import java.util.Properties; | ||
import java.util.UUID; | ||
import java.util.*; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
import java.util.zip.ZipEntry; | ||
|
@@ -89,6 +83,8 @@ public class CaseService { | |
|
||
@Value("${case-store-directory:#{systemProperties['user.home'].concat(\"/cases\")}}") | ||
private String rootDirectory; | ||
@Autowired | ||
private CaseInfosRepository caseInfosRepository; | ||
|
||
public CaseService(CaseMetadataRepository caseMetadataRepository) { | ||
this.caseMetadataRepository = caseMetadataRepository; | ||
|
@@ -179,7 +175,7 @@ boolean caseExists(UUID caseName) { | |
return Files.exists(caseFile) && Files.isRegularFile(caseFile); | ||
} | ||
|
||
UUID importCase(MultipartFile mpf, boolean withExpiration) { | ||
UUID importCase(MultipartFile mpf, boolean withExpiration, boolean indexed) { | ||
checkStorageInitialization(); | ||
|
||
UUID caseUuid = UUID.randomUUID(); | ||
|
@@ -214,14 +210,16 @@ UUID importCase(MultipartFile mpf, boolean withExpiration) { | |
throw e; | ||
} | ||
|
||
createCaseMetadataEntity(caseUuid, withExpiration); | ||
createCaseMetadataEntity(caseUuid, withExpiration, indexed); | ||
CaseInfos caseInfos = createInfos(caseFile.getFileName().toString(), caseUuid, importer.getFormat()); | ||
caseInfosService.addCaseInfos(caseInfos); | ||
if (indexed) { | ||
caseInfosService.addCaseInfos(caseInfos); | ||
} | ||
sendImportMessage(caseInfos.createMessage()); | ||
return caseUuid; | ||
} | ||
|
||
UUID duplicateCase(UUID sourceCaseUuid, boolean withExpiration) { | ||
UUID duplicateCase(UUID sourceCaseUuid, boolean withExpiration, boolean indexed) { | ||
try { | ||
Path existingCaseFile = getCaseFile(sourceCaseUuid); | ||
if (existingCaseFile == null || existingCaseFile.getParent() == null) { | ||
|
@@ -237,8 +235,10 @@ UUID duplicateCase(UUID sourceCaseUuid, boolean withExpiration) { | |
|
||
CaseInfos existingCaseInfos = caseInfosService.getCaseInfosByUuid(sourceCaseUuid.toString()).orElseThrow(); | ||
CaseInfos caseInfos = createInfos(existingCaseInfos.getName(), newCaseUuid, existingCaseInfos.getFormat()); | ||
caseInfosService.addCaseInfos(caseInfos); | ||
createCaseMetadataEntity(newCaseUuid, withExpiration); | ||
if (indexed) { | ||
caseInfosService.addCaseInfos(caseInfos); | ||
} | ||
createCaseMetadataEntity(newCaseUuid, withExpiration, indexed); | ||
|
||
sendImportMessage(caseInfos.createMessage()); | ||
return newCaseUuid; | ||
|
@@ -248,12 +248,23 @@ UUID duplicateCase(UUID sourceCaseUuid, boolean withExpiration) { | |
} | ||
} | ||
|
||
private void createCaseMetadataEntity(UUID newCaseUuid, boolean withExpiration) { | ||
private void createCaseMetadataEntity(UUID newCaseUuid, boolean withExpiration, boolean indexed) { | ||
Instant expirationTime = null; | ||
if (withExpiration) { | ||
expirationTime = Instant.now().plus(1, ChronoUnit.HOURS); | ||
} | ||
caseMetadataRepository.save(new CaseMetadataEntity(newCaseUuid, expirationTime)); | ||
caseMetadataRepository.save(new CaseMetadataEntity(newCaseUuid, expirationTime, indexed)); | ||
} | ||
|
||
public Set<UUID> getCaseToReindex() { | ||
return caseMetadataRepository.findAllByIndexedTrue() | ||
.stream() | ||
.map(CaseMetadataEntity::getId) | ||
.collect(Collectors.toSet()); | ||
} | ||
|
||
public List<CaseInfos> getAllCases() { | ||
return getCases(getStorageRootDir()); | ||
} | ||
|
||
CaseInfos createInfos(String fileBaseName, UUID caseUuid, String format) { | ||
|
@@ -273,6 +284,12 @@ public void disableCaseExpiration(UUID caseUuid) { | |
caseMetadataEntity.setExpirationDate(null); | ||
} | ||
|
||
@Transactional | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
public void enableCaseIndexation(UUID caseUuid, boolean indexed) { | ||
CaseMetadataEntity caseMetadataEntity = caseMetadataRepository.findById(caseUuid).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "case " + caseUuid + " not found")); | ||
caseMetadataEntity.setIndexed(indexed); | ||
} | ||
|
||
Optional<Network> loadNetwork(UUID caseUuid) { | ||
checkStorageInitialization(); | ||
|
||
|
@@ -373,10 +390,6 @@ private void sendImportMessage(Message<String> message) { | |
caseInfosPublisher.send("publishCaseImport-out-0", message); | ||
} | ||
|
||
public void reindexAllCases() { | ||
caseInfosService.recreateAllCaseInfos(getCases(getStorageRootDir())); | ||
} | ||
|
||
public List<CaseInfos> getMetadata(List<UUID> ids) { | ||
List<CaseInfos> cases = new ArrayList<>(); | ||
ids.forEach(caseUuid -> { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/** | ||
* Copyright (c) 2024, RTE (http://www.rte-france.com) | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
package com.powsybl.caseserver; | ||
|
||
import com.powsybl.caseserver.elasticsearch.CaseInfosService; | ||
import com.powsybl.caseserver.services.SupervisionService; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.data.elasticsearch.client.ClientConfiguration; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
/** | ||
* @author Jamal KHEYYAD <jamal.kheyyad at rte-international.com> | ||
*/ | ||
@RestController | ||
@RequestMapping(value = "/" + CaseConstants.API_VERSION + "/supervision") | ||
@Tag(name = "case-server - Supervision") | ||
public class SupervisionController { | ||
private static final Logger LOGGER = LoggerFactory.getLogger(SupervisionController.class); | ||
|
||
private final SupervisionService supervisionService; | ||
private final ClientConfiguration elasticsearchClientConfiguration; | ||
private final CaseInfosService caseInfosService; | ||
|
||
public SupervisionController(SupervisionService supervisionService, ClientConfiguration elasticsearchClientConfiguration, CaseInfosService caseInfosService) { | ||
this.supervisionService = supervisionService; | ||
this.elasticsearchClientConfiguration = elasticsearchClientConfiguration; | ||
this.caseInfosService = caseInfosService; | ||
} | ||
|
||
@GetMapping(value = "/elasticsearch-host") | ||
@Operation(summary = "get the elasticsearch address") | ||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "the elasticsearch address")}) | ||
public ResponseEntity<String> getElasticsearchHost() { | ||
String host = elasticsearchClientConfiguration.getEndpoints().get(0).getHostName() | ||
+ ":" | ||
+ elasticsearchClientConfiguration.getEndpoints().get(0).getPort(); | ||
return ResponseEntity.ok().contentType(MediaType.TEXT_PLAIN).body(host); | ||
} | ||
|
||
@GetMapping(value = "/cases/index-name") | ||
@Operation(summary = "get the indexed directory elements index name") | ||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Indexed directory elements index name")}) | ||
public ResponseEntity<String> getIndexedDirectoryElementsIndexName() { | ||
return ResponseEntity.ok().contentType(MediaType.TEXT_PLAIN).body(caseInfosService.getDirectoryElementsIndexName()); | ||
} | ||
|
||
@PostMapping(value = "/cases/reindex") | ||
@Operation(summary = "reindex all cases") | ||
public ResponseEntity<Void> reindexAllCases() { | ||
LOGGER.debug("reindex all cases request received"); | ||
supervisionService.reindexAllCases(); | ||
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@DeleteMapping(value = "/cases/indexation") | ||
@Operation(summary = "delete indexed elements") | ||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "all indexed elements have been deleted")}) | ||
public ResponseEntity<String> deleteIndexedDirectoryElements() { | ||
return ResponseEntity.ok().contentType(MediaType.TEXT_PLAIN).body(Long.toString(supervisionService.deleteIndexedDirectoryElements())); | ||
} | ||
|
||
@GetMapping(value = "/cases/indexation-count") | ||
@Operation(summary = "get indexed cases count") | ||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Indexed cases count")}) | ||
public ResponseEntity<String> getIndexedDirectoryElementsCount() { | ||
return ResponseEntity.ok().contentType(MediaType.TEXT_PLAIN).body(Long.toString(supervisionService.getIndexedCaseElementsCount())); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import java.util.List; | ||
import java.util.UUID; | ||
|
||
/** | ||
|
@@ -17,4 +18,8 @@ | |
@Repository | ||
public interface CaseMetadataRepository extends JpaRepository<CaseMetadataEntity, UUID> { | ||
|
||
@Override | ||
List<CaseMetadataEntity> findAllById(Iterable<UUID> uuids); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
||
List<CaseMetadataEntity> findAllByIndexedTrue(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/** | ||
* Copyright (c) 2024, RTE (http://www.rte-france.com) | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
package com.powsybl.caseserver.services; | ||
|
||
import com.powsybl.caseserver.CaseService; | ||
import com.powsybl.caseserver.dto.CaseInfos; | ||
import com.powsybl.caseserver.elasticsearch.CaseInfosRepository; | ||
import com.powsybl.caseserver.elasticsearch.CaseInfosService; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.UUID; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
|
||
/** | ||
* @author Jamal KHEYYAD <jamal.kheyyad at rte-international.com> | ||
*/ | ||
@Service | ||
public class SupervisionService { | ||
private static final Logger LOGGER = LoggerFactory.getLogger(SupervisionService.class); | ||
|
||
private final CaseInfosService caseInfosService; | ||
private final CaseService caseService; | ||
private final CaseInfosRepository caseInfosRepository; | ||
|
||
public SupervisionService(CaseInfosService caseInfosService, CaseService caseService, CaseInfosRepository caseInfosRepository) { | ||
this.caseInfosService = caseInfosService; | ||
this.caseService = caseService; | ||
this.caseInfosRepository = caseInfosRepository; | ||
} | ||
|
||
public void reindexAllCases() { | ||
List<CaseInfos> allCases = caseService.getAllCases(); | ||
Set<UUID> casesToIndex = caseService.getCaseToReindex(); | ||
List<CaseInfos> data = allCases.stream().filter(c -> casesToIndex.contains(c.getUuid())).toList(); | ||
caseInfosService.recreateAllCaseInfos(data); | ||
} | ||
|
||
public long deleteIndexedDirectoryElements() { | ||
AtomicReference<Long> startTime = new AtomicReference<>(); | ||
startTime.set(System.nanoTime()); | ||
|
||
long nbIndexesToDelete = getIndexedCaseElementsCount(); | ||
caseInfosRepository.deleteAll(); | ||
LOGGER.trace("Indexed directory elements deletion : {} seconds", TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); | ||
return nbIndexesToDelete; | ||
} | ||
|
||
public long getIndexedCaseElementsCount() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
return caseInfosRepository.count(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?xml version="1.1" encoding="UTF-8" standalone="no"?> | ||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd"> | ||
<changeSet author="jamalk (generated)" id="1722005243703-1"> | ||
<addColumn tableName="case_metadata"> | ||
<column defaultValueBoolean="false" name="indexed" type="boolean"> | ||
<constraints nullable="false"/> | ||
</column> | ||
</addColumn> | ||
</changeSet> | ||
</databaseChangeLog> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename by
withIndexation
But in database leave
indexed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done