108 lines
3.1 KiB
Go
108 lines
3.1 KiB
Go
// Copyright (c) quickfixengine.org All rights reserved.
|
|
//
|
|
// This file may be distributed under the terms of the quickfixengine.org
|
|
// license as defined by quickfixengine.org and appearing in the file
|
|
// LICENSE included in the packaging of this file.
|
|
//
|
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
|
|
// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
//
|
|
// Contact ask@quickfixengine.org if any conditions of this licensing
|
|
// are not clear to you.
|
|
|
|
package quickfix
|
|
|
|
type routeKey struct {
|
|
FIXVersion string
|
|
MsgType string
|
|
}
|
|
|
|
// FIX ApplVerID string values.
|
|
const (
|
|
ApplVerIDFIX27 = "0"
|
|
ApplVerIDFIX30 = "1"
|
|
ApplVerIDFIX40 = "2"
|
|
ApplVerIDFIX41 = "3"
|
|
ApplVerIDFIX42 = "4"
|
|
ApplVerIDFIX43 = "5"
|
|
ApplVerIDFIX44 = "6"
|
|
ApplVerIDFIX50 = "7"
|
|
ApplVerIDFIX50SP1 = "8"
|
|
ApplVerIDFIX50SP2 = "9"
|
|
)
|
|
|
|
// A MessageRoute is a function that can process a fromApp/fromAdmin callback.
|
|
type MessageRoute func(msg *Message, sessionID SessionID) MessageRejectError
|
|
|
|
// A MessageRouter is a mutex for MessageRoutes.
|
|
type MessageRouter struct {
|
|
routes map[routeKey]MessageRoute
|
|
}
|
|
|
|
// NewMessageRouter returns an initialized MessageRouter instance.
|
|
func NewMessageRouter() *MessageRouter {
|
|
return &MessageRouter{routes: make(map[routeKey]MessageRoute)}
|
|
}
|
|
|
|
// AddRoute adds a route to the MessageRouter instance keyed to begin string and msgType.
|
|
func (c MessageRouter) AddRoute(beginString string, msgType string, router MessageRoute) {
|
|
c.routes[routeKey{beginString, msgType}] = router
|
|
}
|
|
|
|
// Route may be called from the fromApp/fromAdmin callbacks. Messages that cannot be routed will be rejected with UnsupportedMessageType.
|
|
func (c MessageRouter) Route(msg *Message, sessionID SessionID) MessageRejectError {
|
|
beginString, err := msg.Header.GetBytes(tagBeginString)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
msgType, err := msg.Header.GetBytes(tagMsgType)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return c.tryRoute(string(beginString), string(msgType), msg, sessionID)
|
|
}
|
|
|
|
func (c MessageRouter) tryRoute(beginString string, msgType string, msg *Message, sessionID SessionID) MessageRejectError {
|
|
fixVersion := beginString
|
|
isAdminMsg := isAdminMessageType([]byte(msgType))
|
|
|
|
if beginString == BeginStringFIXT11 && !isAdminMsg {
|
|
var applVerID FIXString
|
|
if err := msg.Header.GetField(tagApplVerID, &applVerID); err != nil {
|
|
session, _ := lookupSession(sessionID)
|
|
applVerID = FIXString(session.TargetDefaultApplicationVersionID())
|
|
}
|
|
|
|
switch applVerID {
|
|
case ApplVerIDFIX40:
|
|
fixVersion = BeginStringFIX40
|
|
case ApplVerIDFIX41:
|
|
fixVersion = BeginStringFIX41
|
|
case ApplVerIDFIX42:
|
|
fixVersion = BeginStringFIX42
|
|
case ApplVerIDFIX43:
|
|
fixVersion = BeginStringFIX43
|
|
case ApplVerIDFIX44:
|
|
fixVersion = BeginStringFIX44
|
|
default:
|
|
fixVersion = string(applVerID)
|
|
}
|
|
}
|
|
|
|
if route, ok := c.routes[routeKey{fixVersion, msgType}]; ok {
|
|
return route(msg, sessionID)
|
|
}
|
|
|
|
switch {
|
|
case isAdminMsg || msgType == "j":
|
|
return nil
|
|
}
|
|
|
|
return UnsupportedMessageType()
|
|
}
|