Skip to content

Commit 54ad35f

Browse files
Fix set site settings in swagger_ui so it function correctly. (#8582) (#8589)
Prior to this fix, the swagger ui for applying site settings was not working. (cherry picked from commit 21f0dc8) Co-authored-by: Ian <[email protected]>
1 parent fb73d28 commit 54ad35f

File tree

2 files changed

+90
-13
lines changed

2 files changed

+90
-13
lines changed

services/src/main/java/org/fao/geonet/api/site/SiteApi.java

+56-11
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@
2323

2424
package org.fao.geonet.api.site;
2525

26+
import com.fasterxml.jackson.core.type.TypeReference;
27+
import com.fasterxml.jackson.databind.ObjectMapper;
2628
import io.swagger.v3.oas.annotations.Parameter;
29+
import io.swagger.v3.oas.annotations.media.Content;
30+
import io.swagger.v3.oas.annotations.media.ExampleObject;
31+
import io.swagger.v3.oas.annotations.media.Schema;
2732
import io.swagger.v3.oas.annotations.responses.ApiResponse;
2833
import io.swagger.v3.oas.annotations.responses.ApiResponses;
2934
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -90,10 +95,7 @@
9095
import javax.servlet.http.HttpServletRequest;
9196
import javax.servlet.http.HttpSession;
9297
import java.awt.image.BufferedImage;
93-
import java.io.File;
94-
import java.io.IOException;
95-
import java.io.InputStream;
96-
import java.io.OutputStream;
98+
import java.io.*;
9799
import java.nio.file.DirectoryStream;
98100
import java.nio.file.Files;
99101
import java.nio.file.Path;
@@ -391,11 +393,45 @@ public List<Setting> getSettingsDetails(
391393

392394
@io.swagger.v3.oas.annotations.Operation(
393395
summary = "Save settings",
394-
description = "")
395-
@RequestMapping(
396+
description = "Save the provided settings.",
397+
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
398+
description = "Map of settings to be saved",
399+
required = true,
400+
content = {
401+
@Content(
402+
mediaType = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
403+
schema = @Schema(implementation = Map.class),
404+
examples = {
405+
@ExampleObject(
406+
name = "Example setting (application/x-www-form-urlencoded)",
407+
value = "{\n \"additionalProp1\": \"string\",\n \"additionalProp2\": \"string\",\n \"additionalProp3\": \"string\"\n}"
408+
),
409+
@ExampleObject(
410+
name = "Example setting selection manager max records to 1000 (application/x-www-form-urlencoded)",
411+
value = "{\n \"system/selectionmanager/maxrecords\": \"1000\"\n}"
412+
)
413+
}
414+
),
415+
@Content(
416+
mediaType = MediaType.APPLICATION_JSON_VALUE,
417+
schema = @Schema(implementation = Map.class),
418+
examples = {
419+
@ExampleObject(
420+
name = "Example setting (application/json)",
421+
value = "{\n \"additionalProp1\": \"string\",\n \"additionalProp2\": \"string\",\n \"additionalProp3\": \"string\"\n}"
422+
),
423+
@ExampleObject(
424+
name = "Example setting selection manager max records to 1000 (application/json)",
425+
value = "{\n \"system/selectionmanager/maxrecords\": \"1000\"\n}"
426+
)
427+
}
428+
)
429+
}
430+
)
431+
)
432+
@PostMapping(
396433
path = "/settings",
397-
produces = MediaType.APPLICATION_JSON_VALUE,
398-
method = RequestMethod.POST
434+
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.APPLICATION_JSON_VALUE}
399435
)
400436
@PreAuthorize("hasAuthority('Administrator')")
401437
@ResponseStatus(HttpStatus.NO_CONTENT)
@@ -404,11 +440,20 @@ public List<Setting> getSettingsDetails(
404440
@ApiResponse(responseCode = "403", description = ApiParams.API_RESPONSE_NOT_ALLOWED_ONLY_ADMIN)
405441
})
406442
public void saveSettings(
407-
@Parameter(hidden = false)
408-
@RequestParam
409-
Map<String, String> allRequestParams,
443+
// Mark parameter as hidden in open api specification as the Operation requestBody(above) will describe the format to be supplied
444+
// Without this fix, the swagger ui will fail to work correctly.
445+
@Parameter(description = "Map of settings to be saved",
446+
required = true, hidden = true)
447+
@RequestParam Map<String, String> allRequestParams,
410448
HttpServletRequest request
411449
) throws Exception {
450+
//If sent as JSON then the allRequestParams will be empty, and we need to manually load it from the request body
451+
if (MediaType.APPLICATION_JSON_VALUE.equals(request.getContentType()) && allRequestParams.isEmpty()) {
452+
BufferedReader reader = request.getReader();
453+
ObjectMapper mapper = new ObjectMapper();
454+
allRequestParams = mapper.readValue(reader, new TypeReference<Map<String, String>>() {});
455+
}
456+
412457
ApplicationContext applicationContext = ApplicationContextHolder.get();
413458
String currentUuid = settingManager.getSiteId();
414459
String oldSiteName = settingManager.getSiteName();

services/src/test/java/org/fao/geonet/api/site/SiteApiTest.java

+34-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public void getSettingsSet() throws Exception {
6262

6363

6464
@Test
65-
public void updateSettings() throws Exception {
65+
public void updateSettingsFormUrlEncoded() throws Exception {
6666
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
6767

6868
this.mockHttpSession = loginAsAdmin();
@@ -78,10 +78,42 @@ public void updateSettings() throws Exception {
7878

7979
String newName = "DataHub";
8080
this.mockMvc.perform(post("/srv/api/site/settings")
81+
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
8182
.param("system/site/name", newName)
83+
.session(this.mockHttpSession))
84+
.andExpect(status().is(204))
85+
.andExpect(content().string("")); // No content should be returned.
86+
87+
this.mockMvc.perform(get("/srv/api/site/settings")
8288
.session(this.mockHttpSession)
8389
.accept(MediaType.parseMediaType("application/json")))
84-
.andExpect(status().is(204));
90+
.andExpect(status().isOk())
91+
.andExpect(content().contentType(API_JSON_EXPECTED_ENCODING))
92+
.andExpect(jsonPath("$['system/site/name']", is(newName)));
93+
}
94+
95+
@Test
96+
public void updateSettingsJson() throws Exception {
97+
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
98+
99+
this.mockHttpSession = loginAsAdmin();
100+
101+
encryptor.initialize();
102+
103+
this.mockMvc.perform(get("/srv/api/site/settings")
104+
.session(this.mockHttpSession)
105+
.accept(MediaType.parseMediaType("application/json")))
106+
.andExpect(status().isOk())
107+
.andExpect(content().contentType(API_JSON_EXPECTED_ENCODING))
108+
.andExpect(jsonPath("$['system/site/name']", is("My GeoNetwork catalogue")));
109+
110+
String newName = "JsonDataHub";
111+
this.mockMvc.perform(post("/srv/api/site/settings")
112+
.contentType(MediaType.APPLICATION_JSON_VALUE)
113+
.content("{\"system/site/name\": \"" + newName + "\"}")
114+
.session(this.mockHttpSession))
115+
.andExpect(status().is(204))
116+
.andExpect(content().string("")); // No content should be returned.
85117

86118
this.mockMvc.perform(get("/srv/api/site/settings")
87119
.session(this.mockHttpSession)

0 commit comments

Comments
 (0)