From b164737a4756886ef9d6d9681ac548118c9349f3 Mon Sep 17 00:00:00 2001 From: dankl Date: Fri, 4 Oct 2019 00:11:53 +0200 Subject: [PATCH] Implemented MessageBuilder to have a way to calculate message size and to generically create messages --- .../kotlin/net/dankito/fints/FinTsClient.kt | 8 +- .../dankito/fints/messages/MessageBuilder.kt | 76 +++++++++++++++++++ .../DialoginitialisierungAnonym.kt | 20 ----- ...ungAnonymTest.kt => MessageBuilderTest.kt} | 14 ++-- 4 files changed, 89 insertions(+), 29 deletions(-) create mode 100644 fints4javaLib/src/main/kotlin/net/dankito/fints/messages/MessageBuilder.kt delete mode 100644 fints4javaLib/src/main/kotlin/net/dankito/fints/messages/nachrichten/implementierte/DialoginitialisierungAnonym.kt rename fints4javaLib/src/test/kotlin/net/dankito/fints/messages/{nachrichten/implementierte/DialoginitialisierungAnonymTest.kt => MessageBuilderTest.kt} (54%) diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/FinTsClient.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/FinTsClient.kt index 97c48e62..7d1754ad 100644 --- a/fints4javaLib/src/main/kotlin/net/dankito/fints/FinTsClient.kt +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/FinTsClient.kt @@ -1,6 +1,6 @@ package net.dankito.fints -import net.dankito.fints.messages.nachrichten.implementierte.DialoginitialisierungAnonym +import net.dankito.fints.messages.MessageBuilder import net.dankito.fints.model.BankInfo import net.dankito.fints.model.ProductInfo import net.dankito.fints.util.IBase64Service @@ -11,15 +11,15 @@ import net.dankito.utils.web.client.RequestParameters open class FinTsClient( protected val base64Service: IBase64Service, - protected val webClient: IWebClient = OkHttpWebClient() + protected val webClient: IWebClient = OkHttpWebClient(), + protected val messageBuilder: MessageBuilder = MessageBuilder() ) { fun getBankInfo(bankInfo: BankInfo, productInfo: ProductInfo) { - val dialogInit = DialoginitialisierungAnonym(bankInfo.countryCode, bankInfo.bankCode, + val requestBody = messageBuilder.createAnonymousDialogInitMessage(bankInfo.countryCode, bankInfo.bankCode, productInfo.productName, productInfo.productVersion) - val requestBody = dialogInit.format() val encodedRequestBody = base64Service.encode(requestBody) val response = webClient.post(RequestParameters(bankInfo.finTsServerAddress, encodedRequestBody, "application/octet-stream")) diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/MessageBuilder.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/MessageBuilder.kt new file mode 100644 index 00000000..d9066161 --- /dev/null +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/MessageBuilder.kt @@ -0,0 +1,76 @@ +package net.dankito.fints.messages + +import net.dankito.fints.messages.datenelemente.implementierte.* +import net.dankito.fints.messages.nachrichten.Nachricht +import net.dankito.fints.messages.segmente.Segment +import net.dankito.fints.messages.segmente.implementierte.IdentifikationsSegment +import net.dankito.fints.messages.segmente.implementierte.Nachrichtenabschluss +import net.dankito.fints.messages.segmente.implementierte.Nachrichtenkopf +import net.dankito.fints.messages.segmente.implementierte.Verarbeitungsvorbereitung + + +/** + * Takes the Segments of they payload, may signs and encrypts them, calculates message size, + * adds the message header and closing, and formats the whole message to string. + */ +open class MessageBuilder { + + companion object { + const val MessageHeaderLength = 30 + const val MessageClosingLength = 11 + const val AddedSeparatorsLength = 3 + } + + + /** + * Um Kunden die Möglichkeit zu geben, sich anonym anzumelden, um sich bspw. über die + * angebotenen Geschäftsvorfälle fremder Kreditinstitute (von denen sie keine BPD besitzen) + * zu informieren bzw. nicht-signierungspflichtige Aufträge bei fremden Kreditinstituten + * einreichen zu können, kann sich der Kunde anonym (als Gast) anmelden. + * + * Bei anonymen Dialogen werden Nachrichten weder signiert, noch können sie verschlüsselt und komprimiert werden. + */ + open fun createAnonymousDialogInitMessage( + bankCountryCode: Int, + bankCode: String, + productName: String, + productVersion: String + ): String { + return createDialogInitMessage(bankCountryCode, bankCode, KundenID.Anonymous, KundensystemID.Anonymous, + BPDVersion.VersionNotReceivedYet, UPDVersion.VersionNotReceivedYet, Dialogsprache.Default, productName, productVersion) + } + + open fun createDialogInitMessage( + bankCountryCode: Int, + bankCode: String, + customerId: String, + customerSystemId: String, + bpdVersion: Int, + updVersion: Int, + language: Dialogsprache, + productName: String, + productVersion: String + ): String { + return createMessage(listOf( + IdentifikationsSegment(2, bankCountryCode, bankCode, customerId, customerSystemId), + Verarbeitungsvorbereitung(3, bpdVersion, updVersion, language, productName, productVersion) + )) + } + + + open fun createMessage(payloadSegments: List): String { + + val payload = payloadSegments.joinToString(Nachricht.SegmentSeparator) { it.format() } + + val messageSize = payload.length + MessageHeaderLength + MessageClosingLength + AddedSeparatorsLength + val messageNumber = Nachrichtennummer.FirstMessageNumber + + val header = Nachrichtenkopf(1, messageSize, "0", messageNumber) + + val closing = Nachrichtenabschluss(4, messageNumber) + + return listOf(header.format(), payload, closing.format()) + .joinToString(Nachricht.SegmentSeparator, postfix = Nachricht.SegmentSeparator) + } + +} \ No newline at end of file diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/nachrichten/implementierte/DialoginitialisierungAnonym.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/nachrichten/implementierte/DialoginitialisierungAnonym.kt deleted file mode 100644 index 835f7458..00000000 --- a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/nachrichten/implementierte/DialoginitialisierungAnonym.kt +++ /dev/null @@ -1,20 +0,0 @@ -package net.dankito.fints.messages.nachrichten.implementierte - -import net.dankito.fints.messages.datenelemente.implementierte.* - - -/** - * Um Kunden die Möglichkeit zu geben, sich anonym anzumelden, um sich bspw. über die - * angebotenen Geschäftsvorfälle fremder Kreditinstitute (von denen sie keine BPD besitzen) - * zu informieren bzw. nicht-signierungspflichtige Aufträge bei fremden Kreditinstituten - * einreichen zu können, kann sich der Kunde anonym (als Gast) anmelden. - * - * Bei anonymen Dialogen werden Nachrichten weder signiert, noch können sie verschlüsselt und komprimiert werden. - */ -open class DialoginitialisierungAnonym( - bankCountryCode: Int, - bankCode: String, - productName: String, - productVersion: String -) : Dialoginitialisierung(125, bankCountryCode, bankCode, KundenID.Anonymous, KundensystemID.Anonymous, - BPDVersion.VersionNotReceivedYet, UPDVersion.VersionNotReceivedYet, Dialogsprache.Default, productName, productVersion) \ No newline at end of file diff --git a/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/nachrichten/implementierte/DialoginitialisierungAnonymTest.kt b/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/MessageBuilderTest.kt similarity index 54% rename from fints4javaLib/src/test/kotlin/net/dankito/fints/messages/nachrichten/implementierte/DialoginitialisierungAnonymTest.kt rename to fints4javaLib/src/test/kotlin/net/dankito/fints/messages/MessageBuilderTest.kt index c9645fa3..6e9a6176 100644 --- a/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/nachrichten/implementierte/DialoginitialisierungAnonymTest.kt +++ b/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/MessageBuilderTest.kt @@ -1,17 +1,21 @@ -package net.dankito.fints.messages.nachrichten.implementierte +package net.dankito.fints.messages import net.dankito.fints.messages.datenelemente.implementierte.Laenderkennzeichen import org.assertj.core.api.Assertions.assertThat import org.junit.Test -class DialoginitialisierungAnonymTest { +class MessageBuilderTest { + + private val underTest = MessageBuilder() + @Test - fun format() { + fun createAnonymousDialogInitMessage() { // given - val underTest = DialoginitialisierungAnonym(Laenderkennzeichen.Germany, "12345678", "36792786FA12F235F04647689", "3") + val underTest = underTest.createAnonymousDialogInitMessage( + Laenderkennzeichen.Germany, "12345678", "FinTS-TestClient25Stellen", "1") // when val result = underTest.format() @@ -20,7 +24,7 @@ class DialoginitialisierungAnonymTest { assertThat(result).isEqualTo( "HNHBK:1:3+000000000125+300+0+1'" + "HKIDN:2:2+280:12345678+9999999999+0+0'" + - "HKVVB:3:3+0+0+0+36792786FA12F235F04647689+3'" + + "HKVVB:3:3+0+0+0+FinTS-TestClient25Stellen+1'" + "HNHBS:4:1+1'" ) }