Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(openapi)!: add health endpoint to openapi #2709

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@

package org.eclipse.sw360.rest.resourceserver;

import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.media.MediaType;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import org.eclipse.sw360.datahandler.common.CommonUtils;
Expand All @@ -25,6 +32,7 @@
import org.eclipse.sw360.rest.resourceserver.security.apiToken.ApiTokenAuthenticationFilter;
import org.springdoc.core.utils.SpringDocUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
Expand All @@ -45,7 +53,7 @@
@Import(Sw360CORSFilter.class)
public class Sw360ResourceServer extends SpringBootServletInitializer {

private static final String REST_BASE_PATH = "/api";
public static final String REST_BASE_PATH = "/api";

@Value("${spring.data.rest.default-page-size:10}")
private int defaultPageSize;
Expand Down Expand Up @@ -168,6 +176,36 @@ public OpenAPI customOpenAPI() {
.info(new Info().title("SW360 API").license(new License().name("EPL-2.0")
.url("https://github.com/eclipse-sw360/sw360/blob/main/LICENSE"))
.version(restVersionString))
.servers(List.of(server));
.servers(List.of(server))
.path("/health", new PathItem().get(
new Operation().tags(Collections.singletonList("Health"))
.summary("Health endpoint").operationId("health")
.responses(new ApiResponses().addApiResponse("200",
new ApiResponse().description("OK")
.content(new Content()
.addMediaType("application/json", new MediaType()
.example("""
{
"status": "UP",
"components": {
"SW360Rest": {
"status": "UP",
"details": {
"Rest State": {
"isDbReachable": true,
"isThriftReachable": true
}
}
},
"ping": {
"status": "UP"
}
}
}
""")
.schema(new Schema<Health>())
))
))
));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3264,7 +3264,7 @@ public ResponseEntity<?> createDuplicateProjectWithDependencyNetwork(
if (reqBodyMap.get("dependencyNetwork") != null) {
try {
addOrPatchDependencyNetworkToProject(duplicatedProject, reqBodyMap, ProjectOperation.CREATE);
} catch (JsonProcessingException | NoSuchElementException | InvalidPropertiesFormatException e) {
} catch (JsonProcessingException | NoSuchElementException e) {
log.error(e.getMessage());
return ResponseEntity.badRequest().body(e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ public class ResourceServerConfiguration {

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers("/", "/*/*.html", "/*/*.css", "/*/*.js", "/*.js", "/*.json", "/*/*.json", "/*/*.png", "/*/*.gif", "/*/*.ico", "/*/*.woff/*", "/*/*.ttf", "/*/*.html", "/*/*/*.html", "/*/*.yaml", "/v3/api-docs/**");
return (web) -> web.ignoring().requestMatchers("/", "/*/*.html", "/*/*.css", "/*/*.js", "/*.js", "/*.json",
"/*/*.json", "/*/*.png", "/*/*.gif", "/*/*.ico", "/*/*.woff/*", "/*/*.ttf", "/*/*.html", "/*/*/*.html",
"/*/*.yaml", "/v3/api-docs/**", "/api/health", "/api/info");
}

@Bean
Expand All @@ -80,8 +82,8 @@ public SecurityFilterChain securityFilterChainRS1(HttpSecurity http) throws Exce
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
SimpleAuthenticationEntryPoint saep = new SimpleAuthenticationEntryPoint();
return http.addFilterBefore(filter, BasicAuthenticationFilter.class).authorizeHttpRequests(auth -> {
auth.requestMatchers(HttpMethod.GET, "/health").permitAll();
auth.requestMatchers(HttpMethod.GET, "/info").hasAuthority("WRITE");
auth.requestMatchers(HttpMethod.GET, "/api/health").permitAll();
auth.requestMatchers(HttpMethod.GET, "/api/info").hasAuthority("WRITE");
auth.requestMatchers(HttpMethod.GET, "/api").permitAll();
auth.requestMatchers(HttpMethod.GET, "/api/reports/download").permitAll();
auth.requestMatchers(HttpMethod.GET, "/api/**").hasAuthority("READ");
Expand Down
10 changes: 9 additions & 1 deletion rest/resource-server/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ management:
base-path: /
exposure:
include: health,info
path-mapping:
health: /api/health
info: /api/info
endpoint:
health:
show-details: always
Expand All @@ -28,6 +31,11 @@ management:
enabled: true
security:
enabled: true
health:
diskspace:
enabled: true # Disable to hide sensitive system information
ping:
enabled: true

spring:
application:
Expand Down Expand Up @@ -83,4 +91,4 @@ springdoc:
enabled: true
default-consumes-media-type: application/json
default-produces-media-type: application/hal+json
paths-to-exclude: /api/**
paths-to-exclude: /api/**
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public class SW360RestHealthIndicatorTest {
*/
private ResponseEntity<Map> getMapResponseEntityForHealthEndpointRequest(String endpoint) {
return this.testRestTemplate.getForEntity(
"http://localhost:" + this.port + endpoint, Map.class);
"http://localhost:" + this.port + Sw360ResourceServer.REST_BASE_PATH + endpoint, Map.class);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public SecurityFilterChain appSecurtiy(HttpSecurity httpSecurity) throws Excepti
SimpleAuthenticationEntryPoint saep = new SimpleAuthenticationEntryPoint();
httpSecurity.authorizeHttpRequests(
authz -> authz
.requestMatchers(HttpMethod.GET, "/health").permitAll()
.requestMatchers(HttpMethod.GET, "/info").permitAll()
.requestMatchers(HttpMethod.GET, "/api/health").permitAll()
.requestMatchers(HttpMethod.GET, "/api/info").permitAll()
.anyRequest().authenticated()
).httpBasic(Customizer.withDefaults()).formLogin(Customizer.withDefaults())
.exceptionHandling(x -> x.authenticationEntryPoint(saep));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public void should_document_get_health() throws Exception {
given(this.restHealthIndicatorMock.health()).willReturn(spring_health);


mockMvc.perform(get("/health")
mockMvc.perform(get("/api/health")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(this.documentationHandler.document(
Expand Down Expand Up @@ -72,7 +72,7 @@ public void should_document_get_health_unhealthy() throws Exception {
.build();
given(this.restHealthIndicatorMock.health()).willReturn(spring_health_down);

mockMvc.perform(get("/health")
mockMvc.perform(get("/api/health")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().is2xxSuccessful())
.andDo(this.documentationHandler.document(
Expand Down
41 changes: 25 additions & 16 deletions rest/resource-server/src/test/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
#SPDX-FileCopyrightText: © 2024 Siemens AG
#SPDX-License-Identifier: EPL-2.0

spring:
profiles:
active: SECURITY_MOCK
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8080/authorization/oauth2/jwks
jwk-set-uri: http://localhost:8080/authorization/oauth2/jwks
application:
name: resource
server:
servlet:
multipart:
max-file-size: 500MB
max-request-size: 600MB
context-path: /

management:
endpoints:
web:
base-path: /
exposure:
include: health,info
path-mapping:
health: /api/health
info: /api/info
endpoint:
health:
show-details: always
Expand All @@ -31,9 +22,27 @@ management:
enabled: true
security:
enabled: true
server:
health:
diskspace:
enabled: true # Disable to hide sensitive system information
ping:
enabled: true

spring:
profiles:
active: SECURITY_MOCK
application:
name: resource
servlet:
context-path: /
multipart:
max-file-size: 500MB
max-request-size: 600MB
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8080/authorization/oauth2/jwks
jwk-set-uri: http://localhost:8080/authorization/oauth2/jwks

#logging:
# level:
Expand Down