Skip to content

Commit

Permalink
Fix set site settings in swagger_ui so it function correctly.
Browse files Browse the repository at this point in the history
Prior to this fix, the swagger ui for applying site settings was not working.
  • Loading branch information
ianwallen committed Dec 25, 2024
1 parent 490e6b9 commit c9e0ae9
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 14 deletions.
67 changes: 55 additions & 12 deletions services/src/main/java/org/fao/geonet/api/site/SiteApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@

import co.elastic.clients.elasticsearch.core.CountRequest;
import co.elastic.clients.elasticsearch.core.CountResponse;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
Expand Down Expand Up @@ -88,10 +91,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.*;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -387,24 +387,67 @@ public List<Setting> getSettingsDetails(

@io.swagger.v3.oas.annotations.Operation(
summary = "Save settings",
description = "")
@RequestMapping(
description = "Save the provided settings.",
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "Map of settings to be saved",
required = true,
content = {
@Content(
mediaType = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
schema = @Schema(implementation = Map.class),
examples = {
@ExampleObject(
name = "Example setting (application/x-www-form-urlencoded)",
value = "{\n \"additionalProp1\": \"string\",\n \"additionalProp2\": \"string\",\n \"additionalProp3\": \"string\"\n}"
),
@ExampleObject(
name = "Example setting selection manager max records to 1000 (application/x-www-form-urlencoded)",
value = "{\n \"system/selectionmanager/maxrecords\": \"1000\"\n}"
)
}
),
@Content(
mediaType = MediaType.APPLICATION_JSON_VALUE,
schema = @Schema(implementation = Map.class),
examples = {
@ExampleObject(
name = "Example setting (application/json)",
value = "{\n \"additionalProp1\": \"string\",\n \"additionalProp2\": \"string\",\n \"additionalProp3\": \"string\"\n}"
),
@ExampleObject(
name = "Example setting selection manager max records to 1000 (application/json)",
value = "{\n \"system/selectionmanager/maxrecords\": \"1000\"\n}"
)
}
)
}
)
)
@PostMapping(
path = "/settings",
produces = MediaType.APPLICATION_JSON_VALUE,
method = RequestMethod.POST
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.APPLICATION_JSON_VALUE}
)
@PreAuthorize("hasAuthority('Administrator')")
@ResponseStatus(HttpStatus.NO_CONTENT)
@ApiResponses(value = {
@ApiResponse(responseCode = "204", description = "Settings saved.", content = {@Content(schema = @Schema(hidden = true))}),
@ApiResponse(responseCode = "204", description = "Settings saved."),
@ApiResponse(responseCode = "403", description = ApiParams.API_RESPONSE_NOT_ALLOWED_ONLY_ADMIN)
})
public void saveSettings(
@Parameter(hidden = false)
@RequestParam
Map<String, String> allRequestParams,
// Mark parameter as hidden in open api specification as the Operation requestBody(above) will describe the format to be supplied
// Without this fix, the swagger ui will fail to work correctly.
@Parameter(description = "Map of settings to be saved",
required = true, hidden = true)
@RequestParam Map<String, String> allRequestParams,
HttpServletRequest request
) throws Exception {
//If sent as JSON then the allRequestParams will be empty, and we need to manually load it from the request body
if (MediaType.APPLICATION_JSON_VALUE.equals(request.getContentType()) && allRequestParams.isEmpty()) {
BufferedReader reader = request.getReader();
ObjectMapper mapper = new ObjectMapper();
allRequestParams = mapper.readValue(reader, new TypeReference<Map<String, String>>() {});
}

ApplicationContext applicationContext = ApplicationContextHolder.get();
String currentUuid = settingManager.getSiteId();
String oldSiteName = settingManager.getSiteName();
Expand Down
36 changes: 34 additions & 2 deletions services/src/test/java/org/fao/geonet/api/site/SiteApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public void getSettingsSet() throws Exception {


@Test
public void updateSettings() throws Exception {
public void updateSettingsFormUrlEncoded() throws Exception {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();

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

String newName = "DataHub";
this.mockMvc.perform(post("/srv/api/site/settings")
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.param("system/site/name", newName)
.session(this.mockHttpSession))
.andExpect(status().is(204))
.andExpect(content().string("")); // No content should be returned.

this.mockMvc.perform(get("/srv/api/site/settings")
.session(this.mockHttpSession)
.accept(MediaType.parseMediaType("application/json")))
.andExpect(status().is(204));
.andExpect(status().isOk())
.andExpect(content().contentType(API_JSON_EXPECTED_ENCODING))
.andExpect(jsonPath("$['system/site/name']", is(newName)));
}

@Test
public void updateSettingsJson() throws Exception {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();

this.mockHttpSession = loginAsAdmin();

encryptor.initialize();

this.mockMvc.perform(get("/srv/api/site/settings")
.session(this.mockHttpSession)
.accept(MediaType.parseMediaType("application/json")))
.andExpect(status().isOk())
.andExpect(content().contentType(API_JSON_EXPECTED_ENCODING))
.andExpect(jsonPath("$['system/site/name']", is("My GeoNetwork catalogue")));

String newName = "JsonDataHub";
this.mockMvc.perform(post("/srv/api/site/settings")
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content("{\"system/site/name\": \"" + newName + "\"}")
.session(this.mockHttpSession))
.andExpect(status().is(204))
.andExpect(content().string("")); // No content should be returned.

this.mockMvc.perform(get("/srv/api/site/settings")
.session(this.mockHttpSession)
Expand Down

0 comments on commit c9e0ae9

Please sign in to comment.