Skip to content
Merged
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
20 changes: 18 additions & 2 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"fmt"
)

//DoNotSend is a convenience error to indicate a DoNotSend in ToApp
var DoNotSend = errors.New("Do Not Send")
//ErrDoNotSend is a convenience error to indicate a DoNotSend in ToApp
var ErrDoNotSend = errors.New("Do Not Send")

//rejectReason enum values.
const (
Expand Down Expand Up @@ -37,6 +37,22 @@ type MessageRejectError interface {
IsBusinessReject() bool
}

//RejectLogon indicates the application is rejecting permission to logon. Implements MessageRejectError
type RejectLogon struct {
Text string
}

func (e RejectLogon) Error() string { return e.Text }

//RefTagID implements MessageRejectError
func (RejectLogon) RefTagID() *Tag { return nil }

//RejectReason implements MessageRejectError
func (RejectLogon) RejectReason() int { return 0 }

//IsBusinessReject implements MessageRejectError
func (RejectLogon) IsBusinessReject() bool { return false }

type messageRejectError struct {
rejectReason int
text string
Expand Down
19 changes: 18 additions & 1 deletion logon_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,24 @@ func (s logonState) FixMsgIn(session *session, msg Message) (nextState sessionSt
}

if err := session.handleLogon(msg); err != nil {
return handleStateError(session, err)
switch err := err.(type) {
case RejectLogon:
session.log.OnEvent(err.Text)
msg := session.buildLogout(err.Text)

if err := session.dropAndSend(msg, false); err != nil {
session.logError(err)
}

if err := session.store.IncrNextTargetMsgSeqNum(); err != nil {
session.logError(err)
}

return latentState{}

default:
return handleStateError(session, err)
}
}
return inSession{}
}
Expand Down
32 changes: 28 additions & 4 deletions logon_state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ func (s *LogonStateTestSuite) TestFixMsgInNotLogon() {
}

func (s *LogonStateTestSuite) TestFixMsgInLogon() {
s.store.IncrNextSenderMsgSeqNum()
s.Require().Nil(s.store.IncrNextSenderMsgSeqNum())
s.MessageFactory.seqNum = 1
s.store.IncrNextTargetMsgSeqNum()
s.Require().Nil(s.store.IncrNextTargetMsgSeqNum())

logon := s.Logon()
logon.Body.SetField(tagHeartBtInt, FIXInt(32))
Expand All @@ -93,9 +93,9 @@ func (s *LogonStateTestSuite) TestFixMsgInLogon() {

func (s *LogonStateTestSuite) TestFixMsgInLogonInitiateLogon() {
s.session.InitiateLogon = true
s.store.IncrNextSenderMsgSeqNum()
s.Require().Nil(s.store.IncrNextSenderMsgSeqNum())
s.MessageFactory.seqNum = 1
s.store.IncrNextTargetMsgSeqNum()
s.Require().Nil(s.store.IncrNextTargetMsgSeqNum())

logon := s.Logon()
logon.Body.SetField(tagHeartBtInt, FIXInt(32))
Expand Down Expand Up @@ -150,3 +150,27 @@ func (s *LogonStateTestSuite) TestStop() {
s.Stopped()
}
}

func (s *LogonStateTestSuite) TestFixMsgInLogonRejectLogon() {
s.Require().Nil(s.store.IncrNextSenderMsgSeqNum())
s.MessageFactory.seqNum = 1
s.Require().Nil(s.store.IncrNextTargetMsgSeqNum())

logon := s.Logon()
logon.Body.SetField(tagHeartBtInt, FIXInt(32))

s.MockApp.On("FromAdmin").Return(RejectLogon{"reject message"})
s.MockApp.On("ToAdmin")
s.fixMsgIn(s.session, logon)

s.MockApp.AssertExpectations(s.T())

s.State(latentState{})

s.LastToAdminMessageSent()
s.MessageType(enum.MsgType_LOGOUT, s.MockApp.lastToAdmin)
s.FieldEquals(tagText, "reject message", s.MockApp.lastToAdmin.Body)

s.NextTargetMsgSeqNum(3)
s.NextSenderMsgSeqNum(3)
}
8 changes: 7 additions & 1 deletion session.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func (s *session) sendLogon(resetStore, setResetSeqNum bool) error {
return nil
}

func (s *session) sendLogout(reason string) error {
func (s *session) buildLogout(reason string) Message {
logout := NewMessage()
logout.Header.SetField(tagMsgType, FIXString("5"))
logout.Header.SetField(tagBeginString, FIXString(s.sessionID.BeginString))
Expand All @@ -137,6 +137,12 @@ func (s *session) sendLogout(reason string) error {
if reason != "" {
logout.Body.SetField(tagText, FIXString(reason))
}

return logout
}

func (s *session) sendLogout(reason string) error {
logout := s.buildLogout(reason)
return s.send(logout)
}

Expand Down
8 changes: 4 additions & 4 deletions session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -611,8 +611,8 @@ func (suite *SessionSendTestSuite) TestQueueForSendAppMessage() {
}

func (suite *SessionSendTestSuite) TestQueueForSendDoNotSendAppMessage() {
suite.MockApp.On("ToApp").Return(DoNotSend)
suite.Equal(DoNotSend, suite.queueForSend(suite.NewOrderSingle()))
suite.MockApp.On("ToApp").Return(ErrDoNotSend)
suite.Equal(ErrDoNotSend, suite.queueForSend(suite.NewOrderSingle()))

suite.MockApp.AssertExpectations(suite.T())
suite.NoMessagePersisted(1)
Expand Down Expand Up @@ -649,8 +649,8 @@ func (suite *SessionSendTestSuite) TestSendAppMessage() {
}

func (suite *SessionSendTestSuite) TestSendAppDoNotSendMessage() {
suite.MockApp.On("ToApp").Return(DoNotSend)
suite.Equal(DoNotSend, suite.send(suite.NewOrderSingle()))
suite.MockApp.On("ToApp").Return(ErrDoNotSend)
suite.Equal(ErrDoNotSend, suite.send(suite.NewOrderSingle()))

suite.MockApp.AssertExpectations(suite.T())
suite.NextSenderMsgSeqNum(1)
Expand Down