From fcdd0058aa936db64171027f22db7a6e3a4cae33 Mon Sep 17 00:00:00 2001 From: Oleg Smelov Date: Fri, 2 Jun 2023 03:03:15 +0400 Subject: [PATCH 01/19] th2 transport protocol support --- build.gradle | 6 +- .../th2/codec/http/HttpPipelineCodec.kt | 222 ++++++++++++++++-- .../com/exactpro/th2/codec/http/DecodeTest.kt | 114 ++++++++- .../com/exactpro/th2/codec/http/EncodeTest.kt | 74 +++++- 4 files changed, 367 insertions(+), 49 deletions(-) diff --git a/build.gradle b/build.gradle index 9c8567b..c452d1b 100644 --- a/build.gradle +++ b/build.gradle @@ -96,10 +96,10 @@ jar { } dependencies { - api platform('com.exactpro.th2:bom:4.1.0') + api platform('com.exactpro.th2:bom:4.2.0') - implementation 'com.exactpro.th2:common:5.1.0-dev-version-5+' - implementation 'com.exactpro.th2:codec:5.0.0-dev-version-5+' + implementation 'com.exactpro.th2:common:5.3.0-json-raw-body-5144283961-5ae02cd-SNAPSHOT' + implementation 'com.exactpro.th2:codec:5.2.0-new-proto-5111859401-e24c7b8-SNAPSHOT' implementation 'com.exactpro.th2:sailfish-utils:3.14.0' diff --git a/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt b/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt index 762283c..7061a21 100644 --- a/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt +++ b/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 Exactpro (Exactpro Systems Limited) + * Copyright 2020-2023 Exactpro (Exactpro Systems Limited) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,20 +23,21 @@ import com.exactpro.th2.common.grpc.AnyMessage.KindCase.RAW_MESSAGE import com.exactpro.th2.common.grpc.Direction.FIRST import com.exactpro.th2.common.grpc.Direction.SECOND import com.exactpro.th2.common.grpc.EventID -import com.exactpro.th2.common.grpc.Message -import com.exactpro.th2.common.grpc.MessageGroup +import com.exactpro.th2.common.grpc.Message as ProtoMessage +import com.exactpro.th2.common.grpc.MessageGroup as ProtoMessageGroup import com.exactpro.th2.common.grpc.MessageID -import com.exactpro.th2.common.grpc.RawMessage +import com.exactpro.th2.common.grpc.RawMessage as ProtoRawMessage import com.exactpro.th2.common.grpc.Value import com.exactpro.th2.common.grpc.Value.KindCase.LIST_VALUE import com.exactpro.th2.common.grpc.Value.KindCase.MESSAGE_VALUE import com.exactpro.th2.common.grpc.Value.KindCase.SIMPLE_VALUE import com.exactpro.th2.common.message.addField import com.exactpro.th2.common.message.plusAssign +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.* import com.exactpro.th2.common.value.toValue import com.google.protobuf.ByteString import com.google.protobuf.MessageLite.Builder -import com.google.protobuf.Timestamp +import io.netty.buffer.Unpooled import rawhttp.core.HttpMessage import rawhttp.core.HttpVersion.HTTP_1_1 import rawhttp.core.RawHttp @@ -54,7 +55,7 @@ import java.net.URI import kotlin.text.Charsets.UTF_8 class HttpPipelineCodec : IPipelineCodec { - override fun encode(messageGroup: MessageGroup): MessageGroup { + override fun encode(messageGroup: ProtoMessageGroup): ProtoMessageGroup { val messages = messageGroup.messagesList if (messages.isEmpty()) { @@ -68,13 +69,13 @@ class HttpPipelineCodec : IPipelineCodec { require(message.metadata.protocol == PROTOCOL) { "Unsupported protocol: ${message.metadata.protocol}" } - val body: RawMessage? = messages.getOrNull(1)?.run { + val body: ProtoRawMessage? = messages.getOrNull(1)?.run { require(kindCase == RAW_MESSAGE) { "Second message must be a raw message" } rawMessage } val messageFields = message.fieldsMap - val builder = MessageGroup.newBuilder() + val builder = ProtoMessageGroup.newBuilder() val httpMessage: HttpMessage = when (val messageType = message.metadata.messageType) { REQUEST_MESSAGE -> messageFields.run { @@ -119,7 +120,7 @@ class HttpPipelineCodec : IPipelineCodec { val metadata = message.metadata - builder += httpMessage.toByteArray().toRawMessage( + builder += httpMessage.toByteArray().toProtoRawMessage( metadata.id, metadata.propertiesMap, body?.metadata?.propertiesMap, @@ -129,7 +130,78 @@ class HttpPipelineCodec : IPipelineCodec { return builder.build() } - override fun decode(messageGroup: MessageGroup): MessageGroup { + override fun encode(messageGroup: MessageGroup): MessageGroup { + val messages = messageGroup.messages + + if (messages.isEmpty()) { + return messageGroup + } + + require(messages.size <= 2) { "Message group must contain at most 2 messages" } + val message = messages[0] as? ParsedMessage ?: error("First message must be a parsed message") + + require(message.protocol == PROTOCOL) { "Unsupported protocol: ${message.protocol}" } + + val body: RawMessage? = messages.getOrNull(1)?.run { + require(this is RawMessage) { "Second message must be a raw message" } + this + } + + val encodedMessages = mutableListOf>() + + val httpMessage: HttpMessage = when (val messageType = message.type) { + REQUEST_MESSAGE -> message.body.run { + requireKnownFields(REQUEST_FIELDS) + + val uri = get(URI_FIELD) as String + val method = get(METHOD_FIELD) as String + val headers = RawHttpHeaders.newBuilder().apply { + (get(HEADERS_FIELD) as? MutableMap)?.fillHeaders(this) + } + + RawHttpRequest( + RequestLine(method, URI(uri), HTTP_1_1), + headers.build(), + null, + null + ).run { + body?.toBody().run(::withBody) ?: this + } + } + RESPONSE_MESSAGE -> message.body.run { + requireKnownFields(RESPONSE_FIELDS) + + val statusCode = (get(STATUS_CODE_FIELD) as String).toIntOrNull() ?: error("$STATUS_CODE_FIELD is not a number") + val reason = get(REASON_FIELD) as String + val headers = RawHttpHeaders.newBuilder().apply { + (get(HEADERS_FIELD) as? MutableMap)?.fillHeaders(this) + } + + RawHttpResponse( + null, + null, + StatusLine(HTTP_1_1, statusCode, reason), + headers.build(), + null + ).run { + body?.toBody().run(::withBody) ?: this + } + } + else -> error("Unsupported message type: $messageType") + } + + encodedMessages += RawMessage( + message.id, + message.eventId, + message.metadata, + message.protocol, + Unpooled.wrappedBuffer(httpMessage.toByteArray()) + ) + + return MessageGroup(encodedMessages) + } + + override fun decode(messageGroup: ProtoMessageGroup): ProtoMessageGroup { val messages = messageGroup.messagesList if (messages.isEmpty()) { @@ -141,7 +213,7 @@ class HttpPipelineCodec : IPipelineCodec { val message = messages[0].rawMessage val body = message.body.toByteArray().toString(UTF_8) - val builder = MessageGroup.newBuilder() + val builder = ProtoMessageGroup.newBuilder() when (val direction = message.metadata.id.direction) { FIRST -> RAW_HTTP.parseResponse(body).convert(RESPONSE_MESSAGE, message, builder) { httpMessage, _ -> @@ -160,6 +232,38 @@ class HttpPipelineCodec : IPipelineCodec { return builder.build() } + override fun decode(messageGroup: MessageGroup): MessageGroup { + val messages = messageGroup.messages + + if (messages.isEmpty()) { + return messageGroup + } + + require(messages.size == 1) { "Message group must contain only 1 message" } + + val message = messages[0] + require(message is RawMessage) { "Message must be a raw message" } + + val body = message.body.toByteArray().toString(UTF_8) + val decodedMessages = mutableListOf>() + + when (val direction = message.id.direction) { + Direction.INCOMING -> RAW_HTTP.parseResponse(body).convert(RESPONSE_MESSAGE, message, decodedMessages) { httpMessage, _ -> + httpMessage[STATUS_CODE_FIELD] = statusCode + httpMessage[REASON_FIELD] = reason + } + Direction.OUTGOING -> RAW_HTTP.parseRequest(body).convert(REQUEST_MESSAGE, message, decodedMessages) { httpMessage, metadataProperties -> + httpMessage[METHOD_FIELD] = method + httpMessage[URI_FIELD] = uri + metadataProperties[METHOD_METADATA_PROPERTY] = method + metadataProperties[URI_METADATA_PROPERTY] = uri.toString() + } + else -> error("Unsupported message direction: $direction") + } + + return MessageGroup(decodedMessages) + } + companion object { const val REQUEST_MESSAGE = "Request" const val RESPONSE_MESSAGE = "Response" @@ -208,20 +312,24 @@ class HttpPipelineCodec : IPipelineCodec { } } - private fun RawMessage.toBody() = BytesBody(body.toByteArray()) + private fun Map.fillHeaders(builder: RawHttpHeaders.Builder) = + forEach { (name, value) -> builder.with(name, value) } + + private fun ProtoRawMessage.toBody() = BytesBody(body.toByteArray()) + private fun RawMessage.toBody() = BytesBody(body.array()) private fun Writable.toByteArray() = ByteArrayOutputStream().apply(::writeTo).toByteArray() private inline operator fun T.invoke(block: T.() -> Unit) = apply(block) - private fun ByteArray.toRawMessage( + private fun ByteArray.toProtoRawMessage( messageId: MessageID, metadataProperties: Map, additionalMetadataProperties: Map? = null, subsequence: Iterable = messageId.subsequenceList.dropLast(1), eventID: EventID - ): RawMessage = RawMessage.newBuilder().apply { - this.body = ByteString.copyFrom(this@toRawMessage) + ): ProtoRawMessage = ProtoRawMessage.newBuilder().apply { + this.body = ByteString.copyFrom(this@toProtoRawMessage) parentEventIdBuilder.mergeFrom(eventID) this.metadataBuilder { putAllProperties(metadataProperties) @@ -234,10 +342,10 @@ class HttpPipelineCodec : IPipelineCodec { private fun HttpMessage.convert( type: String, - source: RawMessage, - builder: MessageGroup.Builder, + source: ProtoRawMessage, + builder: ProtoMessageGroup.Builder, handleStartLine: T.( - httpMessage: Message.Builder, + httpMessage: ProtoMessage.Builder, metadataProperties: MutableMap ) -> Unit ) { @@ -247,7 +355,7 @@ class HttpPipelineCodec : IPipelineCodec { val messageId = metadata.id val subsequence = messageId.subsequenceList - builder += Message.newBuilder().apply { + builder += ProtoMessage.newBuilder().apply { handleStartLine(startLine as T, this, additionalMetadataProperties) parentEventIdBuilder.mergeFrom(source.parentEventId) @@ -255,7 +363,7 @@ class HttpPipelineCodec : IPipelineCodec { val headerList = arrayListOf() headers.forEach { name, value -> - val headerMessage = Message.newBuilder() + val headerMessage = ProtoMessage.newBuilder() headerMessage.addField(HEADER_NAME_FIELD, name) headerMessage.addField(HEADER_VALUE_FIELD, value) headerList += headerMessage.toValue() @@ -278,7 +386,7 @@ class HttpPipelineCodec : IPipelineCodec { body.map(BodyReader::decodeBody) .filter(ByteArray::isNotEmpty) .ifPresent { - builder += it.toRawMessage( + builder += it.toProtoRawMessage( messageId, metadataProperties, additionalMetadataProperties, @@ -288,12 +396,74 @@ class HttpPipelineCodec : IPipelineCodec { } } + private fun HttpMessage.convert( + type: String, + source: RawMessage, + resultMessages: MutableList>, + handleStartLine: T.( + httpMessageBody: MutableMap, + metadataProperties: MutableMap + ) -> Unit + ) { + val additionalMetadataProperties = mutableMapOf() + val messageId = source.id.toBuilder().addSubsequence(1).build() + val parsedBody = mutableMapOf() + + handleStartLine(startLine as T, parsedBody, additionalMetadataProperties) + + if (!headers.isEmpty) { + parsedBody[HEADERS_FIELD] = mutableMapOf().apply { + headers.forEach { name, value -> this[name] = value } + } + } + + resultMessages += ParsedMessage( + messageId.toBuilder().addSubsequence(1).build(), + source.eventId, + type, + source.metadata, + PROTOCOL, + parsedBody + ) + + body.map(BodyReader::decodeBody) + .filter(ByteArray::isNotEmpty) + .ifPresent { + resultMessages += RawMessage( + messageId.toBuilder().addSubsequence(2).build(), + source.eventId, + source.metadata, + body = Unpooled.wrappedBuffer(it) + ) + } + } + + private fun RawHttpRequest.convert( + type: String, + source: ProtoRawMessage, + builder: ProtoMessageGroup.Builder, + handleStartLine: RequestLine.( + httpMessage: ProtoMessage.Builder, + metadataProperties: MutableMap + ) -> Unit + ) = convert(type, source, builder, handleStartLine) + + private fun RawHttpResponse<*>.convert( + type: String, + source: ProtoRawMessage, + builder: ProtoMessageGroup.Builder, + handleStartLine: StatusLine.( + httpMessage: ProtoMessage.Builder, + metadataProperties: MutableMap + ) -> Unit + ) = convert(type, source, builder, handleStartLine) + private fun RawHttpRequest.convert( type: String, source: RawMessage, - builder: MessageGroup.Builder, + builder: MutableList>, handleStartLine: RequestLine.( - httpMessage: Message.Builder, + httpMessage: MutableMap, metadataProperties: MutableMap ) -> Unit ) = convert(type, source, builder, handleStartLine) @@ -301,11 +471,11 @@ class HttpPipelineCodec : IPipelineCodec { private fun RawHttpResponse<*>.convert( type: String, source: RawMessage, - builder: MessageGroup.Builder, + builder: MutableList>, handleStartLine: StatusLine.( - httpMessage: Message.Builder, + httpMessage: MutableMap, metadataProperties: MutableMap ) -> Unit ) = convert(type, source, builder, handleStartLine) } -} +} \ No newline at end of file diff --git a/src/test/kotlin/com/exactpro/th2/codec/http/DecodeTest.kt b/src/test/kotlin/com/exactpro/th2/codec/http/DecodeTest.kt index 9450571..8eae15e 100644 --- a/src/test/kotlin/com/exactpro/th2/codec/http/DecodeTest.kt +++ b/src/test/kotlin/com/exactpro/th2/codec/http/DecodeTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 Exactpro (Exactpro Systems Limited) + * Copyright 2020-2023 Exactpro (Exactpro Systems Limited) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,22 @@ package com.exactpro.th2.codec.http import com.exactpro.th2.codec.http.HttpPipelineCodecFactory.Companion.PROTOCOL -import com.exactpro.th2.common.grpc.AnyMessage -import com.exactpro.th2.common.grpc.Direction -import com.exactpro.th2.common.grpc.MessageGroup -import com.exactpro.th2.common.grpc.RawMessage +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.RawMessage +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.ParsedMessage +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.EventId +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.MessageGroup +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.MessageId +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.Direction +import com.exactpro.th2.common.grpc.AnyMessage as ProtoAnyMessage +import com.exactpro.th2.common.grpc.Direction as ProtoDirection +import com.exactpro.th2.common.grpc.MessageGroup as ProtoMessageGroup +import com.exactpro.th2.common.grpc.RawMessage as ProtoRawMessage import com.google.protobuf.ByteString +import io.netty.buffer.Unpooled import kotlin.test.assertEquals import org.junit.jupiter.api.Test +import java.net.URI +import java.time.Instant class DecodeTest { @@ -40,14 +49,14 @@ class DecodeTest { val codec = HttpPipelineCodec() - val message = RawMessage.newBuilder().apply { + val message = ProtoRawMessage.newBuilder().apply { parentEventIdBuilder.id = eventID metadataBuilder.protocol = PROTOCOL - metadataBuilder.idBuilder.direction = Direction.SECOND + metadataBuilder.idBuilder.direction = ProtoDirection.SECOND body = ByteString.copyFrom(request.toByteArray()) } - val messageGroup = MessageGroup.newBuilder().addMessages(AnyMessage.newBuilder().setRawMessage(message).build()).build() + val messageGroup = ProtoMessageGroup.newBuilder().addMessages(ProtoAnyMessage.newBuilder().setRawMessage(message).build()).build() val decodedEventID = codec.decode(messageGroup).getMessages(0).message.parentEventId @@ -66,18 +75,101 @@ class DecodeTest { val codec = HttpPipelineCodec() - val message = RawMessage.newBuilder().apply { + val message = ProtoRawMessage.newBuilder().apply { parentEventIdBuilder.id = eventID metadataBuilder.protocol = PROTOCOL - metadataBuilder.idBuilder.direction = Direction.FIRST + metadataBuilder.idBuilder.direction = ProtoDirection.FIRST body = ByteString.copyFrom(response.toByteArray()) } - val messageGroup = MessageGroup.newBuilder().addMessages(AnyMessage.newBuilder().setRawMessage(message).build()).build() + val messageGroup = ProtoMessageGroup.newBuilder().addMessages(ProtoAnyMessage.newBuilder().setRawMessage(message).build()).build() val decodedEventID = codec.decode(messageGroup).getMessages(0).message.parentEventId assertEquals(eventID, decodedEventID.id) } + @Test + fun `parent event id test - response (transport)`() { + val eventID = "123" + + val response = """ + HTTP/1.1 200 OK + Content-Type: text/plain + Content-Length: 0 + """.trimIndent() + + + val codec = HttpPipelineCodec() + val message = RawMessage( + id = MessageId("alias_01", Direction.INCOMING, 1, Instant.now()), + eventId = EventId(eventID, "book_01", "scope_01", Instant.now()), + protocol = PROTOCOL, + body = Unpooled.wrappedBuffer(response.toByteArray()) + ) + + val messageGroup = MessageGroup(listOf(message)) + + val decodedGroup = codec.decode(messageGroup) + + val decodedMessage = decodedGroup.messages[0] as ParsedMessage + + val decodedEventID = decodedMessage.eventId + val decodedBody = decodedMessage.body + + assertEquals(PROTOCOL, decodedMessage.protocol) + assertEquals("Response", decodedMessage.type) + assertEquals(3, decodedBody.size) + assertEquals(200, decodedBody["statusCode"]) + assertEquals("OK", decodedBody["reason"]) + val decodedHeaders = decodedBody["headers"] as Map + assertEquals(2, decodedHeaders.size) + assertEquals("text/plain", decodedHeaders["Content-Type"]) + assertEquals("0", decodedHeaders["Content-Length"]) + assertEquals(eventID, decodedEventID?.id) + } + + @Test + fun `parent event id test - request (transport)`() { + val eventID = "123" + + val request = """ + GET /hello.txt HTTP/1.1 + User-Agent: OpenSSL/0.9.7l + Host: www.test.com + Accept-Language: en, mi + """.trimIndent() + + + val codec = HttpPipelineCodec() + val message = RawMessage( + id = MessageId("alias_01", Direction.OUTGOING, 1, Instant.now()), + eventId = EventId(eventID, "book_01", "scope_01", Instant.now()), + protocol = PROTOCOL, + body = Unpooled.wrappedBuffer(request.toByteArray()) + ) + + val messageGroup = MessageGroup(listOf(message)) + + val decodedGroup = codec.decode(messageGroup) + + assertEquals(1, decodedGroup.messages.size) + + val decodedMessage = decodedGroup.messages[0] as ParsedMessage + + val decodedEventID = decodedMessage.eventId + val decodedBody = decodedMessage.body + + assertEquals(PROTOCOL, decodedMessage.protocol) + assertEquals("Request", decodedMessage.type) + assertEquals("GET", decodedBody["method"]) + assertEquals(URI("http://www.test.com/hello.txt"), decodedBody["uri"]) + val decodedHeaders = decodedBody["headers"] as Map + assertEquals(3, decodedHeaders.size) + assertEquals("OpenSSL/0.9.7l", decodedHeaders["User-Agent"]) + assertEquals("www.test.com", decodedHeaders["Host"]) + assertEquals("en, mi", decodedHeaders["Accept-Language"]) + + assertEquals(eventID, decodedEventID?.id) + } } \ No newline at end of file diff --git a/src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt b/src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt index f0ea6d5..10384fb 100644 --- a/src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt +++ b/src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 Exactpro (Exactpro Systems Limited) + * Copyright 2020-2023 Exactpro (Exactpro Systems Limited) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,18 @@ package com.exactpro.th2.codec.http import com.exactpro.th2.codec.http.HttpPipelineCodecFactory.Companion.PROTOCOL -import com.exactpro.th2.common.grpc.AnyMessage -import com.exactpro.th2.common.grpc.Message -import com.exactpro.th2.common.grpc.MessageGroup +import com.exactpro.th2.common.grpc.AnyMessage as ProtoAnyMessage +import com.exactpro.th2.common.grpc.Message as ProtoMessage +import com.exactpro.th2.common.grpc.MessageGroup as ProtoMessageGroup import com.exactpro.th2.common.message.addField import com.exactpro.th2.common.message.messageType +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.EventId +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.MessageGroup +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.ParsedMessage +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.RawMessage import kotlin.test.assertEquals import org.junit.jupiter.api.Test +import java.time.Instant class EncodeTest { @@ -32,7 +37,7 @@ class EncodeTest { val eventID = "123" val codec = HttpPipelineCodec() - val message = Message.newBuilder().apply { + val message = ProtoMessage.newBuilder().apply { messageType = HttpPipelineCodec.REQUEST_MESSAGE addField(HttpPipelineCodec.URI_FIELD, "/test") addField(HttpPipelineCodec.METHOD_FIELD, "GET") @@ -40,7 +45,7 @@ class EncodeTest { metadataBuilder.protocol = PROTOCOL } - val messageGroup = MessageGroup.newBuilder().addMessages(AnyMessage.newBuilder().setMessage(message).build()).build() + val messageGroup = ProtoMessageGroup.newBuilder().addMessages(ProtoAnyMessage.newBuilder().setMessage(message).build()).build() val encodedEventID = codec.encode(messageGroup).getMessages(0).rawMessage.parentEventId @@ -52,7 +57,7 @@ class EncodeTest { val eventID = "123" val codec = HttpPipelineCodec() - val message = Message.newBuilder().apply { + val message = ProtoMessage.newBuilder().apply { messageType = HttpPipelineCodec.RESPONSE_MESSAGE addField(HttpPipelineCodec.STATUS_CODE_FIELD, "200") addField(HttpPipelineCodec.REASON_FIELD, "OK") @@ -60,11 +65,62 @@ class EncodeTest { metadataBuilder.protocol = PROTOCOL } - val messageGroup = MessageGroup.newBuilder().addMessages(AnyMessage.newBuilder().setMessage(message).build()).build() - + val messageGroup = ProtoMessageGroup.newBuilder().addMessages(ProtoAnyMessage.newBuilder().setMessage(message).build()).build() val encodedEventID = codec.encode(messageGroup).getMessages(0).rawMessage.parentEventId assertEquals(eventID, encodedEventID.id) } + @Test + fun `parent event id test - request (transport)`() { + val eventID = "123" + + val codec = HttpPipelineCodec() + val message = ParsedMessage( + eventId = EventId(eventID, "book_1", "scope_1", Instant.now()), + type = HttpPipelineCodec.REQUEST_MESSAGE, + protocol = PROTOCOL, + body = mapOf( + HttpPipelineCodec.URI_FIELD to "/test", + HttpPipelineCodec.METHOD_FIELD to "GET" + ) + ) + + val messageGroup = MessageGroup(listOf(message)) + val encodedGroup = codec.encode(messageGroup) + val encodedMessage = encodedGroup.messages[0] as RawMessage + val encodedEventID = encodedMessage.eventId + + assertEquals(1, encodedGroup.messages.size) + assertEquals(PROTOCOL, encodedMessage.protocol) + assertEquals(22, encodedMessage.body.array().size) + assertEquals(eventID, encodedEventID?.id) + } + + @Test + fun `parent event id test - response (transport)`() { + val eventID = "123" + + val codec = HttpPipelineCodec() + val message = ParsedMessage( + eventId = EventId(eventID, "book_1", "scope_1", Instant.now()), + type = HttpPipelineCodec.RESPONSE_MESSAGE, + protocol = PROTOCOL, + body = mapOf( + HttpPipelineCodec.STATUS_CODE_FIELD to "200", + HttpPipelineCodec.REASON_FIELD to "OK" + ) + ) + + val messageGroup = MessageGroup(listOf(message)) + val encodedGroup = codec.encode(messageGroup) + + val encodedMessage = encodedGroup.messages[0] as RawMessage + val encodedEventID = encodedMessage.eventId + + assertEquals(1, encodedGroup.messages.size) + assertEquals(PROTOCOL, encodedMessage.protocol) + assertEquals(19, encodedMessage.body.array().size) + assertEquals(eventID, encodedEventID?.id) + } } \ No newline at end of file From 794d62340557d950e7cd2359af322037b9b2dd46 Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Fri, 2 Jun 2023 14:30:59 +0400 Subject: [PATCH 02/19] [TH2-4934] Refactoring --- Dockerfile | 2 +- build.gradle | 41 +++++---- gradle/wrapper/gradle-wrapper.properties | 2 +- .../th2/codec/http/HttpPipelineCodec.kt | 84 +++++++++---------- 4 files changed, 67 insertions(+), 62 deletions(-) diff --git a/Dockerfile b/Dockerfile index 84de259..3ee4f84 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM gradle:7.5-jdk11 AS build +FROM gradle:7.6-jdk11 AS build ARG release_version COPY ./ . RUN gradle --no-daemon clean build dockerPrepare -Prelease_version=${release_version} diff --git a/build.gradle b/build.gradle index c452d1b..729a748 100644 --- a/build.gradle +++ b/build.gradle @@ -2,17 +2,11 @@ plugins { id 'com.palantir.docker' version '0.25.0' id 'org.jetbrains.kotlin.jvm' version "${kotlin_version}" id 'application' - id "org.owasp.dependencycheck" version "7.2.0" id 'org.jetbrains.kotlin.kapt' version "${kotlin_version}" -} - -dependencyCheck { - format='HTML' - failBuildOnCVSS=5 + id "org.owasp.dependencycheck" version "8.2.1" } ext { - sharedDir = file("${project.rootDir}/shared") sailfishVersion = '3.3.54' } @@ -30,11 +24,6 @@ ext.excludeSailfish = { rcd -> } repositories { - maven { - name 'MavenLocal' - url sharedDir - } - maven { name 'Sonatype_snapshots' url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' @@ -75,7 +64,7 @@ repositories { mavenCentral() mavenLocal() - configurations.all { + configurations.configureEach { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds' } @@ -99,16 +88,15 @@ dependencies { api platform('com.exactpro.th2:bom:4.2.0') implementation 'com.exactpro.th2:common:5.3.0-json-raw-body-5144283961-5ae02cd-SNAPSHOT' + implementation 'com.exactpro.th2:common-utils:2.1.0-transport-protocol-5153730274-14792e9-SNAPSHOT' implementation 'com.exactpro.th2:codec:5.2.0-new-proto-5111859401-e24c7b8-SNAPSHOT' - implementation 'com.exactpro.th2:sailfish-utils:3.14.0' - + implementation 'com.exactpro.th2:sailfish-utils:4.0.0-TH2-4891-5111848206-3d59c47-SNAPSHOT' + compileOnly 'com.google.auto.service:auto-service:1.0.1' annotationProcessor 'com.google.auto.service:auto-service:1.0.1' - implementation group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: kotlin_version - implementation group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: kotlin_version - implementation group: 'io.github.microutils', name: 'kotlin-logging', version: '1.7.9' + implementation group: 'io.github.microutils', name: 'kotlin-logging', version: '3.0.0' implementation group: 'com.athaydes.rawhttp', name: 'rawhttp-core', version: '2.4.1' testImplementation group: 'org.jetbrains.kotlin', name: 'kotlin-test-junit5', version: kotlin_version @@ -149,3 +137,20 @@ compileTestKotlin { test { useJUnitPlatform() } + +configurations { + compileClasspath { + resolutionStrategy.activateDependencyLocking() + } +} + +dependencyCheck { + formats = ['SARIF', 'JSON', 'HTML'] + failBuildOnCVSS = 5 + + analyzers { + assemblyEnabled = false + nugetconfEnabled = false + nodeEnabled = false + } +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 11abb6d..2b20ca3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ #Mon May 25 11:22:24 MSK 2020 -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists diff --git a/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt b/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt index 7061a21..8fc4897 100644 --- a/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt +++ b/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt @@ -23,10 +23,7 @@ import com.exactpro.th2.common.grpc.AnyMessage.KindCase.RAW_MESSAGE import com.exactpro.th2.common.grpc.Direction.FIRST import com.exactpro.th2.common.grpc.Direction.SECOND import com.exactpro.th2.common.grpc.EventID -import com.exactpro.th2.common.grpc.Message as ProtoMessage -import com.exactpro.th2.common.grpc.MessageGroup as ProtoMessageGroup import com.exactpro.th2.common.grpc.MessageID -import com.exactpro.th2.common.grpc.RawMessage as ProtoRawMessage import com.exactpro.th2.common.grpc.Value import com.exactpro.th2.common.grpc.Value.KindCase.LIST_VALUE import com.exactpro.th2.common.grpc.Value.KindCase.MESSAGE_VALUE @@ -34,6 +31,7 @@ import com.exactpro.th2.common.grpc.Value.KindCase.SIMPLE_VALUE import com.exactpro.th2.common.message.addField import com.exactpro.th2.common.message.plusAssign import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.* +import com.exactpro.th2.common.utils.message.transport.getMap import com.exactpro.th2.common.value.toValue import com.google.protobuf.ByteString import com.google.protobuf.MessageLite.Builder @@ -53,15 +51,15 @@ import rawhttp.core.body.BytesBody import java.io.ByteArrayOutputStream import java.net.URI import kotlin.text.Charsets.UTF_8 +import com.exactpro.th2.common.grpc.Message as ProtoMessage +import com.exactpro.th2.common.grpc.MessageGroup as ProtoMessageGroup +import com.exactpro.th2.common.grpc.RawMessage as ProtoRawMessage class HttpPipelineCodec : IPipelineCodec { + override fun encode(messageGroup: ProtoMessageGroup): ProtoMessageGroup { val messages = messageGroup.messagesList - if (messages.isEmpty()) { - return messageGroup - } - require(messages.size <= 2) { "Message group must contain at most 2 messages" } require(messages[0].kindCase == MESSAGE) { "First message must be a parsed message" } @@ -96,10 +94,12 @@ class HttpPipelineCodec : IPipelineCodec { body?.toBody().run(::withBody) ?: this } } + RESPONSE_MESSAGE -> messageFields.run { requireKnownFields(RESPONSE_FIELDS) - val statusCode = getString(STATUS_CODE_FIELD).toIntOrNull() ?: error("$STATUS_CODE_FIELD is not a number") + val statusCode = + getString(STATUS_CODE_FIELD).toIntOrNull() ?: error("$STATUS_CODE_FIELD is not a number") val reason = getString(REASON_FIELD) val headers = RawHttpHeaders.newBuilder() @@ -115,6 +115,7 @@ class HttpPipelineCodec : IPipelineCodec { body?.toBody().run(::withBody) ?: this } } + else -> error("Unsupported message type: $messageType") } @@ -133,10 +134,6 @@ class HttpPipelineCodec : IPipelineCodec { override fun encode(messageGroup: MessageGroup): MessageGroup { val messages = messageGroup.messages - if (messages.isEmpty()) { - return messageGroup - } - require(messages.size <= 2) { "Message group must contain at most 2 messages" } val message = messages[0] as? ParsedMessage ?: error("First message must be a parsed message") @@ -156,7 +153,7 @@ class HttpPipelineCodec : IPipelineCodec { val uri = get(URI_FIELD) as String val method = get(METHOD_FIELD) as String val headers = RawHttpHeaders.newBuilder().apply { - (get(HEADERS_FIELD) as? MutableMap)?.fillHeaders(this) + (getMap(HEADERS_FIELD) as? Map)?.fillHeaders(this) } RawHttpRequest( @@ -168,13 +165,15 @@ class HttpPipelineCodec : IPipelineCodec { body?.toBody().run(::withBody) ?: this } } + RESPONSE_MESSAGE -> message.body.run { requireKnownFields(RESPONSE_FIELDS) - val statusCode = (get(STATUS_CODE_FIELD) as String).toIntOrNull() ?: error("$STATUS_CODE_FIELD is not a number") + val statusCode = + (get(STATUS_CODE_FIELD) as String).toIntOrNull() ?: error("$STATUS_CODE_FIELD is not a number") val reason = get(REASON_FIELD) as String val headers = RawHttpHeaders.newBuilder().apply { - (get(HEADERS_FIELD) as? MutableMap)?.fillHeaders(this) + (getMap(HEADERS_FIELD) as? Map)?.fillHeaders(this) } RawHttpResponse( @@ -187,6 +186,7 @@ class HttpPipelineCodec : IPipelineCodec { body?.toBody().run(::withBody) ?: this } } + else -> error("Unsupported message type: $messageType") } @@ -204,10 +204,6 @@ class HttpPipelineCodec : IPipelineCodec { override fun decode(messageGroup: ProtoMessageGroup): ProtoMessageGroup { val messages = messageGroup.messagesList - if (messages.isEmpty()) { - return messageGroup - } - require(messages.size == 1) { "Message group must contain only 1 message" } require(messages[0].kindCase == RAW_MESSAGE) { "Message must be a raw message" } @@ -220,12 +216,15 @@ class HttpPipelineCodec : IPipelineCodec { httpMessage.addField(STATUS_CODE_FIELD, statusCode) httpMessage.addField(REASON_FIELD, reason) } - SECOND -> RAW_HTTP.parseRequest(body).convert(REQUEST_MESSAGE, message, builder) { httpMessage, metadataProperties -> - httpMessage.addField(METHOD_FIELD, method) - httpMessage.addField(URI_FIELD, uri) - metadataProperties[METHOD_METADATA_PROPERTY] = method - metadataProperties[URI_METADATA_PROPERTY] = uri.toString() - } + + SECOND -> RAW_HTTP.parseRequest(body) + .convert(REQUEST_MESSAGE, message, builder) { httpMessage, metadataProperties -> + httpMessage.addField(METHOD_FIELD, method) + httpMessage.addField(URI_FIELD, uri) + metadataProperties[METHOD_METADATA_PROPERTY] = method + metadataProperties[URI_METADATA_PROPERTY] = uri.toString() + } + else -> error("Unsupported message direction: $direction") } @@ -235,10 +234,6 @@ class HttpPipelineCodec : IPipelineCodec { override fun decode(messageGroup: MessageGroup): MessageGroup { val messages = messageGroup.messages - if (messages.isEmpty()) { - return messageGroup - } - require(messages.size == 1) { "Message group must contain only 1 message" } val message = messages[0] @@ -248,16 +243,20 @@ class HttpPipelineCodec : IPipelineCodec { val decodedMessages = mutableListOf>() when (val direction = message.id.direction) { - Direction.INCOMING -> RAW_HTTP.parseResponse(body).convert(RESPONSE_MESSAGE, message, decodedMessages) { httpMessage, _ -> - httpMessage[STATUS_CODE_FIELD] = statusCode - httpMessage[REASON_FIELD] = reason - } - Direction.OUTGOING -> RAW_HTTP.parseRequest(body).convert(REQUEST_MESSAGE, message, decodedMessages) { httpMessage, metadataProperties -> - httpMessage[METHOD_FIELD] = method - httpMessage[URI_FIELD] = uri - metadataProperties[METHOD_METADATA_PROPERTY] = method - metadataProperties[URI_METADATA_PROPERTY] = uri.toString() - } + Direction.INCOMING -> RAW_HTTP.parseResponse(body) + .convert(RESPONSE_MESSAGE, message, decodedMessages) { httpMessage, _ -> + httpMessage[STATUS_CODE_FIELD] = statusCode + httpMessage[REASON_FIELD] = reason + } + + Direction.OUTGOING -> RAW_HTTP.parseRequest(body) + .convert(REQUEST_MESSAGE, message, decodedMessages) { httpMessage, metadataProperties -> + httpMessage[METHOD_FIELD] = method + httpMessage[URI_FIELD] = uri + metadataProperties[METHOD_METADATA_PROPERTY] = method + metadataProperties[URI_METADATA_PROPERTY] = uri.toString() + } + else -> error("Unsupported message direction: $direction") } @@ -284,9 +283,10 @@ class HttpPipelineCodec : IPipelineCodec { private val RAW_HTTP = RawHttp() - private fun Map.requireKnownFields(messageFields: Set) = require(keys.all(messageFields::contains)) { - "Message contains unknown fields: ${keys.filterNot(messageFields::contains)}" - } + private fun Map.requireKnownFields(messageFields: Set) = + require(keys.all(messageFields::contains)) { + "Message contains unknown fields: ${keys.filterNot(messageFields::contains)}" + } private fun Map.getString(fieldName: String) = get(fieldName)?.run { require(kindCase == SIMPLE_VALUE) { "$fieldName is not a string" } From 858ea9bdc3423ad0896528feb80e3ed8dde88e20 Mon Sep 17 00:00:00 2001 From: Oleg Smelov Date: Mon, 12 Jun 2023 17:38:39 +0400 Subject: [PATCH 03/19] fixed ByteBuf data access --- build.gradle | 6 +++--- .../kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt | 2 +- src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 729a748..0410fb9 100644 --- a/build.gradle +++ b/build.gradle @@ -87,9 +87,9 @@ jar { dependencies { api platform('com.exactpro.th2:bom:4.2.0') - implementation 'com.exactpro.th2:common:5.3.0-json-raw-body-5144283961-5ae02cd-SNAPSHOT' + implementation 'com.exactpro.th2:common:5.3.0-json-raw-body-5242142633-7ac1672-SNAPSHOT' implementation 'com.exactpro.th2:common-utils:2.1.0-transport-protocol-5153730274-14792e9-SNAPSHOT' - implementation 'com.exactpro.th2:codec:5.2.0-new-proto-5111859401-e24c7b8-SNAPSHOT' + implementation 'com.exactpro.th2:codec:5.3.0-new-proto-5241354905-69d03b5-SNAPSHOT' implementation 'com.exactpro.th2:sailfish-utils:4.0.0-TH2-4891-5111848206-3d59c47-SNAPSHOT' @@ -100,7 +100,7 @@ dependencies { implementation group: 'com.athaydes.rawhttp', name: 'rawhttp-core', version: '2.4.1' testImplementation group: 'org.jetbrains.kotlin', name: 'kotlin-test-junit5', version: kotlin_version - testImplementation 'org.junit.jupiter:junit-jupiter:5.9.0' + testImplementation 'org.junit.jupiter:junit-jupiter:5.9.3' kapt 'com.google.auto.service:auto-service:1.0.1' } diff --git a/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt b/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt index 8fc4897..6d2c911 100644 --- a/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt +++ b/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt @@ -316,7 +316,7 @@ class HttpPipelineCodec : IPipelineCodec { forEach { (name, value) -> builder.with(name, value) } private fun ProtoRawMessage.toBody() = BytesBody(body.toByteArray()) - private fun RawMessage.toBody() = BytesBody(body.array()) + private fun RawMessage.toBody() = BytesBody(body.toByteArray()) private fun Writable.toByteArray() = ByteArrayOutputStream().apply(::writeTo).toByteArray() diff --git a/src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt b/src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt index 10384fb..95e2798 100644 --- a/src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt +++ b/src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt @@ -93,7 +93,7 @@ class EncodeTest { assertEquals(1, encodedGroup.messages.size) assertEquals(PROTOCOL, encodedMessage.protocol) - assertEquals(22, encodedMessage.body.array().size) + assertEquals(22, encodedMessage.body.readableBytes()) assertEquals(eventID, encodedEventID?.id) } @@ -120,7 +120,7 @@ class EncodeTest { assertEquals(1, encodedGroup.messages.size) assertEquals(PROTOCOL, encodedMessage.protocol) - assertEquals(19, encodedMessage.body.array().size) + assertEquals(19, encodedMessage.body.readableBytes()) assertEquals(eventID, encodedEventID?.id) } } \ No newline at end of file From 2004f32800637060a7f7a48ddd7e71f7302430b4 Mon Sep 17 00:00:00 2001 From: Oleg Smelov Date: Mon, 12 Jun 2023 21:16:51 +0400 Subject: [PATCH 04/19] version bump README update --- README.md | 5 ++++- gradle.properties | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 85dad91..1bb6c08 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# HTTP Codec v0.2.0 +# HTTP Codec v0.4.0 This microservice can encode and decode HTTP messages @@ -128,6 +128,9 @@ It's been verified that Sailfish itself is compatible with versions from BOM and # Release notes +## 0.3.0 ++ TH2 transport protocol support + ## 0.3.0 * th2-common upgrade to `3.44.0` * th2-bom upgrade to `4.1.0` diff --git a/gradle.properties b/gradle.properties index b63fa03..247b36e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ kotlin.code.style=official kotlin_version=1.6.21 -release_version=0.3.0 \ No newline at end of file +release_version=0.4.0 \ No newline at end of file From 79f82a7b7658cd3471636b8838255797589643f8 Mon Sep 17 00:00:00 2001 From: Oleg Smelov Date: Mon, 12 Jun 2023 21:33:29 +0400 Subject: [PATCH 05/19] README update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1bb6c08..1aede4e 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ It's been verified that Sailfish itself is compatible with versions from BOM and # Release notes -## 0.3.0 +## 0.4.0 + TH2 transport protocol support ## 0.3.0 From 37d4f8cf458b12d2efd67d6d20f252d9d8f12c3e Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Mon, 26 Jun 2023 16:24:24 +0400 Subject: [PATCH 06/19] [TH2-4934] Updated dependencies --- README.md | 44 +++++++++++++++++++++++++------------------- build.gradle | 19 +++++++++++-------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 1aede4e..ba9c43b 100644 --- a/README.md +++ b/README.md @@ -27,32 +27,33 @@ This codec processes parsed messages with `http` protocol in metadata field 1. HTTP message - `Message` with `Request` or `Response` type (protocol = `http`) 2. HTTP message body - `RawMessage` with a raw message body (if present) -If decoded message was an HTTP request, message body metadata would contain `method` and `uri` properties with HTTP request method name and URI respectively +If decoded message was an HTTP request, message body metadata would contain `method` and `uri` properties with HTTP +request method name and URI respectively ## Message types * Request -|Field|Type|Description| -|:---:|:---:|:---:| -|method|String|HTTP method name (e.g. GET, POST, etc.)| -|uri|String|Request URI (e.g. /some/request/path?param1=value1¶m2=value2...)| -|headers|List\
|HTTP headers (e.g. Host, Content-Length, etc.)| +| Field | Type | Description | +|:-------:|:-------------:|:--------------------------------------------------------------------:| +| method | String | HTTP method name (e.g. GET, POST, etc.) | +| uri | String | Request URI (e.g. /some/request/path?param1=value1¶m2=value2...) | +| headers | List\
| HTTP headers (e.g. Host, Content-Length, etc.) | * Response -|Field|Type|Description| -|:---:|:---:|:---:| -|statusCode|String|HTTP status code (e.g. 200, 403, 500, etc)| -|reason|String|HTTP status reason (e.g. OK, Forbidden, Internal Server Error, etc.)| -|headers|List\
|HTTP headers (e.g. Set-Cookie, Content-Length, etc.)| +| Field | Type | Description | +|:----------:|:-------------:|:--------------------------------------------------------------------:| +| statusCode | String | HTTP status code (e.g. 200, 403, 500, etc) | +| reason | String | HTTP status reason (e.g. OK, Forbidden, Internal Server Error, etc.) | +| headers | List\
| HTTP headers (e.g. Set-Cookie, Content-Length, etc.) | * Header -|Field|Type|Description| -|:---:|:---:|:---:| -|name|String|HTTP header name| -|value|String|HTTP header value| +| Field | Type | Description | +|:-----:|:------:|:-----------------:| +| name | String | HTTP header name | +| value | String | HTTP header value | ## Deployment via `infra-mgr` @@ -120,18 +121,23 @@ spec: ``` ### Gradle metadata note -ignoreGradleMetadataRedirection is used for sonatype because Sailfish dependencies have constrains that interfere with BOM, -so we exclude Gradle metadata for these repositories. -It's been verified that Sailfish itself is compatible with versions from BOM and therefore safe to use. +ignoreGradleMetadataRedirection is used for sonatype because Sailfish dependencies have constrains that interfere with +BOM, so we exclude Gradle metadata for these repositories. +It's been verified that Sailfish itself is compatible with versions from BOM and therefore safe to use. # Release notes ## 0.4.0 -+ TH2 transport protocol support + ++ th2 transport protocol support ++ Updated bom:4.4.0 ++ Updated common:5.3.0 ++ Updated codec:5.3.0 ## 0.3.0 + * th2-common upgrade to `3.44.0` * th2-bom upgrade to `4.1.0` * th2-codec upgrade to `4.7.6` diff --git a/build.gradle b/build.gradle index 0410fb9..930dfba 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { } ext { - sailfishVersion = '3.3.54' + sailfishVersion = '3.3.93' } group = 'com.exactpro.th2' @@ -85,23 +85,26 @@ jar { } dependencies { - api platform('com.exactpro.th2:bom:4.2.0') + api platform('com.exactpro.th2:bom:4.4.0-update-libs-5345334944-c71fdc9-SNAPSHOT') - implementation 'com.exactpro.th2:common:5.3.0-json-raw-body-5242142633-7ac1672-SNAPSHOT' - implementation 'com.exactpro.th2:common-utils:2.1.0-transport-protocol-5153730274-14792e9-SNAPSHOT' - implementation 'com.exactpro.th2:codec:5.3.0-new-proto-5241354905-69d03b5-SNAPSHOT' + implementation('com.exactpro.th2:common:5.3.0-separate-executor-5347518176-63bc4ea-SNAPSHOT') { + exclude group: 'com.exactpro.th2', module: 'cradle-cassandra' + exclude group: 'com.exactpro.th2', module: 'cradle-core' + } + implementation 'com.exactpro.th2:common-utils:2.1.0-transport-protocol-5347774882-e4aa8e6-SNAPSHOT' + implementation 'com.exactpro.th2:codec:5.3.0-new-proto-5377025425-07b1e3e-SNAPSHOT' implementation 'com.exactpro.th2:sailfish-utils:4.0.0-TH2-4891-5111848206-3d59c47-SNAPSHOT' - compileOnly 'com.google.auto.service:auto-service:1.0.1' - annotationProcessor 'com.google.auto.service:auto-service:1.0.1' + compileOnly 'com.google.auto.service:auto-service:1.1.1' + annotationProcessor 'com.google.auto.service:auto-service:1.1.1' + kapt 'com.google.auto.service:auto-service:1.1.1' implementation group: 'io.github.microutils', name: 'kotlin-logging', version: '3.0.0' implementation group: 'com.athaydes.rawhttp', name: 'rawhttp-core', version: '2.4.1' testImplementation group: 'org.jetbrains.kotlin', name: 'kotlin-test-junit5', version: kotlin_version testImplementation 'org.junit.jupiter:junit-jupiter:5.9.3' - kapt 'com.google.auto.service:auto-service:1.0.1' } application { From 638869fe87d79864c95892de4f51e43ef4c57610 Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Tue, 27 Jun 2023 13:50:15 +0400 Subject: [PATCH 07/19] [TH2-4934] Updated dependencies --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 930dfba..96867a5 100644 --- a/build.gradle +++ b/build.gradle @@ -94,7 +94,7 @@ dependencies { implementation 'com.exactpro.th2:common-utils:2.1.0-transport-protocol-5347774882-e4aa8e6-SNAPSHOT' implementation 'com.exactpro.th2:codec:5.3.0-new-proto-5377025425-07b1e3e-SNAPSHOT' - implementation 'com.exactpro.th2:sailfish-utils:4.0.0-TH2-4891-5111848206-3d59c47-SNAPSHOT' + implementation 'com.exactpro.th2:sailfish-utils:4.0.0-TH2-4891-5376991740-142b0a9-SNAPSHOT' compileOnly 'com.google.auto.service:auto-service:1.1.1' annotationProcessor 'com.google.auto.service:auto-service:1.1.1' From d92d1f83a85c980c11cb126995725b2c2d8549fa Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Wed, 12 Jul 2023 16:41:56 +0400 Subject: [PATCH 08/19] [TH2-4887] Used bom:4.4.0 --- build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 96867a5..1530118 100644 --- a/build.gradle +++ b/build.gradle @@ -85,16 +85,16 @@ jar { } dependencies { - api platform('com.exactpro.th2:bom:4.4.0-update-libs-5345334944-c71fdc9-SNAPSHOT') + api platform('com.exactpro.th2:bom:4.4.0') - implementation('com.exactpro.th2:common:5.3.0-separate-executor-5347518176-63bc4ea-SNAPSHOT') { + implementation('com.exactpro.th2:common:5.3.0-separate-executor-+') { exclude group: 'com.exactpro.th2', module: 'cradle-cassandra' exclude group: 'com.exactpro.th2', module: 'cradle-core' } - implementation 'com.exactpro.th2:common-utils:2.1.0-transport-protocol-5347774882-e4aa8e6-SNAPSHOT' - implementation 'com.exactpro.th2:codec:5.3.0-new-proto-5377025425-07b1e3e-SNAPSHOT' + implementation 'com.exactpro.th2:common-utils:2.1.0-transport-protocol-+' + implementation 'com.exactpro.th2:codec:5.3.0-new-proto-+' - implementation 'com.exactpro.th2:sailfish-utils:4.0.0-TH2-4891-5376991740-142b0a9-SNAPSHOT' + implementation 'com.exactpro.th2:sailfish-utils:4.0.0-TH2-4891-+' compileOnly 'com.google.auto.service:auto-service:1.1.1' annotationProcessor 'com.google.auto.service:auto-service:1.1.1' From d06cd4386f0eb42bbeea906d77c76913ea4d0d8c Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Thu, 13 Jul 2023 17:27:43 +0400 Subject: [PATCH 09/19] [TH2-4887] added suppressions.xml --- build.gradle | 2 +- suppressions.xml | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 suppressions.xml diff --git a/build.gradle b/build.gradle index 1530118..cd39222 100644 --- a/build.gradle +++ b/build.gradle @@ -150,7 +150,7 @@ configurations { dependencyCheck { formats = ['SARIF', 'JSON', 'HTML'] failBuildOnCVSS = 5 - + suppressionFile = file('suppressions.xml') analyzers { assemblyEnabled = false nugetconfEnabled = false diff --git a/suppressions.xml b/suppressions.xml new file mode 100644 index 0000000..52da5f2 --- /dev/null +++ b/suppressions.xml @@ -0,0 +1,9 @@ + + + + + + ^pkg:maven/com\.exactpro\.th2/task-utils@.*$ + cpe:/a:utils_project:utils + + \ No newline at end of file From c93fd81c9d4fc8a4ef5348c4277261291f2e7174 Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Thu, 13 Jul 2023 17:27:43 +0400 Subject: [PATCH 10/19] [TH2-4887] added suppressions.xml --- build.gradle | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index cd39222..6003505 100644 --- a/build.gradle +++ b/build.gradle @@ -87,10 +87,7 @@ jar { dependencies { api platform('com.exactpro.th2:bom:4.4.0') - implementation('com.exactpro.th2:common:5.3.0-separate-executor-+') { - exclude group: 'com.exactpro.th2', module: 'cradle-cassandra' - exclude group: 'com.exactpro.th2', module: 'cradle-core' - } + implementation 'com.exactpro.th2:common:5.3.0-separate-executor-+' implementation 'com.exactpro.th2:common-utils:2.1.0-transport-protocol-+' implementation 'com.exactpro.th2:codec:5.3.0-new-proto-+' From 7f5721d2596e70f242eafe62aa09a45beb378e7f Mon Sep 17 00:00:00 2001 From: Oleg Smelov Date: Wed, 2 Aug 2023 16:34:27 +0400 Subject: [PATCH 11/19] dependencies --- build.gradle | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index 6003505..9283b2a 100644 --- a/build.gradle +++ b/build.gradle @@ -85,23 +85,23 @@ jar { } dependencies { - api platform('com.exactpro.th2:bom:4.4.0') + api platform("com.exactpro.th2:bom:4.4.0") - implementation 'com.exactpro.th2:common:5.3.0-separate-executor-+' - implementation 'com.exactpro.th2:common-utils:2.1.0-transport-protocol-+' - implementation 'com.exactpro.th2:codec:5.3.0-new-proto-+' + implementation "com.exactpro.th2:common:5.3.0-separate-executor-5712647407-cd52dd9-SNAPSHOT" + implementation "com.exactpro.th2:common-utils:2.1.0-transport-protocol-5599170164-aa085e1-SNAPSHOT" + implementation "com.exactpro.th2:codec:5.3.0-new-proto-5736204737-92216cf-SNAPSHOT" - implementation 'com.exactpro.th2:sailfish-utils:4.0.0-TH2-4891-+' + implementation "com.exactpro.th2:sailfish-utils:4.0.0-TH2-4891-5551590515-3b92506-SNAPSHOT" - compileOnly 'com.google.auto.service:auto-service:1.1.1' - annotationProcessor 'com.google.auto.service:auto-service:1.1.1' - kapt 'com.google.auto.service:auto-service:1.1.1' + compileOnly "com.google.auto.service:auto-service:1.1.1" + annotationProcessor "com.google.auto.service:auto-service:1.1.1" + kapt "com.google.auto.service:auto-service:1.1.1" - implementation group: 'io.github.microutils', name: 'kotlin-logging', version: '3.0.0' - implementation group: 'com.athaydes.rawhttp', name: 'rawhttp-core', version: '2.4.1' + implementation "io.github.microutils:kotlin-logging:3.0.0" // The last version bases on kotlin 1.6.0 + implementation "com.athaydes.rawhttp:rawhttp-core:2.4.1" - testImplementation group: 'org.jetbrains.kotlin', name: 'kotlin-test-junit5', version: kotlin_version - testImplementation 'org.junit.jupiter:junit-jupiter:5.9.3' + testImplementation "org.jetbrains.kotlin:kotlin-test-junit5:$kotlin_version" + testImplementation "org.junit.jupiter:junit-jupiter:5.9.3" } application { From 4537fce97919c04ca3183beeb325d83737a0e1de Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Sun, 20 Aug 2023 10:53:14 +0400 Subject: [PATCH 12/19] [TH2-4934] Updated dependencies --- build.gradle | 18 +++++++++--------- gradle.properties | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build.gradle b/build.gradle index 9283b2a..02846eb 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { } ext { - sailfishVersion = '3.3.93' + sailfishVersion = '3.3.111' } group = 'com.exactpro.th2' @@ -85,23 +85,23 @@ jar { } dependencies { - api platform("com.exactpro.th2:bom:4.4.0") + api platform("com.exactpro.th2:bom:4.5.0") - implementation "com.exactpro.th2:common:5.3.0-separate-executor-5712647407-cd52dd9-SNAPSHOT" - implementation "com.exactpro.th2:common-utils:2.1.0-transport-protocol-5599170164-aa085e1-SNAPSHOT" - implementation "com.exactpro.th2:codec:5.3.0-new-proto-5736204737-92216cf-SNAPSHOT" + implementation "com.exactpro.th2:common:5.4.0-dev" + implementation "com.exactpro.th2:common-utils:2.2.0-dev" + implementation "com.exactpro.th2:codec:5.3.0-new-proto-+" - implementation "com.exactpro.th2:sailfish-utils:4.0.0-TH2-4891-5551590515-3b92506-SNAPSHOT" + implementation "com.exactpro.th2:sailfish-utils:4.1.0-dev" compileOnly "com.google.auto.service:auto-service:1.1.1" annotationProcessor "com.google.auto.service:auto-service:1.1.1" kapt "com.google.auto.service:auto-service:1.1.1" - implementation "io.github.microutils:kotlin-logging:3.0.0" // The last version bases on kotlin 1.6.0 + implementation "io.github.microutils:kotlin-logging:3.0.5" implementation "com.athaydes.rawhttp:rawhttp-core:2.4.1" - testImplementation "org.jetbrains.kotlin:kotlin-test-junit5:$kotlin_version" - testImplementation "org.junit.jupiter:junit-jupiter:5.9.3" + testImplementation "org.jetbrains.kotlin:kotlin-test-junit5" + testImplementation "org.junit.jupiter:junit-jupiter:5.10.0" } application { diff --git a/gradle.properties b/gradle.properties index 247b36e..a4f6dcb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ kotlin.code.style=official -kotlin_version=1.6.21 +kotlin_version=1.8.22 release_version=0.4.0 \ No newline at end of file From 22cebf13ba3af8af019eb121d7b8718ef5a207bd Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Thu, 7 Dec 2023 19:42:43 +0400 Subject: [PATCH 13/19] [TH2-5143] Updated dependencies --- README.md | 9 ++++++++- build.gradle | 8 ++++---- gradle.properties | 2 +- .../com/exactpro/th2/codec/http/HttpPipelineCodec.kt | 9 +++++---- .../exactpro/th2/codec/http/HttpPipelineCodecFactory.kt | 6 +++--- .../kotlin/com/exactpro/th2/codec/http/DecodeTest.kt | 9 +++++---- .../kotlin/com/exactpro/th2/codec/http/EncodeTest.kt | 9 +++++---- 7 files changed, 31 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index ba9c43b..98612b5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# HTTP Codec v0.4.0 +# HTTP Codec v0.5.0 This microservice can encode and decode HTTP messages @@ -129,6 +129,13 @@ It's been verified that Sailfish itself is compatible with versions from BOM and # Release notes +## 0.5.0 + ++ Updated common: `5.7.2-dev` ++ Updated common-utils: `2.2.2-dev` ++ Updated codec: `5.4.1-dev` ++ Updated sailfish-utils: `4.1.1-dev` + ## 0.4.0 + th2 transport protocol support diff --git a/build.gradle b/build.gradle index 02846eb..2c6b71e 100644 --- a/build.gradle +++ b/build.gradle @@ -87,11 +87,11 @@ jar { dependencies { api platform("com.exactpro.th2:bom:4.5.0") - implementation "com.exactpro.th2:common:5.4.0-dev" - implementation "com.exactpro.th2:common-utils:2.2.0-dev" - implementation "com.exactpro.th2:codec:5.3.0-new-proto-+" + implementation "com.exactpro.th2:common:5.7.2-TH2-5143-+" + implementation "com.exactpro.th2:common-utils:2.2.2-dev" + implementation "com.exactpro.th2:codec:5.4.1-TH2-5143-+" - implementation "com.exactpro.th2:sailfish-utils:4.1.0-dev" + implementation "com.exactpro.th2:sailfish-utils:4.1.1-dev" compileOnly "com.google.auto.service:auto-service:1.1.1" annotationProcessor "com.google.auto.service:auto-service:1.1.1" diff --git a/gradle.properties b/gradle.properties index a4f6dcb..545ac37 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ kotlin.code.style=official kotlin_version=1.8.22 -release_version=0.4.0 \ No newline at end of file +release_version=0.5.0 \ No newline at end of file diff --git a/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt b/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt index 6d2c911..957e05d 100644 --- a/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt +++ b/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt @@ -17,6 +17,7 @@ package com.exactpro.th2.codec.http import com.exactpro.th2.codec.api.IPipelineCodec +import com.exactpro.th2.codec.api.IReportingContext import com.exactpro.th2.codec.http.HttpPipelineCodecFactory.Companion.PROTOCOL import com.exactpro.th2.common.grpc.AnyMessage.KindCase.MESSAGE import com.exactpro.th2.common.grpc.AnyMessage.KindCase.RAW_MESSAGE @@ -57,7 +58,7 @@ import com.exactpro.th2.common.grpc.RawMessage as ProtoRawMessage class HttpPipelineCodec : IPipelineCodec { - override fun encode(messageGroup: ProtoMessageGroup): ProtoMessageGroup { + override fun encode(messageGroup: ProtoMessageGroup, context: IReportingContext): ProtoMessageGroup { val messages = messageGroup.messagesList require(messages.size <= 2) { "Message group must contain at most 2 messages" } @@ -131,7 +132,7 @@ class HttpPipelineCodec : IPipelineCodec { return builder.build() } - override fun encode(messageGroup: MessageGroup): MessageGroup { + override fun encode(messageGroup: MessageGroup, context: IReportingContext): MessageGroup { val messages = messageGroup.messages require(messages.size <= 2) { "Message group must contain at most 2 messages" } @@ -201,7 +202,7 @@ class HttpPipelineCodec : IPipelineCodec { return MessageGroup(encodedMessages) } - override fun decode(messageGroup: ProtoMessageGroup): ProtoMessageGroup { + override fun decode(messageGroup: ProtoMessageGroup, context: IReportingContext): ProtoMessageGroup { val messages = messageGroup.messagesList require(messages.size == 1) { "Message group must contain only 1 message" } @@ -231,7 +232,7 @@ class HttpPipelineCodec : IPipelineCodec { return builder.build() } - override fun decode(messageGroup: MessageGroup): MessageGroup { + override fun decode(messageGroup: MessageGroup, context: IReportingContext): MessageGroup { val messages = messageGroup.messages require(messages.size == 1) { "Message group must contain only 1 message" } diff --git a/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodecFactory.kt b/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodecFactory.kt index 16993a8..c38224f 100644 --- a/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodecFactory.kt +++ b/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodecFactory.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 Exactpro (Exactpro Systems Limited) + * Copyright 2020-2023 Exactpro (Exactpro Systems Limited) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,12 +25,12 @@ import com.google.auto.service.AutoService @AutoService(IPipelineCodecFactory::class) class HttpPipelineCodecFactory : IPipelineCodecFactory { override val settingsClass: Class = HttpPipelineCodecSettings::class.java - @Deprecated("Please migrate to the protocols property") - override val protocol: String = PROTOCOL + override val protocols: Set get() = PROTOCOLS override fun init(pipelineCodecContext: IPipelineCodecContext) = Unit override fun create(settings: IPipelineCodecSettings?): IPipelineCodec = HttpPipelineCodec() companion object { const val PROTOCOL = "http" + private val PROTOCOLS = setOf(PROTOCOL) } } \ No newline at end of file diff --git a/src/test/kotlin/com/exactpro/th2/codec/http/DecodeTest.kt b/src/test/kotlin/com/exactpro/th2/codec/http/DecodeTest.kt index 8eae15e..186d996 100644 --- a/src/test/kotlin/com/exactpro/th2/codec/http/DecodeTest.kt +++ b/src/test/kotlin/com/exactpro/th2/codec/http/DecodeTest.kt @@ -16,6 +16,7 @@ package com.exactpro.th2.codec.http +import com.exactpro.th2.codec.api.impl.ReportingContext import com.exactpro.th2.codec.http.HttpPipelineCodecFactory.Companion.PROTOCOL import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.RawMessage import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.ParsedMessage @@ -58,7 +59,7 @@ class DecodeTest { val messageGroup = ProtoMessageGroup.newBuilder().addMessages(ProtoAnyMessage.newBuilder().setRawMessage(message).build()).build() - val decodedEventID = codec.decode(messageGroup).getMessages(0).message.parentEventId + val decodedEventID = codec.decode(messageGroup, ReportingContext()).getMessages(0).message.parentEventId assertEquals(eventID, decodedEventID.id) } @@ -84,7 +85,7 @@ class DecodeTest { val messageGroup = ProtoMessageGroup.newBuilder().addMessages(ProtoAnyMessage.newBuilder().setRawMessage(message).build()).build() - val decodedEventID = codec.decode(messageGroup).getMessages(0).message.parentEventId + val decodedEventID = codec.decode(messageGroup, ReportingContext()).getMessages(0).message.parentEventId assertEquals(eventID, decodedEventID.id) } @@ -110,7 +111,7 @@ class DecodeTest { val messageGroup = MessageGroup(listOf(message)) - val decodedGroup = codec.decode(messageGroup) + val decodedGroup = codec.decode(messageGroup, ReportingContext()) val decodedMessage = decodedGroup.messages[0] as ParsedMessage @@ -151,7 +152,7 @@ class DecodeTest { val messageGroup = MessageGroup(listOf(message)) - val decodedGroup = codec.decode(messageGroup) + val decodedGroup = codec.decode(messageGroup, ReportingContext()) assertEquals(1, decodedGroup.messages.size) diff --git a/src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt b/src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt index 95e2798..dd10d43 100644 --- a/src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt +++ b/src/test/kotlin/com/exactpro/th2/codec/http/EncodeTest.kt @@ -16,6 +16,7 @@ package com.exactpro.th2.codec.http +import com.exactpro.th2.codec.api.impl.ReportingContext import com.exactpro.th2.codec.http.HttpPipelineCodecFactory.Companion.PROTOCOL import com.exactpro.th2.common.grpc.AnyMessage as ProtoAnyMessage import com.exactpro.th2.common.grpc.Message as ProtoMessage @@ -47,7 +48,7 @@ class EncodeTest { val messageGroup = ProtoMessageGroup.newBuilder().addMessages(ProtoAnyMessage.newBuilder().setMessage(message).build()).build() - val encodedEventID = codec.encode(messageGroup).getMessages(0).rawMessage.parentEventId + val encodedEventID = codec.encode(messageGroup, ReportingContext()).getMessages(0).rawMessage.parentEventId assertEquals(eventID, encodedEventID.id) } @@ -66,7 +67,7 @@ class EncodeTest { } val messageGroup = ProtoMessageGroup.newBuilder().addMessages(ProtoAnyMessage.newBuilder().setMessage(message).build()).build() - val encodedEventID = codec.encode(messageGroup).getMessages(0).rawMessage.parentEventId + val encodedEventID = codec.encode(messageGroup, ReportingContext()).getMessages(0).rawMessage.parentEventId assertEquals(eventID, encodedEventID.id) } @@ -87,7 +88,7 @@ class EncodeTest { ) val messageGroup = MessageGroup(listOf(message)) - val encodedGroup = codec.encode(messageGroup) + val encodedGroup = codec.encode(messageGroup, ReportingContext()) val encodedMessage = encodedGroup.messages[0] as RawMessage val encodedEventID = encodedMessage.eventId @@ -113,7 +114,7 @@ class EncodeTest { ) val messageGroup = MessageGroup(listOf(message)) - val encodedGroup = codec.encode(messageGroup) + val encodedGroup = codec.encode(messageGroup, ReportingContext()) val encodedMessage = encodedGroup.messages[0] as RawMessage val encodedEventID = encodedMessage.eventId From 253f278059ce59b461d3db3a03a5c7a5563d669c Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Fri, 8 Dec 2023 17:40:01 +0400 Subject: [PATCH 14/19] [TH2-5143] use release version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2c6b71e..dca60fa 100644 --- a/build.gradle +++ b/build.gradle @@ -87,7 +87,7 @@ jar { dependencies { api platform("com.exactpro.th2:bom:4.5.0") - implementation "com.exactpro.th2:common:5.7.2-TH2-5143-+" + implementation "com.exactpro.th2:common:5.7.2-dev" implementation "com.exactpro.th2:common-utils:2.2.2-dev" implementation "com.exactpro.th2:codec:5.4.1-TH2-5143-+" From c72b7b308c04ed5e8bb37dd31144f5cc9f462d71 Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Mon, 11 Dec 2023 13:49:03 +0400 Subject: [PATCH 15/19] [TH2-5143] refactored after review --- README.md | 9 +--- build.gradle | 44 +------------------ .../th2/codec/http/HttpPipelineCodec.kt | 2 +- 3 files changed, 3 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 98612b5..a8e7813 100644 --- a/README.md +++ b/README.md @@ -120,13 +120,6 @@ spec: enabled: false ``` -### Gradle metadata note - -ignoreGradleMetadataRedirection is used for sonatype because Sailfish dependencies have constrains that interfere with -BOM, so we exclude Gradle metadata for these repositories. - -It's been verified that Sailfish itself is compatible with versions from BOM and therefore safe to use. - # Release notes ## 0.5.0 @@ -134,7 +127,7 @@ It's been verified that Sailfish itself is compatible with versions from BOM and + Updated common: `5.7.2-dev` + Updated common-utils: `2.2.2-dev` + Updated codec: `5.4.1-dev` -+ Updated sailfish-utils: `4.1.1-dev` ++ Removed sailfish-utils ## 0.4.0 diff --git a/build.gradle b/build.gradle index dca60fa..2ed2790 100644 --- a/build.gradle +++ b/build.gradle @@ -6,62 +6,22 @@ plugins { id "org.owasp.dependencycheck" version "8.2.1" } -ext { - sailfishVersion = '3.3.111' -} - group = 'com.exactpro.th2' version = release_version sourceCompatibility = 11 targetCompatibility = 11 -ext.excludeSailfish = { rcd -> - rcd.excludeModule("com.exactpro.sf", "sailfish-core") - rcd.excludeModule("com.exactpro.sf", "sailfish-common") - rcd.excludeModule("com.exactpro.sf", "sailfish-rest-api-client") - rcd.excludeModule("com.exactpro.sf", "service-http") -} - repositories { + mavenCentral() maven { name 'Sonatype_snapshots' url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' - content { - excludeSailfish(it) - } - } - - // ignoreGradleMetadataRedirection is used for sonatype because - // Sailfish dependencies have constrains that interfere with our BOM - // so we exclude Gradle metadata for this repositories. - // We've checked these versions - they are compatible and safe to use - maven { - name 'Sonatype_snapshots' - url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' - metadataSources { - mavenPom() - artifact() - ignoreGradleMetadataRedirection() - } - } - maven { - name 'Sonatype_releases' - url 'https://s01.oss.sonatype.org/content/repositories/releases/' - content { - excludeSailfish(it) - } } maven { name 'Sonatype_releases' url 'https://s01.oss.sonatype.org/content/repositories/releases/' - metadataSources { - mavenPom() - artifact() - ignoreGradleMetadataRedirection() - } } - mavenCentral() mavenLocal() configurations.configureEach { @@ -91,8 +51,6 @@ dependencies { implementation "com.exactpro.th2:common-utils:2.2.2-dev" implementation "com.exactpro.th2:codec:5.4.1-TH2-5143-+" - implementation "com.exactpro.th2:sailfish-utils:4.1.1-dev" - compileOnly "com.google.auto.service:auto-service:1.1.1" annotationProcessor "com.google.auto.service:auto-service:1.1.1" kapt "com.google.auto.service:auto-service:1.1.1" diff --git a/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt b/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt index 957e05d..700bc9e 100644 --- a/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt +++ b/src/main/kotlin/com/exactpro/th2/codec/http/HttpPipelineCodec.kt @@ -240,7 +240,7 @@ class HttpPipelineCodec : IPipelineCodec { val message = messages[0] require(message is RawMessage) { "Message must be a raw message" } - val body = message.body.toByteArray().toString(UTF_8) + val body = message.body.toString(UTF_8) val decodedMessages = mutableListOf>() when (val direction = message.id.direction) { From 70586c801fc62ab9e023e4140c4bd61874ee3cf7 Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Thu, 21 Dec 2023 11:49:00 +0400 Subject: [PATCH 16/19] [TH2-5143] bumped rebuild --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 545ac37..6403218 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ kotlin.code.style=official kotlin_version=1.8.22 -release_version=0.5.0 \ No newline at end of file +release_version=0.5.0 From 8b2b934a16feb7bbb2342b399aeadeea6af9295a Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Fri, 29 Dec 2023 12:06:18 +0400 Subject: [PATCH 17/19] [TH2-5143] migrate to th2-codec release --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2ed2790..9155ccd 100644 --- a/build.gradle +++ b/build.gradle @@ -49,7 +49,7 @@ dependencies { implementation "com.exactpro.th2:common:5.7.2-dev" implementation "com.exactpro.th2:common-utils:2.2.2-dev" - implementation "com.exactpro.th2:codec:5.4.1-TH2-5143-+" + implementation "com.exactpro.th2:codec:5.4.1-dev" compileOnly "com.google.auto.service:auto-service:1.1.1" annotationProcessor "com.google.auto.service:auto-service:1.1.1" From 76916e893ede302dcbf0cbd8db9cb5719c313a8f Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Fri, 29 Dec 2023 13:20:39 +0400 Subject: [PATCH 18/19] [TH2-5143] rollback release version because previous release wasn't published --- README.md | 14 +++++--------- gradle.properties | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a8e7813..cc401ce 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# HTTP Codec v0.5.0 +# HTTP Codec v0.4.0 This microservice can encode and decode HTTP messages @@ -122,20 +122,16 @@ spec: # Release notes -## 0.5.0 +## 0.4.0 ++ th2 transport protocol support ++ Updated bom: `4.5.0-dev` + Updated common: `5.7.2-dev` + Updated common-utils: `2.2.2-dev` + Updated codec: `5.4.1-dev` ++ Updated kotlin: `1.8.22` + Removed sailfish-utils -## 0.4.0 - -+ th2 transport protocol support -+ Updated bom:4.4.0 -+ Updated common:5.3.0 -+ Updated codec:5.3.0 - ## 0.3.0 * th2-common upgrade to `3.44.0` diff --git a/gradle.properties b/gradle.properties index 6403218..2412c75 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ kotlin.code.style=official kotlin_version=1.8.22 -release_version=0.5.0 +release_version=0.4.0 From 225e15632dd77185380f31f21b1568acad00fc73 Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Fri, 29 Dec 2023 14:04:29 +0400 Subject: [PATCH 19/19] Added dev-release github workflow --- ...lease-java-publish-sonatype-and-docker.yml | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/dev-release-java-publish-sonatype-and-docker.yml diff --git a/.github/workflows/dev-release-java-publish-sonatype-and-docker.yml b/.github/workflows/dev-release-java-publish-sonatype-and-docker.yml new file mode 100644 index 0000000..e515f3a --- /dev/null +++ b/.github/workflows/dev-release-java-publish-sonatype-and-docker.yml @@ -0,0 +1,22 @@ +name: Build and release Java distributions to sonatype. + +on: + push: + tags: + - \d+.\d+.\d+-dev + +jobs: + build: + uses: th2-net/.github/.github/workflows/compound-java.yml@main + with: + build-target: 'Docker' + runsOn: ubuntu-latest + gradleVersion: '7' + docker-username: ${{ github.actor }} + devRelease: true + secrets: + sonatypeUsername: ${{ secrets.SONATYPE_NEXUS_USERNAME }} + sonatypePassword: ${{ secrets.SONATYPE_NEXUS_PASSWORD }} + sonatypeSigningKey: ${{ secrets.SONATYPE_GPG_ARMORED_KEY }} + sonatypeSigningPassword: ${{ secrets.SONATYPE_SIGNING_PASSWORD }} + docker-password: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file