Skip to content

Commit e8694b3

Browse files
feat: add profile-aware endpoint for swagger/openapi URL
Agent-Logs-Url: https://github.com/conorheffron/ironoc/sessions/40192244-9ac4-4d16-9a96-7c8b085fdb31 Co-authored-by: conorheffron <8218626+conorheffron@users.noreply.github.com>
1 parent 5ff66cf commit e8694b3

2 files changed

Lines changed: 71 additions & 1 deletion

File tree

src/main/java/net/ironoc/portfolio/controller/VersionController.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,35 @@
11
package net.ironoc.portfolio.controller;
22

3+
import module java.base;
4+
35
import io.swagger.v3.oas.annotations.Operation;
46
import io.swagger.v3.oas.annotations.responses.ApiResponse;
57
import io.swagger.v3.oas.annotations.responses.ApiResponses;
8+
import jakarta.servlet.http.HttpServletRequest;
69
import org.springframework.beans.factory.annotation.Autowired;
710
import org.springframework.boot.info.BuildProperties;
11+
import org.springframework.core.env.Environment;
812
import org.springframework.http.MediaType;
913
import org.springframework.web.bind.annotation.GetMapping;
1014
import org.springframework.web.bind.annotation.RequestMapping;
1115
import org.springframework.web.bind.annotation.RestController;
16+
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
1217

1318
@RestController
1419
@RequestMapping("/api")
1520
public class VersionController {
1621

22+
private static final String PROD_PROFILE = "prod";
23+
private static final String OPEN_API_PATH = "/api-docs";
24+
private static final String SWAGGER_UI_PATH = "/swagger-ui-ironoc.html";
25+
1726
private final BuildProperties buildProperties;
27+
private final Environment environment;
1828

19-
public VersionController(@Autowired BuildProperties buildProperties) {
29+
public VersionController(@Autowired BuildProperties buildProperties,
30+
@Autowired Environment environment) {
2031
this.buildProperties = buildProperties;
32+
this.environment = environment;
2133
}
2234

2335
@Operation(summary = "Get ironoc Application Version",
@@ -30,4 +42,23 @@ public VersionController(@Autowired BuildProperties buildProperties) {
3042
public String getApplicationVersion() {
3143
return "Version: " + this.buildProperties.getVersion();
3244
}
45+
46+
@Operation(summary = "Get iRonoc API documentation endpoint",
47+
description = "Returns the fully qualified Swagger/OpenAPI documentation URL based on the active run profile")
48+
@ApiResponses(value = {
49+
@ApiResponse(responseCode = "200",
50+
description = "Successfully retrieved iRonoc API documentation endpoint.")
51+
})
52+
@GetMapping(value = {"/application/openapi-endpoint"}, produces= MediaType.TEXT_PLAIN_VALUE)
53+
public String getOpenApiDocumentationEndpoint(HttpServletRequest request) {
54+
String endpointPath = isProdProfileActive() ? OPEN_API_PATH : SWAGGER_UI_PATH;
55+
return ServletUriComponentsBuilder.fromContextPath(request)
56+
.path(endpointPath)
57+
.toUriString();
58+
}
59+
60+
private boolean isProdProfileActive() {
61+
return Arrays.stream(environment.getActiveProfiles())
62+
.anyMatch(PROD_PROFILE::equalsIgnoreCase);
63+
}
3364
}

src/test/java/net/ironoc/portfolio/controller/VersionControllerTest.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import org.mockito.Mock;
99
import org.mockito.junit.jupiter.MockitoExtension;
1010
import org.springframework.boot.info.BuildProperties;
11+
import org.springframework.core.env.Environment;
12+
import org.springframework.mock.web.MockHttpServletRequest;
1113

1214
import static org.hamcrest.MatcherAssert.assertThat;
1315
import static org.hamcrest.Matchers.is;
@@ -22,6 +24,9 @@ public class VersionControllerTest {
2224
@Mock
2325
private BuildProperties buildPropertiesMock;
2426

27+
@Mock
28+
private Environment environmentMock;
29+
2530
@InjectMocks
2631
private VersionController versionController;
2732

@@ -38,4 +43,38 @@ public void test_getApplicationVersion_success() {
3843

3944
assertThat(response, is("Version: " + TEST_VERSION));
4045
}
46+
47+
@Test
48+
public void test_getOpenApiDocumentationEndpoint_nonProdProfile_success() {
49+
// given
50+
when(environmentMock.getActiveProfiles()).thenReturn(new String[]{"dev"});
51+
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/api/application/openapi-endpoint");
52+
request.setScheme("http");
53+
request.setServerName("localhost");
54+
request.setServerPort(8080);
55+
56+
// when
57+
String response = versionController.getOpenApiDocumentationEndpoint(request);
58+
59+
// then
60+
verify(environmentMock).getActiveProfiles();
61+
assertThat(response, is("http://localhost:8080/swagger-ui-ironoc.html"));
62+
}
63+
64+
@Test
65+
public void test_getOpenApiDocumentationEndpoint_prodProfile_success() {
66+
// given
67+
when(environmentMock.getActiveProfiles()).thenReturn(new String[]{"prod"});
68+
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/api/application/openapi-endpoint");
69+
request.setScheme("https");
70+
request.setServerName("ironoc.net");
71+
request.setServerPort(443);
72+
73+
// when
74+
String response = versionController.getOpenApiDocumentationEndpoint(request);
75+
76+
// then
77+
verify(environmentMock).getActiveProfiles();
78+
assertThat(response, is("https://ironoc.net/api-docs"));
79+
}
4180
}

0 commit comments

Comments
 (0)