diff --git a/.devcontainer/Dockerfile.dev b/.devcontainer/Dockerfile.dev
index 14c7119a9..6a0aa8e95 100644
--- a/.devcontainer/Dockerfile.dev
+++ b/.devcontainer/Dockerfile.dev
@@ -1 +1 @@
-FROM mcr.microsoft.com/vscode/devcontainers/go:0-1.18
\ No newline at end of file
+FROM mcr.microsoft.com/devcontainers/go:1.23
\ No newline at end of file
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 709a7468d..0bd1b3749 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -21,31 +21,142 @@ jobs:
name: Linter
runs-on: ubuntu-latest
steps:
- - name: Checkout source code
+ - uses: actions/checkout@v4
+ - uses: actions/setup-go@v5
+ with:
+ go-version: '1.21'
+ - name: golangci-lint
+ uses: golangci/golangci-lint-action@v4
+ with:
+ version: v1.64.6
+
+ build:
+ name: Build Source
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go: [1.21]
+ steps:
+ - name: Setup
+ uses: actions/setup-go@v2
+ with:
+ go-version: ${{ matrix.go }}
+ - name: Check out source
uses: actions/checkout@v2
- - name: Setup Go
+ - name: Build
+ run: make build-src
+
+ unittest:
+ name: Unit Tests
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go: [1.21]
+ steps:
+ - name: Setup
uses: actions/setup-go@v2
with:
- go-version: '1.18'
- - name: Install golangci-lint
- run: |
- curl -sSLO https://github.com/golangci/golangci-lint/releases/download/v$GOLANGCI_LINT_VERSION/golangci-lint-$GOLANGCI_LINT_VERSION-linux-amd64.tar.gz
- tar -xf golangci-lint-$GOLANGCI_LINT_VERSION-linux-amd64.tar.gz
- sudo mv golangci-lint-$GOLANGCI_LINT_VERSION-linux-amd64/golangci-lint /usr/local/bin/golangci-lint
- rm -rf golangci-lint-$GOLANGCI_LINT_VERSION-linux-amd64*
+ go-version: ${{ matrix.go }}
+ - name: Check out source
+ uses: actions/checkout@v2
+ - name: Start MongoDB
+ uses: supercharge/mongodb-github-action@1.8.0
+ with:
+ mongodb-replica-set: replicaset
+ - name: Unit test
env:
- GOLANGCI_LINT_VERSION: '1.50.1'
- - name: Run Lint
- run: make lint
+ MONGODB_TEST_CXN: mongodb://localhost:27017
+ run: make test-ci
- build:
- name: build
+ servermem:
+ name: Server MemoryStore Suite
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go: [1.21]
+ fix-version:
+ - fix40
+ - fix41
+ - fix42
+ - fix43
+ - fix44
+ - fix50
+ - fix50sp1
+ - fix50sp2
+ steps:
+ - name: Setup
+ uses: actions/setup-go@v2
+ with:
+ go-version: ${{ matrix.go }}
+ - name: Check out source
+ uses: actions/checkout@v2
+ - name: Install ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.0'
+ - name: Acceptance test
+ env:
+ GO111MODULE: on
+ FIX_TEST: ${{ matrix.fix-version }}
+ STORE_TYPE: memory
+ ACCEPTANCE_SET: server
+ run: make generate-ci && make build && make $FIX_TEST
+ - name: Acceptance test with udecimal
+ env:
+ GO111MODULE: on
+ FIX_TEST: ${{ matrix.fix-version }}
+ STORE_TYPE: memory
+ ACCEPTANCE_SET: server
+ run: make generate-ci-udecimal && make build && make $FIX_TEST
+
+ serverfile:
+ name: Server FileStore Suite
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go: [1.21]
+ fix-version:
+ - fix40
+ - fix41
+ - fix42
+ - fix43
+ - fix44
+ - fix50
+ - fix50sp1
+ - fix50sp2
+ steps:
+ - name: Setup
+ uses: actions/setup-go@v2
+ with:
+ go-version: ${{ matrix.go }}
+ - name: Check out source
+ uses: actions/checkout@v2
+ - name: Install ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.0'
+ - name: Acceptance test
+ env:
+ GO111MODULE: on
+ FIX_TEST: ${{ matrix.fix-version }}
+ STORE_TYPE: file
+ ACCEPTANCE_SET: server
+ run: make generate-ci && make build && make $FIX_TEST
+ - name: Acceptance test with udecimal
+ env:
+ GO111MODULE: on
+ FIX_TEST: ${{ matrix.fix-version }}
+ STORE_TYPE: file
+ ACCEPTANCE_SET: server
+ run: make generate-ci-udecimal && make build && make $FIX_TEST
+
+ servermongo:
+ name: Server MongoStore Suite
runs-on: ubuntu-latest
strategy:
matrix:
- go: [1.18]
+ go: [1.21]
fix-version:
- -
- fix40
- fix41
- fix42
@@ -69,9 +180,135 @@ jobs:
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'
- - name: Test
+ - name: Acceptance test
env:
GO111MODULE: on
MONGODB_TEST_CXN: mongodb://localhost:27017
FIX_TEST: ${{ matrix.fix-version }}
- run: if [ -z $FIX_TEST ]; then make build-src && make test-ci; else make generate-ci && make build && make $FIX_TEST; fi
+ STORE_TYPE: mongo
+ ACCEPTANCE_SET: server
+ run: make generate-ci && make build && make $FIX_TEST
+ - name: Acceptance test with udecimal
+ env:
+ GO111MODULE: on
+ FIX_TEST: ${{ matrix.fix-version }}
+ STORE_TYPE: mongo
+ ACCEPTANCE_SET: server
+ run: make generate-ci-udecimal && make build && make $FIX_TEST
+
+ resendreqchunksize:
+ name: ResendRequestChunkSize Suite
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go: [1.21]
+ fix-version:
+ - fix40
+ - fix41
+ - fix42
+ - fix43
+ - fix44
+ - fix50
+ - fix50sp1
+ - fix50sp2
+ steps:
+ - name: Setup
+ uses: actions/setup-go@v2
+ with:
+ go-version: ${{ matrix.go }}
+ - name: Check out source
+ uses: actions/checkout@v2
+ - name: Install ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.0'
+ - name: Acceptance test
+ env:
+ GO111MODULE: on
+ FIX_TEST: ${{ matrix.fix-version }}
+ STORE_TYPE: memory
+ ACCEPTANCE_SET: resendreqchunksize
+ run: make generate-ci && make build && make $FIX_TEST
+ - name: Acceptance test with udecimal
+ env:
+ GO111MODULE: on
+ FIX_TEST: ${{ matrix.fix-version }}
+ STORE_TYPE: memory
+ ACCEPTANCE_SET: resendreqchunksize
+ run: make generate-ci-udecimal && make build && make $FIX_TEST
+
+ lastseqnumprocessed:
+ name: LastSeqNumProcessed Suite
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go: [1.21]
+ fix-version:
+ - fix42
+ - fix43
+ - fix44
+ - fix50
+ - fix50sp1
+ - fix50sp2
+ steps:
+ - name: Setup
+ uses: actions/setup-go@v2
+ with:
+ go-version: ${{ matrix.go }}
+ - name: Check out source
+ uses: actions/checkout@v2
+ - name: Install ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.0'
+ - name: Acceptance test
+ env:
+ GO111MODULE: on
+ FIX_TEST: ${{ matrix.fix-version }}
+ STORE_TYPE: memory
+ ACCEPTANCE_SET: lastseqnumprocessed
+ run: make generate-ci && make build && make $FIX_TEST
+ - name: Acceptance test with udecimal
+ env:
+ GO111MODULE: on
+ FIX_TEST: ${{ matrix.fix-version }}
+ STORE_TYPE: memory
+ ACCEPTANCE_SET: lastseqnumprocessed
+ run: make generate-ci-udecimal && make build && make $FIX_TEST
+
+ nextexpectedseqnum:
+ name: NextExpectedSeqNum Suite
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go: [1.21]
+ fix-version:
+ - fix44
+ - fix50
+ - fix50sp1
+ - fix50sp2
+ steps:
+ - name: Setup
+ uses: actions/setup-go@v2
+ with:
+ go-version: ${{ matrix.go }}
+ - name: Check out source
+ uses: actions/checkout@v2
+ - name: Install ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.0'
+ - name: Acceptance test
+ env:
+ GO111MODULE: on
+ FIX_TEST: ${{ matrix.fix-version }}
+ STORE_TYPE: memory
+ ACCEPTANCE_SET: nextexpectedseqnum
+ run: make generate-ci && make build && make $FIX_TEST
+ - name: Acceptance test with udecimal
+ env:
+ GO111MODULE: on
+ FIX_TEST: ${{ matrix.fix-version }}
+ STORE_TYPE: memory
+ ACCEPTANCE_SET: nextexpectedseqnum
+ run: make generate-ci-udecimal && make build && make $FIX_TEST
diff --git a/.gitignore b/.gitignore
index 13b074258..5eb1c3b7f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ _test/test
_test/echo_server
_test/tmp
_vendor*
+.DS_Store
diff --git a/.golangci.yml b/.golangci.yml
index 7d3a47ddb..b0bd0347b 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -1,6 +1,12 @@
run:
timeout: 10m
- skip-dirs:
+ # deprecated config -
+ # skip-dirs:
+ # - gen
+ # - vendor
+
+issues:
+ exclude-dirs:
- gen
- vendor
@@ -17,11 +23,10 @@ linters:
- revive
- unused
- staticcheck
+ - godot
linters-settings:
gofmt:
simplify: true
- goimports:
- local-prefixes: github.com/quickfixgo/quickfix
dupl:
threshold: 400
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b1bb9b03e..2cb801918 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,193 @@
+## 0.9.10 (August 8, 2025)
+
+### BUG FIXES
+* Send Reset if the ResetTime elapsed in between checks [#725](https://github.com/quickfixgo/quickfix/pull/725)
+
+## 0.9.9 (July 31, 2025)
+
+### BUG FIXES
+* Adds missing tz for resetseqtime without starttime endtime #723 [#723](https://github.com/quickfixgo/quickfix/pull/723)
+
+## 0.9.8 (July 21, 2025)
+
+### ENHANCEMENTS
+* Add DB name configuration [#711](https://github.com/quickfixgo/quickfix/pull/711)
+* Change ResetSeqTime to time.Time based on the config's timeZone [#712](https://github.com/quickfixgo/quickfix/pull/712)
+
+### BUG FIXES
+* Block Sends when Resend Request is active [#715](https://github.com/quickfixgo/quickfix/pull/715)
+* Fix the issue of incorrect time range calculation across days [#718](https://github.com/quickfixgo/quickfix/pull/718)
+
+## 0.9.7 (April 23, 2025)
+
+### FEATURES
+* Adds SQL, MongoDB and Composite FIX Log and LogFactory implementations, see `config/configuration.go` for details [#672](https://github.com/quickfixgo/quickfix/pull/672)
+* Adds convenience getters for session log and store [#675](https://github.com/quickfixgo/quickfix/pull/675)
+* Adds config option for ResetSeqTime [#705](https://github.com/quickfixgo/quickfix/pull/705)
+
+### ENHANCEMENTS
+* File store uses files exclusively [#680](https://github.com/quickfixgo/quickfix/pull/680)
+* Protect concurrent usage of filestore [#688](https://github.com/quickfixgo/quickfix/pull/688)
+* Support udecimal library in code generation [#700](https://github.com/quickfixgo/quickfix/pull/700)
+
+### BUG FIXES
+* Avoid unkeyed fields usage for exported struct in generated code [#683](https://github.com/quickfixgo/quickfix/pull/683)
+* Iterate messages in filestore opens a separate file to avoid deadlock [#703](https://github.com/quickfixgo/quickfix/pull/703)
+* Correct ordering in message trailer [#707](https://github.com/quickfixgo/quickfix/pull/707)
+
+## 0.9.6 (September 20, 2024)
+
+### ENHANCEMENTS
+* Allow the clients of acceptor to specify their own tls.Config https://github.com/quickfixgo/quickfix/pull/667
+* Adds NextExpectedSeqNum setting https://github.com/quickfixgo/quickfix/pull/668
+
+### BUG FIXES
+* Reinit stop sync to prevent deadlock on sequential start/stops https://github.com/quickfixgo/quickfix/pull/669
+* Check logon auth before resetting store https://github.com/quickfixgo/quickfix/pull/670
+* Reverts ToAdmin call sequencing https://github.com/quickfixgo/quickfix/pull/674
+
+## 0.9.5 (August 14, 2024)
+
+### ENHANCEMENTS
+* Introduce message iterator to avoid loading all messages into memory at once upon resend request https://github.com/quickfixgo/quickfix/pull/659
+* Only lock fieldmap once during message parsing https://github.com/quickfixgo/quickfix/pull/658
+* Optimize tag value parsing https://github.com/quickfixgo/quickfix/pull/657
+* Use bytes.Count to count the number of message fields https://github.com/quickfixgo/quickfix/pull/655
+* Port config documentation into proper go doc format https://github.com/quickfixgo/quickfix/pull/649
+* Support TLS configuration as raw bytes https://github.com/quickfixgo/quickfix/pull/647
+
+### BUG FIXES
+* Use the Go generated file convention https://github.com/quickfixgo/quickfix/pull/660
+* Fix stuck call to Dial when calling Stop on the Initiator https://github.com/quickfixgo/quickfix/pull/654
+* Do not increment NextTargetMsgSeqNum for out of sequence Logout and Test Requests https://github.com/quickfixgo/quickfix/pull/645
+
+## 0.9.4 (May 29, 2024)
+
+### ENHANCEMENTS
+* Adds log to readLoop just like writeLoop https://github.com/quickfixgo/quickfix/pull/642
+
+### BUG FIXES
+* Maintain repeating group field order when parsing messages https://github.com/quickfixgo/quickfix/pull/636
+
+## 0.9.3 (May 9, 2024)
+
+### BUG FIXES
+* Change filestore.offsets from map[int]msgDef to sync.Map https://github.com/quickfixgo/quickfix/pull/639
+* Unregister sessions on stop https://github.com/quickfixgo/quickfix/pull/637
+* Corrects ResetOnLogon behavior for initiators https://github.com/quickfixgo/quickfix/pull/635
+
+### FEATURES
+* Add AllowUnknownMessageFields & CheckUserDefinedFields settings as included in QuickFIX/J https://github.com/quickfixgo/quickfix/pull/632
+
+## 0.9.2 (April 23, 2024)
+
+### BUG FIXES
+* Prevent message queue blocking in the case of network connection trouble https://github.com/quickfixgo/quickfix/pull/615 https://github.com/quickfixgo/quickfix/pull/628
+* Corrects validation of multiple repeating groups with different fields https://github.com/quickfixgo/quickfix/pull/623
+
+## 0.9.1 (April 15, 2024)
+
+### BUG FIXES
+* Preserve original body when resending https://github.com/quickfixgo/quickfix/pull/624
+
+## 0.9.0 (November 13, 2023)
+
+### FEATURES
+* Add Weekdays config setting as included in QuickFIX/J https://github.com/quickfixgo/quickfix/pull/590
+* `MessageStore` Refactor
+
+The message store types external to a quickfix-go application have been refactored into individual sub-packages within `quickfix`. The benefit of this is that the dependencies for these specific store types are no longer included in the quickfix package itself, so many projects depending on the quickfix package will no longer be bloated with large indirect dependencies if they are not specifically implemented in your application. This applies to the `mongo` (MongoDB), `file` (A file on-disk), and `sql` (Any db accessed with a go sql driver interface). The `memorystore` (in-memory message store) syntax remains unchanged. The minor drawback to this is that with some re-packaging came some minor syntax changes. See https://github.com/quickfixgo/quickfix/issues/547 and https://github.com/quickfixgo/quickfix/pull/592 for more information. The relevant examples are below.
+
+MONGO
+```go
+import "github.com/quickfixgo/quickfix"
+
+...
+acceptor, err = quickfix.NewAcceptor(app, quickfix.NewMongoStoreFactory(appSettings), appSettings, fileLogFactory)
+```
+becomes
+```go
+import (
+ "github.com/quickfixgo/quickfix"
+ "github.com/quickfixgo/quickfix/store/mongo"
+)
+
+...
+acceptor, err = quickfix.NewAcceptor(app, mongo.NewStoreFactory(appSettings), appSettings, fileLogFactory)
+```
+
+FILE
+```go
+import "github.com/quickfixgo/quickfix"
+
+...
+acceptor, err = quickfix.NewAcceptor(app, quickfix.NewFileStoreFactory(appSettings), appSettings, fileLogFactory)
+```
+becomes
+```go
+import (
+ "github.com/quickfixgo/quickfix"
+ "github.com/quickfixgo/quickfix/store/file"
+)
+
+...
+acceptor, err = quickfix.NewAcceptor(app, file.NewStoreFactory(appSettings), appSettings, fileLogFactory)
+```
+
+SQL
+
+```go
+import "github.com/quickfixgo/quickfix"
+
+...
+acceptor, err = quickfix.NewAcceptor(app, quickfix.NewSQLStoreFactory(appSettings), appSettings, fileLogFactory)
+```
+becomes
+```go
+import (
+ "github.com/quickfixgo/quickfix"
+ "github.com/quickfixgo/quickfix/store/sql"
+)
+
+...
+acceptor, err = quickfix.NewAcceptor(app, sql.NewStoreFactory(appSettings), appSettings, fileLogFactory)
+```
+
+
+### ENHANCEMENTS
+* Acceptance suite store type expansions https://github.com/quickfixgo/quickfix/pull/596 and https://github.com/quickfixgo/quickfix/pull/591
+* Support Go v1.21 https://github.com/quickfixgo/quickfix/pull/589
+
+
+### BUG FIXES
+* Resolves outstanding issues with postgres db creation syntax and `pgx` driver https://github.com/quickfixgo/quickfix/pull/598
+* Fix sequence number bug when storage fails https://github.com/quickfixgo/quickfix/pull/432
+
+
+## 0.8.1 (October 27, 2023)
+
+BUG FIXES
+
+* Remove initiator wait [GH 587]
+* for xml charset and bug of "Incorrect NumInGroup" [GH 368, 363, 365, 366]
+* Allow time.Duration or int for timeouts [GH 477]
+* Trim extra non-ascii characters that can arise from manually editing [GH 463, 464]
+
+## 0.8.0 (October 25, 2023)
+
+ENHANCEMENTS
+
+* Remove tag from field map [GH 544]
+* Add message.Bytes() to avoid string conversion [GH 546]
+* Check RejectInvalidMessage on FIXT validation [GH 572]
+
+BUG FIXES
+
+* Fix repeating group read tags lost [GH 462]
+* Acceptance test result must be predictable [GH 578]
+* Makes event timer stop idempotent [GH 580, 581]
+* Added WaitGroup Wait in Initiator [GH 584]
+
## 0.7.0 (January 2, 2023)
FEATURES
diff --git a/LICENSE.txt b/LICENSE
similarity index 95%
rename from LICENSE.txt
rename to LICENSE
index d9eb36409..273a59dad 100644
--- a/LICENSE.txt
+++ b/LICENSE
@@ -1,6 +1,6 @@
The QuickFIX Software License, Version 1.0
-Copyright (c) 2001-2010 quickfixengine.org All rights
+Copyright (c) 2001- quickfixengine.org All rights
reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/Makefile b/Makefile
index 2e0799d43..960ccacd6 100644
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,9 @@ clean:
generate: clean
mkdir -p gen; cd gen; go run ../cmd/generate-fix/generate-fix.go -pkg-root=github.com/quickfixgo/quickfix/gen ../spec/*.xml
+generate-udecimal: clean
+ mkdir -p gen; cd gen; go run ../cmd/generate-fix/generate-fix.go -use-udecimal=true -pkg-root=github.com/quickfixgo/quickfix/gen ../spec/*.xml
+
fmt:
gofmt -l -w -s $(shell find . -type f -name '*.go')
@@ -14,38 +17,54 @@ vet:
go vet `go list ./... | grep -v quickfix/gen`
test:
- MONGODB_TEST_CXN=mongodb://db:27017 go test -v -cover . ./datadictionary ./internal
+ MONGODB_TEST_CXN=mongodb://db:27017 go test -v -cover `go list ./... | grep -v quickfix/gen`
linters-install:
@golangci-lint --version >/dev/null 2>&1 || { \
echo "installing linting tools..."; \
- curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.50.1; \
+ curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.64.6; \
}
lint: linters-install
golangci-lint run
+# An easy way to run the linter without going through the install process -
+# docker run -t --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.64.6 golangci-lint run -v
+# See https://golangci-lint.run/welcome/install/ for more details.
+
# ---------------------------------------------------------------
# Targets related to running acceptance tests -
+ifdef STORE_TYPE
+STORE := $(STORE_TYPE)
+else
+STORE := memory
+endif
+
+ifdef ACCEPTANCE_SET
+TEST_SET := $(ACCEPTANCE_SET)
+else
+TEST_SET := server
+endif
+
build-test-srv:
- cd _test; go build -o echo_server ./test-server/
+ cd _test; go build -v -o echo_server ./test-server/
fix40:
- cd _test; ./runat.sh $@.cfg 5001 "definitions/server/$@/*.def"
+ cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5001 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
fix41:
- cd _test; ./runat.sh $@.cfg 5002 "definitions/server/$@/*.def"
+ cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5002 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
fix42:
- cd _test; ./runat.sh $@.cfg 5003 "definitions/server/$@/*.def"
+ cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5003 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
fix43:
- cd _test; ./runat.sh $@.cfg 5004 "definitions/server/$@/*.def"
+ cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5004 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
fix44:
- cd _test; ./runat.sh $@.cfg 5005 "definitions/server/$@/*.def"
+ cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5005 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
fix50:
- cd _test; ./runat.sh $@.cfg 5006 "definitions/server/$@/*.def"
+ cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5006 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
fix50sp1:
- cd _test; ./runat.sh $@.cfg 5007 "definitions/server/$@/*.def"
+ cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5007 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
fix50sp2:
- cd _test; ./runat.sh $@.cfg 5008 "definitions/server/$@/*.def"
+ cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5008 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
ACCEPT_SUITE=fix40 fix41 fix42 fix43 fix44 fix50 fix50sp1 fix50sp2
accept: $(ACCEPT_SUITE)
@@ -62,9 +81,12 @@ build-src:
build: build-src build-test-srv
test-ci:
- go test -v -cover . ./datadictionary ./internal
+ go test -v -cover `go list ./... | grep -v quickfix/gen`
generate-ci: clean
- mkdir -p gen; cd gen; go run ../cmd/generate-fix/generate-fix.go -pkg-root=github.com/quickfixgo/quickfix/gen ../spec/$(shell echo $(FIX_TEST) | tr '[:lower:]' '[:upper:]').xml;
+ mkdir -p gen; cd gen; go run ../cmd/generate-fix/generate-fix.go -pkg-root=github.com/quickfixgo/quickfix/gen ../spec/$(shell echo $(FIX_TEST) | tr '[:lower:]' '[:upper:]').xml;
+
+generate-ci-udecimal: clean
+ mkdir -p gen; cd gen; go run ../cmd/generate-fix/generate-fix.go -use-udecimal=true -pkg-root=github.com/quickfixgo/quickfix/gen ../spec/$(shell echo $(FIX_TEST) | tr '[:lower:]' '[:upper:]').xml;
# ---------------------------------------------------------------
diff --git a/README.md b/README.md
index 350c7f6c9..192700e88 100644
--- a/README.md
+++ b/README.md
@@ -4,13 +4,17 @@
Open Source [FIX Protocol](http://www.fixprotocol.org/) library implemented in Go
+### Looking for help with `MessageStore` syntax changes?
+See v0.9.0 release notes [here](https://github.com/quickfixgo/quickfix/releases/tag/v0.9.0)
+
+
## About
QuickFIX/Go is a FIX Protocol Community implementation for the Go programming language.
- 100% free and open source with a liberal license
- Supports FIX versions 4.0 - 5.0SP2
- - Runs on any hardware and operating system supported by Go (1.18+ required)
+ - Runs on any hardware and operating system supported by Go (1.21+ required)
- Spec driven run-time message validation
- Spec driven code generation of type-safe FIX messages, fields, and repeating groups
- Support for protocol customizations
@@ -24,7 +28,7 @@ Open Source [FIX Protocol](http://www.fixprotocol.org/) library implemented in G
-
+
## Installation
@@ -44,7 +48,7 @@ go get -u github.com/quickfixgo/quickfix
## Getting Started
-* [QuickFIX User Manual](http://quickfixgo.org/docs)
+* [QuickFIX User Manual](https://quickfixengine.org/go/documentation/)
* [Go API Documentation](https://godoc.org/github.com/quickfixgo/quickfix)
* See [examples](https://github.com/quickfixgo/examples) for some simple examples of using QuickFIX/Go.
diff --git a/_sql/postgresql/create.bat b/_sql/postgresql/create.bat
index 9d9b7c40e..8cb54a0c5 100644
--- a/_sql/postgresql/create.bat
+++ b/_sql/postgresql/create.bat
@@ -1,3 +1,3 @@
-dropdb -U postgres -q quickfix
+dropdb -U postgres --if-exists quickfix
createdb -U postgres quickfix
psql -U postgres -d quickfix -f postgresql.sql
diff --git a/_sql/postgresql/create.sh b/_sql/postgresql/create.sh
index 9d9b7c40e..8cb54a0c5 100644
--- a/_sql/postgresql/create.sh
+++ b/_sql/postgresql/create.sh
@@ -1,3 +1,3 @@
-dropdb -U postgres -q quickfix
+dropdb -U postgres --if-exists quickfix
createdb -U postgres quickfix
psql -U postgres -d quickfix -f postgresql.sql
diff --git a/_test/Reflector.rb b/_test/Reflector.rb
index fe9535f39..3e86af7a1 100644
--- a/_test/Reflector.rb
+++ b/_test/Reflector.rb
@@ -61,6 +61,8 @@ def processLine(lineNum, line, body, cid)
connectAction(cid)
elsif body == "DISCONNECT"
disconnectAction(cid)
+ elsif body.index("SET_SESSION") == 0
+ setSeqnum(body)
else
raise "Syntax error: " + body
end
diff --git a/_test/ReflectorClient.rb b/_test/ReflectorClient.rb
index c22858984..148867b40 100644
--- a/_test/ReflectorClient.rb
+++ b/_test/ReflectorClient.rb
@@ -19,6 +19,8 @@
require 'Reflector'
require 'FixParser'
require "socket"
+require 'uri'
+require 'net/http'
class ReflectorClient
@@ -62,16 +64,26 @@ def @reflector.disconnectAction(cid)
@sockets.delete(cid)
@parsers.delete(cid)
end
+
+ def @reflector.setSeqnum(body)
+ left_array = body.split(" ")
+ uri = URI('http://localhost:8095/seqnum?SESSION='+left_array[1]+'&'+left_array[2])
+ Net::HTTP.get_response(uri)
+ end
def @reflector.waitConnectAction(cid)
end
def @reflector.waitDisconnectAction(cid)
- socket = @sockets[cid]
- if IO.select([socket], nil, nil, 10) == nil then
- raise "Connection hangs after ten seconds."
- elsif !socket.eof? then
- raise "Expected disconnection, got data"
+ begin
+ socket = @sockets[cid]
+ if IO.select([socket], nil, nil, 10) == nil then
+ raise "Connection hangs after ten seconds."
+ elsif !socket.eof? then
+ raise "Expected disconnection, got data"
+ end
+ rescue Errno::ECONNRESET
+ # Ignore, server has already disconnected the socket
end
end
diff --git a/_test/ReflectorServer.rb b/_test/ReflectorServer.rb
index 184c77ca7..43113157d 100644
--- a/_test/ReflectorServer.rb
+++ b/_test/ReflectorServer.rb
@@ -58,10 +58,14 @@ def @reflector.waitConnectAction(cid)
end
def @reflector.waitDisconnectAction(cid)
- if IO.select([@socket], nil, nil, 10) == nil then
- raise "Connection hangs after five seconds."
- elsif !@socket.eof? then
- raise "Expected disconnection, got data"
+ begin
+ if IO.select([@socket], nil, nil, 10) == nil then
+ raise "Connection hangs after five seconds."
+ elsif !@socket.eof? then
+ raise "Expected disconnection, got data"
+ end
+ rescue Errno::ECONNRESET
+ # Ignore, client has already disconnected the socket
end
end
diff --git a/_test/cfg/lastseqnumprocessed/fix42.cfg b/_test/cfg/lastseqnumprocessed/fix42.cfg
new file mode 100644
index 000000000..1ed8e572a
--- /dev/null
+++ b/_test/cfg/lastseqnumprocessed/fix42.cfg
@@ -0,0 +1,11 @@
+[DEFAULT]
+SocketAcceptPort=5003
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIX.4.2
+DataDictionary=../spec/FIX42.xml
+EnableLastMsgSeqNumProcessed=Y
\ No newline at end of file
diff --git a/_test/cfg/lastseqnumprocessed/fix43.cfg b/_test/cfg/lastseqnumprocessed/fix43.cfg
new file mode 100644
index 000000000..4675e6b5d
--- /dev/null
+++ b/_test/cfg/lastseqnumprocessed/fix43.cfg
@@ -0,0 +1,11 @@
+[DEFAULT]
+SocketAcceptPort=5004
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIX.4.3
+DataDictionary=../spec/FIX43.xml
+EnableLastMsgSeqNumProcessed=Y
\ No newline at end of file
diff --git a/_test/cfg/lastseqnumprocessed/fix44.cfg b/_test/cfg/lastseqnumprocessed/fix44.cfg
new file mode 100644
index 000000000..0f3cc8c24
--- /dev/null
+++ b/_test/cfg/lastseqnumprocessed/fix44.cfg
@@ -0,0 +1,11 @@
+[DEFAULT]
+SocketAcceptPort=5005
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIX.4.4
+DataDictionary=../spec/FIX44.xml
+EnableLastMsgSeqNumProcessed=Y
\ No newline at end of file
diff --git a/_test/cfg/lastseqnumprocessed/fix50.cfg b/_test/cfg/lastseqnumprocessed/fix50.cfg
new file mode 100644
index 000000000..f3c7c37ad
--- /dev/null
+++ b/_test/cfg/lastseqnumprocessed/fix50.cfg
@@ -0,0 +1,14 @@
+[DEFAULT]
+SocketAcceptPort=5006
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIXT.1.1
+SessionQualifier=FIX50
+DefaultApplVerID=FIX.5.0
+TransportDataDictionary=../spec/FIXT11.xml
+AppDataDictionary=../spec/FIX50.xml
+EnableLastMsgSeqNumProcessed=Y
\ No newline at end of file
diff --git a/_test/cfg/lastseqnumprocessed/fix50sp1.cfg b/_test/cfg/lastseqnumprocessed/fix50sp1.cfg
new file mode 100644
index 000000000..4757e9e93
--- /dev/null
+++ b/_test/cfg/lastseqnumprocessed/fix50sp1.cfg
@@ -0,0 +1,14 @@
+[DEFAULT]
+SocketAcceptPort=5007
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIXT.1.1
+SessionQualifier=FIX50SP1
+DefaultApplVerID=FIX.5.0SP1
+TransportDataDictionary=../spec/FIXT11.xml
+AppDataDictionary=../spec/FIX50SP1.xml
+EnableLastMsgSeqNumProcessed=Y
\ No newline at end of file
diff --git a/_test/cfg/lastseqnumprocessed/fix50sp2.cfg b/_test/cfg/lastseqnumprocessed/fix50sp2.cfg
new file mode 100644
index 000000000..1ae2c09b1
--- /dev/null
+++ b/_test/cfg/lastseqnumprocessed/fix50sp2.cfg
@@ -0,0 +1,14 @@
+[DEFAULT]
+SocketAcceptPort=5008
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIXT.1.1
+SessionQualifier=FIX50SP2
+DefaultApplVerID=FIX.5.0SP2
+TransportDataDictionary=../spec/FIXT11.xml
+AppDataDictionary=../spec/FIX50SP2.xml
+EnableLastMsgSeqNumProcessed=Y
\ No newline at end of file
diff --git a/_test/cfg/nextexpectedseqnum/fix44.cfg b/_test/cfg/nextexpectedseqnum/fix44.cfg
new file mode 100644
index 000000000..b31219439
--- /dev/null
+++ b/_test/cfg/nextexpectedseqnum/fix44.cfg
@@ -0,0 +1,10 @@
+[DEFAULT]
+SocketAcceptPort=5005
+SenderCompID=ISLD
+TargetCompID=TW
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIX.4.4
+DataDictionary=../spec/FIX44.xml
+EnableNextExpectedMsgSeqNum=Y
diff --git a/_test/cfg/nextexpectedseqnum/fix50.cfg b/_test/cfg/nextexpectedseqnum/fix50.cfg
new file mode 100644
index 000000000..c60f608e2
--- /dev/null
+++ b/_test/cfg/nextexpectedseqnum/fix50.cfg
@@ -0,0 +1,12 @@
+[DEFAULT]
+SocketAcceptPort=5006
+SenderCompID=ISLD
+TargetCompID=TW
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIXT.1.1
+DefaultApplVerID=FIX.5.0
+TransportDataDictionary=../spec/FIXT11.xml
+AppDataDictionary=../spec/FIX50.xml
+EnableNextExpectedMsgSeqNum=Y
diff --git a/_test/cfg/nextexpectedseqnum/fix50sp1.cfg b/_test/cfg/nextexpectedseqnum/fix50sp1.cfg
new file mode 100644
index 000000000..f1ec2103b
--- /dev/null
+++ b/_test/cfg/nextexpectedseqnum/fix50sp1.cfg
@@ -0,0 +1,12 @@
+[DEFAULT]
+SocketAcceptPort=5007
+SenderCompID=ISLD
+TargetCompID=TW
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIXT.1.1
+DefaultApplVerID=FIX.5.0SP1
+TransportDataDictionary=../spec/FIXT11.xml
+AppDataDictionary=../spec/FIX50SP1.xml
+EnableNextExpectedMsgSeqNum=Y
diff --git a/_test/cfg/nextexpectedseqnum/fix50sp2.cfg b/_test/cfg/nextexpectedseqnum/fix50sp2.cfg
new file mode 100644
index 000000000..4a1db4eef
--- /dev/null
+++ b/_test/cfg/nextexpectedseqnum/fix50sp2.cfg
@@ -0,0 +1,12 @@
+[DEFAULT]
+SocketAcceptPort=5008
+SenderCompID=ISLD
+TargetCompID=TW
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIXT.1.1
+DefaultApplVerID=FIX.5.0SP2
+TransportDataDictionary=../spec/FIXT11.xml
+AppDataDictionary=../spec/FIX50SP2.xml
+EnableNextExpectedMsgSeqNum=Y
diff --git a/_test/cfg/resendreqchunksize/fix40.cfg b/_test/cfg/resendreqchunksize/fix40.cfg
new file mode 100644
index 000000000..a2b8210f2
--- /dev/null
+++ b/_test/cfg/resendreqchunksize/fix40.cfg
@@ -0,0 +1,11 @@
+[DEFAULT]
+SocketAcceptPort=5001
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIX.4.0
+DataDictionary=../spec/FIX40.xml
+ResendRequestChunkSize=5
\ No newline at end of file
diff --git a/_test/cfg/resendreqchunksize/fix41.cfg b/_test/cfg/resendreqchunksize/fix41.cfg
new file mode 100644
index 000000000..07ad38aa4
--- /dev/null
+++ b/_test/cfg/resendreqchunksize/fix41.cfg
@@ -0,0 +1,11 @@
+[DEFAULT]
+SocketAcceptPort=5002
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIX.4.1
+DataDictionary=../spec/FIX41.xml
+ResendRequestChunkSize=5
\ No newline at end of file
diff --git a/_test/fix42.cfg b/_test/cfg/resendreqchunksize/fix42.cfg
similarity index 87%
rename from _test/fix42.cfg
rename to _test/cfg/resendreqchunksize/fix42.cfg
index 3bbfe829f..b6bdb2318 100644
--- a/_test/fix42.cfg
+++ b/_test/cfg/resendreqchunksize/fix42.cfg
@@ -8,3 +8,4 @@ FileLogPath=tmp
[SESSION]
BeginString=FIX.4.2
DataDictionary=../spec/FIX42.xml
+ResendRequestChunkSize=5
\ No newline at end of file
diff --git a/_test/cfg/resendreqchunksize/fix43.cfg b/_test/cfg/resendreqchunksize/fix43.cfg
new file mode 100644
index 000000000..875ac7d1d
--- /dev/null
+++ b/_test/cfg/resendreqchunksize/fix43.cfg
@@ -0,0 +1,11 @@
+[DEFAULT]
+SocketAcceptPort=5004
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIX.4.3
+DataDictionary=../spec/FIX43.xml
+ResendRequestChunkSize=5
\ No newline at end of file
diff --git a/_test/cfg/resendreqchunksize/fix44.cfg b/_test/cfg/resendreqchunksize/fix44.cfg
new file mode 100644
index 000000000..ad88660aa
--- /dev/null
+++ b/_test/cfg/resendreqchunksize/fix44.cfg
@@ -0,0 +1,11 @@
+[DEFAULT]
+SocketAcceptPort=5005
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIX.4.4
+DataDictionary=../spec/FIX44.xml
+ResendRequestChunkSize=5
\ No newline at end of file
diff --git a/_test/cfg/resendreqchunksize/fix50.cfg b/_test/cfg/resendreqchunksize/fix50.cfg
new file mode 100644
index 000000000..516096b28
--- /dev/null
+++ b/_test/cfg/resendreqchunksize/fix50.cfg
@@ -0,0 +1,14 @@
+[DEFAULT]
+SocketAcceptPort=5006
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIXT.1.1
+SessionQualifier=FIX50
+DefaultApplVerID=FIX.5.0
+TransportDataDictionary=../spec/FIXT11.xml
+AppDataDictionary=../spec/FIX50.xml
+ResendRequestChunkSize=5
\ No newline at end of file
diff --git a/_test/cfg/resendreqchunksize/fix50sp1.cfg b/_test/cfg/resendreqchunksize/fix50sp1.cfg
new file mode 100644
index 000000000..b89038936
--- /dev/null
+++ b/_test/cfg/resendreqchunksize/fix50sp1.cfg
@@ -0,0 +1,14 @@
+[DEFAULT]
+SocketAcceptPort=5007
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIXT.1.1
+SessionQualifier=FIX50SP1
+DefaultApplVerID=FIX.5.0SP1
+TransportDataDictionary=../spec/FIXT11.xml
+AppDataDictionary=../spec/FIX50SP1.xml
+ResendRequestChunkSize=5
\ No newline at end of file
diff --git a/_test/cfg/resendreqchunksize/fix50sp2.cfg b/_test/cfg/resendreqchunksize/fix50sp2.cfg
new file mode 100644
index 000000000..5bbaed9a3
--- /dev/null
+++ b/_test/cfg/resendreqchunksize/fix50sp2.cfg
@@ -0,0 +1,14 @@
+[DEFAULT]
+SocketAcceptPort=5008
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIXT.1.1
+SessionQualifier=FIX50SP2
+DefaultApplVerID=FIX.5.0SP2
+TransportDataDictionary=../spec/FIXT11.xml
+AppDataDictionary=../spec/FIX50SP2.xml
+ResendRequestChunkSize=5
\ No newline at end of file
diff --git a/_test/fix40.cfg b/_test/cfg/server/fix40.cfg
similarity index 100%
rename from _test/fix40.cfg
rename to _test/cfg/server/fix40.cfg
diff --git a/_test/fix41.cfg b/_test/cfg/server/fix41.cfg
similarity index 100%
rename from _test/fix41.cfg
rename to _test/cfg/server/fix41.cfg
diff --git a/_test/cfg/server/fix42.cfg b/_test/cfg/server/fix42.cfg
new file mode 100644
index 000000000..b81521c27
--- /dev/null
+++ b/_test/cfg/server/fix42.cfg
@@ -0,0 +1,10 @@
+[DEFAULT]
+SocketAcceptPort=5003
+SenderCompID=ISLD
+TargetCompID=TW
+ResetOnLogon=Y
+FileLogPath=tmp
+
+[SESSION]
+BeginString=FIX.4.2
+DataDictionary=../spec/FIX42.xml
\ No newline at end of file
diff --git a/_test/fix43.cfg b/_test/cfg/server/fix43.cfg
similarity index 100%
rename from _test/fix43.cfg
rename to _test/cfg/server/fix43.cfg
diff --git a/_test/fix44.cfg b/_test/cfg/server/fix44.cfg
similarity index 100%
rename from _test/fix44.cfg
rename to _test/cfg/server/fix44.cfg
diff --git a/_test/fix50.cfg b/_test/cfg/server/fix50.cfg
similarity index 100%
rename from _test/fix50.cfg
rename to _test/cfg/server/fix50.cfg
diff --git a/_test/fix50sp1.cfg b/_test/cfg/server/fix50sp1.cfg
similarity index 100%
rename from _test/fix50sp1.cfg
rename to _test/cfg/server/fix50sp1.cfg
diff --git a/_test/fix50sp2.cfg b/_test/cfg/server/fix50sp2.cfg
similarity index 100%
rename from _test/fix50sp2.cfg
rename to _test/cfg/server/fix50sp2.cfg
diff --git a/_test/definitions/lastseqnumprocessed/fix42/LastProcessedMsgSeqNum.def b/_test/definitions/lastseqnumprocessed/fix42/LastProcessedMsgSeqNum.def
new file mode 100644
index 000000000..1486575da
--- /dev/null
+++ b/_test/definitions/lastseqnumprocessed/fix42/LastProcessedMsgSeqNum.def
@@ -0,0 +1,21 @@
+iCONNECT
+
+I8=FIX.4.235=A34=149=TW52=