Skip to content

Commit

Permalink
build(refactor): switch to web mvc (#1084)
Browse files Browse the repository at this point in the history
* refactor(mvc): refactor ddi to lunatic controllers and services

* refactor: synchronous calls in eno xml redirection controllers

* refactor: property for max upload size

* chore: release version 3.24.0
  • Loading branch information
nsenave authored Jul 23, 2024
1 parent 313e40a commit 2066636
Show file tree
Hide file tree
Showing 23 changed files with 546 additions and 427 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ tasks.withType(JavaCompile).configureEach {

allprojects {
group = 'fr.insee.eno'
version = '3.23.8'
version = '3.24.0'
}

subprojects {
Expand Down
8 changes: 5 additions & 3 deletions eno-ws/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,19 @@ dependencies {
// Lunatic
implementation libs.lunatic.model
// Spring Web
implementation 'org.springframework.boot:spring-boot-starter-web'
// Web Client
// since Spring MVC RestTemplate class is deprecated, the webflux dependency is added to import WebClient
implementation 'org.springframework.boot:spring-boot-starter-webflux'
// Open API // https://springdoc.org/v2/#spring-webflux-support
implementation 'org.springdoc:springdoc-openapi-starter-webflux-ui:2.6.0'
// Open API
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// Spring devtools
developmentOnly 'org.springframework.boot:spring-boot-devtools'
// Tests
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

Expand Down
12 changes: 8 additions & 4 deletions eno-ws/src/main/java/fr/insee/eno/ws/EnoWsApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.web.reactive.config.WebFluxConfigurer;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.result.view.UrlBasedViewResolver;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.InetSocketAddress;
import java.net.ProxySelector;
Expand All @@ -26,8 +27,12 @@ public static void main(String[] args) {
}

@Bean
public WebClient webClient(@Value("${eno.legacy.ws.url}") String baseUrl,
@Value("${proxy.host}") Optional<String> proxyHost,
public UriComponentsBuilder uriBuilderWithBaseUrl(@Value("${eno.legacy.ws.url}") String baseUrl) {
return UriComponentsBuilder.fromHttpUrl(baseUrl);
}

@Bean
public WebClient webClient(@Value("${proxy.host}") Optional<String> proxyHost,
@Value("${proxy.port}") Optional<Integer> proxyPort,
WebClient.Builder builder) {
if (proxyHost.isPresent() && proxyPort.isPresent()) {
Expand All @@ -38,8 +43,7 @@ public WebClient webClient(@Value("${eno.legacy.ws.url}") String baseUrl,
} else {
builder.clientConnector(new JdkClientHttpConnector());
}
return builder.baseUrl(baseUrl)
.build();
return builder.build();
}

@Configuration
Expand Down
82 changes: 0 additions & 82 deletions eno-ws/src/main/java/fr/insee/eno/ws/PassThrough.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
package fr.insee.eno.ws.controller;

import fr.insee.eno.ws.PassThrough;
import fr.insee.eno.ws.controller.utils.ReactiveControllerUtils;
import fr.insee.eno.core.exceptions.business.EnoParametersException;
import fr.insee.eno.legacy.parameters.OutFormat;
import fr.insee.eno.ws.controller.utils.EnoJavaControllerUtils;
import fr.insee.eno.ws.controller.utils.EnoXmlControllerUtils;
import fr.insee.eno.ws.exception.DDIToLunaticException;
import fr.insee.eno.ws.exception.EnoControllerException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.codec.multipart.Part;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import reactor.core.publisher.Mono;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URI;

import static fr.insee.eno.ws.controller.utils.EnoXmlControllerUtils.addMultipartToBody;
import static fr.insee.eno.ws.controller.utils.EnoXmlControllerUtils.questionnaireFilename;

@Tag(name = "Generation from DDI (custom parameters)")
@Controller
Expand All @@ -26,12 +31,12 @@
@SuppressWarnings("unused")
public class GenerationCustomController {

private final PassThrough passePlat;
private final ReactiveControllerUtils controllerUtils;
private final EnoJavaControllerUtils javaControllerUtils;
private final EnoXmlControllerUtils xmlControllerUtils;

public GenerationCustomController(PassThrough passePlat, ReactiveControllerUtils controllerUtils) {
this.passePlat = passePlat;
this.controllerUtils = controllerUtils;
public GenerationCustomController(EnoJavaControllerUtils javaControllerUtils, EnoXmlControllerUtils xmlControllerUtils) {
this.javaControllerUtils = javaControllerUtils;
this.xmlControllerUtils = xmlControllerUtils;
}

@Operation(
Expand All @@ -42,19 +47,12 @@ public GenerationCustomController(PassThrough passePlat, ReactiveControllerUtils
"You can get a parameters file by using the endpoint `/parameters/java/{context}/LUNATIC/{mode}`")
@PostMapping(value = "ddi-2-lunatic-json",
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<ResponseEntity<String>> generateLunaticCustomParams(
@RequestPart(value="in") Mono<FilePart> ddiFile,
@RequestPart(value="params") Mono<FilePart> parametersFile,
@Parameter(name = "specificTreatment", schema = @Schema(type="string", format="binary"))
@RequestPart(value="specificTreatment", required=false) Mono<Part> specificTreatment) {
/*
specificTreatment parameter is a part instead of a FilePart. This workaround is used to make swagger work
when empty value is checked for this input file on the endpoint.
When empty value is checked, swagger send no content-type nor filename for this multipart file. In this case,
Spring considers having a DefaultFormField object instead of FilePart and exceptions is thrown
There is no way at this moment to disable the allow empty value when filed is not required.
*/
return controllerUtils.ddiToLunaticJson(ddiFile, parametersFile, specificTreatment);
public ResponseEntity<String> generateLunaticCustomParams(
@RequestPart(value="in") MultipartFile ddiFile,
@RequestPart(value="params") MultipartFile parametersFile,
@RequestPart(value="specificTreatment", required=false) MultipartFile specificTreatment)
throws DDIToLunaticException, EnoControllerException, EnoParametersException, IOException {
return javaControllerUtils.ddiToLunaticJson(ddiFile, parametersFile, specificTreatment);
}

@Operation(
Expand All @@ -66,13 +64,24 @@ public Mono<ResponseEntity<String>> generateLunaticCustomParams(
"You can get a parameters file by using the endpoint `/parameters/xml/BUSINESS/XFORMS`")
@PostMapping(value = "ddi-2-xforms",
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<Void> generateXformsCustomParams(
@RequestPart(value="in") Mono<FilePart> in,
@RequestPart(value="params") Mono<FilePart> params,
@RequestPart(value="metadata") Mono<FilePart> metadata,
@RequestPart(value="specificTreatment", required=false) Mono<FilePart> specificTreatment,
ServerHttpRequest request, ServerHttpResponse response) {
return passePlat.passePlatPost(request, response);
public ResponseEntity<String> generateXformsCustomParams(
@RequestPart(value="in") MultipartFile in,
@RequestPart(value="params") MultipartFile params,
@RequestPart(value="metadata") MultipartFile metadata,
@RequestPart(value="specificTreatment", required=false) MultipartFile specificTreatment)
throws EnoControllerException {
//
MultipartBodyBuilder multipartBodyBuilder = new MultipartBodyBuilder();
addMultipartToBody(multipartBodyBuilder, in, "in");
addMultipartToBody(multipartBodyBuilder, params, "params");
if (metadata != null)
addMultipartToBody(multipartBodyBuilder, metadata, "metadata");
if (specificTreatment != null)
addMultipartToBody(multipartBodyBuilder, specificTreatment, "specificTreatment");
//
URI uri = xmlControllerUtils.newUriBuilder().path("questionnaire/ddi-2-xforms").build().toUri();
String outFilename = questionnaireFilename(OutFormat.XFORMS, false);
return xmlControllerUtils.sendPostRequest(uri, multipartBodyBuilder, outFilename);
}

@Operation(
Expand All @@ -84,13 +93,24 @@ public Mono<Void> generateXformsCustomParams(
"You can get a parameters file by using the endpoint `/parameters/xml/{context}/FO`")
@PostMapping(value = "ddi-2-fo",
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<Void> generateFOCustomParams(
@RequestPart(value="in") Mono<FilePart> in,
@RequestPart(value="params") Mono<FilePart> params,
@RequestPart(value="metadata") Mono<FilePart> metadata,
@RequestPart(value="specificTreatment", required=false) Mono<FilePart> specificTreatment,
ServerHttpRequest request, ServerHttpResponse response) {
return passePlat.passePlatPost(request, response);
public ResponseEntity<String> generateFOCustomParams(
@RequestPart(value="in") MultipartFile in,
@RequestPart(value="params") MultipartFile params,
@RequestPart(value="metadata") MultipartFile metadata,
@RequestPart(value="specificTreatment", required=false) MultipartFile specificTreatment)
throws EnoControllerException {
//
MultipartBodyBuilder multipartBodyBuilder = new MultipartBodyBuilder();
addMultipartToBody(multipartBodyBuilder, in, "in");
addMultipartToBody(multipartBodyBuilder, params, "params");
if (metadata != null)
addMultipartToBody(multipartBodyBuilder, metadata, "metadata");
if (specificTreatment != null)
addMultipartToBody(multipartBodyBuilder, specificTreatment, "specificTreatment");
//
URI uri = xmlControllerUtils.newUriBuilder().path("questionnaire/ddi-2-fo").build().toUri();
String outFilename = questionnaireFilename(OutFormat.XFORMS, false);
return xmlControllerUtils.sendPostRequest(uri, multipartBodyBuilder, outFilename);
}

}
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
package fr.insee.eno.ws.controller;

import fr.insee.eno.ws.PassThrough;
import fr.insee.eno.legacy.parameters.OutFormat;
import fr.insee.eno.ws.controller.utils.EnoXmlControllerUtils;
import fr.insee.eno.ws.exception.EnoControllerException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import reactor.core.publisher.Mono;
import org.springframework.web.multipart.MultipartFile;

import java.net.URI;

import static fr.insee.eno.ws.controller.utils.EnoXmlControllerUtils.addMultipartToBody;
import static fr.insee.eno.ws.controller.utils.EnoXmlControllerUtils.questionnaireFilename;

@Tag(name = "Generation from Pogues")
@Controller
Expand All @@ -21,10 +27,10 @@
@SuppressWarnings("unused")
public class GenerationPoguesController {

private final PassThrough passThrough;
private final EnoXmlControllerUtils xmlControllerUtils;

public GenerationPoguesController(PassThrough passThrough) {
this.passThrough = passThrough;
public GenerationPoguesController(EnoXmlControllerUtils xmlControllerUtils) {
this.xmlControllerUtils = xmlControllerUtils;
}

@Operation(
Expand All @@ -33,10 +39,15 @@ public GenerationPoguesController(PassThrough passThrough) {
"Generation of a DDI from a Pogues questionnaire (in the xml format).")
@PostMapping(value="poguesxml-2-ddi",
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<Void> generateDDIQuestionnaire(
@RequestPart(value="in") Mono<FilePart> in,
ServerHttpRequest request, ServerHttpResponse response) {
return passThrough.passePlatPost(request, response);
public ResponseEntity<String> generateDDIQuestionnaire(
@RequestPart(value="in") MultipartFile in) throws EnoControllerException {
//
MultipartBodyBuilder multipartBodyBuilder = new MultipartBodyBuilder();
addMultipartToBody(multipartBodyBuilder, in, "in");
//
URI uri = xmlControllerUtils.newUriBuilder().path("questionnaire/poguesxml-2-ddi").build().toUri();
String outFilename = questionnaireFilename(OutFormat.XFORMS, false);
return xmlControllerUtils.sendPostRequest(uri, multipartBodyBuilder, outFilename);
}

}
Loading

0 comments on commit 2066636

Please sign in to comment.