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

Refactor code and fix bugs on payload #5

Draft
wants to merge 6 commits into
base: feat/kotlin-migration
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
# Indexes for parallel jobs (starting from zero).
# E.g. use [0, 1] for 2 parallel jobs, [0, 1, 2] for 3 parallel jobs, etc.
#ci_node_index: [0, 1, 2, 3, 4, 5, 6, 7]
java-version: ['11', '17', '21']
java-version: ['17', '21']

env:
TZ: "Europe/Ireland"
Expand Down
2 changes: 1 addition & 1 deletion examples/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
id("org.springframework.boot") version "3.1.3"
id("io.spring.dependency-management") version "1.1.2"
kotlin("jvm") version "1.6.10"
kotlin("jvm") version "1.8.20"
}

group = "com.github.firetail-io"
Expand Down
6 changes: 6 additions & 0 deletions examples/src/main/java/com/example/demo/DemoApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.Clock;
Expand All @@ -23,4 +24,9 @@ public static void main(String[] args) {
public String hello() {
return String.format("Hello %s, utc: %s!", LocalDateTime.now(), ZonedDateTime.now(Clock.systemUTC()));
}

@PostMapping("/hello")
public String helloPost() {
return String.format("Hello %s, utc: %s!", LocalDateTime.now(), ZonedDateTime.now(Clock.systemUTC()));
}
}
178 changes: 0 additions & 178 deletions pom.xml

This file was deleted.

2 changes: 1 addition & 1 deletion src/main/kotlin/io/firetail/logging/core/FiretailLogger.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ class FiretailLogger (val firetailConfig: FiretailConfig) {
companion object {
val LOGGER = LoggerFactory.getLogger(FiretailLogger::class.java)
}
}
}
12 changes: 11 additions & 1 deletion src/main/kotlin/io/firetail/logging/servlet/FiretailFilter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.springframework.web.method.HandlerMethod
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
import java.util.*
import java.util.concurrent.CompletableFuture
import java.nio.charset.Charset

@Service
@ConditionalOnClass(FiretailConfig::class)
Expand All @@ -31,6 +32,7 @@ class FiretailFilter(
private val firetailConfig: FiretailConfig,
private val firetailMapper: FiretailMapper,
) {

@Autowired
private lateinit var firetailBuffer: FiretailBuffer

Expand Down Expand Up @@ -58,19 +60,27 @@ class FiretailFilter(
val startTime = System.currentTimeMillis()
val wrappedRequest = SpringRequestWrapper(request)
firetailLogger.logRequest(wrappedRequest)
val wrappedResponse = SpringResponseWrapper(response)
val wrappedResponse = SpringResponseWrapper(response)
try {
with(wrappedResponse) {
setHeader(REQUEST_ID, firetailLogContext.get(REQUEST_ID))
setHeader(CORRELATION_ID, firetailLogContext.get(CORRELATION_ID))
}

chain.doFilter(wrappedRequest, wrappedResponse)

val charset: Charset = Charsets.UTF_8
val responseArray: ByteArray = wrappedResponse.contentAsByteArray
val responseBody: String = responseArray.toString(charset)
wrappedResponse.copyBodyToResponse()

val duration = System.currentTimeMillis() - startTime
firetailLogger.logResponse(wrappedResponse, duration = duration)
val firetailLog =
firetailMapper.from(
wrappedRequest,
wrappedResponse,
responseBody,
duration,
)
CompletableFuture.runAsync {
Expand Down
13 changes: 9 additions & 4 deletions src/main/kotlin/io/firetail/logging/servlet/FiretailMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import io.firetail.logging.core.FtResponse
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import java.util.HashMap
import java.io.StringWriter
import java.io.InputStreamReader

class FiretailMapper {
private val objectMapper = ObjectMapper()
fun from(request: HttpServletRequest, response: HttpServletResponse, executionTime: Long): FiretailData {
return FiretailData(request = from(request), response = from(response), executionTime = executionTime.toInt())
fun from(request: HttpServletRequest, response: HttpServletResponse, responseBody: String, executionTime: Long): FiretailData {
return FiretailData(request = from(request), response = from(response, responseBody), executionTime = executionTime.toInt())
}

fun from(request: HttpServletRequest): FtRequest {
Expand All @@ -20,23 +22,26 @@ class FiretailMapper {
.mapIndexed { _, value -> value to listOf(request.getHeader(value)) }
.toMap()

val body = request.inputStream.bufferedReader().use { it.readText() }
return FtRequest(
httpProtocol = request.protocol,
method = request.method,
headers = headers,
body = body,
ip = request.remoteAddr,
resource = request.requestURI,
uri = request.requestURL.toString(), // FT calls the defines the URI as URL.
)
}

fun from(response: HttpServletResponse): FtResponse {
fun from(response: HttpServletResponse, body: String): FtResponse {
val headers = response.headerNames
.mapIndexed { _, value -> value to listOf(response.getHeader(value)) }
.toMap()

return FtResponse(
statusCode = response.status,
body = "",
body = body,
headers = headers,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,10 @@ import jakarta.servlet.http.HttpServletResponseWrapper
import java.io.OutputStreamWriter
import java.io.PrintWriter
import java.util.function.Consumer
import org.springframework.web.util.ContentCachingResponseWrapper

class SpringResponseWrapper(response: HttpServletResponse?) : HttpServletResponseWrapper(response) {
private var outputStream: ServletOutputStream? = null
private var writer: PrintWriter? = null
private var copier: ServletOutputStreamWrapper? = null
class SpringResponseWrapper(response: HttpServletResponse) : ContentCachingResponseWrapper(response) {

override fun getOutputStream(): ServletOutputStream {
check(writer == null) { "getWriter() has already been called on this response." }
copier = ServletOutputStreamWrapper(response.outputStream)
return copier!!
}

override fun getWriter(): PrintWriter {
check(outputStream == null) { "getOutputStream() has already been called on this response." }
if (writer == null) {
copier = ServletOutputStreamWrapper(response.outputStream)
writer = PrintWriter(OutputStreamWriter(copier!!, response.characterEncoding), true)
}
return writer!!
}

override fun flushBuffer() {
if (writer != null) {
writer!!.flush()
} else if (outputStream != null) {
copier!!.flush()
}
}

val contentAsByteArray: ByteArray
get() = if (copier != null) {
copier!!.getCopy()
} else {
empty
}
val allHeaders: Map<String, String>
get() {
val headers: MutableMap<String, String> = HashMap()
Expand Down
34 changes: 0 additions & 34 deletions src/test/kotlin/io/firetail/logging/FiretailMapperTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,6 @@ import java.util.*

class FiretailMapperTest {

private val firetailMapper = FiretailMapper()

@Test
fun fromResponse() {
val mockResponse: HttpServletResponse = Mockito.mock(HttpServletResponse::class.java)
Mockito.`when`(mockResponse.headerNames).thenReturn(listOf(TEST))
Mockito.`when`(mockResponse.getHeader(TEST)).thenReturn(TEST_RESULTS)
val result = firetailMapper.from(mockResponse)
Assertions.assertThat(result.headers)
.isNotNull
.hasFieldOrPropertyWithValue(TEST, listOf(TEST_RESULTS))
}

@Test
fun fromRequest() {
val mockRequest: HttpServletRequest = Mockito.mock(HttpServletRequest::class.java)

Mockito.`when`(mockRequest.protocol).thenReturn("HTTP")
Mockito.`when`(mockRequest.method).thenReturn("GET")
Mockito.`when`(mockRequest.requestURI).thenReturn("/")
Mockito.`when`(mockRequest.requestURL).thenReturn(StringBuffer().append("http://blah.com"))
Mockito.`when`(mockRequest.remoteAddr).thenReturn("127.0.0.1")
Mockito.`when`(mockRequest.queryString).thenReturn("123")
Mockito.`when`(mockRequest.getHeader(TEST)).thenReturn(TEST_RESULTS)
Mockito.`when`(mockRequest.headerNames)
.thenReturn(Collections.enumeration(Collections.singletonList(TEST)))

val result = firetailMapper.from(mockRequest)

Assertions.assertThat(result.headers)
.isNotNull
.hasFieldOrPropertyWithValue(TEST, listOf(TEST_RESULTS))
}

@Test
fun jsonNd() {
val firetailMapper = FiretailMapper()
Expand Down
Loading