Implemented MessageBuilder to have a way to calculate message size and to generically create messages

This commit is contained in:
dankl 2019-10-04 00:11:53 +02:00 committed by dankito
parent 41e8dfae41
commit b164737a47
4 changed files with 89 additions and 29 deletions

View File

@ -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"))

View File

@ -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<Segment>): 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)
}
}

View File

@ -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)

View File

@ -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'"
)
}