From e5b52c0828dd11ae0d4359569629ff65f51315ab Mon Sep 17 00:00:00 2001 From: Darwayne Date: Sat, 28 Jul 2018 21:00:08 -0400 Subject: [PATCH] Adds support for RejectInvalidMessage configuration. --- config/configuration.go | 1 + config/doc.go | 8 ++++++++ session_factory.go | 6 ++++++ validation.go | 17 ++++++++++++----- validation_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 5 deletions(-) diff --git a/config/configuration.go b/config/configuration.go index a8b5ae2cf..cf208cfa7 100644 --- a/config/configuration.go +++ b/config/configuration.go @@ -48,4 +48,5 @@ const ( TimeStampPrecision string = "TimeStampPrecision" MaxLatency string = "MaxLatency" PersistMessages string = "PersistMessages" + RejectInvalidMessage string = "RejectInvalidMessage" ) diff --git a/config/doc.go b/config/doc.go index 48b4113b7..2338543f0 100644 --- a/config/doc.go +++ b/config/doc.go @@ -202,6 +202,14 @@ If set to N, fields that are out of order (i.e. body fields in the header, or he Defaults to Y. +RejectInvalidMessage + +If RejectInvalidMessage is set to N, zero errors will be thrown on reception of message that fails data dictionary validation. Valid Values: + Y + N + +Defaults to Y. + CheckLatency If set to Y, messages must be received from the counterparty within a defined number of seconds. It is useful to turn this off if a system uses localtime for it's timestamps instead of GMT. Valid Values: diff --git a/session_factory.go b/session_factory.go index 90e118290..36e294837 100644 --- a/session_factory.go +++ b/session_factory.go @@ -76,6 +76,12 @@ func (f sessionFactory) newSession( } } + if settings.HasSetting(config.RejectInvalidMessage) { + if validatorSettings.RejectInvalidMessage, err = settings.BoolSetting(config.RejectInvalidMessage); err != nil { + return + } + } + if sessionID.IsFIXT() { if s.DefaultApplVerID, err = settings.Setting(config.DefaultApplVerID); err != nil { return diff --git a/validation.go b/validation.go index 92aed28d5..6e28b8cd0 100644 --- a/validation.go +++ b/validation.go @@ -10,12 +10,15 @@ type validator interface { type validatorSettings struct { CheckFieldsOutOfOrder bool + RejectInvalidMessage bool + } //Default configuration for message validation. //See http://www.quickfixengine.org/quickfix/doc/html/configuration.html. var defaultValidatorSettings = validatorSettings{ CheckFieldsOutOfOrder: true, + RejectInvalidMessage: true, } type fixValidator struct { @@ -74,14 +77,18 @@ func validateFIX(d *datadictionary.DataDictionary, settings validatorSettings, m } } - if err := validateFields(d, d, msgType, msg); err != nil { - return err - } + if settings.RejectInvalidMessage { + if err := validateFields(d, d, msgType, msg); err != nil { + return err + } - if err := validateWalk(d, d, msgType, msg); err != nil { - return err + if err := validateWalk(d, d, msgType, msg); err != nil { + return err + } } + + return nil } diff --git a/validation_test.go b/validation_test.go index 1bc7c7000..7e5a7a3bc 100644 --- a/validation_test.go +++ b/validation_test.go @@ -37,6 +37,8 @@ func TestValidate(t *testing.T) { tcTagIsDefinedForMessage(), tcFieldNotFoundBody(), tcFieldNotFoundHeader(), + tcInvalidTagCheckDisabled(), + tcInvalidTagCheckEnabled(), } msg := NewMessage() @@ -378,6 +380,43 @@ func tcTagSpecifiedOutOfRequiredOrderTrailer() validateTest { } } +func tcInvalidTagCheckDisabled() validateTest { + dict, _ := datadictionary.Parse("spec/FIX40.xml") + validator := &fixValidator{dict, defaultValidatorSettings} + validator.settings.RejectInvalidMessage = false + + builder := createFIX40NewOrderSingle() + tag := Tag(9999) + builder.Body.SetField(tag, FIXString("hello")) + msgBytes := builder.build() + + return validateTest{ + TestName: "Invalid Tag Check - Disabled", + Validator: validator, + MessageBytes: msgBytes, + DoNotExpectReject: true, + } +} + +func tcInvalidTagCheckEnabled() validateTest { + dict, _ := datadictionary.Parse("spec/FIX40.xml") + validator := &fixValidator{dict, defaultValidatorSettings} + validator.settings.RejectInvalidMessage = true + + builder := createFIX40NewOrderSingle() + tag := Tag(9999) + builder.Body.SetField(tag, FIXString("hello")) + msgBytes := builder.build() + + return validateTest{ + TestName: "Invalid Tag Check - Enabled", + Validator: validator, + MessageBytes: msgBytes, + DoNotExpectReject: false, + ExpectedRefTagID: &tag, + } +} + func tcTagSpecifiedOutOfRequiredOrderDisabledHeader() validateTest { dict, _ := datadictionary.Parse("spec/FIX40.xml") validator := &fixValidator{dict, defaultValidatorSettings}