Skip to content

Commit a6be1ef

Browse files
committed
refactor: add collectionInstrumentId to data context
1 parent 4667c63 commit a6be1ef

17 files changed

+925
-228
lines changed

src/main/java/fr/insee/genesis/controller/mappers/DataProcessingContextMapperDto.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,13 @@ public List<ScheduleDto> dataProcessingContextListToScheduleDtoList(List<DataPro
2323
}
2424
return dtos;
2525
}
26+
27+
public DataProcessingContextModel scheduleDtoToDataProcessingContext (ScheduleDto schedule){
28+
return DataProcessingContextModel.builder()
29+
.partitionId(schedule.surveyName())
30+
.collectionInstrumentId(schedule.collectionInstrumentId())
31+
.lastExecution(schedule.lastExecution())
32+
.kraftwerkExecutionScheduleList(schedule.kraftwerkExecutionScheduleList())
33+
.build();
34+
}
2635
}

src/main/java/fr/insee/genesis/controller/rest/DataProcessingContextController.java

Lines changed: 142 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
package fr.insee.genesis.controller.rest;
22

3-
import com.fasterxml.jackson.databind.ObjectMapper;
4-
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
53
import fr.insee.genesis.Constants;
64
import fr.insee.genesis.controller.dto.ScheduleDto;
7-
import fr.insee.genesis.domain.model.context.schedule.KraftwerkExecutionSchedule;
85
import fr.insee.genesis.domain.model.context.schedule.ServiceToCall;
96
import fr.insee.genesis.domain.model.context.schedule.TrustParameters;
107
import fr.insee.genesis.domain.ports.api.DataProcessingContextApiPort;
@@ -21,31 +18,25 @@
2118
import org.springframework.stereotype.Controller;
2219
import org.springframework.web.bind.annotation.DeleteMapping;
2320
import org.springframework.web.bind.annotation.GetMapping;
21+
import org.springframework.web.bind.annotation.PathVariable;
2422
import org.springframework.web.bind.annotation.PostMapping;
2523
import org.springframework.web.bind.annotation.PutMapping;
2624
import org.springframework.web.bind.annotation.RequestBody;
27-
import org.springframework.web.bind.annotation.RequestMapping;
2825
import org.springframework.web.bind.annotation.RequestParam;
2926

30-
import java.io.IOException;
31-
import java.nio.file.Files;
32-
import java.nio.file.Path;
33-
import java.nio.file.StandardOpenOption;
3427
import java.time.LocalDateTime;
35-
import java.util.HashSet;
3628
import java.util.List;
37-
import java.util.Set;
3829

39-
@RequestMapping(path = "/context" )
4030
@Controller
4131
@AllArgsConstructor
4232
@Slf4j
4333
public class DataProcessingContextController {
4434
private DataProcessingContextApiPort dataProcessingContextApiPort;
4535
private final FileUtils fileUtils;
4636

37+
@Deprecated(forRemoval = true)
4738
@Operation(summary = "Create or update a data processing context")
48-
@PutMapping(path = "/review")
39+
@PutMapping(path = "/context/review")
4940
@PreAuthorize("hasAnyRole('USER_PLATINE', 'USER_BACK_OFFICE', 'SCHEDULER')")
5041
public ResponseEntity<Object> saveContext(
5142
@Parameter(description = "Identifier of the partition", required = true) @RequestParam("partitionId") String partitionId,
@@ -60,8 +51,40 @@ public ResponseEntity<Object> saveContext(
6051
return ResponseEntity.ok().build();
6152
}
6253

54+
@Operation(summary = "Create or update a data processing context")
55+
@PutMapping(path = "/contexts/{collectionInstrumentId}/review")
56+
@PreAuthorize("hasAnyRole('USER_PLATINE', 'USER_BACK_OFFICE', 'SCHEDULER')")
57+
public ResponseEntity<Object> saveContextWithCollectionInstrumentId(
58+
@PathVariable("collectionInstrumentId") String collectionInstrumentId,
59+
@Parameter(description = "Allow reviewing") @RequestParam(value = "withReview", defaultValue = "false") Boolean withReview
60+
){
61+
try {
62+
withReview = withReview != null && withReview; //False if null
63+
dataProcessingContextApiPort.saveContextByCollectionInstrumentId(collectionInstrumentId, withReview);
64+
}catch (GenesisException e){
65+
return new ResponseEntity<>(e.getMessage(), HttpStatusCode.valueOf(e.getStatus()));
66+
}
67+
return ResponseEntity.ok().build();
68+
}
69+
70+
71+
@Operation(summary = "Returns partition review indicator")
72+
@GetMapping(path = "/contexts/{collectionInstrumentId}/review")
73+
@PreAuthorize("hasAnyRole('USER_BACK_OFFICE','SCHEDULER','USER_PLATINE')")
74+
public ResponseEntity<Object> getReviewIndicatorByCollectionInstrumentId(
75+
@PathVariable("collectionInstrumentId") String collectionInstrumentId
76+
){
77+
try {
78+
boolean withReview = dataProcessingContextApiPort.getReviewByCollectionInstrumentId(collectionInstrumentId);
79+
return ResponseEntity.ok(withReview);
80+
}catch (GenesisException e){
81+
return new ResponseEntity<>(e.getMessage(), HttpStatusCode.valueOf(e.getStatus()));
82+
}
83+
}
84+
85+
@Deprecated(forRemoval = true)
6386
@Operation(summary = "Returns partition review indicator")
64-
@GetMapping(path = "/review")
87+
@GetMapping(path = "/context/review")
6588
@PreAuthorize("hasAnyRole('USER_BACK_OFFICE','SCHEDULER','USER_PLATINE')")
6689
public ResponseEntity<Object> getReviewIndicator(
6790
@Parameter(description = "Identifier of the partition", required = true) @RequestParam("partitionId") String partitionId
@@ -74,8 +97,9 @@ public ResponseEntity<Object> getReviewIndicator(
7497
}
7598
}
7699

100+
@Deprecated(forRemoval = true)
77101
@Operation(summary = "Schedule a Kraftwerk execution")
78-
@PutMapping(path = "/schedules")
102+
@PutMapping(path = "/context/schedules")
79103
@PreAuthorize("hasRole('USER_KRAFTWERK')")
80104
public ResponseEntity<Object> saveSchedule(
81105
@Parameter(description = "Partition identifier to call Kraftwerk on") @RequestParam("partitionId") String partitionId,
@@ -119,8 +143,55 @@ public ResponseEntity<Object> saveSchedule(
119143
return ResponseEntity.ok().build();
120144
}
121145

146+
// Should be refactored to make it restfull
147+
@Operation(summary = "Schedule a Kraftwerk execution using the collection instrument")
148+
@PutMapping(path = "/contexts/schedules")
149+
@PreAuthorize("hasRole('USER_KRAFTWERK')")
150+
public ResponseEntity<Object> saveScheduleWithCollectionInstrumentId(
151+
@Parameter(description = "Collection instrument to call Kraftwerk on") @RequestParam("collectionInstrumentId") String collectionInstrumentId,
152+
@Parameter(description = "Kraftwerk endpoint") @RequestParam(value = "serviceTocall", defaultValue = Constants.KRAFTWERK_MAIN_ENDPOINT) ServiceToCall serviceToCall,
153+
@Parameter(description = "Frequency in Spring cron format (6 inputs, go to https://crontab.cronhub.io/ for generator) \n Example : 0 0 6 * * *") @RequestParam("frequency") String frequency,
154+
@Parameter(description = "Schedule effective date and time", example = "2024-01-01T12:00:00") @RequestParam("scheduleBeginDate") LocalDateTime scheduleBeginDate,
155+
@Parameter(description = "Schedule end date and time", example = "2024-01-01T12:00:00") @RequestParam("scheduleEndDate") LocalDateTime scheduleEndDate,
156+
@Parameter(description = "Encrypt after process ? Ignore next parameters if false") @RequestParam(value =
157+
"useEncryption",
158+
defaultValue = "false") boolean useEncryption,
159+
@Parameter(description = "(Encryption) vault path") @RequestParam(value = "encryptionVaultPath", defaultValue = "") String encryptionVaultPath,
160+
@Parameter(description = "(Encryption) output folder") @RequestParam(value = "encryptionOutputFolder",
161+
defaultValue = "") String encryptionOutputFolder,
162+
@Parameter(description = "(Encryption) Use signature system") @RequestParam(value = "useSignature", defaultValue = "false") boolean useSignature
163+
) {
164+
try {
165+
//Check frequency
166+
if(!CronExpression.isValidExpression(frequency)) {
167+
log.warn("Returned error for wrong frequency : {}", frequency);
168+
throw new GenesisException(400, "Wrong frequency syntax");
169+
}
170+
171+
TrustParameters trustParameters = null;
172+
if(useEncryption) {
173+
trustParameters = new TrustParameters(
174+
fileUtils.getKraftwerkOutFolder(collectionInstrumentId),
175+
encryptionOutputFolder,
176+
encryptionVaultPath,
177+
useSignature
178+
);
179+
}
180+
dataProcessingContextApiPort.saveKraftwerkExecutionScheduleByCollectionInstrumentId(
181+
collectionInstrumentId,
182+
serviceToCall == null ? ServiceToCall.MAIN : serviceToCall,
183+
frequency,
184+
scheduleBeginDate, scheduleEndDate, trustParameters
185+
);
186+
}catch (GenesisException e){
187+
return new ResponseEntity<>(e.getMessage(), HttpStatusCode.valueOf(e.getStatus()));
188+
}
189+
return ResponseEntity.ok().build();
190+
}
191+
192+
@Deprecated(forRemoval = true)
122193
@Operation(summary = "Fetch all schedules")
123-
@GetMapping(path = "/schedules")
194+
@GetMapping(path = "/context/schedules")
124195
@PreAuthorize("hasAnyRole('SCHEDULER','READER')")
125196
public ResponseEntity<Object> getAllSchedules() {
126197
log.debug("Got GET all schedules request");
@@ -131,8 +202,23 @@ public ResponseEntity<Object> getAllSchedules() {
131202
return ResponseEntity.ok(surveyScheduleDocumentModels);
132203
}
133204

205+
//It is just a change of path in the url
206+
@Operation(summary = "Fetch all schedules")
207+
@GetMapping(path = "/contexts/schedules")
208+
@PreAuthorize("hasAnyRole('SCHEDULER','READER')")
209+
public ResponseEntity<Object> getAllSchedulesV2() {
210+
log.debug("Got GET all schedules request");
211+
212+
List<ScheduleDto> surveyScheduleDocumentModels = dataProcessingContextApiPort.getAllSchedules();
213+
214+
log.info("Returning {} schedule documents...", surveyScheduleDocumentModels.size());
215+
return ResponseEntity.ok(surveyScheduleDocumentModels);
216+
}
217+
218+
219+
@Deprecated(forRemoval = true)
134220
@Operation(summary = "Set last execution date of a partition with new date or nothing")
135-
@PostMapping(path = "/schedules/lastExecutionDate")
221+
@PostMapping(path = "/context/schedules/lastExecutionDate")
136222
@PreAuthorize("hasRole('SCHEDULER')")
137223
public ResponseEntity<Object> setSurveyLastExecution(
138224
@Parameter(description = "Survey name to call Kraftwerk on") @RequestBody String partitionId,
@@ -147,8 +233,25 @@ public ResponseEntity<Object> setSurveyLastExecution(
147233
return ResponseEntity.ok().build();
148234
}
149235

236+
@Operation(summary = "Update the date of the last extraction of data corresponding to a collection instrument")
237+
@PutMapping(path = "/contexts/{collectionInstrumentId}/lastExecutionDate")
238+
@PreAuthorize("hasRole('SCHEDULER')")
239+
public ResponseEntity<Object> setSurveyLastExecutionByCollectionInstrumentId(
240+
@PathVariable("collectionInstrumentId") @RequestBody String collectionInstrumentId,
241+
@Parameter(description = "Date to save as last execution date", example = "2024-01-01T12:00:00") @RequestParam("newDate") LocalDateTime newDate
242+
) {
243+
try {
244+
dataProcessingContextApiPort.updateLastExecutionDateByCollectionInstrumentId(collectionInstrumentId, newDate);
245+
log.info("{} last execution updated at {} !", collectionInstrumentId, newDate);
246+
}catch (GenesisException e){
247+
return new ResponseEntity<>(e.getMessage(), HttpStatusCode.valueOf(e.getStatus()));
248+
}
249+
return ResponseEntity.ok().build();
250+
}
251+
252+
@Deprecated(forRemoval = true)
150253
@Operation(summary = "Delete the Kraftwerk execution schedules of a partition")
151-
@DeleteMapping(path = "/schedules")
254+
@DeleteMapping(path = "/context/schedules")
152255
@PreAuthorize("hasRole('USER_KRAFTWERK')")
153256
public ResponseEntity<Object> deleteSchedules(
154257
@Parameter(description = "Survey name of the schedule(s) to delete") @RequestParam("partitionId") String partitionId
@@ -162,36 +265,31 @@ public ResponseEntity<Object> deleteSchedules(
162265
return ResponseEntity.ok().build();
163266
}
164267

268+
@Operation(summary = "Delete the Kraftwerk execution schedules of a collection instrument id")
269+
@DeleteMapping(path = "/context/{collectionInstrumentId}/schedules")
270+
@PreAuthorize("hasRole('USER_KRAFTWERK')")
271+
public ResponseEntity<Object> deleteSchedulesByCollectionInstrumentId(
272+
@PathVariable("collectionInstrumentId") String collectionInstrumentId
273+
){
274+
try {
275+
dataProcessingContextApiPort.deleteSchedulesByCollectionInstrumentId(collectionInstrumentId);
276+
}catch (GenesisException e){
277+
return new ResponseEntity<>(e.getMessage(), HttpStatusCode.valueOf(e.getStatus()));
278+
}
279+
log.info("Schedule deleted for survey {}", collectionInstrumentId);
280+
return ResponseEntity.ok().build();
281+
}
282+
165283
@Operation(summary = "Delete expired schedules")
166-
@DeleteMapping(path = "/schedules/expired-schedules")
284+
@DeleteMapping(path = "/context/schedules/expired-schedules")
167285
@PreAuthorize("hasRole('SCHEDULER')")
168-
public ResponseEntity<Object> deleteExpiredSchedules() throws GenesisException, IOException {
169-
Set<String> storedSurveySchedulesNames = new HashSet<>();
170-
for(ScheduleDto scheduleDto : dataProcessingContextApiPort.getAllSchedules()){
171-
storedSurveySchedulesNames.add(scheduleDto.surveyName());
172-
}
173-
for (String surveyScheduleName : storedSurveySchedulesNames) {
174-
List<KraftwerkExecutionSchedule> deletedKraftwerkExecutionSchedules = dataProcessingContextApiPort.deleteExpiredSchedules(surveyScheduleName);
175-
//Save in JSON log
176-
if(!deletedKraftwerkExecutionSchedules.isEmpty()) {
177-
Path jsonLogPath = Path.of(fileUtils.getLogFolder(), Constants.SCHEDULE_ARCHIVE_FOLDER_NAME,
178-
surveyScheduleName + ".json");
179-
ObjectMapper objectMapper = new ObjectMapper().findAndRegisterModules();
180-
objectMapper.registerModule(new JavaTimeModule());
181-
String jsonToWrite = objectMapper.writeValueAsString(deletedKraftwerkExecutionSchedules);
182-
if(Files.exists(jsonLogPath)){
183-
//Remove last ] and append survey
184-
StringBuilder content = new StringBuilder(Files.readString(jsonLogPath));
185-
content.setCharAt(content.length()-1, ',');
186-
content.append(jsonToWrite, 1, jsonToWrite.length()-1);
187-
content.append(']');
188-
Files.write(jsonLogPath, content.toString().getBytes(), StandardOpenOption.TRUNCATE_EXISTING);
189-
}else {
190-
Files.createDirectories(jsonLogPath.getParent());
191-
Files.write(jsonLogPath, jsonToWrite.getBytes());
192-
}
193-
}
286+
public ResponseEntity<Object> deleteExpiredSchedules(){
287+
try{
288+
dataProcessingContextApiPort.deleteExpiredSchedules(fileUtils.getLogFolder());
289+
} catch (GenesisException e){
290+
return new ResponseEntity<>(e.getMessage(), HttpStatusCode.valueOf(e.getStatus()));
194291
}
292+
log.info("Expired schedules deleted");
195293
return ResponseEntity.ok().build();
196294
}
197295
}

src/main/java/fr/insee/genesis/domain/model/context/DataProcessingContextModel.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class DataProcessingContextModel {
2020
@Id
2121
private ObjectId id; //Used to remove warning
2222

23+
@Deprecated(forRemoval = true)
2324
private String partitionId;
2425

2526
private String collectionInstrumentId; //QuestionnaireId

src/main/java/fr/insee/genesis/domain/ports/api/DataProcessingContextApiPort.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import fr.insee.genesis.controller.dto.ScheduleDto;
44
import fr.insee.genesis.domain.model.context.DataProcessingContextModel;
5-
import fr.insee.genesis.domain.model.context.schedule.KraftwerkExecutionSchedule;
65
import fr.insee.genesis.domain.model.context.schedule.ServiceToCall;
76
import fr.insee.genesis.domain.model.context.schedule.TrustParameters;
87
import fr.insee.genesis.exceptions.GenesisException;
@@ -12,21 +11,32 @@
1211

1312
public interface DataProcessingContextApiPort {
1413
void saveContext(String partitionId, Boolean withReview) throws GenesisException;
14+
void saveContextByCollectionInstrumentId(String collectionInstrumentID, Boolean withReview) throws GenesisException;
1515

16+
@Deprecated(forRemoval = true)
1617
void saveKraftwerkExecutionSchedule(String partitionId,
1718
ServiceToCall serviceToCall,
1819
String frequency,
1920
LocalDateTime startDate,
2021
LocalDateTime endDate,
2122
TrustParameters trustParameters) throws GenesisException;
2223

24+
void saveKraftwerkExecutionScheduleByCollectionInstrumentId(String collectionInstrumentId,
25+
ServiceToCall serviceToCall,
26+
String frequency,
27+
LocalDateTime startDate,
28+
LocalDateTime endDate,
29+
TrustParameters trustParameters) throws GenesisException;
30+
2331
void updateLastExecutionDate(String surveyName, LocalDateTime newDate) throws GenesisException;
32+
void updateLastExecutionDateByCollectionInstrumentId(String collectionInstrumentId, LocalDateTime newDate) throws GenesisException;
2433

2534
void deleteSchedules(String surveyName) throws GenesisException;
35+
void deleteSchedulesByCollectionInstrumentId(String collectionInstrumentId) throws GenesisException;
2636

2737
List<ScheduleDto> getAllSchedules();
2838

29-
List<KraftwerkExecutionSchedule> deleteExpiredSchedules(String surveyScheduleName) throws GenesisException;
39+
void deleteExpiredSchedules(String logFolder) throws GenesisException;
3040

3141
long countSchedules();
3242

@@ -41,5 +51,10 @@ void saveKraftwerkExecutionSchedule(String partitionId,
4151
* @param partitionId id of the partition
4252
* @return the review indicator stored in genesis
4353
*/
54+
@Deprecated(forRemoval = true)
4455
boolean getReviewByPartitionId(String partitionId) throws GenesisException;
56+
57+
boolean getReviewByCollectionInstrumentId(String collectionInstrumentId) throws GenesisException;
58+
59+
4560
}

src/main/java/fr/insee/genesis/domain/ports/spi/DataProcessingContextPersistancePort.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
import fr.insee.genesis.domain.model.context.schedule.KraftwerkExecutionSchedule;
55
import fr.insee.genesis.infrastructure.document.context.DataProcessingContextDocument;
66

7+
import java.io.IOException;
78
import java.util.List;
89

910
public interface DataProcessingContextPersistancePort {
1011
DataProcessingContextDocument findByPartitionId(String partitionId);
1112

1213
List<DataProcessingContextModel> findByPartitionIds(List<String> partitionIds);
1314

15+
DataProcessingContextModel findByCollectionInstrumentId(String collectionInstrumentId);
16+
1417
List<DataProcessingContextModel> findByCollectionInstrumentIds(List<String> collectionInstrumentIds);
1518

1619
void save(DataProcessingContextDocument dataProcessingContextDocument);
@@ -23,7 +26,7 @@ public interface DataProcessingContextPersistancePort {
2326

2427
long count();
2528

26-
List<KraftwerkExecutionSchedule> removeExpiredSchedules(DataProcessingContextModel dataProcessingContextModel);
29+
List<KraftwerkExecutionSchedule> removeExpiredSchedules(DataProcessingContextModel dataProcessingContextModel) throws IOException;
2730

2831
List<DataProcessingContextDocument> findAllByReview(boolean withReview);
2932
}

0 commit comments

Comments
 (0)