Skip to content

Commit c672960

Browse files
committed
Merge branch 'main' into devAuth
2 parents 7ef5527 + 8d5906a commit c672960

File tree

51 files changed

+1935
-500
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1935
-500
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,5 @@ src/test/resources/OUT/*
4949
/src/test/resources/genesis_deleted_schedules/*
5050
/src/test/resources/IN/WEB/SAMPLETEST/
5151
/src/test/resources/IN/WEB/TEST-EDITED-PREVIOUS/
52+
/src/test/resources/IN/WEB/TEST-EDITED-EXTERNAL/
5253
/src/main/resources/application-mbg.properties

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
# Changelog
2+
## 1.6.2 [2025-07-21]
3+
### Added
4+
- Edited contextual variables storage
5+
26
## 1.6.1 [2025-07-15]
37
### Added
48
- Extract Raw responses for Generic endpoint

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>fr.insee.genesis</groupId>
66
<artifactId>genesis-api</artifactId>
7-
<version>1.6.1</version>
7+
<version>1.6.2</version>
88
<packaging>jar</packaging>
99
<name>genesis-api</name>
1010

src/main/java/fr/insee/genesis/Constants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class Constants {
1919
public static final String MONGODB_SCHEDULE_COLLECTION_NAME = "schedules";
2020
public static final String MONGODB_CONTEXT_COLLECTION_NAME = "dataProcessingContexts";
2121
public static final String MONGODB_EDITED_PREVIOUS_COLLECTION_NAME = "editedPrevious";
22+
public static final String MONGODB_EDITED_EXTERNAL_COLLECTION_NAME = "editedExternal";
2223
public static final String LOOP_NAME_PREFIX = "BOUCLE";
2324
public static final String MONGODB_RESPONSE_COLLECTION_NAME = "responses";
2425
public static final String MONGODB_RESPONSE_RAW_COLLECTION_NAME = "lunaticjsondata";

src/main/java/fr/insee/genesis/configuration/auth/security/ApplicationRole.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public enum ApplicationRole {
66
USER_PLATINE,
77
COLLECT_PLATFORM,
88
SCHEDULER,
9-
READER
9+
READER,
10+
USER_BATCH_GENERIC
1011
}
1112

src/main/java/fr/insee/genesis/configuration/auth/security/RoleConfiguration.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ public class RoleConfiguration {
3434
@Value("#{'${app.role.scheduler.claims}'.split(',')}")
3535
private List<String> schedulerClaims;
3636

37+
@Value("#{'${app.role.batch-generic.claims}'.split(',')}")
38+
private List<String> batchGenericClaims;
39+
40+
3741
public Map<String, List<String>> getRolesByClaim() {
3842
return rolesByClaim;
3943
}
@@ -52,6 +56,7 @@ static RoleHierarchy roleHierarchy() {
5256
.role(ApplicationRole.ADMIN.toString()).implies(ApplicationRole.USER_PLATINE.toString())
5357
.role(ApplicationRole.ADMIN.toString()).implies(ApplicationRole.COLLECT_PLATFORM.toString())
5458
.role(ApplicationRole.ADMIN.toString()).implies(ApplicationRole.SCHEDULER.toString())
59+
.role(ApplicationRole.ADMIN.toString()).implies(ApplicationRole.USER_BATCH_GENERIC.toString())
5560
.role(ApplicationRole.USER_KRAFTWERK.toString()).implies(ApplicationRole.READER.toString())
5661
.role(ApplicationRole.USER_PLATINE.toString()).implies(ApplicationRole.READER.toString())
5762
.build();
@@ -100,6 +105,11 @@ public void initialization() {
100105
.computeIfAbsent(claim, k -> new ArrayList<>())
101106
.add(String.valueOf(ApplicationRole.SCHEDULER)));
102107

108+
//Add claims for the USER_BATCH_GENERIC role
109+
batchGenericClaims.forEach(claim -> rolesByClaim
110+
.computeIfAbsent(claim, k -> new ArrayList<>())
111+
.add(String.valueOf(ApplicationRole.USER_BATCH_GENERIC)));
112+
103113
log.info("Roles configuration : {}", rolesByClaim);
104114
}
105115

src/main/java/fr/insee/genesis/controller/rest/responses/EditedPreviousResponseController.java

Lines changed: 0 additions & 70 deletions
This file was deleted.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package fr.insee.genesis.controller.rest.responses;
2+
3+
import fr.insee.genesis.configuration.Config;
4+
import fr.insee.genesis.domain.model.surveyunit.Mode;
5+
import fr.insee.genesis.domain.ports.api.EditedExternalResponseApiPort;
6+
import fr.insee.genesis.domain.ports.api.EditedPreviousResponseApiPort;
7+
import fr.insee.genesis.domain.ports.api.EditedResponseApiPort;
8+
import fr.insee.genesis.exceptions.GenesisException;
9+
import fr.insee.genesis.infrastructure.utils.FileUtils;
10+
import io.swagger.v3.oas.annotations.Operation;
11+
import lombok.AllArgsConstructor;
12+
import lombok.extern.slf4j.Slf4j;
13+
import org.springframework.http.HttpStatusCode;
14+
import org.springframework.http.ResponseEntity;
15+
import org.springframework.security.access.prepost.PreAuthorize;
16+
import org.springframework.stereotype.Controller;
17+
import org.springframework.web.bind.annotation.GetMapping;
18+
import org.springframework.web.bind.annotation.PostMapping;
19+
import org.springframework.web.bind.annotation.RequestMapping;
20+
import org.springframework.web.bind.annotation.RequestParam;
21+
22+
import java.io.FileInputStream;
23+
import java.io.FileNotFoundException;
24+
import java.io.IOException;
25+
import java.io.InputStream;
26+
import java.nio.file.Path;
27+
28+
@RequestMapping(path = "/edited")
29+
@Controller
30+
@Slf4j
31+
@AllArgsConstructor
32+
public class EditedResponseController {
33+
34+
private final EditedPreviousResponseApiPort editedPreviousResponseApiPort;
35+
private final EditedExternalResponseApiPort editedExternalResponseApiPort;
36+
private final EditedResponseApiPort editedResponseApiPort;
37+
private final Config config;
38+
39+
@Operation(summary = "Get edited variables (edited and previous)")
40+
@GetMapping(path = "/")
41+
@PreAuthorize("hasRole('USER_PLATINE')")
42+
public ResponseEntity<Object> getEditedResponses(
43+
@RequestParam("questionnaireId") String questionnaireId,
44+
@RequestParam("interrogationId") String interrogationId
45+
){
46+
return ResponseEntity.ok().body(
47+
editedResponseApiPort.getEditedResponse(questionnaireId, interrogationId)
48+
);
49+
}
50+
51+
@Operation(summary = "Add edited previous json file")
52+
@PostMapping(path = "previous/json")
53+
@PreAuthorize("hasAnyRole('USER_PLATINE','SCHEDULER')")
54+
public ResponseEntity<Object> readEditedPreviousJson(
55+
@RequestParam("questionnaireId") String questionnaireId,
56+
@RequestParam("mode") Mode mode,
57+
@RequestParam(value = "sourceState", required = false) String sourceState,
58+
@RequestParam(value = "jsonFileName") String jsonFileName
59+
){
60+
try {
61+
FileUtils fileUtils = new FileUtils(config);
62+
63+
String filePath = "%s/%s".formatted(
64+
fileUtils.getDataFolder(questionnaireId, mode.getFolder(), null),
65+
jsonFileName
66+
);
67+
if (!jsonFileName.toLowerCase().endsWith(".json")) {
68+
throw new GenesisException(400, "File must be a JSON file !");
69+
}
70+
readEditedPreviousFile(questionnaireId, sourceState, filePath);
71+
moveFiles(questionnaireId, mode, fileUtils, filePath);
72+
return ResponseEntity.ok("Edited previous variable file %s saved !".formatted(filePath));
73+
}catch (GenesisException ge){
74+
return ResponseEntity.status(HttpStatusCode.valueOf(ge.getStatus())).body(ge.getMessage());
75+
}
76+
}
77+
78+
@Operation(summary = "Add edited external json file")
79+
@PostMapping(path = "/external/json")
80+
@PreAuthorize("hasAnyRole('USER_PLATINE','SCHEDULER')")
81+
public ResponseEntity<Object> readEditedExternalJson(
82+
@RequestParam("questionnaireId") String questionnaireId,
83+
@RequestParam("mode") Mode mode,
84+
@RequestParam(value = "jsonFileName") String jsonFileName
85+
){
86+
try {
87+
FileUtils fileUtils = new FileUtils(config);
88+
89+
String filePath = "%s/%s".formatted(
90+
fileUtils.getDataFolder(questionnaireId, mode.getFolder(), null),
91+
jsonFileName
92+
);
93+
if (!jsonFileName.toLowerCase().endsWith(".json")) {
94+
throw new GenesisException(400, "File must be a JSON file !");
95+
}
96+
readEditedExternalFile(questionnaireId, filePath);
97+
moveFiles(questionnaireId, mode, fileUtils, filePath);
98+
return ResponseEntity.ok("Edited external variable file %s saved !".formatted(filePath));
99+
}catch (GenesisException ge){
100+
return ResponseEntity.status(HttpStatusCode.valueOf(ge.getStatus())).body(ge.getMessage());
101+
}
102+
}
103+
104+
private void readEditedPreviousFile(String questionnaireId, String sourceState, String filePath) throws GenesisException {
105+
try (InputStream inputStream = new FileInputStream(filePath)) {
106+
editedPreviousResponseApiPort.readEditedPreviousFile(inputStream, questionnaireId, sourceState);
107+
} catch (FileNotFoundException e) {
108+
throw new GenesisException(404, "File %s not found".formatted(filePath));
109+
} catch (IOException e) {
110+
throw new GenesisException(500, e.toString());
111+
}
112+
}
113+
114+
private void readEditedExternalFile(String questionnaireId, String filePath) throws GenesisException {
115+
try (InputStream inputStream = new FileInputStream(filePath)) {
116+
editedExternalResponseApiPort.readEditedExternalFile(inputStream, questionnaireId);
117+
} catch (FileNotFoundException e) {
118+
throw new GenesisException(404, "File %s not found".formatted(filePath));
119+
} catch (IOException e) {
120+
throw new GenesisException(500, e.toString());
121+
}
122+
}
123+
124+
private static void moveFiles(String questionnaireId, Mode mode, FileUtils fileUtils, String filePath) throws GenesisException {
125+
try {
126+
fileUtils.moveFiles(Path.of(filePath), fileUtils.getDoneFolder(questionnaireId, mode.getFolder()));
127+
} catch (IOException e) {
128+
throw new GenesisException(500, "Error while moving file to done : %s".formatted(e.toString()));
129+
}
130+
}
131+
}

src/main/java/fr/insee/genesis/controller/rest/responses/RawResponseController.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,17 +191,18 @@ public ResponseEntity<Map<String, List<String>>> getProcessedDataIdsSinceHours(
191191
Map<String, List<String>> result = lunaticJsonRawDataApiPort.findProcessedIdsgroupedByQuestionnaireSince(LocalDateTime.now().minusHours(hours).minusMinutes(10));
192192
return ResponseEntity.ok(result);
193193
}
194-
@Operation(summary = "Get lunatic JSON data from one campaign in Genesis Database, filtered by optional start and end dates")
194+
195+
@Operation(summary = "Get lunatic JSON data from one campaign in Genesis Database, filtered by start and end dates")
195196
@GetMapping(path = "/lunatic-json/{campaignId}")
196-
@PreAuthorize("hasRole('USER_KRAFTWERK')")
197+
@PreAuthorize("hasRole('USER_BATCH_GENERIC')")
197198
public ResponseEntity<PagedModel<LunaticJsonRawDataModel>> getRawResponsesFromJsonBody(
198199
@PathVariable String campaignId,
199200
@RequestParam(value = "startDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant startDate,
200201
@RequestParam(value = "endDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant endDate,
201202
@RequestParam(value = "page", defaultValue = "0") int page,
202203
@RequestParam(value = "size", defaultValue = "1000") int size
203204
) {
204-
log.info("Try to read raw JSONs for campaign {}, with startDate={} and endDate={}", campaignId, startDate, endDate);
205+
log.info("Try to read raw JSONs for campaign {}, with startDate={} and endDate={} - page={} - size={}", campaignId, startDate, endDate,page,size);
205206
Pageable pageable = PageRequest.of(page, size);
206207
Page<LunaticJsonRawDataModel> rawResponses = lunaticJsonRawDataApiPort.findRawDataByCampaignIdAndDate(campaignId, startDate, endDate, pageable);
207208
log.info("rawResponses=" + rawResponses.getContent().size());
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package fr.insee.genesis.domain.model.editedresponse;
2+
3+
import lombok.Builder;
4+
import lombok.Data;
5+
6+
import java.util.Map;
7+
8+
@Builder
9+
@Data
10+
public class EditedExternalResponseModel {
11+
String id;
12+
String questionnaireId;
13+
String interrogationId;
14+
Map<String,Object> variables;
15+
}

0 commit comments

Comments
 (0)