adding quickfix
This commit is contained in:
254
quickfix/_test/test-server/main.go
Normal file
254
quickfix/_test/test-server/main.go
Normal file
@ -0,0 +1,254 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"quantex.com/qfixdpl/quickfix"
|
||||
"quantex.com/qfixdpl/quickfix/config"
|
||||
field "quantex.com/qfixdpl/quickfix/gen/field"
|
||||
tag "quantex.com/qfixdpl/quickfix/gen/tag"
|
||||
filelog "quantex.com/qfixdpl/quickfix/log/file"
|
||||
"quantex.com/qfixdpl/quickfix/store/file"
|
||||
"quantex.com/qfixdpl/quickfix/store/mongo"
|
||||
)
|
||||
|
||||
var router *quickfix.MessageRouter = quickfix.NewMessageRouter()
|
||||
|
||||
type EchoApplication struct {
|
||||
log *log.Logger
|
||||
OrderIds map[string]bool
|
||||
}
|
||||
|
||||
func (e EchoApplication) OnCreate(sessionID quickfix.SessionID) {
|
||||
e.log.Printf("OnCreate %v\n", sessionID.String())
|
||||
}
|
||||
func (e *EchoApplication) OnLogon(sessionID quickfix.SessionID) {
|
||||
e.log.Printf("OnLogon %v\n", sessionID.String())
|
||||
e.OrderIds = make(map[string]bool)
|
||||
}
|
||||
func (e *EchoApplication) OnLogout(sessionID quickfix.SessionID) {
|
||||
e.log.Printf("OnLogout %v\n", sessionID.String())
|
||||
}
|
||||
func (e EchoApplication) ToAdmin(msgBuilder *quickfix.Message, sessionID quickfix.SessionID) {
|
||||
}
|
||||
|
||||
func (e EchoApplication) ToApp(msgBuilder *quickfix.Message, sessionID quickfix.SessionID) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e EchoApplication) FromAdmin(msg *quickfix.Message, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e *EchoApplication) FromApp(msg *quickfix.Message, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) {
|
||||
e.log.Println("Got Message ", msg)
|
||||
return router.Route(msg, sessionID)
|
||||
}
|
||||
|
||||
func (e *EchoApplication) processMsg(msg *quickfix.Message, sessionID quickfix.SessionID) quickfix.MessageRejectError {
|
||||
var possResend field.PossResendField
|
||||
msg.Header.Get(&possResend)
|
||||
|
||||
if msg.Body.Has(tag.ClOrdID) {
|
||||
var orderID field.ClOrdIDField
|
||||
|
||||
if err := msg.Body.Get(&orderID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sessionOrderID := sessionID.String() + orderID.String()
|
||||
|
||||
if bytes.Equal(possResend.Write(), []byte("Y")) {
|
||||
if e.OrderIds[sessionOrderID] {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
e.OrderIds[sessionOrderID] = true
|
||||
}
|
||||
|
||||
reply := copyMessage(msg)
|
||||
if bytes.Equal(possResend.Write(), []byte("Y")) {
|
||||
reply.Header.Set(possResend)
|
||||
}
|
||||
|
||||
quickfix.SendToTarget(reply, sessionID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyMessage(msg *quickfix.Message) *quickfix.Message {
|
||||
msgType := new(field.MsgTypeField)
|
||||
msg.Header.Get(msgType)
|
||||
|
||||
msg.Header.Clear()
|
||||
msg.Trailer.Clear()
|
||||
|
||||
msg.Header.Set(msgType)
|
||||
|
||||
return msg
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := &EchoApplication{}
|
||||
app.log = log.New(io.Discard, "", log.LstdFlags)
|
||||
//app.log = log.New(os.Stdout, "", log.LstdFlags)
|
||||
|
||||
router.AddRoute(quickfix.BeginStringFIX40, "D", app.processMsg)
|
||||
router.AddRoute(quickfix.BeginStringFIX41, "D", app.processMsg)
|
||||
router.AddRoute(quickfix.BeginStringFIX42, "D", app.processMsg)
|
||||
router.AddRoute(quickfix.BeginStringFIX43, "D", app.processMsg)
|
||||
router.AddRoute(quickfix.BeginStringFIX44, "D", app.processMsg)
|
||||
router.AddRoute(quickfix.ApplVerIDFIX50, "D", app.processMsg)
|
||||
router.AddRoute(quickfix.ApplVerIDFIX50SP1, "D", app.processMsg)
|
||||
router.AddRoute(quickfix.ApplVerIDFIX50SP2, "D", app.processMsg)
|
||||
|
||||
router.AddRoute(quickfix.BeginStringFIX42, "d", app.processMsg)
|
||||
router.AddRoute(quickfix.BeginStringFIX43, "d", app.processMsg)
|
||||
router.AddRoute(quickfix.BeginStringFIX44, "d", app.processMsg)
|
||||
router.AddRoute(quickfix.ApplVerIDFIX50, "d", app.processMsg)
|
||||
router.AddRoute(quickfix.ApplVerIDFIX50SP1, "d", app.processMsg)
|
||||
router.AddRoute(quickfix.ApplVerIDFIX50SP2, "d", app.processMsg)
|
||||
|
||||
fmt.Println("starting test server")
|
||||
cfg, err := os.Open(os.Args[1])
|
||||
if err != nil {
|
||||
fmt.Printf("Error opening %v, %v\n", os.Args[1], err)
|
||||
return
|
||||
}
|
||||
|
||||
appSettings, err := quickfix.ParseSettings(cfg)
|
||||
if err != nil {
|
||||
fmt.Println("Error reading cfg:", err)
|
||||
return
|
||||
}
|
||||
|
||||
fileLogFactory, err := filelog.NewLogFactory(appSettings)
|
||||
if err != nil {
|
||||
fmt.Println("Error creating file log factory:", err)
|
||||
return
|
||||
}
|
||||
//fileLogFactory := quickfix.NewScreenLogFactory()
|
||||
// if err != nil {
|
||||
// fmt.Println("Error creating file log factory:", err)
|
||||
// return
|
||||
// }
|
||||
|
||||
storeType := os.Args[2]
|
||||
|
||||
var acceptor *quickfix.Acceptor
|
||||
switch strings.ToUpper(storeType) {
|
||||
case "MONGO":
|
||||
mongoDbCxn := "mongodb://localhost:27017"
|
||||
mongoDatabase := "automated_testing_database"
|
||||
mongoReplicaSet := "replicaset"
|
||||
|
||||
appSettings.GlobalSettings().Set(config.MongoStoreConnection, mongoDbCxn)
|
||||
appSettings.GlobalSettings().Set(config.MongoStoreDatabase, mongoDatabase)
|
||||
appSettings.GlobalSettings().Set(config.MongoStoreReplicaSet, mongoReplicaSet)
|
||||
appSettings.GlobalSettings().Set(config.DynamicSessions, "Y")
|
||||
|
||||
acceptor, err = quickfix.NewAcceptor(app, mongo.NewStoreFactory(appSettings), appSettings, fileLogFactory)
|
||||
case "FILE":
|
||||
fileStoreRootPath := path.Join(os.TempDir(), fmt.Sprintf("FileStoreTestSuite-%d", os.Getpid()))
|
||||
fileStorePath := path.Join(fileStoreRootPath, fmt.Sprintf("%d", time.Now().UnixNano()))
|
||||
appSettings.GlobalSettings().Set(config.FileStorePath, fileStorePath)
|
||||
appSettings.GlobalSettings().Set(config.DynamicSessions, "Y")
|
||||
|
||||
acceptor, err = quickfix.NewAcceptor(app, file.NewStoreFactory(appSettings), appSettings, fileLogFactory)
|
||||
case "MEMORY":
|
||||
fallthrough
|
||||
default:
|
||||
acceptor, err = quickfix.NewAcceptor(app, quickfix.NewMemoryStoreFactory(), appSettings, fileLogFactory)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Unable to create Acceptor: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = acceptor.Start(); err != nil {
|
||||
fmt.Println("Unable to start Acceptor: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
// http handler for seqnum resets for specific test defs. not applicable for most tests.
|
||||
http.HandleFunc("/seqnum", func(w http.ResponseWriter, r *http.Request) {
|
||||
defer w.WriteHeader(http.StatusOK)
|
||||
queryParams := r.URL.Query()
|
||||
sessionStr, ok := queryParams["SESSION"]
|
||||
if !ok {
|
||||
fmt.Println("cannot find session")
|
||||
os.Exit(1)
|
||||
}
|
||||
splts := strings.Split(sessionStr[0], ":")
|
||||
parties := strings.Split(splts[1], "->")
|
||||
sessionID := quickfix.SessionID{
|
||||
BeginString: splts[0],
|
||||
SenderCompID: parties[0],
|
||||
TargetCompID: parties[1],
|
||||
}
|
||||
num, ok := queryParams["NEXTTARGETSEQNUM"]
|
||||
if ok {
|
||||
seqnumInt, cErr := strconv.Atoi(num[0])
|
||||
if cErr != nil {
|
||||
fmt.Println("cannot find seqnum")
|
||||
os.Exit(1)
|
||||
}
|
||||
setErr := quickfix.SetNextTargetMsgSeqNum(sessionID, seqnumInt)
|
||||
if setErr != nil {
|
||||
fmt.Println("err setting target seqnum: " + setErr.Error())
|
||||
return
|
||||
}
|
||||
fmt.Println("set target seqnum to: " + num[0])
|
||||
return
|
||||
}
|
||||
|
||||
num, ok = queryParams["NEXTSENDERSEQNUM"]
|
||||
if ok {
|
||||
seqnumInt, cErr := strconv.Atoi(num[0])
|
||||
if cErr != nil {
|
||||
fmt.Println("cannot find seqnum")
|
||||
os.Exit(1)
|
||||
}
|
||||
setErr := quickfix.SetNextSenderMsgSeqNum(sessionID, seqnumInt)
|
||||
if setErr != nil {
|
||||
fmt.Println("err setting sender seqnum: " + setErr.Error())
|
||||
return
|
||||
}
|
||||
fmt.Println("set sender seqnum to: " + num[0])
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("never found seqnum")
|
||||
os.Exit(1)
|
||||
})
|
||||
websrvr := http.Server{Addr: ":8095"}
|
||||
defer func() {
|
||||
if err := websrvr.Close(); err != nil {
|
||||
fmt.Println("unable to stop srver: ", err)
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
if err := websrvr.ListenAndServe(); err != http.ErrServerClosed {
|
||||
fmt.Println("websrvr err: ", err)
|
||||
}
|
||||
}()
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
<-c
|
||||
fmt.Println("stopping test server")
|
||||
|
||||
acceptor.Stop()
|
||||
}
|
||||
Reference in New Issue
Block a user