Compare commits

...

8 Commits

Author SHA1 Message Date
Denis Kazantsev 8b39e59c46 Moved properties, modified readMe 2022-04-08 18:19:51 +03:00
Denis Kazantsev 4b026ec78c Moved service, changed componentScan, refactored serverInfoAdvice 2022-04-08 18:08:14 +03:00
Denis Kazantsev aebc35ca3e Added readMe 2022-04-08 12:24:52 +03:00
Denis Kazantsev 9cfe8ee7ba Fixed test 2022-04-07 22:54:35 +03:00
Denis Kazantsev 66c99227b9 Added test 2022-04-07 22:53:11 +03:00
Denis Kazantsev 91e23327a2 Renamed annotation 2022-04-07 22:41:46 +03:00
Denis Kazantsev 9cb8099371 Renamed package, added annotations 2022-04-07 22:36:42 +03:00
Denis Kazantsev cffefac613 Added new module serverInfo 2022-04-07 21:40:12 +03:00
12 changed files with 186 additions and 0 deletions

View File

@ -199,3 +199,17 @@ Disables Spring OAuth2 resource server for testing.
## s3-storage
Amazon S3 support.
## server-info-spring-web
Allow include headers with information about the server in responses
To get started you need:
1) Add annotation to configuration
2) Add property to yml/properties file:
```
server.info:
buildVersion: ${buildVersion}
```
3) Implement ServerInfoService (optional. If you want to add other headers)
4) Add dir with impl ServerInfoService in ComponentScan annotation

View File

@ -0,0 +1,13 @@
plugins {
id("kotlin")
id("kotlin-spring")
id("maven-publish")
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.springframework.boot:spring-boot-starter-web")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}

View File

@ -0,0 +1,7 @@
package ru.touchin.server.info
import org.springframework.context.annotation.Import
import ru.touchin.server.info.configurations.ServerInfo
@Import(value = [ServerInfo::class])
annotation class EnableServerInfoHeaders

View File

@ -0,0 +1,43 @@
package ru.touchin.server.info.advices
import org.springframework.core.MethodParameter
import org.springframework.http.MediaType
import org.springframework.http.converter.HttpMessageConverter
import org.springframework.http.server.ServerHttpRequest
import org.springframework.http.server.ServerHttpResponse
import org.springframework.web.bind.annotation.RestControllerAdvice
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice
import ru.touchin.server.info.services.ServerInfoService
@RestControllerAdvice
class ServerInfoAdvice(
private val serverInfoService: List<ServerInfoService>
) : ResponseBodyAdvice<Any> {
override fun supports(
returnType: MethodParameter,
converterType: Class<out HttpMessageConverter<*>>
): Boolean {
return true
}
override fun beforeBodyWrite(
body: Any?,
returnType: MethodParameter,
selectedContentType: MediaType,
selectedConverterType: Class<out HttpMessageConverter<*>>,
request: ServerHttpRequest,
response: ServerHttpResponse
): Any? {
for (service in serverInfoService) {
response
.headers
.addAll(
service.getHeaders()
)
}
return body
}
}

View File

@ -0,0 +1,11 @@
package ru.touchin.server.info.configurations
import org.springframework.boot.context.properties.ConfigurationPropertiesScan
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
@Suppress("SpringFacetCodeInspection")
@Configuration
@ComponentScan("ru.touchin.server.info.advices")
@ConfigurationPropertiesScan("ru.touchin.server.info")
class ServerInfo

View File

@ -0,0 +1,9 @@
package ru.touchin.server.info.services
import org.springframework.util.MultiValueMap
interface ServerInfoService {
fun getHeaders(): MultiValueMap<String, String>
}

View File

@ -0,0 +1,21 @@
package ru.touchin.server.info.services.version
import org.springframework.stereotype.Service
import org.springframework.util.LinkedMultiValueMap
import org.springframework.util.MultiValueMap
import ru.touchin.server.info.services.version.properties.ServerInfoProperties
import ru.touchin.server.info.services.ServerInfoService
@Service
class BuildVersionServiceImpl(
private val serverInfoProperties: ServerInfoProperties
) : ServerInfoService {
override fun getHeaders(): MultiValueMap<String, String> {
return LinkedMultiValueMap<String, String>()
.apply {
this.add("X-App-Build-Version", serverInfoProperties.buildVersion)
}
}
}

View File

@ -0,0 +1,10 @@
package ru.touchin.server.info.services.version.properties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConstructorBinding
@ConstructorBinding
@ConfigurationProperties(prefix = "server.info")
data class ServerInfoProperties(
val buildVersion: String
)

View File

@ -0,0 +1,7 @@
package ru.touchin.server.info
import org.springframework.boot.autoconfigure.SpringBootApplication
@SpringBootApplication
@EnableServerInfoHeaders
class TestApplication

View File

@ -0,0 +1,48 @@
package ru.touchin.server.info.advices
import org.hamcrest.Matchers
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultHandlers
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/test")
class TestController {
@GetMapping()
fun wrap(): String {
return "ok"
}
}
@ActiveProfiles("test")
@SpringBootTest
@AutoConfigureMockMvc
internal class ServerInfoHeaderMvcTest {
@Autowired
private lateinit var mockMvc: MockMvc
@Test
@DisplayName("Результат должен иметь заголовок X-App-Build-Version")
fun shouldBeWrappedResponse() {
mockMvc
.perform(MockMvcRequestBuilders.get("/test"))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isOk)
.andExpect(MockMvcResultMatchers.header().exists("X-App-Build-Version"))
}
}

View File

@ -0,0 +1,2 @@
server.info:
buildVersion: 1

View File

@ -51,3 +51,4 @@ include("security-resource-server-custom-jwt-configuration")
include("security-resource-server-test-jwt-configuration")
include("security-jwt-common")
include("s3-storage")
include("server-info-spring-web")