Compare commits
9 Commits
bfeecb334a
...
setup
| Author | SHA1 | Date | |
|---|---|---|---|
| f940f5a0f9 | |||
| ac285e662b | |||
| 0424e2ed79 | |||
| 072d44f3c3 | |||
| dcb1916c39 | |||
| c09a1fd21a | |||
| 9e55c5c562 | |||
| b45efdb297 | |||
| aa0525a78c |
115
.gitignore
vendored
Normal file
115
.gitignore
vendored
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# IDEA IDE
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# User-specific stuff:
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/dictionaries
|
||||||
|
|
||||||
|
# Sensitive or high-churn files:
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.xml
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
|
||||||
|
# Gradle:
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Mongo Explorer plugin:
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
## File-based project format:
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# MAC cache files
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
## Plugin-specific files:
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# vscode config
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
#-----------------------------------
|
||||||
|
# Golang
|
||||||
|
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, build with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||||
|
.glide/
|
||||||
|
|
||||||
|
# GO compiled
|
||||||
|
/pkg/
|
||||||
|
|
||||||
|
# GO binaries
|
||||||
|
/bin/
|
||||||
|
|
||||||
|
# GO vendoring
|
||||||
|
/vendor/
|
||||||
|
|
||||||
|
# Project autogenerated documentation
|
||||||
|
/doc/
|
||||||
|
|
||||||
|
#-----------------------------------
|
||||||
|
# General
|
||||||
|
|
||||||
|
out.log
|
||||||
|
|
||||||
|
# generated binary
|
||||||
|
/main
|
||||||
|
|
||||||
|
|
||||||
|
# Autogenerated by go-bindata
|
||||||
|
# bindata.go
|
||||||
|
|
||||||
|
# Autogenerated strings by stringer for const values (enums)
|
||||||
|
/src/**/*_string.go
|
||||||
|
|
||||||
|
# Autogenerated files by go-enum for enum values.
|
||||||
|
/src/**/*_enum.go
|
||||||
|
|
||||||
|
# Binary tools
|
||||||
|
tools/bin/
|
||||||
|
|
||||||
|
# Build folders and files
|
||||||
|
/build/
|
||||||
|
|
||||||
|
todo.md
|
||||||
|
|
||||||
|
/logs/
|
||||||
|
|
||||||
|
conf.toml
|
||||||
|
|
||||||
|
src/client/api/rest/docs
|
||||||
|
|
||||||
|
.gitlab-ci-local
|
||||||
|
|
||||||
|
*conf.toml
|
||||||
|
|
||||||
|
diffs
|
||||||
|
|
||||||
|
.linter_version.txt
|
||||||
|
|
||||||
|
multiDBLogs/
|
||||||
3
.gitlab-ci-local-variables.yml
Normal file
3
.gitlab-ci-local-variables.yml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
MULTIDB_ACCESS_TOKEN: <ACCESS_TOKEN>
|
||||||
|
USERNAME: <USERNAME>
|
||||||
99
.gitlab-ci.yml
Normal file
99
.gitlab-ci.yml
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
# Official framework image. Look for the different tagged releases at:
|
||||||
|
# https://hub.docker.com/r/library/node/tags/
|
||||||
|
image: golang:1.24
|
||||||
|
|
||||||
|
default:
|
||||||
|
before_script:
|
||||||
|
- go clean -modcache
|
||||||
|
- git config --global url."https://$USERNAME:$MULTIDB_ACCESS_TOKEN@gitlab.com/quantex-exchange".insteadOf "https://gitlab.com/quantex-exchange"
|
||||||
|
- export GOPRIVATE="quantex.com.ar/multidb"
|
||||||
|
- go get quantex.com.ar/multidb@v1.2.2
|
||||||
|
- make gogenerate
|
||||||
|
- make swag
|
||||||
|
- go mod vendor
|
||||||
|
artifacts:
|
||||||
|
when: always
|
||||||
|
paths:
|
||||||
|
- qfixpt.gz
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- lint
|
||||||
|
- build
|
||||||
|
|
||||||
|
regular:
|
||||||
|
stage: build
|
||||||
|
needs: []
|
||||||
|
except:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
- demo
|
||||||
|
- open-demo
|
||||||
|
script:
|
||||||
|
- go clean -cache
|
||||||
|
- make gogenerate
|
||||||
|
- make swag
|
||||||
|
- make test
|
||||||
|
- make check
|
||||||
|
- make build
|
||||||
|
- mv build/out/distribution/qfixpt.gz .
|
||||||
|
|
||||||
|
develop:
|
||||||
|
stage: build
|
||||||
|
needs: []
|
||||||
|
only:
|
||||||
|
- develop
|
||||||
|
script:
|
||||||
|
- make gogenerate
|
||||||
|
- make swag
|
||||||
|
- make test
|
||||||
|
- make only-build
|
||||||
|
- mv build/out/distribution/qfixpt.gz .
|
||||||
|
environment:
|
||||||
|
name: dev
|
||||||
|
url: https://dev.quantex.com.ar
|
||||||
|
|
||||||
|
master:
|
||||||
|
stage: build
|
||||||
|
needs: []
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
script:
|
||||||
|
- go clean -cache
|
||||||
|
- make gogenerate
|
||||||
|
- make swag
|
||||||
|
- make test
|
||||||
|
- make build
|
||||||
|
- mv build/out/distribution/qfixpt.gz .
|
||||||
|
environment:
|
||||||
|
name: prod
|
||||||
|
url: https://app.quantex.com.ar
|
||||||
|
|
||||||
|
demo:
|
||||||
|
stage: build
|
||||||
|
needs: []
|
||||||
|
only:
|
||||||
|
- demo
|
||||||
|
script:
|
||||||
|
- make test
|
||||||
|
- make only-build
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install sshpass
|
||||||
|
- mv build/out/distribution/qfixpt.gz .
|
||||||
|
environment:
|
||||||
|
name: demo
|
||||||
|
url: https://demo.quantex.com.ar
|
||||||
|
|
||||||
|
open-demo:
|
||||||
|
stage: build
|
||||||
|
needs: []
|
||||||
|
only:
|
||||||
|
- open-demo
|
||||||
|
script:
|
||||||
|
- make test
|
||||||
|
- make only-build
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install sshpass
|
||||||
|
- mv build/out/distribution/qfixpt.gz .
|
||||||
|
environment:
|
||||||
|
name: open-demo
|
||||||
|
url: https://open-demo.quantex.com.ar
|
||||||
26
.gitlab/issue_templates/Default.md
Normal file
26
.gitlab/issue_templates/Default.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
## ℹ️ Issue Type
|
||||||
|
|
||||||
|
- [ ] feature
|
||||||
|
- [ ] hotfix
|
||||||
|
- [ ] refactor
|
||||||
|
- [ ] improvement
|
||||||
|
- [ ] doc
|
||||||
|
- [ ] fix
|
||||||
|
|
||||||
|
## ❌ Issue Description
|
||||||
|
|
||||||
|
Summary_of_what_is_the_issue_and_include_screenshots_and_links_of_slack_to_follow_the_problem
|
||||||
|
|
||||||
|
## ✅ Expected Behaviuor
|
||||||
|
|
||||||
|
Explain_little_about_how_it_should_be_working
|
||||||
|
|
||||||
|
## 📋 Steps to Reproduce
|
||||||
|
|
||||||
|
What_steps_should_someone_take_to_reproduce_the_issue_include_screenshots_and_links
|
||||||
|
|
||||||
|
## 🐛 Possible Impacts
|
||||||
|
|
||||||
|
What_other_areas_in_our_code_might_be_affected_or_is_it_possible_that_something_else_broke_with_these_changes
|
||||||
|
|
||||||
30
.gitlab/merge_request_templates/Default.md
Normal file
30
.gitlab/merge_request_templates/Default.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
|
||||||
|
## 🐛 Reason to Be
|
||||||
|
|
||||||
|
Double_click_to_replace_with_a_brief_summary_of_what_this_MR_does_including_a_summary_of_the_original_issue_and_include_screenshots_and_links_to_designs_if_this_MR_has_a_UI_component
|
||||||
|
|
||||||
|
Resolves #Issue_number
|
||||||
|
|
||||||
|
Related #Issue_number
|
||||||
|
|
||||||
|
|
||||||
|
## ✅ Expected Behaviuor
|
||||||
|
|
||||||
|
Explain_little_about_how_is_it_working_in_the_current_MR
|
||||||
|
|
||||||
|
|
||||||
|
## 📋 How To Test
|
||||||
|
|
||||||
|
What_steps_should_someone_take_to_test_these_changes_include_screenshots_and_links_to_mocks_for_any_ui_work
|
||||||
|
|
||||||
|
|
||||||
|
## ⚠️ Check List
|
||||||
|
|
||||||
|
1. [ ] Title format _**SKL-33: Implement Logging using Qapix Endpoints**_ (PREFIX-Issue#: Message)
|
||||||
|
2. [ ] Run `make ci` at your end
|
||||||
|
3. [ ] Check the pipeline is **🟢 SUCCESS**
|
||||||
|
4. [ ] Set the Assignee and Reviewer
|
||||||
|
5. [ ] Create 2 PRs for ⚡ HOTFIX in master and develop️
|
||||||
|
|
||||||
|
|
||||||
24
AGENTS.md
Normal file
24
AGENTS.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Repository Guidelines
|
||||||
|
|
||||||
|
## Project Structure & Module Organization
|
||||||
|
The service boots from `main.go`, and all Go packages live under `src`. Use `src/app` for orchestration, `src/domain` for entities and ports, `src/common` for shared helpers, `src/client/api/rest` for HTTP handlers and Swagger assets, and `src/cmd` for runnable entrypoints. Configuration samples live in `conf.toml`, `my_global_conf.toml`, and `res/`, while automation scripts sit in `build/` and `tools/`; vendor-locked dependencies remain in `vendor/` for reproducible builds.
|
||||||
|
|
||||||
|
## Build, Test, and Development Commands
|
||||||
|
- `make dev` – runs the contributor checklist plus lint gate before coding.
|
||||||
|
- `make check` – installs toolchains and executes golangci-lint, gosec, revive, errcheck, and dependency audits.
|
||||||
|
- `make test` – calls `go test ./...`; use `go test ./src/... -run TestName` for a focused run.
|
||||||
|
- `make build e=dev` – compiles via `tools/build.sh`; switch `e` to `prod`, `demo`, or `open-demo`.
|
||||||
|
- `QUANTEX_ENVIRONMENT="dev" go run main.go -c -run service` – starts the service with text logs (omit `-c` for JSON).
|
||||||
|
- `make deploy e=<alias>` – pushes a build using the target defined in `build/deploy.sh`.
|
||||||
|
|
||||||
|
## Coding Style & Naming Conventions
|
||||||
|
Run `make fmt` to apply gofumpt, gci, and goimports; Go’s formatter enforces tab indentation and canonical spacing. Follow idiomatic naming—PascalCase for exported symbols, camelCase for internals, lowercase filenames—and keep package paths under `quantex.com/qfixpt/<module>`. Group imports as standard library, third-party, then `quantex.com`, and avoid formatting-only commits.
|
||||||
|
|
||||||
|
## Testing Guidelines
|
||||||
|
Keep `*_test.go` files beside the code and prefer table-driven cases. Guard integration tests with `QUANTEX_ENVIRONMENT` so they hit the intended backend, and regenerate Swagger with `make swag` whenever REST contracts change. Spot-check concurrency with `go test -race ./src/<package>` and store fixtures under package-level `testdata/` directories.
|
||||||
|
|
||||||
|
## Commit & Pull Request Guidelines
|
||||||
|
Use `make branch t=<type> u=<user> n=<issue> m="summary"` to produce names such as `feature/jdoe/SKL-123/add_logger`. Write commit subjects in the imperative mood, referencing `SKL-###` when relevant. Pull requests must include a concise summary, linked issue, confirmation of `make test` and `make check`, and evidence (logs or screenshots) when altering responses or logging; call out configuration changes explicitly.
|
||||||
|
|
||||||
|
## Configuration & Deployment Tips
|
||||||
|
Treat `conf.toml` and `my_global_conf.toml` as templates and override secrets via environment variables. Confirm build metadata with `make print-version` before deploying, and promote builds through `make deploy e=<alias>`. When exploring logging formats pass `-f text|json|tint1|tint2`, and follow the `README.md` guidance for multi-DB runs that require elevated permissions.
|
||||||
138
Makefile
Normal file
138
Makefile
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
# Copyright 2019 PingCAP, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
include Makefile.common
|
||||||
|
|
||||||
|
.PHONY: help all clean dev check checklist tidy
|
||||||
|
|
||||||
|
vendor:
|
||||||
|
go mod vendor
|
||||||
|
|
||||||
|
push: vendor ci check-dirty ## Push the current branch to remote server
|
||||||
|
git push origin $$(git rev-parse --abbrev-ref HEAD)
|
||||||
|
|
||||||
|
branch: ## Create a new branch and checkout it. Usage: make branch (interactive)
|
||||||
|
@./tools/branch.sh
|
||||||
|
|
||||||
|
dev: checklist check
|
||||||
|
|
||||||
|
# Note from Fede:
|
||||||
|
# See https://github.com/golang/go/issues/44129
|
||||||
|
# If issues run: go env -w GOFLAGS=-mod=mod
|
||||||
|
# Run swag just in case
|
||||||
|
ci: swag fmt tidy check ## Run formatters (could modify the code), checks and linters
|
||||||
|
|
||||||
|
check: check-static dependencies-check ## Run checks and linters
|
||||||
|
|
||||||
|
download-versions:
|
||||||
|
curl --url "https://app.quantex.com.ar/linter_version.txt" -o $(linter_version_file)
|
||||||
|
|
||||||
|
test: ## Run all the tests
|
||||||
|
go test ./...
|
||||||
|
|
||||||
|
VALID_ENV_TYPES := prod dev demo open-demo
|
||||||
|
check-env:
|
||||||
|
@if [ "$(filter $(e),$(VALID_ENV_TYPES))" != "$(e)" ]; then \
|
||||||
|
echo "\033[31mError: Invalid environment type $(e). Types can be: prod, dev, demo, open-demo"; \
|
||||||
|
exit 1; \
|
||||||
|
fi;
|
||||||
|
# set dev as default
|
||||||
|
$(eval e := dev)
|
||||||
|
|
||||||
|
print-version: check-env ## Print the version of the latest build
|
||||||
|
OUT_PATH=$(DEFAULT_OUT_PATH) tools/print-version.sh $(e)
|
||||||
|
|
||||||
|
build: check-env swag vendor only-build # Build a native version. Set e=environment: prod, dev, demo, open-demo
|
||||||
|
|
||||||
|
only-build: check-env
|
||||||
|
@echo "Building for $(e) environment..."
|
||||||
|
env OUT_PATH=$(DEFAULT_OUT_PATH) GOARCH=amd64 GOOS=linux tools/build.sh $(e)
|
||||||
|
|
||||||
|
linux-build: check-env swag # Build a linux version for prod environment. Set e=environment: prod, dev, demo, open-demo
|
||||||
|
env OUT_PATH=$(DEFAULT_OUT_PATH) GOARCH=amd64 GOOS=linux tools/build.sh $(e)
|
||||||
|
|
||||||
|
deploy: check-env # Deploy to remote server. Set e=environment: prod, dev, demo, open-demo; s=serverName; i=instance; e.g. make deploy e=dev s=nonprodFix i=qfixpt
|
||||||
|
make build e=$(e) && qscp build/out/distribution/qfixdpl.gz $(s):/home/quantex/qfixtb/$(i)/
|
||||||
|
|
||||||
|
fmt: download-versions # Apply the Go formatter to the code
|
||||||
|
cd tools/check; unset GOPATH; GOBIN=$$PWD/../bin go install mvdan.cc/gofumpt@$(call get_version,gofumpt);
|
||||||
|
@echo "running fmt..."
|
||||||
|
@echo $(GIT_TREE_STATE)
|
||||||
|
@echo "> running gofumpt..."
|
||||||
|
@tools/bin/gofumpt -l -w main.go 2>&1
|
||||||
|
@tools/bin/gofumpt -l -w $(FILES) 2>&1
|
||||||
|
|
||||||
|
swag: download-versions
|
||||||
|
@echo "installing swag..."
|
||||||
|
cd tools/check; unset GOPATH; GOBIN=$$PWD/../bin go install github.com/swaggo/swag/cmd/swag@$(call get_version,swag);
|
||||||
|
@echo "running swag..."
|
||||||
|
rm -f src/client/api/rest/docs/swagger.json
|
||||||
|
rm -f src/client/api/rest/docs/swagger.yaml
|
||||||
|
rm -f src/client/api/rest/docs/docs.go
|
||||||
|
mkdir -p src/client/api/rest/docs
|
||||||
|
echo "package docs" > src/client/api/rest/docs/docs.go # This empty file is needed for the initial build. Then is overwritten by Swag.
|
||||||
|
tools/bin/swag init --parseDependency -g server.go -d src/client/api/rest -o src/client/api/rest/docs/
|
||||||
|
|
||||||
|
check-static: download-versions
|
||||||
|
@echo "installing golangci-lint..."
|
||||||
|
cd tools/check; unset GOPATH; GOBIN=$$PWD/../bin go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(call get_version,golangci-lint);
|
||||||
|
@echo "running golangci-lint..."
|
||||||
|
@echo $$($(PACKAGE_DIRECTORIES))
|
||||||
|
|
||||||
|
tools/bin/golangci-lint run -v -c tools/check/golangci.yml --timeout 5m0s ./...
|
||||||
|
|
||||||
|
check-dirty:
|
||||||
|
$(if $(filter dirty,$(GIT_TREE_STATE)), $(error git state is not clean <$(GIT_TREE_STATE)>))
|
||||||
|
|
||||||
|
dependencies-check: download-versions
|
||||||
|
@echo "installing govulncheck..."
|
||||||
|
cd tools/check; unset GOPATH; GOBIN=$$PWD/../bin go install golang.org/x/vuln/cmd/govulncheck@$(call get_version,govulncheck);
|
||||||
|
@echo "running govulncheck..."
|
||||||
|
@tools/bin/govulncheck -show verbose ./...
|
||||||
|
|
||||||
|
gogenerate: download-versions
|
||||||
|
@echo "installing go-enum..."
|
||||||
|
cd tools/check; unset GOPATH; GOBIN=$$PWD/../bin go install github.com/abice/go-enum@$(call get_version,go-enum);
|
||||||
|
@echo "running go generate ./.."
|
||||||
|
./tools/check/check-gogenerate.sh
|
||||||
|
|
||||||
|
tidy:
|
||||||
|
@echo "running go mod tidy..."
|
||||||
|
./tools/check/check-tidy.sh
|
||||||
|
|
||||||
|
server_coverage:
|
||||||
|
ifeq ($(TARGET), "")
|
||||||
|
$(GOBUILDCOVERAGE) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(COVERAGE_SERVER_LDFLAGS) $(CHECK_FLAG)' -o ../bin/bitlab-coverage
|
||||||
|
else
|
||||||
|
$(GOBUILDCOVERAGE) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(COVERAGE_SERVER_LDFLAGS) $(CHECK_FLAG)' -o '$(TARGET)'
|
||||||
|
endif
|
||||||
|
|
||||||
|
checklist:
|
||||||
|
cat checklist.md
|
||||||
|
|
||||||
|
linter_version_file = .linter_version.txt
|
||||||
|
|
||||||
|
define get_version
|
||||||
|
$(shell grep "^$(1):" $(linter_version_file) | cut -d: -f2 | tr -d ' ')
|
||||||
|
endef
|
||||||
|
|
||||||
|
init: ## Install dependencies to run the project
|
||||||
|
make swag
|
||||||
|
make gogenerate
|
||||||
|
go install ./...
|
||||||
|
|
||||||
|
# Absolutely awesome: http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
|
||||||
|
help:
|
||||||
|
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' Makefile | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := help
|
||||||
62
Makefile.common
Normal file
62
Makefile.common
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# Copyright 2020 PingCAP, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
##################################
|
||||||
|
# Set this values for each project
|
||||||
|
|
||||||
|
PROJECT := qfixpt
|
||||||
|
DOMAIN := quantex.com
|
||||||
|
|
||||||
|
##################################
|
||||||
|
|
||||||
|
ISSUE_PREFIX := QPT
|
||||||
|
GOPATH ?= $(shell go env GOPATH)
|
||||||
|
|
||||||
|
P=8
|
||||||
|
|
||||||
|
GIT_TREE_STATE=$(shell (git status --porcelain | grep -q .) && echo dirty || echo clean)
|
||||||
|
|
||||||
|
# Ensure GOPATH is set before running build process.
|
||||||
|
ifeq "$(GOPATH)" ""
|
||||||
|
$(error Please set the environment variable GOPATH before running `make`)
|
||||||
|
endif
|
||||||
|
FAIL_ON_STDOUT := awk '{ print } END { if (NR > 0) { exit 1 } }'
|
||||||
|
|
||||||
|
CURDIR := $(shell pwd)
|
||||||
|
path_to_add := $(addsuffix /bin,$(subst :,/bin:,$(GOPATH))):$(PWD)/tools/bin
|
||||||
|
export PATH := $(path_to_add):$(PATH)
|
||||||
|
|
||||||
|
GOBUILD := go build $(BUILD_FLAG) -tags codes
|
||||||
|
GOBUILDCOVERAGE := GOPATH=$(GOPATH) cd tidb-server; $(GO) test -coverpkg="../..." -c .
|
||||||
|
GOTEST := go test -p $(P)
|
||||||
|
|
||||||
|
LINUX := "Linux"
|
||||||
|
MAC := "Darwin"
|
||||||
|
# PACKAGE_LIST := go list ./...| grep -vE "cmd|$(DOMAIN)\/$(PROJECT)\/tests"
|
||||||
|
PACKAGE_LIST := go list ./...| grep -vE "$(DOMAIN)\/$(PROJECT)\/tests"
|
||||||
|
PACKAGES ?= $$($(PACKAGE_LIST))
|
||||||
|
PACKAGE_DIRECTORIES := $(PACKAGE_LIST) | sed 's|$(DOMAIN)/$(PROJECT)/||' | sed 's|$(DOMAIN)/$(PROJECT)||'
|
||||||
|
FILES := $$(find $$($(PACKAGE_DIRECTORIES)) -name "*.go")
|
||||||
|
|
||||||
|
DEFAULT_OUT_PATH := "./build/out/distribution"
|
||||||
|
|
||||||
|
RACE_FLAG =
|
||||||
|
ifeq ("$(WITH_RACE)", "1")
|
||||||
|
RACE_FLAG = -race
|
||||||
|
GOBUILD = GOPATH=$(GOPATH) $(GO) build
|
||||||
|
endif
|
||||||
|
|
||||||
|
CHECK_FLAG =
|
||||||
|
ifeq ("$(WITH_CHECK)", "1")
|
||||||
|
CHECK_FLAG = $(TEST_LDFLAGS)
|
||||||
|
endif
|
||||||
31
checklist.md
Normal file
31
checklist.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Following the checklist saves the reviewers' time and gets your PR reviewed faster.
|
||||||
|
|
||||||
|
# Self Review
|
||||||
|
|
||||||
|
Have you reviewed every line of your changes by yourself?
|
||||||
|
|
||||||
|
# Test
|
||||||
|
|
||||||
|
Have you added enough test cases to cover the new feature or bug fix? Also, add comments to describe your test cases.
|
||||||
|
|
||||||
|
# Naming
|
||||||
|
|
||||||
|
Do function names keep consistent with its behavior? Is it easy to infer the function's behavior by its name?
|
||||||
|
|
||||||
|
# Comment
|
||||||
|
|
||||||
|
Is there any code that confuses the reviewer? Add comments on them! You'll be asked to do so anyway. Make sure there is
|
||||||
|
no syntax or spelling error in your comments. Some online syntax checking tools like Grammarly may be helpful.
|
||||||
|
|
||||||
|
# Refactor
|
||||||
|
|
||||||
|
Is there any way to refactor the code to make it more readable? If the refactoring touches a lot of existing code, send
|
||||||
|
another PR to do it.
|
||||||
|
|
||||||
|
# Single Purpose
|
||||||
|
|
||||||
|
Make sure the PR does only one thing and nothing else.
|
||||||
|
|
||||||
|
# Diff Size
|
||||||
|
|
||||||
|
Make sure the diff size is no more than 500, split it into small PRs if it is too large.
|
||||||
417
docs/JWT_SERVICE_AUTHENTICATION.md
Normal file
417
docs/JWT_SERVICE_AUTHENTICATION.md
Normal file
@ -0,0 +1,417 @@
|
|||||||
|
# JWT Service-to-Service Authentication
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Services authenticate with each other using JWT tokens. The system uses **two-factor authentication**: JWT signature validation + user credential validation against the database.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
### Outgoing Request (Skeleton → QApix)
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Skeleton wants to call QApix
|
||||||
|
2. Creates JWT with:
|
||||||
|
- iss: "Skeleton"
|
||||||
|
- token: "franco:bpa31kniubroq28rpvg010" (from External.QApix.Token in config)
|
||||||
|
- iat: current timestamp
|
||||||
|
3. Signs JWT with QAPIX_QUANTEX_SECRET_KEY
|
||||||
|
4. Sends request with header: Authorization: {JWT}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Incoming Request (QApix → Skeleton)
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Skeleton receives JWT from QApix
|
||||||
|
2. Validates JWT signature with SKELETON_QUANTEX_SECRET_KEY
|
||||||
|
3. Checks "QApix" is in AuthorizedServices config
|
||||||
|
4. Checks QApix has required permissions (currently FullAccess)
|
||||||
|
5. Extracts token claim: "franco:bpa31kniubroq28rpvg010"
|
||||||
|
6. Looks up user "franco" in database
|
||||||
|
7. Verifies password "bpa31kniubroq28rpvg010" matches
|
||||||
|
8. ✅ Request allowed
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### conf.toml
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# Enable/disable JWT authentication
|
||||||
|
EnableJWTAuth = true # Set to true to enable JWT authentication checks
|
||||||
|
|
||||||
|
# Who we call (outgoing requests)
|
||||||
|
[External.QApix]
|
||||||
|
Name = "QApix"
|
||||||
|
Token = "franco:bpa31kniubroq28rpvg010" # Credentials we use to authenticate
|
||||||
|
Host = "https://qapix.example.com"
|
||||||
|
Port = "5001"
|
||||||
|
|
||||||
|
# Who can call us (incoming requests)
|
||||||
|
[AuthorizedServices.QApix]
|
||||||
|
Name = "QApix"
|
||||||
|
Permissions = ["FullAccess"] # What QApix is allowed to do
|
||||||
|
# Token validated against user DB - not stored in config
|
||||||
|
```
|
||||||
|
|
||||||
|
**Configuration Options:**
|
||||||
|
- `EnableJWTAuth` (bool): Controls whether JWT authentication is enabled
|
||||||
|
- `true`: Enables JWT authentication and health check validation
|
||||||
|
- `false`: Disables JWT authentication features (default for local development)
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# On Skeleton
|
||||||
|
export SKELETON_QUANTEX_SECRET_KEY="..." # Validates incoming JWTs
|
||||||
|
export QAPIX_QUANTEX_SECRET_KEY="..." # Signs outgoing JWTs to QApix
|
||||||
|
|
||||||
|
# On QApix
|
||||||
|
export QAPIX_QUANTEX_SECRET_KEY="..." # Validates incoming JWTs
|
||||||
|
export SKELETON_QUANTEX_SECRET_KEY="..." # Signs outgoing JWTs to Skeleton
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important**: Secret keys must match across services:
|
||||||
|
- `SKELETON_QUANTEX_SECRET_KEY` on Skeleton = `SKELETON_QUANTEX_SECRET_KEY` on QApix
|
||||||
|
- `QAPIX_QUANTEX_SECRET_KEY` on Skeleton = `QAPIX_QUANTEX_SECRET_KEY` on QApix
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Layers
|
||||||
|
|
||||||
|
| Layer | Description | Purpose |
|
||||||
|
|-------|-------------|---------|
|
||||||
|
| 1. JWT Signature | Validates HS256 signature | Proves caller has secret key |
|
||||||
|
| 2. Issuer Whitelist | Checks AuthorizedServices | Only known services allowed |
|
||||||
|
| 3. Permission Check | Validates service permissions | ReadOnly/ReadWrite/FullAccess |
|
||||||
|
| 4. User Validation | Checks token against user DB | Real credentials required |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Code Flow
|
||||||
|
|
||||||
|
### Creating JWT
|
||||||
|
**Location**: `src/common/jwttoken/jwt.go`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Encrypt(auth app.ExtAuth) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
```go
|
||||||
|
auth := app.ExtAuth{
|
||||||
|
Name: "QApix",
|
||||||
|
Token: "franco:bpa31kniubroq28rpvg010",
|
||||||
|
}
|
||||||
|
jwt, err := jwttoken.Encrypt(auth)
|
||||||
|
// Returns signed JWT token
|
||||||
|
```
|
||||||
|
|
||||||
|
### Validating JWT
|
||||||
|
**Location**: `src/common/jwttoken/jwt.go`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Validate(token string, authServices map[string]AuthorizedService) (*AuthorizedService, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
```go
|
||||||
|
service, err := jwttoken.Validate(jwtToken, config.AuthorizedServices)
|
||||||
|
// Returns authorized service with token and permissions
|
||||||
|
```
|
||||||
|
|
||||||
|
### Middleware
|
||||||
|
**Location**: `src/client/api/rest/midlewares.go`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (cont *Controller) JWTTokenAuth(reqToken string, ctx *gin.Context)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Flow**:
|
||||||
|
1. Receives JWT from Authorization header
|
||||||
|
2. Calls `jwttoken.Validate()` to verify JWT and check permissions
|
||||||
|
3. Calls `validateServiceToken(token)` to verify user credentials in database
|
||||||
|
4. Sets `authorized_service` in Gin context
|
||||||
|
5. Proceeds to next handler
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## JWT Token Structure
|
||||||
|
|
||||||
|
### Claims
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"iss": "Skeleton", // Issuer (who created the token)
|
||||||
|
"token": "franco:bpa31kniubroq28rpvg010", // User credentials
|
||||||
|
"iat": 1704481490 // Issued at (Unix timestamp)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Header
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"alg": "HS256", // Algorithm (HMAC SHA-256)
|
||||||
|
"typ": "JWT" // Type
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Service Permissions
|
||||||
|
|
||||||
|
Defined in `src/app/model.go`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ServicePermission int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ServicePermissionReadOnly // Read-only access
|
||||||
|
ServicePermissionReadWrite // Read and write access
|
||||||
|
ServicePermissionFullAccess // Full access to all operations
|
||||||
|
ServicePermissionUndefined // No permissions
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Permission Check**:
|
||||||
|
```go
|
||||||
|
service.HasPermissions(app.ServicePermissionFullAccess) // Returns bool
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Benefits
|
||||||
|
|
||||||
|
- ✅ **No credentials in config** - Token validated against user database
|
||||||
|
- ✅ **Recipient controls access** - Permissions defined by recipient, not sender
|
||||||
|
- ✅ **Two-factor auth** - Secret key + user credentials
|
||||||
|
- ✅ **Easy rotation** - Change user password → JWT auth automatically updates
|
||||||
|
- ✅ **Audit trail** - Know which service user made each request
|
||||||
|
- ✅ **Single source of truth** - User credentials only in database
|
||||||
|
- ✅ **Configurable** - Enable/disable JWT auth per environment via `EnableJWTAuth`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### Generate JWT Token
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Set environment variable
|
||||||
|
export SKELETON_QUANTEX_SECRET_KEY="your-secret-key"
|
||||||
|
|
||||||
|
# Run generator
|
||||||
|
cd tools
|
||||||
|
./generate-jwt.sh
|
||||||
|
|
||||||
|
# Follow prompts:
|
||||||
|
# Issuer: Skeleton
|
||||||
|
# Service: SKELETON
|
||||||
|
# Token: franco:bpa31kniubroq28rpvg010
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test with curl
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Store generated token
|
||||||
|
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||||||
|
|
||||||
|
# Test endpoint
|
||||||
|
curl -H "Authorization: $TOKEN" \
|
||||||
|
http://localhost:8097/api/v1/endpoint
|
||||||
|
|
||||||
|
# Expected: 200 OK (if token valid and user exists)
|
||||||
|
# Expected: 401 Unauthorized (if token invalid or user not found)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Scenarios
|
||||||
|
|
||||||
|
| Scenario | Expected Result |
|
||||||
|
|----------|-----------------|
|
||||||
|
| Valid JWT + Valid user | ✅ 200 OK |
|
||||||
|
| Valid JWT + Invalid user | ❌ 401 Unauthorized |
|
||||||
|
| Invalid JWT signature | ❌ 401 Unauthorized |
|
||||||
|
| Unknown issuer | ❌ 401 Unauthorized |
|
||||||
|
| Insufficient permissions | ❌ 403 Forbidden |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authentication Flow Diagram
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────┐ ┌─────────────┐
|
||||||
|
│ Skeleton │ │ QApix │
|
||||||
|
└──────┬──────┘ └──────┬──────┘
|
||||||
|
│ │
|
||||||
|
│ 1. Create JWT │
|
||||||
|
│ - iss: "Skeleton" │
|
||||||
|
│ - token: "franco:password" │
|
||||||
|
│ │
|
||||||
|
│ 2. Sign with QAPIX_QUANTEX_SECRET_KEY │
|
||||||
|
│ │
|
||||||
|
│ 3. HTTP Request │
|
||||||
|
│ Authorization: {JWT} │
|
||||||
|
├─────────────────────────────────────────────────>│
|
||||||
|
│ │
|
||||||
|
│ 4. Decrypt JWT│
|
||||||
|
│ (QAPIX_QUANTEX_SECRET_KEY) │
|
||||||
|
│ │
|
||||||
|
│ 5. Validate claims │
|
||||||
|
│ (iss, token) │
|
||||||
|
│ │
|
||||||
|
│ 6. Check AuthorizedServices│
|
||||||
|
│ ("Skeleton" allowed?)│
|
||||||
|
│ │
|
||||||
|
│ 7. Check permissions │
|
||||||
|
│ (FullAccess?) │
|
||||||
|
│ │
|
||||||
|
│ 8. Validate user in DB │
|
||||||
|
│ (franco:password exists?)│
|
||||||
|
│ │
|
||||||
|
│ 9. Response (200 OK or 401/403) │
|
||||||
|
│<─────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
**"Invalid JWT"**
|
||||||
|
- Check secret key environment variable is set
|
||||||
|
- Verify secret keys match on both services
|
||||||
|
|
||||||
|
**"Service not authorized"**
|
||||||
|
- Add service to `AuthorizedServices` in conf.toml
|
||||||
|
- Verify `Name` matches JWT `iss` claim
|
||||||
|
|
||||||
|
**"Invalid credentials"**
|
||||||
|
- Check user exists in database
|
||||||
|
- Verify token format is `email:password`
|
||||||
|
- Ensure password matches user record
|
||||||
|
|
||||||
|
**"Insufficient permissions"**
|
||||||
|
- Check service has required permission in `AuthorizedServices`
|
||||||
|
- Update `Permissions` array in conf.toml
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Files Reference
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `src/common/jwttoken/jwt.go` | JWT encryption, decryption, validation |
|
||||||
|
| `src/client/api/rest/midlewares.go` | HTTP middleware for JWT authentication |
|
||||||
|
| `src/client/api/rest/controller.go` | REST controllers including health check with JWT validation |
|
||||||
|
| `src/app/model.go` | AuthorizedService, ServicePermission types, EnableJWTAuth config |
|
||||||
|
| `src/client/api/rest/server.go` | REST API server configuration |
|
||||||
|
| `src/cmd/service/service.go` | Service runner that initializes JWT config |
|
||||||
|
| `conf.toml` | Service configuration |
|
||||||
|
| `tools/generate-jwt.sh` | JWT token generator for testing |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migration Notes
|
||||||
|
|
||||||
|
### From Old System
|
||||||
|
|
||||||
|
**Before** (self-declared permissions):
|
||||||
|
```toml
|
||||||
|
[External.QApix]
|
||||||
|
Token = "franco:password"
|
||||||
|
Permissions = ["QApixAccess"] # ❌ Sender declares own permissions
|
||||||
|
```
|
||||||
|
|
||||||
|
**After** (recipient-controlled):
|
||||||
|
```toml
|
||||||
|
[External.QApix]
|
||||||
|
Token = "franco:password"
|
||||||
|
# ✅ No permissions - recipient decides
|
||||||
|
|
||||||
|
[AuthorizedServices.QApix]
|
||||||
|
Permissions = ["FullAccess"] # ✅ Recipient controls access
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deployment Steps
|
||||||
|
|
||||||
|
1. Update `conf.toml` on both services
|
||||||
|
- Set `EnableJWTAuth = true` for production environments
|
||||||
|
- Set `EnableJWTAuth = false` for local development
|
||||||
|
- Configure `External` and `AuthorizedServices` sections
|
||||||
|
2. Set environment variables for secret keys
|
||||||
|
3. Restart services
|
||||||
|
4. Test with `generate-jwt.sh`
|
||||||
|
5. Verify health endpoint shows `jwtAuthentications: "ok"`
|
||||||
|
6. Monitor logs for authentication errors
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Best Practices
|
||||||
|
|
||||||
|
1. **Rotate Secret Keys Regularly** - Update environment variables periodically
|
||||||
|
2. **Use Strong Secrets** - Minimum 32 bytes, cryptographically random
|
||||||
|
3. **HTTPS Only** - Never send JWTs over unencrypted connections
|
||||||
|
4. **Monitor Auth Logs** - Track failed authentication attempts
|
||||||
|
5. **Principle of Least Privilege** - Use ReadOnly when possible
|
||||||
|
6. **Separate Service Users** - Don't share user credentials across services
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Health Check Endpoint
|
||||||
|
|
||||||
|
The `/health` endpoint provides service health status and optionally includes JWT authentication validation when enabled.
|
||||||
|
|
||||||
|
### Response Structure
|
||||||
|
|
||||||
|
**When `EnableJWTAuth = false`** (default for local development):
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "ok",
|
||||||
|
"build": "feature-branch",
|
||||||
|
"sha": "abc123def"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**When `EnableJWTAuth = true`** (production):
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "ok",
|
||||||
|
"build": "feature-branch",
|
||||||
|
"sha": "abc123def",
|
||||||
|
"jwtAuthentications": "ok"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**When JWT validation fails** (`EnableJWTAuth = true`):
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "degraded",
|
||||||
|
"build": "feature-branch",
|
||||||
|
"sha": "abc123def",
|
||||||
|
"jwtAuthentications": "error"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Health Check Validation
|
||||||
|
|
||||||
|
When `EnableJWTAuth = true`, the health endpoint validates JWT authentication by:
|
||||||
|
1. Attempting to fetch a test user from the database
|
||||||
|
2. Verifying the database connection is working
|
||||||
|
3. Returning `jwtAuthentications: "ok"` if successful
|
||||||
|
4. Returning `jwtAuthentications: "error"` and `status: "degraded"` if validation fails
|
||||||
|
|
||||||
|
**Location**: `src/client/api/rest/controller.go:178`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
- [JWT RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519)
|
||||||
|
- [golang-jwt/jwt](https://github.com/golang-jwt/jwt)
|
||||||
|
- Internal: `tools/README-JWT-GENERATOR.md`
|
||||||
125
go.mod
Normal file
125
go.mod
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
module quantex.com/qfixpt
|
||||||
|
|
||||||
|
go 1.24.6
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/BurntSushi/toml v1.4.0
|
||||||
|
github.com/eclipse/paho.mqtt.golang v1.5.1
|
||||||
|
github.com/gin-gonic/gin v1.10.0
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.3.0
|
||||||
|
github.com/gomodule/redigo v1.9.2
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.34
|
||||||
|
github.com/mitchellh/panicwrap v1.0.0
|
||||||
|
github.com/pires/go-proxyproto v0.11.0
|
||||||
|
github.com/pkg/errors v0.9.1
|
||||||
|
github.com/quagmt/udecimal v1.10.0
|
||||||
|
github.com/rs/zerolog v1.15.0
|
||||||
|
github.com/sasha-s/go-deadlock v0.3.5
|
||||||
|
github.com/satori/go.uuid v1.2.0
|
||||||
|
github.com/shopspring/decimal v1.4.0
|
||||||
|
github.com/stretchr/testify v1.9.0
|
||||||
|
github.com/swaggo/files v1.0.1
|
||||||
|
github.com/swaggo/gin-swagger v1.6.0
|
||||||
|
github.com/swaggo/swag v1.16.4
|
||||||
|
go.mongodb.org/mongo-driver v1.17.9
|
||||||
|
golang.org/x/net v0.47.0
|
||||||
|
quantex.com.ar/multidb v1.2.2
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||||
|
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
|
||||||
|
github.com/aead/chacha20poly1305 v0.0.0-20201124145622-1a5aba2a8b29 // indirect
|
||||||
|
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 // indirect
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/bytedance/sonic v1.12.4 // indirect
|
||||||
|
github.com/bytedance/sonic/loader v0.2.1 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
|
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||||
|
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||||
|
github.com/codenotary/immudb v1.9.5 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
|
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.6 // indirect
|
||||||
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
|
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||||
|
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||||
|
github.com/go-openapi/spec v0.21.0 // indirect
|
||||||
|
github.com/go-openapi/swag v0.23.0 // indirect
|
||||||
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/go-playground/validator/v10 v10.22.1 // indirect
|
||||||
|
github.com/goccy/go-json v0.10.3 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.4 // indirect
|
||||||
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||||
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||||
|
github.com/jackc/pgconn v1.14.3 // indirect
|
||||||
|
github.com/jackc/pgio v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgproto3/v2 v2.3.3 // indirect
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
|
github.com/jackc/pgtype v1.14.4 // indirect
|
||||||
|
github.com/jackc/pgx/v4 v4.18.3 // indirect
|
||||||
|
github.com/jackc/puddle v1.3.0 // indirect
|
||||||
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/klauspost/compress v1.17.9 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||||
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/montanaflynn/stats v0.7.1 // indirect
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
|
github.com/o1egl/paseto v1.0.0 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||||
|
github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
|
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||||
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
|
github.com/prometheus/common v0.60.1 // indirect
|
||||||
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
|
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
||||||
|
github.com/rs/xid v1.6.0 // indirect
|
||||||
|
github.com/sagikazarmark/locafero v0.6.0 // indirect
|
||||||
|
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||||
|
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||||
|
github.com/spf13/afero v1.11.0 // indirect
|
||||||
|
github.com/spf13/cast v1.7.0 // indirect
|
||||||
|
github.com/spf13/cobra v1.8.1 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/spf13/viper v1.19.0 // indirect
|
||||||
|
github.com/stretchr/objx v0.5.2 // indirect
|
||||||
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||||
|
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||||
|
github.com/xdg-go/scram v1.1.2 // indirect
|
||||||
|
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||||
|
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||||
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
|
golang.org/x/arch v0.12.0 // indirect
|
||||||
|
golang.org/x/crypto v0.45.0 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
|
||||||
|
golang.org/x/sync v0.18.0 // indirect
|
||||||
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
|
golang.org/x/term v0.37.0 // indirect
|
||||||
|
golang.org/x/text v0.31.0 // indirect
|
||||||
|
golang.org/x/tools v0.38.0 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20241113154021-e0fbfb71d213 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20241113154021-e0fbfb71d213 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20241113154021-e0fbfb71d213 // indirect
|
||||||
|
google.golang.org/grpc v1.68.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.35.1 // indirect
|
||||||
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
||||||
532
go.sum
Normal file
532
go.sum
Normal file
@ -0,0 +1,532 @@
|
|||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||||
|
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
|
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||||
|
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||||
|
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||||
|
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
|
||||||
|
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
|
||||||
|
github.com/aead/chacha20poly1305 v0.0.0-20170617001512-233f39982aeb/go.mod h1:UzH9IX1MMqOcwhoNOIjmTQeAxrFgzs50j4golQtXXxU=
|
||||||
|
github.com/aead/chacha20poly1305 v0.0.0-20201124145622-1a5aba2a8b29 h1:1DcvRPZOdbQRg5nAHt2jrc5QbV0AGuhDdfQI6gXjiFE=
|
||||||
|
github.com/aead/chacha20poly1305 v0.0.0-20201124145622-1a5aba2a8b29/go.mod h1:UzH9IX1MMqOcwhoNOIjmTQeAxrFgzs50j4golQtXXxU=
|
||||||
|
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw=
|
||||||
|
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635/go.mod h1:lmLxL+FV291OopO93Bwf9fQLQeLyt33VJRUg5VJ30us=
|
||||||
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/bytedance/sonic v1.12.4 h1:9Csb3c9ZJhfUWeMtpCDCq6BUoH5ogfDFLUgQ/jG+R0k=
|
||||||
|
github.com/bytedance/sonic v1.12.4/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||||
|
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
|
github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E=
|
||||||
|
github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||||
|
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||||
|
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||||
|
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||||
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
|
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||||
|
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||||
|
github.com/codenotary/immudb v1.9.5 h1:z4DdsDLalQFVcuOktLw2H95BjFnvFL4TxY2tkYwOkkk=
|
||||||
|
github.com/codenotary/immudb v1.9.5/go.mod h1:+Sex0kDu5F1hE+ydm9p+mpZixjlSeBqrgUZUjNayrNg=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/eclipse/paho.mqtt.golang v1.5.1 h1:/VSOv3oDLlpqR2Epjn1Q7b2bSTplJIeV2ISgCl2W7nE=
|
||||||
|
github.com/eclipse/paho.mqtt.golang v1.5.1/go.mod h1:1/yJCneuyOoCOzKSsOTUc0AJfpsItBGWvYpBLimhArU=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
|
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||||
|
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||||
|
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||||
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
|
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||||
|
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||||
|
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||||
|
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
|
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||||
|
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||||
|
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
|
||||||
|
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
|
||||||
|
github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
|
||||||
|
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||||
|
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||||
|
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
|
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
|
||||||
|
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||||
|
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
|
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||||
|
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||||
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
|
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||||
|
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/gomodule/redigo v1.9.2 h1:HrutZBLhSIU8abiSfW8pj8mPhOyMYjZT/wcA4/L9L9s=
|
||||||
|
github.com/gomodule/redigo v1.9.2/go.mod h1:KsU3hiK/Ay8U42qpaJk+kuNa3C+spxapWpM+ywhcgtw=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||||
|
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
|
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||||
|
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||||
|
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||||
|
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||||
|
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
|
||||||
|
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
|
||||||
|
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
|
||||||
|
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
|
||||||
|
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
|
||||||
|
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
||||||
|
github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w=
|
||||||
|
github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM=
|
||||||
|
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||||
|
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||||
|
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||||
|
github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
|
||||||
|
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc=
|
||||||
|
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
|
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag=
|
||||||
|
github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
|
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||||
|
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||||
|
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||||
|
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
|
||||||
|
github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||||
|
github.com/jackc/pgtype v1.14.4 h1:fKuNiCumbKTAIxQwXfB/nsrnkEI6bPJrrSiMKgbJ2j8=
|
||||||
|
github.com/jackc/pgtype v1.14.4/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA=
|
||||||
|
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||||
|
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||||
|
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||||
|
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
|
||||||
|
github.com/jackc/pgx/v4 v4.18.2/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw=
|
||||||
|
github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA=
|
||||||
|
github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw=
|
||||||
|
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
|
||||||
|
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||||
|
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
|
||||||
|
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
|
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||||
|
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
|
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||||
|
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||||
|
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||||
|
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
|
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||||
|
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/mitchellh/panicwrap v1.0.0 h1:67zIyVakCIvcs69A0FGfZjBdPleaonSgGlXRSRlb6fE=
|
||||||
|
github.com/mitchellh/panicwrap v1.0.0/go.mod h1:pKvZHwWrZowLUzftuFq7coarnxbBXU4aQh3N0BJOeeA=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
|
||||||
|
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
|
github.com/o1egl/paseto v1.0.0 h1:bwpvPu2au176w4IBlhbyUv/S5VPptERIA99Oap5qUd0=
|
||||||
|
github.com/o1egl/paseto v1.0.0/go.mod h1:5HxsZPmw/3RI2pAwGo1HhOOwSdvBpcuVzO7uDkm+CLU=
|
||||||
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||||
|
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
|
||||||
|
github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 h1:qli3BGQK0tYDkSEvZ/FzZTi9ZrOX86Q6CIhKLGc489A=
|
||||||
|
github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
|
||||||
|
github.com/pires/go-proxyproto v0.11.0 h1:gUQpS85X/VJMdUsYyEgyn59uLJvGqPhJV5YvG68wXH4=
|
||||||
|
github.com/pires/go-proxyproto v0.11.0/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
|
||||||
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||||
|
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
|
github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc=
|
||||||
|
github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
|
||||||
|
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
|
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
|
github.com/quagmt/udecimal v1.10.0 h1:r8VgL1ns0HruRrTX4aRRIE4J5FGdjd1sGRwG7eZGx7A=
|
||||||
|
github.com/quagmt/udecimal v1.10.0/go.mod h1:ScmJ/xTGZcEoYiyMMzgDLn79PEJHcMBiJ4NNRT3FirA=
|
||||||
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||||
|
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||||
|
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||||
|
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||||
|
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||||
|
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||||
|
github.com/rs/zerolog v1.15.0 h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY=
|
||||||
|
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk=
|
||||||
|
github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0=
|
||||||
|
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||||
|
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||||
|
github.com/sasha-s/go-deadlock v0.3.5 h1:tNCOEEDG6tBqrNDOX35j/7hL5FcFViG6awUGROb2NsU=
|
||||||
|
github.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6vCBBsiChJQ5U=
|
||||||
|
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||||
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
|
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
|
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||||
|
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||||
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||||
|
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||||
|
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||||
|
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||||
|
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
||||||
|
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
|
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||||
|
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||||
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
|
||||||
|
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||||
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||||
|
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||||
|
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
||||||
|
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||||
|
github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M=
|
||||||
|
github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
|
||||||
|
github.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A=
|
||||||
|
github.com/swaggo/swag v1.16.4/go.mod h1:VBsHJRsDvfYvqoiMKnsdwhNV9LEMHgEDZcyVYX0sxPg=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
|
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||||
|
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||||
|
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||||
|
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||||
|
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||||
|
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||||
|
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||||
|
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
|
||||||
|
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
|
||||||
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||||
|
go.mongodb.org/mongo-driver v1.17.9 h1:IexDdCuuNJ3BHrELgBlyaH9p60JXAvdzWR128q+U5tU=
|
||||||
|
go.mongodb.org/mongo-driver v1.17.9/go.mod h1:LlOhpH5NUEfhxcAwG0UEkMqwYcc4JU18gtCdGudk/tQ=
|
||||||
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
|
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||||
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
|
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||||
|
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||||
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
|
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
|
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||||
|
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||||
|
golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg=
|
||||||
|
golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
|
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
|
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
|
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
||||||
|
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||||
|
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||||
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
|
||||||
|
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||||
|
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
|
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
|
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||||
|
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||||
|
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
|
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||||
|
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||||
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||||
|
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
|
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
|
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||||
|
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
|
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
|
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
|
google.golang.org/genproto v0.0.0-20241113154021-e0fbfb71d213 h1:aK1CSq3+WIXZj6XcWhK0fAb303nF8sta2eca0DSARwQ=
|
||||||
|
google.golang.org/genproto v0.0.0-20241113154021-e0fbfb71d213/go.mod h1:Q5m6g8b5KaFFzsQFIGdJkSJDGeJiybVenoYFMMa3ohI=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20241113154021-e0fbfb71d213 h1:cNftAhx0Q32f3Fz2+BLargfsMD6pGINE+/mUZneTMyk=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20241113154021-e0fbfb71d213/go.mod h1:Yo94eF2nj7igQt+TiJ49KxjIH8ndLYPZMIRSiRcEbg0=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20241113154021-e0fbfb71d213 h1:L+WcQXqkyf5MX6g7AudgYEuJjmYbqSRkTmJqGfAPw+Y=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20241113154021-e0fbfb71d213/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
|
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
|
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||||
|
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||||
|
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
|
||||||
|
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
|
||||||
|
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||||
|
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||||
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
|
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
|
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||||
|
quantex.com.ar/multidb v1.2.2 h1:vYZkOI/srWFlfUk8ZsbmcNp7OWiPWflBnaLYaPTPgAs=
|
||||||
|
quantex.com.ar/multidb v1.2.2/go.mod h1:aIxLGHeesPkmSocw/VSZBc+pGDmxx7QRUSd+TxjAFFc=
|
||||||
1
last_update_info.txt
Normal file
1
last_update_info.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Thu Feb 19 05:35:16 2026 -0600
|
||||||
12
linter_version.txt
Normal file
12
linter_version.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
golangci-lint: v1.63.4
|
||||||
|
revive: v1.5.1
|
||||||
|
gosec: v2.22.0
|
||||||
|
errcheck: v1.8.0
|
||||||
|
unconvert: latest
|
||||||
|
goimports: v0.29.0
|
||||||
|
gci: v0.13.5
|
||||||
|
gofumpt: v0.7.0
|
||||||
|
staticcheck: v0.5.1
|
||||||
|
swag: v1.16.4
|
||||||
|
go-enum: v0.6.0
|
||||||
|
govulncheck: latest
|
||||||
206
main.go
Normal file
206
main.go
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
// package qfixpt is a Micro service quantex base project
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/mitchellh/panicwrap"
|
||||||
|
|
||||||
|
"quantex.com/qfixpt/src/app"
|
||||||
|
"quantex.com/qfixpt/src/app/mode"
|
||||||
|
"quantex.com/qfixpt/src/app/version"
|
||||||
|
"quantex.com/qfixpt/src/client/config"
|
||||||
|
googlechat "quantex.com/qfixpt/src/client/notify/google"
|
||||||
|
"quantex.com/qfixpt/src/client/res"
|
||||||
|
"quantex.com/qfixpt/src/cmd"
|
||||||
|
"quantex.com/qfixpt/src/cmd/example"
|
||||||
|
"quantex.com/qfixpt/src/cmd/service"
|
||||||
|
"quantex.com/qfixpt/src/common/logger"
|
||||||
|
"quantex.com/qfixpt/src/common/logger/tint"
|
||||||
|
"quantex.com/qfixpt/src/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Embed the entire directory.
|
||||||
|
|
||||||
|
//go:embed res
|
||||||
|
var resources embed.FS
|
||||||
|
|
||||||
|
type flagsType struct {
|
||||||
|
runner, globalCfg, serviceCfg, logLevel, logFormat string
|
||||||
|
debug, version bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flags := parseFlags()
|
||||||
|
|
||||||
|
if len(os.Args) == 1 {
|
||||||
|
flag.Usage()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if flags.version {
|
||||||
|
fmt.Printf("%s version %s", version.AppName, version.Info())
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg, err := config.Read([]string{flags.globalCfg, flags.serviceCfg})
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("Something went wrong reading the config. %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
notify := googlechat.New(cfg.Notify.Google)
|
||||||
|
|
||||||
|
exitStatus, err := panicwrap.BasicWrap(func(output string) {
|
||||||
|
notify.SendMsg(domain.MessageChannelPanic, output, domain.MessageStatusStopper, nil)
|
||||||
|
os.Exit(1)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
// Something went wrong setting up the panic wrapper.
|
||||||
|
panic(fmt.Sprintf("Something went wrong setting up the panic wrapper. %s", err))
|
||||||
|
}
|
||||||
|
// If exitStatus >= 0, then we're the parent process and the panicwrap
|
||||||
|
// re-executed ourselves and completed. Just exit with the proper status.
|
||||||
|
if exitStatus >= 0 {
|
||||||
|
os.Exit(exitStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
handler, err := newLogHandler(flags)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hook := logger.NewQuantexHandler(handler, []slog.Level{slog.LevelError, slog.LevelWarn})
|
||||||
|
slog.SetDefault(slog.New(hook))
|
||||||
|
|
||||||
|
slog.Info("New Run ----------------------------------------------------------------------------")
|
||||||
|
|
||||||
|
slog.Debug(fmt.Sprintf("flags: %+v", flags))
|
||||||
|
|
||||||
|
v := version.AppName + " version " + version.Info()
|
||||||
|
fmt.Println(v)
|
||||||
|
slog.Info(v)
|
||||||
|
|
||||||
|
setDebugMode(flags.debug)
|
||||||
|
|
||||||
|
startRunner(flags.runner, flags.globalCfg, flags.serviceCfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseFlags() (f flagsType) {
|
||||||
|
fmt.Println(f.runner)
|
||||||
|
flag.StringVar(&f.runner, "run", "", "run the specified service")
|
||||||
|
|
||||||
|
flag.StringVar(&f.globalCfg, "global-cfg", "../global_conf.toml", "set the config global file name")
|
||||||
|
|
||||||
|
flag.StringVar(&f.serviceCfg, "service-cfg", "conf.toml", "set the config service file name")
|
||||||
|
|
||||||
|
const u0 = "set the logs output format: text, json, tint1 (one line), tint2 (two lines)"
|
||||||
|
flag.StringVar(&f.logFormat, "logs-format", "json", u0)
|
||||||
|
flag.StringVar(&f.logFormat, "f", "json", u0+" (shorthand)")
|
||||||
|
|
||||||
|
const u1 = "set the debug mode"
|
||||||
|
flag.BoolVar(&f.debug, "debug", false, u1)
|
||||||
|
flag.BoolVar(&f.debug, "d", false, u1+" (shorthand)")
|
||||||
|
|
||||||
|
const u2 = "show the program version"
|
||||||
|
flag.BoolVar(&f.version, "version", false, u2)
|
||||||
|
flag.BoolVar(&f.version, "v", false, u2+" (shorthand)")
|
||||||
|
|
||||||
|
const u3 = "set the log level: debug, info, warn, error"
|
||||||
|
flag.StringVar(&f.logLevel, "level", "info", u3)
|
||||||
|
flag.StringVar(&f.logLevel, "l", "info", u3+" (shorthand)")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLogHandler(flags flagsType) (slog.Handler, error) {
|
||||||
|
logLevel, err := parseLogLevel(flags.logLevel)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch flags.logFormat {
|
||||||
|
case "json":
|
||||||
|
return logger.NewJSONHandler(logLevel), nil
|
||||||
|
case "text":
|
||||||
|
return logger.NewTextHandler(logLevel), nil
|
||||||
|
case "tint1":
|
||||||
|
return logger.NewTextHandlerTint(logLevel, tint.OneLine), nil
|
||||||
|
case "tint2":
|
||||||
|
return logger.NewTextHandlerTint(logLevel, tint.TwoLines), nil
|
||||||
|
default:
|
||||||
|
flag.PrintDefaults()
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("invalid log format option: \"%s\"", flags.logFormat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setDebugMode(debug bool) {
|
||||||
|
mode.Debug = debug
|
||||||
|
|
||||||
|
var msg string
|
||||||
|
|
||||||
|
if mode.Debug {
|
||||||
|
res.Set(os.DirFS("./"))
|
||||||
|
|
||||||
|
msg = fmt.Sprintf("Running %s in DEBUG mode!", version.AppName)
|
||||||
|
} else {
|
||||||
|
res.Set(resources)
|
||||||
|
|
||||||
|
msg = fmt.Sprintf("Running %s!", version.AppName)
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.Info(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseLogLevel(level string) (slog.Level, error) {
|
||||||
|
switch level {
|
||||||
|
case "debug":
|
||||||
|
return slog.LevelDebug, nil
|
||||||
|
case "info":
|
||||||
|
return slog.LevelInfo, nil
|
||||||
|
case "warn":
|
||||||
|
return slog.LevelWarn, nil
|
||||||
|
case "error":
|
||||||
|
return slog.LevelError, nil
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("invalid log level: %s", level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startRunner(runner, globalCfg, serviceCfg string) {
|
||||||
|
var fn func(cfg app.Config) error
|
||||||
|
|
||||||
|
if runner == "" {
|
||||||
|
runner = "service"
|
||||||
|
}
|
||||||
|
|
||||||
|
switch runner {
|
||||||
|
case "service":
|
||||||
|
fn = service.Runner
|
||||||
|
case "async":
|
||||||
|
fn = example.AsyncRunner
|
||||||
|
case "external":
|
||||||
|
fn = example.ExternalRunner
|
||||||
|
case "tracerr":
|
||||||
|
fn = example.TracerrRunner
|
||||||
|
case "logger":
|
||||||
|
fn = example.LogsRunner
|
||||||
|
default:
|
||||||
|
panic("Invalid runner option: \"" + runner + "\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cmd.NewRunner(fn)(globalCfg, serviceCfg); err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
// Time guard to allow to notify to send the message
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
399
quickfix/CHANGELOG.md
Normal file
399
quickfix/CHANGELOG.md
Normal file
@ -0,0 +1,399 @@
|
|||||||
|
## 0.9.10 (August 8, 2025)
|
||||||
|
|
||||||
|
### BUG FIXES
|
||||||
|
* Send Reset if the ResetTime elapsed in between checks [#725](https://quantex.com/qfixpt/quickfix/pull/725)
|
||||||
|
|
||||||
|
## 0.9.9 (July 31, 2025)
|
||||||
|
|
||||||
|
### BUG FIXES
|
||||||
|
* Adds missing tz for resetseqtime without starttime endtime #723 [#723](https://quantex.com/qfixpt/quickfix/pull/723)
|
||||||
|
|
||||||
|
## 0.9.8 (July 21, 2025)
|
||||||
|
|
||||||
|
### ENHANCEMENTS
|
||||||
|
* Add DB name configuration [#711](https://quantex.com/qfixpt/quickfix/pull/711)
|
||||||
|
* Change ResetSeqTime to time.Time based on the config's timeZone [#712](https://quantex.com/qfixpt/quickfix/pull/712)
|
||||||
|
|
||||||
|
### BUG FIXES
|
||||||
|
* Block Sends when Resend Request is active [#715](https://quantex.com/qfixpt/quickfix/pull/715)
|
||||||
|
* Fix the issue of incorrect time range calculation across days [#718](https://quantex.com/qfixpt/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://quantex.com/qfixpt/quickfix/pull/672)
|
||||||
|
* Adds convenience getters for session log and store [#675](https://quantex.com/qfixpt/quickfix/pull/675)
|
||||||
|
* Adds config option for ResetSeqTime [#705](https://quantex.com/qfixpt/quickfix/pull/705)
|
||||||
|
|
||||||
|
### ENHANCEMENTS
|
||||||
|
* File store uses files exclusively [#680](https://quantex.com/qfixpt/quickfix/pull/680)
|
||||||
|
* Protect concurrent usage of filestore [#688](https://quantex.com/qfixpt/quickfix/pull/688)
|
||||||
|
* Support udecimal library in code generation [#700](https://quantex.com/qfixpt/quickfix/pull/700)
|
||||||
|
|
||||||
|
### BUG FIXES
|
||||||
|
* Avoid unkeyed fields usage for exported struct in generated code [#683](https://quantex.com/qfixpt/quickfix/pull/683)
|
||||||
|
* Iterate messages in filestore opens a separate file to avoid deadlock [#703](https://quantex.com/qfixpt/quickfix/pull/703)
|
||||||
|
* Correct ordering in message trailer [#707](https://quantex.com/qfixpt/quickfix/pull/707)
|
||||||
|
|
||||||
|
## 0.9.6 (September 20, 2024)
|
||||||
|
|
||||||
|
### ENHANCEMENTS
|
||||||
|
* Allow the clients of acceptor to specify their own tls.Config https://quantex.com/qfixpt/quickfix/pull/667
|
||||||
|
* Adds NextExpectedSeqNum setting https://quantex.com/qfixpt/quickfix/pull/668
|
||||||
|
|
||||||
|
### BUG FIXES
|
||||||
|
* Reinit stop sync to prevent deadlock on sequential start/stops https://quantex.com/qfixpt/quickfix/pull/669
|
||||||
|
* Check logon auth before resetting store https://quantex.com/qfixpt/quickfix/pull/670
|
||||||
|
* Reverts ToAdmin call sequencing https://quantex.com/qfixpt/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://quantex.com/qfixpt/quickfix/pull/659
|
||||||
|
* Only lock fieldmap once during message parsing https://quantex.com/qfixpt/quickfix/pull/658
|
||||||
|
* Optimize tag value parsing https://quantex.com/qfixpt/quickfix/pull/657
|
||||||
|
* Use bytes.Count to count the number of message fields https://quantex.com/qfixpt/quickfix/pull/655
|
||||||
|
* Port config documentation into proper go doc format https://quantex.com/qfixpt/quickfix/pull/649
|
||||||
|
* Support TLS configuration as raw bytes https://quantex.com/qfixpt/quickfix/pull/647
|
||||||
|
|
||||||
|
### BUG FIXES
|
||||||
|
* Use the Go generated file convention https://quantex.com/qfixpt/quickfix/pull/660
|
||||||
|
* Fix stuck call to Dial when calling Stop on the Initiator https://quantex.com/qfixpt/quickfix/pull/654
|
||||||
|
* Do not increment NextTargetMsgSeqNum for out of sequence Logout and Test Requests https://quantex.com/qfixpt/quickfix/pull/645
|
||||||
|
|
||||||
|
## 0.9.4 (May 29, 2024)
|
||||||
|
|
||||||
|
### ENHANCEMENTS
|
||||||
|
* Adds log to readLoop just like writeLoop https://quantex.com/qfixpt/quickfix/pull/642
|
||||||
|
|
||||||
|
### BUG FIXES
|
||||||
|
* Maintain repeating group field order when parsing messages https://quantex.com/qfixpt/quickfix/pull/636
|
||||||
|
|
||||||
|
## 0.9.3 (May 9, 2024)
|
||||||
|
|
||||||
|
### BUG FIXES
|
||||||
|
* Change filestore.offsets from map[int]msgDef to sync.Map https://quantex.com/qfixpt/quickfix/pull/639
|
||||||
|
* Unregister sessions on stop https://quantex.com/qfixpt/quickfix/pull/637
|
||||||
|
* Corrects ResetOnLogon behavior for initiators https://quantex.com/qfixpt/quickfix/pull/635
|
||||||
|
|
||||||
|
### FEATURES
|
||||||
|
* Add AllowUnknownMessageFields & CheckUserDefinedFields settings as included in QuickFIX/J https://quantex.com/qfixpt/quickfix/pull/632
|
||||||
|
|
||||||
|
## 0.9.2 (April 23, 2024)
|
||||||
|
|
||||||
|
### BUG FIXES
|
||||||
|
* Prevent message queue blocking in the case of network connection trouble https://quantex.com/qfixpt/quickfix/pull/615 https://quantex.com/qfixpt/quickfix/pull/628
|
||||||
|
* Corrects validation of multiple repeating groups with different fields https://quantex.com/qfixpt/quickfix/pull/623
|
||||||
|
|
||||||
|
## 0.9.1 (April 15, 2024)
|
||||||
|
|
||||||
|
### BUG FIXES
|
||||||
|
* Preserve original body when resending https://quantex.com/qfixpt/quickfix/pull/624
|
||||||
|
|
||||||
|
## 0.9.0 (November 13, 2023)
|
||||||
|
|
||||||
|
### FEATURES
|
||||||
|
* Add Weekdays config setting as included in QuickFIX/J https://quantex.com/qfixpt/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://quantex.com/qfixpt/quickfix/issues/547 and https://quantex.com/qfixpt/quickfix/pull/592 for more information. The relevant examples are below.
|
||||||
|
|
||||||
|
MONGO
|
||||||
|
```go
|
||||||
|
import "quantex.com/qfixpt/quickfix"
|
||||||
|
|
||||||
|
...
|
||||||
|
acceptor, err = quickfix.NewAcceptor(app, quickfix.NewMongoStoreFactory(appSettings), appSettings, fileLogFactory)
|
||||||
|
```
|
||||||
|
becomes
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"quantex.com/qfixpt/quickfix"
|
||||||
|
"quantex.com/qfixpt/quickfix/store/mongo"
|
||||||
|
)
|
||||||
|
|
||||||
|
...
|
||||||
|
acceptor, err = quickfix.NewAcceptor(app, mongo.NewStoreFactory(appSettings), appSettings, fileLogFactory)
|
||||||
|
```
|
||||||
|
|
||||||
|
FILE
|
||||||
|
```go
|
||||||
|
import "quantex.com/qfixpt/quickfix"
|
||||||
|
|
||||||
|
...
|
||||||
|
acceptor, err = quickfix.NewAcceptor(app, quickfix.NewFileStoreFactory(appSettings), appSettings, fileLogFactory)
|
||||||
|
```
|
||||||
|
becomes
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"quantex.com/qfixpt/quickfix"
|
||||||
|
"quantex.com/qfixpt/quickfix/store/file"
|
||||||
|
)
|
||||||
|
|
||||||
|
...
|
||||||
|
acceptor, err = quickfix.NewAcceptor(app, file.NewStoreFactory(appSettings), appSettings, fileLogFactory)
|
||||||
|
```
|
||||||
|
|
||||||
|
SQL
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "quantex.com/qfixpt/quickfix"
|
||||||
|
|
||||||
|
...
|
||||||
|
acceptor, err = quickfix.NewAcceptor(app, quickfix.NewSQLStoreFactory(appSettings), appSettings, fileLogFactory)
|
||||||
|
```
|
||||||
|
becomes
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"quantex.com/qfixpt/quickfix"
|
||||||
|
"quantex.com/qfixpt/quickfix/store/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
...
|
||||||
|
acceptor, err = quickfix.NewAcceptor(app, sql.NewStoreFactory(appSettings), appSettings, fileLogFactory)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### ENHANCEMENTS
|
||||||
|
* Acceptance suite store type expansions https://quantex.com/qfixpt/quickfix/pull/596 and https://quantex.com/qfixpt/quickfix/pull/591
|
||||||
|
* Support Go v1.21 https://quantex.com/qfixpt/quickfix/pull/589
|
||||||
|
|
||||||
|
|
||||||
|
### BUG FIXES
|
||||||
|
* Resolves outstanding issues with postgres db creation syntax and `pgx` driver https://quantex.com/qfixpt/quickfix/pull/598
|
||||||
|
* Fix sequence number bug when storage fails https://quantex.com/qfixpt/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
|
||||||
|
|
||||||
|
* PersistMessages Config [GH 297]
|
||||||
|
* MaxLatency [GH 242]
|
||||||
|
* ResetOnDisconnect Configuration [GH 68]
|
||||||
|
* Support for High Precision Timestamps [GH 288]
|
||||||
|
* LogonTimeout [GH 295]
|
||||||
|
* LogoutTimeout [GH 296]
|
||||||
|
* Socks Proxy [GH 375]
|
||||||
|
|
||||||
|
ENHANCEMENTS
|
||||||
|
|
||||||
|
* Add SocketUseSSL parameter to allow SSL/TLS without client certs [GH 311]
|
||||||
|
* Support for RejectInvalidMessage configuration [GH 336]
|
||||||
|
* Add deep copy for Messages [GH 338]
|
||||||
|
* Add Go Module support [GH 340]
|
||||||
|
* Support timeout on ssl connection [GH 347, 349]
|
||||||
|
* Dynamic Sessions [GH 521]
|
||||||
|
* Upgrade Mongo Driver to support transactions [GH 527]
|
||||||
|
|
||||||
|
BUG FIXES
|
||||||
|
|
||||||
|
* header and trailer templates use rootpath [GH 302]
|
||||||
|
* Initiator stop panic if stop chan's already closed [GH 359]
|
||||||
|
* Connection closed when inbound logon has a too-low sequence number [GH 369]
|
||||||
|
* TLS server name config [GH 384]
|
||||||
|
* Fix concurrent map write [GH 436]
|
||||||
|
* Race condition during bilateral initial resend request [GH 439]
|
||||||
|
* Deadlock when disconnecting dynamic session [GH 524]
|
||||||
|
* Align session's ticker with round second [GH 533]
|
||||||
|
* Seqnum persist and increment fix [GH 528]
|
||||||
|
|
||||||
|
|
||||||
|
## 0.6.0 (August 14, 2017)
|
||||||
|
|
||||||
|
FEATURES
|
||||||
|
|
||||||
|
* CheckLatency [GH 241, 266]
|
||||||
|
* ResendRequestChunkSize [GH 243, 245]
|
||||||
|
* EnableLastMsgSeqNumProcessed [GH 253, 256]
|
||||||
|
|
||||||
|
ENHANCEMENTS
|
||||||
|
|
||||||
|
* config.SocketTLSForTesting(bool) [GH 235]
|
||||||
|
* API Interface Enhancements [GH 251, 252, 254, 255, 257, 258, 259]
|
||||||
|
* Misc. Performance Optimizations [GH 260, 261, 263, 264, 265, 268, 270, 271, 272, 273, 274, 275]
|
||||||
|
* TLS Configuration [GH 279, 280]
|
||||||
|
* Use data dictionary for parsing fix messages [GH 281]
|
||||||
|
|
||||||
|
BUG FIXES
|
||||||
|
|
||||||
|
* Resend logon fix [GH 244]
|
||||||
|
* PossDup messages with seqnum too low should not be sent to FromCallbacks [GH 246, 247]
|
||||||
|
* Router should not reject admin messages or business rejects [GH 249, 250]
|
||||||
|
* Fixes file log output for incoming, outgoing [GH 262]
|
||||||
|
* message.String() returns rawMessage if set, builds otherwise [GH 269]
|
||||||
|
* Use timestamp with time zone for postgres sql [GH 286]
|
||||||
|
|
||||||
|
|
||||||
|
## 0.5.0 (September 1, 2016)
|
||||||
|
|
||||||
|
FEATURES
|
||||||
|
|
||||||
|
* Session Scheduling [GH 31, 195, 196, 197, 198, 200, 201, 202, 203, 204, 205, 211, 212, 218, 220]
|
||||||
|
* TimeZone configuration [GH 206]
|
||||||
|
* StartDay, EndDay for week long sessions [GH 207, 239]
|
||||||
|
* Support for connection over SSL [GH 63, 193]
|
||||||
|
* SocketConnectHost/Port<n> [GH 65, 217]
|
||||||
|
* ResetOnLogout Configuration enhancement [GH 67, 192]
|
||||||
|
* SocketAcceptAddress, ipv6 support [GH 83, 215]
|
||||||
|
* RefreshOnLogon [GH 214]
|
||||||
|
|
||||||
|
ENHANCEMENTS
|
||||||
|
|
||||||
|
* Reject Logon Support [GH 57, 225]
|
||||||
|
* FIX Decimal [GH 114, 223, 224, 227, 228]
|
||||||
|
* test refactoring, leveraging testify mock assertions [GH 186]
|
||||||
|
* KISS on registry, session management [GH 208]
|
||||||
|
* moving and renaming test jigs [GH 210]
|
||||||
|
* Config Enhancements [GH 216]
|
||||||
|
* travis uses go 1.7 [GH 219]
|
||||||
|
* adds 'generated.go' suffix to generated source [GH 221]
|
||||||
|
* vendored deps GH [GH 222, 226]
|
||||||
|
* renames SQLStore config settings [GH 229]
|
||||||
|
* Add FieldMap.{SetInt, SetString} [GH 236]
|
||||||
|
|
||||||
|
|
||||||
|
BUG FIXES
|
||||||
|
|
||||||
|
* DefaultApplVerID Configuration not translating enum names [GH 89, 213]
|
||||||
|
* Dropped issues in logout state [GH 187, 188]
|
||||||
|
* correctly increments in target seq num on logout for in session state [GH 189]
|
||||||
|
* SendToTarget should return an error if toApp returns DoNotSend [GH 190, 191]
|
||||||
|
* Logon fix [GH 194]
|
||||||
|
* onlogout calls depend on session state [GH 199]
|
||||||
|
* fixes bug in resend state where resend response is processed incomplete [GH 230]
|
||||||
|
* fixes logic around logon message with sequence number too high [GH 231]
|
||||||
|
* SequenceReset, Resent Messages not hitting ToAdmin/ToApp [GH 232, 233]
|
||||||
|
* Next MsgSeqNo after received ResetSeqNumFlag=Y [GH 238, 240]
|
||||||
|
|
||||||
|
|
||||||
|
## 0.4.0 (August 1, 2016)
|
||||||
|
|
||||||
|
FEATURES
|
||||||
|
|
||||||
|
* ReconnectInterval Initiator Configuration [GH 66, 161]
|
||||||
|
|
||||||
|
ENHANCEMENTS
|
||||||
|
|
||||||
|
* Generate Getters for messages [GH 118]
|
||||||
|
* Drop generate-* apps into cmd/ [GH 125, 150]
|
||||||
|
* Misc field type refactoring [GH 145]
|
||||||
|
* Cmd gen [GH 146, 147]
|
||||||
|
* refactoring enum generation [GH 148]
|
||||||
|
* pipelining generation [GH 149]
|
||||||
|
* Sending a message to an unlogged-in session, results an error [GH 173, 182]
|
||||||
|
* adds event logging related to session events [GH 175]
|
||||||
|
* Error handling around session code enhancement [GH 176]
|
||||||
|
* refactoring of session code [GH 183]
|
||||||
|
* Gen header beginstring [GH 184]
|
||||||
|
|
||||||
|
BUG FIXES
|
||||||
|
|
||||||
|
* Do not incr target seq num when seq num too high [GH 151]
|
||||||
|
* can't parse securitylist message [GH 153, 155]
|
||||||
|
* Concurrent map operations on Acceptor.Stop() [GH 156]
|
||||||
|
* Return requiredConfigurationMissing when "FileStorePath" not found [GH 157]
|
||||||
|
* Checks around HeartBtInt configuration [GH 158]
|
||||||
|
* Removed complexity around closing Initiator sessions [GH 159]
|
||||||
|
* Proper FIX logout sequence [GH 160]
|
||||||
|
* Session logic doesn't account for a failure when calling messageStore methods (e.g. persisting a message) [GH 162]
|
||||||
|
* Session event loop [GH 164]
|
||||||
|
* Session event loop follow up [GH 165]
|
||||||
|
* Handle OnLogon/Logout callbacks in user space [GH 167]
|
||||||
|
* Session deadlocks if both initiator and acceptor enter the resend state [GH 169, 179]
|
||||||
|
* Initiator.Stop() does not wait for Acceptor's logout response, causing a resend on next logon [GH 170, 172]
|
||||||
|
* Reset peer timer after logon [GH 171]
|
||||||
|
* Ensure OnLogon is called even if seq num too high [GH 174]
|
||||||
|
* increment target seq num on logout [GH 177]
|
||||||
|
* fixes bogus resend logic [GH 178]
|
||||||
|
* Session forgets it is in resend state [GH 180, 181]
|
||||||
|
* fixes donotsend logic [GH 185]
|
||||||
|
|
||||||
|
## 0.3.0 (June 3, 2016)
|
||||||
|
|
||||||
|
FEATURES
|
||||||
|
|
||||||
|
* ValidateFieldsOutOfOrder Configuration Option [GH 107]
|
||||||
|
|
||||||
|
ENHANCEMENTS
|
||||||
|
|
||||||
|
* Datadictionary tests [GH 108]
|
||||||
|
* Proposal to add public method to convert raw fix message to quickfix.Message [GH 110]
|
||||||
|
* Make gen package public [GH 113]
|
||||||
|
* Make gen import path relative [GH 119]
|
||||||
|
* Validator interface [GH 120]
|
||||||
|
* Expose IncorrectDataFormat [GH 121]
|
||||||
|
* Spelling, fmtness [GH 123]
|
||||||
|
* More verbose error text on conditionally required field BMR [GH 131]
|
||||||
|
* better error handling in gen package [GH 134]
|
||||||
|
* Include timestamp in messages file log [GH 135]
|
||||||
|
* extracts repeating group interface [GH 137]
|
||||||
|
* Header, Body, Trailer FieldMap types [GH 138]
|
||||||
|
* Datadictionary/Gen refactor [GH 140]
|
||||||
|
* Gen value timestamp [GH 141]
|
||||||
|
* Slight gen revert [GH 142]
|
||||||
|
* replaced regex with faster impl for float parsing [GH 143]
|
||||||
|
* Expose sql.DB's SetConnMaxLifetime() in settings [GH 144, 139]
|
||||||
|
|
||||||
|
BUG FIXES
|
||||||
|
|
||||||
|
* Routing Incorrect for FIXT [GH 101]
|
||||||
|
* Validation Error for component tag [GH 102]
|
||||||
|
* Unmarshal error for repeating Group [GH 103]
|
||||||
|
* Marshaler/Reflector tries to convert time.Time struct into fix format [GH 109]
|
||||||
|
* nil pointer panic if no config.DataDictionary specified [GH 127]
|
||||||
|
* fixes required group validation error [GH 129]
|
||||||
|
* RefTagID is not known to BusinessMessageReject type [GH 130]
|
||||||
|
|
||||||
|
## 0.2.0 (April 19, 2016)
|
||||||
|
|
||||||
|
FEATURES
|
||||||
|
|
||||||
|
* Persisted Store [GH 32]
|
||||||
|
* Initializer Constructors for Generated Messages [GH 69]
|
||||||
|
* Field Setters for generated messages [GH 70]
|
||||||
|
* Support for optional components, component setters [GH 79]
|
||||||
|
* Setters for repeating groups in components [GH 87]
|
||||||
|
* DB Store [GH 88]
|
||||||
|
|
||||||
|
ENHANCEMENTS
|
||||||
|
|
||||||
|
* Gen refactor [GH 78]
|
||||||
|
* Refactoring data dictionary pkg [GH 93]
|
||||||
|
|
||||||
|
BUG FIXES
|
||||||
|
|
||||||
|
* Initiator panic if connection closed [GH 59]
|
||||||
|
* New logs overrides old ones [GH 72]
|
||||||
|
* Session sending message timeout [GH 80]
|
||||||
|
* Potential FIX50 Market Data marshaling bug [GH 91]
|
||||||
|
* Allow settings values to contain equals signs [GH 97]
|
||||||
|
* Error when trying to unmarshal FIX message (FIX 5.0) [GH 99]
|
||||||
|
|
||||||
|
## 0.1.0 (February 21, 2016)
|
||||||
|
|
||||||
|
* Initial release
|
||||||
18
quickfix/CONTRIBUTING.md
Normal file
18
quickfix/CONTRIBUTING.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Contribution Guidelines
|
||||||
|
|
||||||
|
We welcome pull requests, bug fixes and issue reports.
|
||||||
|
|
||||||
|
Please direct questions about using the library to the [Mailing List](https://groups.google.com/forum/#!forum/quickfixgo).
|
||||||
|
|
||||||
|
Before proposing a large change, please discuss your change by raising an issue.
|
||||||
|
|
||||||
|
## Submitting Changes
|
||||||
|
|
||||||
|
* Push your changes to a topic branch in your fork of the repository
|
||||||
|
* Submit a pull request to the repository in the QuickFIXGo Organization
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
* If you report a bug and do not include a fix, please include a failing test
|
||||||
|
* Generally, contributions without tests will not be accepted
|
||||||
|
* Contributions that fail the automated build will not be accepted
|
||||||
46
quickfix/LICENSE
Normal file
46
quickfix/LICENSE
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
The QuickFIX Software License, Version 1.0
|
||||||
|
|
||||||
|
Copyright (c) 2001- quickfixengine.org All rights
|
||||||
|
reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
3. The end-user documentation included with the redistribution,
|
||||||
|
if any, must include the following acknowledgment:
|
||||||
|
"This product includes software developed by
|
||||||
|
quickfixengine.org (http://www.quickfixengine.org/)."
|
||||||
|
Alternately, this acknowledgment may appear in the software itself,
|
||||||
|
if and wherever such third-party acknowledgments normally appear.
|
||||||
|
|
||||||
|
4. The names "QuickFIX" and "quickfixengine.org" must
|
||||||
|
not be used to endorse or promote products derived from this
|
||||||
|
software without prior written permission. For written
|
||||||
|
permission, please contact ask@quickfixengine.org
|
||||||
|
|
||||||
|
5. Products derived from this software may not be called "QuickFIX",
|
||||||
|
nor may "QuickFIX" appear in their name, without prior written
|
||||||
|
permission of quickfixengine.org
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||||
|
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL QUICKFIXENGINE.ORG OR
|
||||||
|
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
92
quickfix/Makefile
Normal file
92
quickfix/Makefile
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
|
||||||
|
all: vet test
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf gen
|
||||||
|
|
||||||
|
generate: clean
|
||||||
|
mkdir -p gen; cd gen; go run ../cmd/generate-fix/generate-fix.go -pkg-root=quantex.com/qfixpt/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=quantex.com/qfixpt/quickfix/gen ../spec/*.xml
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
gofmt -l -w -s $(shell find . -type f -name '*.go')
|
||||||
|
|
||||||
|
vet:
|
||||||
|
go vet `go list ./... | grep -v quickfix/gen`
|
||||||
|
|
||||||
|
test:
|
||||||
|
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.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 -v -o echo_server ./test-server/
|
||||||
|
fix40:
|
||||||
|
cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5001 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
|
||||||
|
fix41:
|
||||||
|
cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5002 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
|
||||||
|
fix42:
|
||||||
|
cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5003 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
|
||||||
|
fix43:
|
||||||
|
cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5004 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
|
||||||
|
fix44:
|
||||||
|
cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5005 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
|
||||||
|
fix50:
|
||||||
|
cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5006 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
|
||||||
|
fix50sp1:
|
||||||
|
cd _test; ./runat.sh cfg/$(TEST_SET)/$@.cfg 5007 $(STORE) "definitions/$(TEST_SET)/$@/*.def"
|
||||||
|
fix50sp2:
|
||||||
|
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)
|
||||||
|
|
||||||
|
.PHONY: test $(ACCEPT_SUITE)
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# These targets are specific to the Github CI Runner -
|
||||||
|
|
||||||
|
build-src:
|
||||||
|
go build -v `go list ./...`
|
||||||
|
|
||||||
|
build: build-src build-test-srv
|
||||||
|
|
||||||
|
test-ci:
|
||||||
|
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=quantex.com/qfixpt/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=quantex.com/qfixpt/quickfix/gen ../spec/$(shell echo $(FIX_TEST) | tr '[:lower:]' '[:upper:]').xml;
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------
|
||||||
156
quickfix/README.md
Normal file
156
quickfix/README.md
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
# QuickFIX/Go
|
||||||
|
|
||||||
|
[](https://quantex.com/qfixpt/quickfix/actions) [](https://godoc.org/quantex.com/qfixpt/quickfix) [](https://goreportcard.com/report/quantex.com/qfixpt/quickfix)
|
||||||
|
|
||||||
|
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://quantex.com/qfixpt/quickfix/releases/tag/v0.9.0)
|
||||||
|
|
||||||
|
|
||||||
|
## About
|
||||||
|
<p>QuickFIX/Go is a <a href="https://www.fixtrading.org/">FIX Protocol Community</a> implementation for the <a href="https://golang.org">Go programming language</a>.</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>100% free and open source with a liberal <a href="https://quantex.com/qfixpt/quickfix/blob/master/LICENSE.txt">license</a></li>
|
||||||
|
<li>Supports FIX versions 4.0 - 5.0SP2</li>
|
||||||
|
<li>Runs on any hardware and operating system supported by Go (1.21+ required)</li>
|
||||||
|
<li>Spec driven run-time message validation</li>
|
||||||
|
<li>Spec driven code generation of type-safe FIX messages, fields, and repeating groups</li>
|
||||||
|
<li>Support for protocol customizations</li>
|
||||||
|
<li>Session state storage options: SQL, MongoDB, On-disk, or In-memory</li>
|
||||||
|
<li>Logging options: File, Screen</li>
|
||||||
|
<li>Failover and High Availability</li>
|
||||||
|
<li>Daily and weekly scheduling of session connections</li>
|
||||||
|
<li>Integrated support for SSL communicaitons</li>
|
||||||
|
<li>Automated unit and acceptance tests</li>
|
||||||
|
<li><a href="https://www.connamara.com/">Commercial Support available</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<img width="208" alt="Sponsored by Connamara" src="https://user-images.githubusercontent.com/3065126/282546730-16220337-4960-48ae-8c2f-760fbaedb135.png">
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
With [Go module](https://github.com/golang/go/wiki/Modules) support, simply add the following import
|
||||||
|
|
||||||
|
```
|
||||||
|
import "quantex.com/qfixpt/quickfix"
|
||||||
|
```
|
||||||
|
|
||||||
|
to your code, and then `go [build|run|test]` will automatically fetch the necessary dependencies.
|
||||||
|
|
||||||
|
Otherwise, run the following Go command to install the `quickfix` package:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go get -u quantex.com/qfixpt/quickfix
|
||||||
|
```
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
* [QuickFIX User Manual](https://quickfixengine.org/go/documentation/)
|
||||||
|
* [Go API Documentation](https://godoc.org/quantex.com/qfixpt/quickfix)
|
||||||
|
* See [examples](https://github.com/quickfixgo/examples) for some simple examples of using QuickFIX/Go.
|
||||||
|
|
||||||
|
## FIX Messaging Model
|
||||||
|
To send and receive messages, your application will need a few additional packages.
|
||||||
|
|
||||||
|
QuickFIX/Go maintains separate packages for tags, fields, enums, messages, and message components auto-generated from the FIX 4.0 - FIX5.0SP2 XML specifications-
|
||||||
|
|
||||||
|
* [Tag](https://github.com/quickfixgo/tag)
|
||||||
|
* [Field](https://github.com/quickfixgo/field)
|
||||||
|
* [Enum](https://github.com/quickfixgo/enum)
|
||||||
|
* [FIX 4.0](https://github.com/quickfixgo/fix40)
|
||||||
|
* [FIX 4.1](https://github.com/quickfixgo/fix41)
|
||||||
|
* [FIX 4.2](https://github.com/quickfixgo/fix42)
|
||||||
|
* [FIX 4.3](https://github.com/quickfixgo/fix43)
|
||||||
|
* [FIX 4.4](https://github.com/quickfixgo/fix44)
|
||||||
|
* [FIX 5.0](https://github.com/quickfixgo/fix50)
|
||||||
|
* [FIX 5.0 SP1](https://github.com/quickfixgo/fix50sp1)
|
||||||
|
* [FIX 5.0 SP2](https://github.com/quickfixgo/fix50sp2)
|
||||||
|
* [FIXT 1.1](https://github.com/quickfixgo/fixt11)
|
||||||
|
|
||||||
|
For most FIX applications, these generated resources are sufficient. Custom FIX applications may generate source specific to the FIX spec of that application using the `generate-fix` tool included with QuickFIX/Go.
|
||||||
|
|
||||||
|
Following installation, `generate-fix` is installed to `$GOPATH/bin/generate-fix`. Run `$GOPATH/bin/generate-fix --help` for usage instructions.
|
||||||
|
|
||||||
|
## General Support
|
||||||
|
<h3>Github Discussions</h3>
|
||||||
|
|
||||||
|
<p>Our <a href="https://quantex.com/qfixpt/quickfix/discussions/categories/q-a">Github Discussions Board</a> is free, public, and easily searchable. It’s the preferred method of user support from the QuickFIX/Go team.
|
||||||
|
|
||||||
|
<p>Please provide as much detail as you can when asking a question, and include relevant configurations and code snippets.</p>
|
||||||
|
|
||||||
|
<h3>FIX Protocol</h3>
|
||||||
|
|
||||||
|
<p>More information about the FIX protocol can be found at the <a href="http://fixtradingcommunity.org">FIX Protocol website</a>.
|
||||||
|
|
||||||
|
<h3>Bugs and Issues</h3>
|
||||||
|
|
||||||
|
<p>Bugs and issues can be submitted by anyone through our GitHub repository issues list.</p>
|
||||||
|
|
||||||
|
<p><strong>Note:</strong> Please do not submit questions or help requests to the issues list. It is for bugs and issues. If you need help, please use the Discussions board as described above and you’ll be able to send your question to the entire community.</p>
|
||||||
|
|
||||||
|
<p><a href="https://quantex.com/qfixpt/quickfix/issues">GitHub Issues</a></p>
|
||||||
|
|
||||||
|
<p>Please provide sample code, logs, and a description of the problem when the issue is submitted.</p>
|
||||||
|
|
||||||
|
<p>We will try to address new issues as quickly as possible, and we welcome contributions for bug fixes and new features!</p>
|
||||||
|
|
||||||
|
## Commercial Support
|
||||||
|
<p><a href="https://connamara.com">Connamara Systems</a> offers commercial support for developers who are integrating any of the QuickFIX implementations (Go, C++, Java, .NET). The support is offered in 10-hour bundles and grants developers access, via telephone or email, to the team that created QuickFIX/Go, QuickFIX/n, and are maintainers of QuickFIX.</p>
|
||||||
|
|
||||||
|
<p>In addition to offering QuickFIX support, Connamara delivers Made-To-Measure Trading Solutions by bridging the gap between buy and build. By using internally developed trading platform components, Connamara delivers the best of off-the-shelf ISV solutions and custom application development. Coupled with Connamara’s unique licensing model, trading firms can get the best of both build and buy.</p>
|
||||||
|
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
If you wish to work on QuickFIX/Go itself, you will need [Docker](https://docs.docker.com/get-docker/) and [VSCode](https://code.visualstudio.com/download) on your machine.
|
||||||
|
|
||||||
|
* Clone the repo and open it with VSCode with Docker running
|
||||||
|
* This repo comes with vscode devcontainer configs in `./.devcontainer/`
|
||||||
|
* Click the pop-up to re-open the project in the Dev Container
|
||||||
|
* This opens the project in a docker container pre-configured with everything you need
|
||||||
|
|
||||||
|
### Build and Test
|
||||||
|
|
||||||
|
The default make target runs [go vet](https://godoc.org/golang.org/x/tools/cmd/vet) and unit tests.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
If this exits with exit status 0, then everything is working!
|
||||||
|
|
||||||
|
### Generated Code
|
||||||
|
|
||||||
|
Generated code from the FIX40-FIX50SP2 specs are available as separate repos under the [QuickFIX/Go organization](https://github.com/quickfixgo). The source specifications for this generated code is located in `spec/`. Generated code can be identified by the `.generated.go` suffix. Any changes to generated code must be captured by changes to source in `cmd/generate-fix`. After making changes to the code generator source, run the following to re-generate the source
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make generate
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are making changes to the generated code, please create Pull Requests for these changes for the affected repos.
|
||||||
|
|
||||||
|
### Acceptance Tests
|
||||||
|
|
||||||
|
QuickFIX/Go has a comprehensive acceptance test suite covering the FIX protocol. These are the same tests used across all QuickFIX implementations.
|
||||||
|
|
||||||
|
QuickFIX/Go acceptance tests depend on ruby in path, if you are using the dev container, it is already installed
|
||||||
|
|
||||||
|
To run acceptance tests,
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# generate code locally
|
||||||
|
make generate
|
||||||
|
|
||||||
|
# build acceptance test rig
|
||||||
|
make build-test-srv
|
||||||
|
|
||||||
|
# run acceptance tests
|
||||||
|
make accept
|
||||||
|
```
|
||||||
|
|
||||||
|
## Licensing
|
||||||
|
|
||||||
|
This software is available under the QuickFIX Software License. Please see the [LICENSE.txt](https://quantex.com/qfixpt/quickfix/blob/main/LICENSE.txt) for the terms specified by the QuickFIX Software License.
|
||||||
6
quickfix/_sql/embed.go
Normal file
6
quickfix/_sql/embed.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package sql
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
|
||||||
|
//go:embed mssql mysql oracle postgresql sqlite3
|
||||||
|
var FS embed.FS
|
||||||
1
quickfix/_sql/mssql/create.bat
Normal file
1
quickfix/_sql/mssql/create.bat
Normal file
@ -0,0 +1 @@
|
|||||||
|
osql -U sa -P -i quickfix_database.sql
|
||||||
65
quickfix/_sql/mssql/quickfix_database.sql
Normal file
65
quickfix/_sql/mssql/quickfix_database.sql
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
DROP DATABASE quickfix;
|
||||||
|
CREATE DATABASE quickfix;
|
||||||
|
|
||||||
|
USE quickfix;
|
||||||
|
CREATE TABLE sessions (
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64) NOT NULL,
|
||||||
|
creation_time DATETIME NOT NULL,
|
||||||
|
incoming_seqnum INT NOT NULL,
|
||||||
|
outgoing_seqnum INT NOT NULL,
|
||||||
|
PRIMARY KEY (beginstring, sendercompid, sendersubid, senderlocid,
|
||||||
|
targetcompid, targetsubid, targetlocid, session_qualifier)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE messages (
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64) NOT NULL,
|
||||||
|
msgseqnum INT NOT NULL,
|
||||||
|
message TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (beginstring, sendercompid, sendersubid, senderlocid,
|
||||||
|
targetcompid, targetsubid, targetlocid, session_qualifier,
|
||||||
|
msgseqnum)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE event_log (
|
||||||
|
id INT NOT NULL IDENTITY,
|
||||||
|
time DATETIME NOT NULL,
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64) NOT NULL,
|
||||||
|
text TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE messages_log (
|
||||||
|
id INT NOT NULL IDENTITY,
|
||||||
|
time DATETIME NOT NULL,
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64) NOT NULL,
|
||||||
|
text TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
1
quickfix/_sql/mysql/create.bat
Normal file
1
quickfix/_sql/mysql/create.bat
Normal file
@ -0,0 +1 @@
|
|||||||
|
mysql -u root --execute="source mysql.sql";
|
||||||
1
quickfix/_sql/mysql/create.sh
Normal file
1
quickfix/_sql/mysql/create.sh
Normal file
@ -0,0 +1 @@
|
|||||||
|
mysql -u root --execute="source mysql.sql";
|
||||||
18
quickfix/_sql/mysql/event_log_table.sql
Normal file
18
quickfix/_sql/mysql/event_log_table.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
USE quickfix;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS event_log;
|
||||||
|
|
||||||
|
CREATE TABLE event_log (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
time DATETIME NOT NULL,
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64),
|
||||||
|
text TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
18
quickfix/_sql/mysql/messages_log_table.sql
Normal file
18
quickfix/_sql/mysql/messages_log_table.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
USE quickfix;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS messages_log;
|
||||||
|
|
||||||
|
CREATE TABLE messages_log (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
time DATETIME NOT NULL,
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64) NOT NULL,
|
||||||
|
text TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
19
quickfix/_sql/mysql/messages_table.sql
Normal file
19
quickfix/_sql/mysql/messages_table.sql
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
USE quickfix;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS messages;
|
||||||
|
|
||||||
|
CREATE TABLE messages (
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64) NOT NULL,
|
||||||
|
msgseqnum INT NOT NULL,
|
||||||
|
message TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (beginstring, sendercompid, sendersubid, senderlocid,
|
||||||
|
targetcompid, targetsubid, targetlocid, session_qualifier,
|
||||||
|
msgseqnum)
|
||||||
|
);
|
||||||
5
quickfix/_sql/mysql/mysql.sql
Normal file
5
quickfix/_sql/mysql/mysql.sql
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
source quickfix_database.sql;
|
||||||
|
source sessions_table.sql;
|
||||||
|
source messages_table.sql;
|
||||||
|
source messages_log_table.sql;
|
||||||
|
source event_log_table.sql;
|
||||||
2
quickfix/_sql/mysql/quickfix_database.sql
Normal file
2
quickfix/_sql/mysql/quickfix_database.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
DROP DATABASE IF EXISTS quickfix;
|
||||||
|
CREATE DATABASE quickfix;
|
||||||
19
quickfix/_sql/mysql/sessions_table.sql
Normal file
19
quickfix/_sql/mysql/sessions_table.sql
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
USE quickfix;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS sessions;
|
||||||
|
|
||||||
|
CREATE TABLE sessions (
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64) NOT NULL,
|
||||||
|
creation_time DATETIME NOT NULL,
|
||||||
|
incoming_seqnum INT NOT NULL,
|
||||||
|
outgoing_seqnum INT NOT NULL,
|
||||||
|
PRIMARY KEY (beginstring, sendercompid, sendersubid, senderlocid,
|
||||||
|
targetcompid, targetsubid, targetlocid, session_qualifier)
|
||||||
|
);
|
||||||
14
quickfix/_sql/oracle/messages_table.sql
Normal file
14
quickfix/_sql/oracle/messages_table.sql
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
CREATE TABLE messages (
|
||||||
|
beginstring VARCHAR2(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR2(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR2(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR2(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR2(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR2(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR2(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR2(64) NOT NULL,
|
||||||
|
msgseqnum INTEGER NOT NULL,
|
||||||
|
message VARCHAR2(4000) NOT NULL,
|
||||||
|
PRIMARY KEY (beginstring, sendercompid, sendersubid, senderlocid,
|
||||||
|
targetcompid, targetsubid, targetlocid, session_qualifier, msgseqnum)
|
||||||
|
);
|
||||||
15
quickfix/_sql/oracle/sessions_table.sql
Normal file
15
quickfix/_sql/oracle/sessions_table.sql
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
CREATE TABLE sessions (
|
||||||
|
beginstring VARCHAR2(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR2(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR2(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR2(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR2(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR2(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR2(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR2(64) NOT NULL,
|
||||||
|
creation_time TIMESTAMP NOT NULL,
|
||||||
|
incoming_seqnum INTEGER NOT NULL,
|
||||||
|
outgoing_seqnum INTEGER NOT NULL,
|
||||||
|
PRIMARY KEY (beginstring, sendercompid, sendersubid, senderlocid,
|
||||||
|
targetcompid, targetsubid, targetlocid, session_qualifier)
|
||||||
|
);
|
||||||
3
quickfix/_sql/postgresql/create.bat
Normal file
3
quickfix/_sql/postgresql/create.bat
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
dropdb -U postgres --if-exists quickfix
|
||||||
|
createdb -U postgres quickfix
|
||||||
|
psql -U postgres -d quickfix -f postgresql.sql
|
||||||
3
quickfix/_sql/postgresql/create.sh
Normal file
3
quickfix/_sql/postgresql/create.sh
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
dropdb -U postgres --if-exists quickfix
|
||||||
|
createdb -U postgres quickfix
|
||||||
|
psql -U postgres -d quickfix -f postgresql.sql
|
||||||
16
quickfix/_sql/postgresql/event_log_table.sql
Normal file
16
quickfix/_sql/postgresql/event_log_table.sql
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
CREATE SEQUENCE event_log_sequence;
|
||||||
|
|
||||||
|
CREATE TABLE event_log (
|
||||||
|
id INTEGER DEFAULT NEXTVAL('event_log_sequence'),
|
||||||
|
time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64),
|
||||||
|
text TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
16
quickfix/_sql/postgresql/messages_log_table.sql
Normal file
16
quickfix/_sql/postgresql/messages_log_table.sql
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
CREATE SEQUENCE messages_log_sequence;
|
||||||
|
|
||||||
|
CREATE TABLE messages_log (
|
||||||
|
id INTEGER DEFAULT NEXTVAL('messages_log_sequence'),
|
||||||
|
time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64),
|
||||||
|
text TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
15
quickfix/_sql/postgresql/messages_table.sql
Normal file
15
quickfix/_sql/postgresql/messages_table.sql
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
CREATE TABLE messages (
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64) NOT NULL,
|
||||||
|
msgseqnum INTEGER NOT NULL,
|
||||||
|
message TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (beginstring, sendercompid, sendersubid, senderlocid,
|
||||||
|
targetcompid, targetsubid, targetlocid, session_qualifier,
|
||||||
|
msgseqnum)
|
||||||
|
);
|
||||||
4
quickfix/_sql/postgresql/postgresql.sql
Normal file
4
quickfix/_sql/postgresql/postgresql.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
\i sessions_table.sql;
|
||||||
|
\i messages_table.sql;
|
||||||
|
\i messages_log_table.sql;
|
||||||
|
\i event_log_table.sql;
|
||||||
15
quickfix/_sql/postgresql/sessions_table.sql
Normal file
15
quickfix/_sql/postgresql/sessions_table.sql
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
CREATE TABLE sessions (
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64) NOT NULL,
|
||||||
|
creation_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
|
incoming_seqnum INTEGER NOT NULL,
|
||||||
|
outgoing_seqnum INTEGER NOT NULL,
|
||||||
|
PRIMARY KEY (beginstring, sendercompid, sendersubid, senderlocid,
|
||||||
|
targetcompid, targetsubid, targetlocid, session_qualifier)
|
||||||
|
);
|
||||||
15
quickfix/_sql/sqlite3/event_log_table.sql
Normal file
15
quickfix/_sql/sqlite3/event_log_table.sql
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
DROP TABLE IF EXISTS event_log;
|
||||||
|
|
||||||
|
CREATE TABLE event_log (
|
||||||
|
id INTEGER PRIMARY KEY NOT NULL,
|
||||||
|
time DATETIME NOT NULL,
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64),
|
||||||
|
text TEXT NOT NULL
|
||||||
|
);
|
||||||
15
quickfix/_sql/sqlite3/messages_log_table.sql
Normal file
15
quickfix/_sql/sqlite3/messages_log_table.sql
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
DROP TABLE IF EXISTS messages_log;
|
||||||
|
|
||||||
|
CREATE TABLE messages_log (
|
||||||
|
id INTEGER PRIMARY KEY NOT NULL,
|
||||||
|
time DATETIME NOT NULL,
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64) NOT NULL,
|
||||||
|
text TEXT NOT NULL
|
||||||
|
);
|
||||||
17
quickfix/_sql/sqlite3/messages_table.sql
Normal file
17
quickfix/_sql/sqlite3/messages_table.sql
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
DROP TABLE IF EXISTS messages;
|
||||||
|
|
||||||
|
CREATE TABLE messages (
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64) NOT NULL,
|
||||||
|
msgseqnum INT NOT NULL,
|
||||||
|
message TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (beginstring, sendercompid, sendersubid, senderlocid,
|
||||||
|
targetcompid, targetsubid, targetlocid, session_qualifier,
|
||||||
|
msgseqnum)
|
||||||
|
);
|
||||||
17
quickfix/_sql/sqlite3/sessions_table.sql
Normal file
17
quickfix/_sql/sqlite3/sessions_table.sql
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
DROP TABLE IF EXISTS sessions;
|
||||||
|
|
||||||
|
CREATE TABLE sessions (
|
||||||
|
beginstring CHAR(8) NOT NULL,
|
||||||
|
sendercompid VARCHAR(64) NOT NULL,
|
||||||
|
sendersubid VARCHAR(64) NOT NULL,
|
||||||
|
senderlocid VARCHAR(64) NOT NULL,
|
||||||
|
targetcompid VARCHAR(64) NOT NULL,
|
||||||
|
targetsubid VARCHAR(64) NOT NULL,
|
||||||
|
targetlocid VARCHAR(64) NOT NULL,
|
||||||
|
session_qualifier VARCHAR(64) NOT NULL,
|
||||||
|
creation_time DATETIME NOT NULL,
|
||||||
|
incoming_seqnum INT NOT NULL,
|
||||||
|
outgoing_seqnum INT NOT NULL,
|
||||||
|
PRIMARY KEY (beginstring, sendercompid, sendersubid, senderlocid,
|
||||||
|
targetcompid, targetsubid, targetlocid, session_qualifier)
|
||||||
|
);
|
||||||
72
quickfix/_test/Comparator.rb
Normal file
72
quickfix/_test/Comparator.rb
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#****************************************************************************
|
||||||
|
# Copyright (c) quickfixengine.org All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is part of the QuickFIX FIX Engine
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#****************************************************************************
|
||||||
|
|
||||||
|
class Comparator < Hash
|
||||||
|
|
||||||
|
def initialize(patterns)
|
||||||
|
patterns.each_line do
|
||||||
|
| line |
|
||||||
|
line.chomp!
|
||||||
|
array = line.split("=")
|
||||||
|
num = array[0].to_i
|
||||||
|
regex = Regexp.new(array[1])
|
||||||
|
self[num] = regex;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def compare(left, right)
|
||||||
|
@reason = nil
|
||||||
|
left_array = left.split("\001")
|
||||||
|
right_array = right.split("\001")
|
||||||
|
# check for number of fields
|
||||||
|
if left_array.size != right_array.size
|
||||||
|
@reason = "Number of fields do not match"
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
left_array.each_index do
|
||||||
|
| index |
|
||||||
|
left_field = left_array[index].split("=")
|
||||||
|
right_field = right_array[index].split("=")
|
||||||
|
# check if field is in same order
|
||||||
|
if left_field[0] != right_field[0]
|
||||||
|
@reason = "Expected field (" + left_field[0] + ") but found field (" + right_field[0] + ")"
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
regexp = self[left_field[0].to_i]
|
||||||
|
# do a straight comparison or regex comparison
|
||||||
|
if regexp == nil
|
||||||
|
if left_field[1] != right_field[1]
|
||||||
|
@reason = "Value in field (" + left_field[0] + ") should be (" + left_field[1] + ") but was (" + right_field[1] + ")"
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if !(regexp === right_field[1])
|
||||||
|
@reason = "Field (" + left_field[0] + ") does not match pattern"
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
def reason()
|
||||||
|
return @reason
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
37
quickfix/_test/ComparatorTestCase.rb
Normal file
37
quickfix/_test/ComparatorTestCase.rb
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
require 'Comparator'
|
||||||
|
require 'runit/testcase'
|
||||||
|
|
||||||
|
class ComparatorTestCase < RUNIT::TestCase
|
||||||
|
|
||||||
|
def test_parsePatterns
|
||||||
|
patterns = "10=\\d{1,3}\n52=\\d{8}-\\d2:\\d2:\\d2\n"
|
||||||
|
comp = Comparator.new(patterns)
|
||||||
|
assert_equals(/\d{1,3}/, comp[10])
|
||||||
|
assert_equals(/\d{8}-\d2:\d2:\d2/, comp[52])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_compare
|
||||||
|
patterns = "10=\\d{1,3}\n52=\\d{8}-\\d{2}:\\d{2}:\\d{2}\n"
|
||||||
|
comp = Comparator.new(patterns)
|
||||||
|
# matching fields
|
||||||
|
assert(comp.compare("1=hello\0012=goodbye\001", "1=hello\0012=goodbye\001"))
|
||||||
|
assert(comp.reason == nil)
|
||||||
|
# non-matching field
|
||||||
|
assert(!comp.compare("1=helloo\0012=goodbye\001", "1=hello\0012=goodbye\001"))
|
||||||
|
assert(comp.reason == "Value in field (1) should be (helloo) but was (hello)")
|
||||||
|
# out of order fields
|
||||||
|
assert(!comp.compare("2=hello\0011=goodbye\001", "1=hello\0012=goodbye\001"))
|
||||||
|
assert(comp.reason == "Expected field (2) but found field (1)")
|
||||||
|
# different number of fields
|
||||||
|
assert(!comp.compare("1=hello\001", "1=hello\0012=goodbye\001"))
|
||||||
|
assert(comp.reason == "Number of fields do not match")
|
||||||
|
# mathing non-deterministic field
|
||||||
|
assert(comp.compare(
|
||||||
|
"1=hello\0012=goodbye\00152=12345678-12:23:34\001", "1=hello\0012=goodbye\00152=87654321-98:87:76\001"))
|
||||||
|
# non-matching non-deterministic field
|
||||||
|
assert(!comp.compare(
|
||||||
|
"1=hello\0012=goodbye\00152=12345678-12:23:34\001", "1=hello\0012=goodbye\00152=7654321-98:87:76\001"))
|
||||||
|
assert(comp.reason == "Field (52) does not match pattern")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
53
quickfix/_test/FixParser.rb
Normal file
53
quickfix/_test/FixParser.rb
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#****************************************************************************
|
||||||
|
# Copyright (c) quickfixengine.org All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is part of the QuickFIX FIX Engine
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#****************************************************************************
|
||||||
|
|
||||||
|
require "socket"
|
||||||
|
|
||||||
|
class FixParser
|
||||||
|
|
||||||
|
def initialize(io)
|
||||||
|
@io = io
|
||||||
|
end
|
||||||
|
|
||||||
|
def readFixMessage()
|
||||||
|
if(@io.eof?)
|
||||||
|
raise "Was disconnected, expected data"
|
||||||
|
end
|
||||||
|
|
||||||
|
m = ""
|
||||||
|
# read to begining of MsgLen field
|
||||||
|
m = @io.gets("\0019=")
|
||||||
|
# read contents of MsgLen field
|
||||||
|
length = @io.gets("\001")
|
||||||
|
m += length
|
||||||
|
length.chop!
|
||||||
|
|
||||||
|
# regex checks to make sure length is an integer
|
||||||
|
# if it isn't there is nothing we can do so
|
||||||
|
# close the connection
|
||||||
|
if( (/^\d*$/ === length) == nil )
|
||||||
|
@io.close
|
||||||
|
end
|
||||||
|
# read body
|
||||||
|
m += @io.read(Integer(length))
|
||||||
|
# read CheckSum
|
||||||
|
m += @io.gets("\001")
|
||||||
|
return m
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
46
quickfix/_test/FixParserTestCase.rb
Normal file
46
quickfix/_test/FixParserTestCase.rb
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
require 'FixParser'
|
||||||
|
require 'runit/testcase'
|
||||||
|
require "thread"
|
||||||
|
require 'SocketServer'
|
||||||
|
|
||||||
|
class FixParserTestCase < RUNIT::TestCase
|
||||||
|
|
||||||
|
def test_readFixMessage
|
||||||
|
fixMsg1 = "8=FIX.4.2\0019=12\00135=A\001108=30\00110=31\001"
|
||||||
|
fixMsg2 = "8=FIX.4.2\0019=17\00135=4\00136=88\001123=Y\00110=34\001"
|
||||||
|
|
||||||
|
server = SocketServer.new
|
||||||
|
def server.message=(m)
|
||||||
|
@message = m
|
||||||
|
end
|
||||||
|
|
||||||
|
def server.connectAction(s)
|
||||||
|
end
|
||||||
|
|
||||||
|
def server.receiveAction(s)
|
||||||
|
s.write(@message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def server.disconnectAction(s)
|
||||||
|
end
|
||||||
|
|
||||||
|
server.message = fixMsg1 + fixMsg2
|
||||||
|
Thread.start do
|
||||||
|
server.listen(RUNIT::TestCase.port)
|
||||||
|
end
|
||||||
|
server.wait
|
||||||
|
|
||||||
|
s = TCPSocket.open("localhost", RUNIT::TestCase.port)
|
||||||
|
parser = FixParser.new(s)
|
||||||
|
begin
|
||||||
|
assert_equals(fixMsg1, parser.readFixMessage)
|
||||||
|
assert_equals(fixMsg2, parser.readFixMessage)
|
||||||
|
rescue IOError
|
||||||
|
# I have no idea why this is being thrown
|
||||||
|
end
|
||||||
|
|
||||||
|
s.close
|
||||||
|
server.stop()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
150
quickfix/_test/Reflector.rb
Normal file
150
quickfix/_test/Reflector.rb
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#****************************************************************************
|
||||||
|
# Copyright (c) quickfixengine.org All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is part of the QuickFIX FIX Engine
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#****************************************************************************
|
||||||
|
|
||||||
|
class Reflector < Array
|
||||||
|
|
||||||
|
def identifyMessage(message)
|
||||||
|
if [?I, ?E, ?R, ?i, ?e].include?(message[0])
|
||||||
|
return message[0]
|
||||||
|
else
|
||||||
|
return ?X
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def processFile(messages)
|
||||||
|
lineNum = 0
|
||||||
|
messages.each_line do
|
||||||
|
| line |
|
||||||
|
lineNum += 1
|
||||||
|
line.chomp!
|
||||||
|
if line.empty? then
|
||||||
|
elsif (/^[IEie]\d{1},/ === line) then
|
||||||
|
cid = line[1].to_i - 48
|
||||||
|
body = fixify!(timify!(line[3, line.length]))
|
||||||
|
else
|
||||||
|
cid = 1
|
||||||
|
body = fixify!(timify!(line[1, line.length]))
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
processLine(lineNum, line, body, cid)
|
||||||
|
rescue
|
||||||
|
errorAction(lineNum, line);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def processLine(lineNum, line, body, cid)
|
||||||
|
if line.empty?
|
||||||
|
elsif line[0] == ?\#
|
||||||
|
elsif identifyMessage(line) == ?I
|
||||||
|
initiateAction(body, cid)
|
||||||
|
elsif identifyMessage(line) == ?E
|
||||||
|
expectedAction(body, cid)
|
||||||
|
elsif identifyMessage(line) == ?i
|
||||||
|
if body == "CONNECT"
|
||||||
|
connectAction(cid)
|
||||||
|
elsif body == "DISCONNECT"
|
||||||
|
disconnectAction(cid)
|
||||||
|
elsif body.index("SET_SESSION") == 0
|
||||||
|
setSeqnum(body)
|
||||||
|
else
|
||||||
|
raise "Syntax error: " + body
|
||||||
|
end
|
||||||
|
elsif identifyMessage(line) == ?e
|
||||||
|
if body == "CONNECT"
|
||||||
|
waitConnectAction(cid)
|
||||||
|
elsif body == "DISCONNECT"
|
||||||
|
waitDisconnectAction(cid)
|
||||||
|
else
|
||||||
|
raise "Syntax error: " + body
|
||||||
|
end
|
||||||
|
else
|
||||||
|
raise "Syntax error: " + body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fixify!(message)
|
||||||
|
hasLength = (message =~ /[\001]9=.*?[\001]/)
|
||||||
|
length = ""
|
||||||
|
|
||||||
|
head = message.slice!(/^8=.*?[\001]/)
|
||||||
|
|
||||||
|
if head == nil
|
||||||
|
return message
|
||||||
|
end
|
||||||
|
|
||||||
|
checksum = message.slice(/[\001]10=.*[\001]$/)
|
||||||
|
if(checksum != nil)
|
||||||
|
message.slice!(/[\001]10=.*[\001]$/)
|
||||||
|
end
|
||||||
|
|
||||||
|
message.chomp!
|
||||||
|
if hasLength == nil
|
||||||
|
length = "9=" + message.length.to_s + "\001"
|
||||||
|
end
|
||||||
|
|
||||||
|
if checksum == nil
|
||||||
|
checksumStr = sprintf("%03d", (head + length + message).sum(8));
|
||||||
|
checksum = "10=" + checksumStr + "\001"
|
||||||
|
end
|
||||||
|
|
||||||
|
message.replace(head + length + message + checksum)
|
||||||
|
return message
|
||||||
|
end
|
||||||
|
|
||||||
|
def timify!(message)
|
||||||
|
copy = ""
|
||||||
|
copy.replace(message)
|
||||||
|
t = getTime
|
||||||
|
|
||||||
|
strtime = t.strftime("%Y%m%d-%H:%M:%S")
|
||||||
|
message.sub!("<TIME>", strtime)
|
||||||
|
if( message != copy )
|
||||||
|
return timify!(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
pos1 = /\<TIME[+-]\d+\>/ =~ message
|
||||||
|
pos2 = /\>/ =~ message
|
||||||
|
if( pos1 != nil )
|
||||||
|
op = message[pos1 + 5]
|
||||||
|
num = message.slice(pos1+6..pos2-1)
|
||||||
|
if( op == ?+ )
|
||||||
|
t += num.to_i
|
||||||
|
else
|
||||||
|
t -= num.to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
strtime = t.strftime("%Y%m%d-%H:%M:%S")
|
||||||
|
exp = Regexp.compile("<TIME[" + op.chr + "]" + num + ">")
|
||||||
|
message.sub!(exp, strtime)
|
||||||
|
if( message != copy )
|
||||||
|
return timify!(message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return message
|
||||||
|
end
|
||||||
|
|
||||||
|
def getTime
|
||||||
|
t = Time.new
|
||||||
|
t = t.gmtime
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
135
quickfix/_test/ReflectorClient.rb
Normal file
135
quickfix/_test/ReflectorClient.rb
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#****************************************************************************
|
||||||
|
# Copyright (c) quickfixengine.org All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is part of the QuickFIX FIX Engine
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#****************************************************************************
|
||||||
|
|
||||||
|
require 'Reflector'
|
||||||
|
require 'FixParser'
|
||||||
|
require "socket"
|
||||||
|
require 'uri'
|
||||||
|
require 'net/http'
|
||||||
|
|
||||||
|
class ReflectorClient
|
||||||
|
|
||||||
|
def initialize(messages, address, port)
|
||||||
|
@reflector = Reflector.new
|
||||||
|
@messages = messages
|
||||||
|
@sockets = Hash.new(nil)
|
||||||
|
@parsers = Hash.new(nil)
|
||||||
|
|
||||||
|
def @reflector.address=(a)
|
||||||
|
@address = a
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.port=(p)
|
||||||
|
@port = p
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.client=(c)
|
||||||
|
@client = c
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.sockets=(s)
|
||||||
|
@sockets = s
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.parsers=(p)
|
||||||
|
@parsers = p
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.connectAction(cid)
|
||||||
|
socket = TCPSocket.open(@address, @port)
|
||||||
|
if socket == nil
|
||||||
|
raise IOError("failed to connect")
|
||||||
|
end
|
||||||
|
@sockets[cid] = socket
|
||||||
|
@parsers[cid] = FixParser.new(socket)
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.disconnectAction(cid)
|
||||||
|
@sockets[cid].close
|
||||||
|
@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)
|
||||||
|
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
|
||||||
|
|
||||||
|
def @reflector.initiateAction(msg, cid)
|
||||||
|
if( @sockets[cid] == nil )
|
||||||
|
raise "Unable to send message because connection was dropped"
|
||||||
|
end
|
||||||
|
@sockets[cid].write(msg)
|
||||||
|
@client.initiateAction(msg, cid)
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.expectedAction(msg, cid)
|
||||||
|
m = @parsers[cid].readFixMessage
|
||||||
|
@client.expectedAction(msg, cid)
|
||||||
|
@client.compareAction(msg, m)
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.errorAction(lineNum, line)
|
||||||
|
@client.errorAction(lineNum, line)
|
||||||
|
end
|
||||||
|
|
||||||
|
@reflector.client = self
|
||||||
|
@reflector.address = address
|
||||||
|
@reflector.port = port
|
||||||
|
@reflector.sockets = @sockets
|
||||||
|
@reflector.parsers = @parsers
|
||||||
|
end
|
||||||
|
|
||||||
|
def start()
|
||||||
|
@reflector.processFile(@messages)
|
||||||
|
end
|
||||||
|
|
||||||
|
def stop()
|
||||||
|
@sockets.each do
|
||||||
|
|cid, s|
|
||||||
|
begin
|
||||||
|
s.close
|
||||||
|
rescue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def initiateAction(msg, cid)
|
||||||
|
end
|
||||||
|
def expectedAction(msg, cid)
|
||||||
|
end
|
||||||
|
def responseAction(msg, cid)
|
||||||
|
end
|
||||||
|
end
|
||||||
55
quickfix/_test/ReflectorClientTestCase.rb
Normal file
55
quickfix/_test/ReflectorClientTestCase.rb
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
require 'ReflectorClient'
|
||||||
|
require 'runit/testcase'
|
||||||
|
require 'ReflectorServer'
|
||||||
|
require "thread"
|
||||||
|
|
||||||
|
class ReflectorClientTestCase < RUNIT::TestCase
|
||||||
|
|
||||||
|
def test_reflectMessages
|
||||||
|
|
||||||
|
serverMessages = "E8=FIX.4.2\0019=13\00135=AC\001108=30\00110=31\001\n"
|
||||||
|
serverMessages += "I8=FIX.4.2\0019=13\00135=AS\001108=10\00110=31\001\n"
|
||||||
|
serverMessages += "E8=FIX.4.2\0019=13\00135=BC\001108=25\00110=31\001\n"
|
||||||
|
serverMessages += "I8=FIX.4.2\0019=13\00135=BS\001108=15\00110=31\001\n"
|
||||||
|
|
||||||
|
clientMessages = "iCONNECT\n"
|
||||||
|
clientMessages += "I8=FIX.4.2\0019=13\00135=AC\001108=30\00110=31\001\n"
|
||||||
|
clientMessages += "E8=FIX.4.2\0019=13\00135=AS\001108=10\00110=31\001\n"
|
||||||
|
clientMessages += "I8=FIX.4.2\0019=13\00135=BC\001108=25\00110=31\001\n"
|
||||||
|
clientMessages += "E8=FIX.4.2\0019=13\00135=BS\001108=15\00110=31\001\n"
|
||||||
|
clientMessages += "iDISCONNECT\n"
|
||||||
|
|
||||||
|
server = ReflectorServer.new(serverMessages)
|
||||||
|
client = ReflectorClient.new(clientMessages, "localhost", RUNIT::TestCase.port)
|
||||||
|
|
||||||
|
def client.next
|
||||||
|
begin
|
||||||
|
return @queue.pop 0
|
||||||
|
rescue
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def client.compareAction(e, a)
|
||||||
|
if !defined? @queue
|
||||||
|
@queue = Queue.new
|
||||||
|
end
|
||||||
|
@queue.push(e)
|
||||||
|
@queue.push(a)
|
||||||
|
end
|
||||||
|
|
||||||
|
Thread.start do
|
||||||
|
server.listen(RUNIT::TestCase.port)
|
||||||
|
end
|
||||||
|
server.wait
|
||||||
|
|
||||||
|
client.start()
|
||||||
|
assert_equals("8=FIX.4.2\0019=13\00135=AS\001108=10\00110=31\001", client.next)
|
||||||
|
assert_equals("8=FIX.4.2\0019=13\00135=AS\001108=10\00110=31\001", client.next)
|
||||||
|
assert_equals("8=FIX.4.2\0019=13\00135=BS\001108=15\00110=31\001", client.next)
|
||||||
|
assert_equals("8=FIX.4.2\0019=13\00135=BS\001108=15\00110=31\001", client.next)
|
||||||
|
assert_equals(nil, client.next)
|
||||||
|
server.stop
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
111
quickfix/_test/ReflectorServer.rb
Normal file
111
quickfix/_test/ReflectorServer.rb
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#****************************************************************************
|
||||||
|
# Copyright (c) quickfixengine.org All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is part of the QuickFIX FIX Engine
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#****************************************************************************
|
||||||
|
|
||||||
|
require 'SocketServer'
|
||||||
|
require 'Reflector'
|
||||||
|
|
||||||
|
class ReflectorServer < SocketServer
|
||||||
|
|
||||||
|
def initialize(messages, address = "localhost", port = 5000)
|
||||||
|
@reflector = Reflector.new
|
||||||
|
@parser = nil
|
||||||
|
@socket = nil
|
||||||
|
@messages = messages
|
||||||
|
@port = port
|
||||||
|
|
||||||
|
def @reflector.socket=(s)
|
||||||
|
@socket = s
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.socket
|
||||||
|
return @socket
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.server=(s)
|
||||||
|
@server = s
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.parser=(s)
|
||||||
|
@parser = s
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.expectedAction(msg, cid)
|
||||||
|
m = @parser.readFixMessage
|
||||||
|
@server.compareAction(msg, m)
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.initiateAction(msg, cid)
|
||||||
|
@socket.write(msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.waitConnectAction(cid)
|
||||||
|
@server.waitConnectAction
|
||||||
|
end
|
||||||
|
|
||||||
|
def @reflector.waitDisconnectAction(cid)
|
||||||
|
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
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def connectAction(s)
|
||||||
|
if @socket == nil
|
||||||
|
@socket = s
|
||||||
|
@reflector.socket = s
|
||||||
|
@reflector.server = self
|
||||||
|
else
|
||||||
|
s.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def waitConnectAction
|
||||||
|
gs = TCPServer.open(@port)
|
||||||
|
addr = gs.addr
|
||||||
|
addr.shift
|
||||||
|
if IO.select([gs], nil, nil, 10) == nil then
|
||||||
|
raise "Connection hangs after ten seconds."
|
||||||
|
end
|
||||||
|
@socket = gs.accept
|
||||||
|
@parser = FixParser.new(@socket)
|
||||||
|
@reflector.parser = @parser
|
||||||
|
@reflector.socket = @socket
|
||||||
|
end
|
||||||
|
|
||||||
|
def disconnectAction(s)
|
||||||
|
end
|
||||||
|
|
||||||
|
def receiveAction(s)
|
||||||
|
end
|
||||||
|
|
||||||
|
def compareAction(e, a)
|
||||||
|
end
|
||||||
|
|
||||||
|
def start
|
||||||
|
@reflector.server = self
|
||||||
|
@reflector.processFile(@messages)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
33
quickfix/_test/ReflectorServerTestCase.rb
Normal file
33
quickfix/_test/ReflectorServerTestCase.rb
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
require 'ReflectorServer'
|
||||||
|
require 'runit/testcase'
|
||||||
|
require "thread"
|
||||||
|
|
||||||
|
class ReflectorServerTestCase < RUNIT::TestCase
|
||||||
|
|
||||||
|
def test_reflectMessages
|
||||||
|
messages = "E8=FIX.4.2\0019=12\00135=A\001108=30\00110=31\001\n"
|
||||||
|
messages += "R8=FIX.4.2\0019=12\00135=A\001108=10\00110=31\001\n"
|
||||||
|
messages += "E8=FIX.4.2\0019=12\00135=A\001108=25\00110=31\001\n"
|
||||||
|
messages += "R8=FIX.4.2\0019=12\00135=A\001108=15\00110=31\001\n"
|
||||||
|
|
||||||
|
server = ReflectorServer.new(messages)
|
||||||
|
Thread.start do
|
||||||
|
server.listen(RUNIT::TestCase.port)
|
||||||
|
end
|
||||||
|
server.wait
|
||||||
|
|
||||||
|
s = TCPSocket.open("localhost", RUNIT::TestCase.port)
|
||||||
|
parser = FixParser.new(s)
|
||||||
|
|
||||||
|
begin
|
||||||
|
s.write("8=FIX.4.2\0019=12\00135=A\001108=30\00110=31\001")
|
||||||
|
assert_equals("8=FIX.4.2\0019=12\00135=A\001108=10\00110=31\001", parser.readFixMessage)
|
||||||
|
s.write("8=FIX.4.2\0019=12\00135=A\001108=30\00125=31\001")
|
||||||
|
assert_equals("8=FIX.4.2\0019=12\00135=A\001108=15\00110=31\001", parser.readFixMessage)
|
||||||
|
rescue IOError
|
||||||
|
end
|
||||||
|
|
||||||
|
s.close
|
||||||
|
server.stop
|
||||||
|
end
|
||||||
|
end
|
||||||
208
quickfix/_test/ReflectorTestCase.rb
Normal file
208
quickfix/_test/ReflectorTestCase.rb
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
require 'Reflector'
|
||||||
|
|
||||||
|
class MockReflector < Reflector
|
||||||
|
def getTime
|
||||||
|
t = Time.gm(2000, "jan", 1, 20, 15, 1)
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
require 'runit/testcase'
|
||||||
|
|
||||||
|
class ReflectorTestCase < RUNIT::TestCase
|
||||||
|
|
||||||
|
def test_identifyMessage
|
||||||
|
reflector = Reflector.new
|
||||||
|
message = "I8=FIX42"
|
||||||
|
assert(reflector.identifyMessage(message) == ?I)
|
||||||
|
message = "E8=FIX42"
|
||||||
|
assert(reflector.identifyMessage(message) == ?E)
|
||||||
|
message = "R8=FIX42"
|
||||||
|
assert(reflector.identifyMessage(message) == ?R)
|
||||||
|
message = "8=FIX42"
|
||||||
|
assert(reflector.identifyMessage(message) == ?X)
|
||||||
|
message = "iACTION"
|
||||||
|
assert(reflector.identifyMessage(message) == ?i)
|
||||||
|
message = "eACTION"
|
||||||
|
assert(reflector.identifyMessage(message) == ?e)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_timify_and_fixify
|
||||||
|
reflector = MockReflector.new
|
||||||
|
|
||||||
|
str = reflector.fixify!(reflector.timify!("8=FIX.4.235=D34=249=PATS52=<TIME>56=RCG1=acct111=121=138=240=154=155=ESU260=<TIME>167=FUT204=1207=CME9701=omni19702=19706=E9707=1239708=G"))
|
||||||
|
assert_equals("8=FIX.4.29=17135=D34=249=PATS52=20000101-20:15:0156=RCG1=acct111=121=138=240=154=155=ESU260=20000101-20:15:01167=FUT204=1207=CME9701=omni19702=19706=E9707=1239708=G10=121", str)
|
||||||
|
|
||||||
|
str = reflector.fixify!(reflector.timify!("8=FIX.4.235=D34=249=PATS52=<TIME>56=RCG1=acct111=121=138=240=154=155=ESU260=<TIME>167=FUT204=1207=CME9701=omni19702=19706=E9707=1239708=G9709=PEA"))
|
||||||
|
assert_equals("8=FIX.4.29=18035=D34=249=PATS52=20000101-20:15:0156=RCG1=acct111=121=138=240=154=155=ESU260=20000101-20:15:01167=FUT204=1207=CME9701=omni19702=19706=E9707=1239708=G9709=PEA10=102", str)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fixify_bang
|
||||||
|
reflector = Reflector.new
|
||||||
|
|
||||||
|
str = "8=FIX.4.235=A34=149=TW52=20000426-12:05:06" +
|
||||||
|
"56=ISLD98=0108=30"
|
||||||
|
reflector.fixify!(str)
|
||||||
|
assert_equals("8=FIX.4.29=5735=A34=149=TW52=20000426-12:05:0656=ISLD98=0108=3010=005", str)
|
||||||
|
|
||||||
|
str = "8=FIX.4.29=5735=A34=149=TW52=20000426-12:05:06" +
|
||||||
|
"56=ISLD98=0108=3010=005"
|
||||||
|
reflector.fixify!(str)
|
||||||
|
assert_equals("8=FIX.4.29=5735=A34=149=TW52=20000426-12:05:0656=ISLD98=0108=3010=005", str)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_timify_bang
|
||||||
|
reflector = Reflector.new
|
||||||
|
|
||||||
|
str = "8=FIX.4.29=5735=A34=149=TW52=20011010-10:10:1056=ISLD98=0108=3010=005"
|
||||||
|
reflector.timify!(str)
|
||||||
|
assert_equals("8=FIX.4.29=5735=A34=149=TW52=20011010-10:10:1056=ISLD98=0108=3010=005", str)
|
||||||
|
|
||||||
|
str = "8=FIX.4.29=5735=A34=149=TW52=<TIME>56=ISLD98=0" +
|
||||||
|
"108=3010=005"
|
||||||
|
reflector.timify!(str)
|
||||||
|
match = (/8=FIX.4.29=5735=A34=149=TW52=\d{8}-\d{2}:\d{2}:\d{2}56=ISLD98=0108=3010=005/ === str)
|
||||||
|
assert(match != nil)
|
||||||
|
|
||||||
|
str = "8=FIX.4.29=5735=A34=149=TW52=<TIME>56=ISLD" +
|
||||||
|
"122=<TIME>98=0108=3010=005"
|
||||||
|
reflector.timify!(str)
|
||||||
|
match = (/8=FIX.4.29=5735=A34=149=TW52=\d{8}-\d{2}:\d{2}:\d{2}56=ISLD122=\d{8}-\d{2}:\d{2}:\d{2}98=0108=3010=005/ === str)
|
||||||
|
assert(match != nil)
|
||||||
|
|
||||||
|
str = "8=FIX.4.29=5735=A34=149=TW52=<TIME+9>56=ISLD98=0" +
|
||||||
|
"108=3010=005"
|
||||||
|
reflector.timify!(str)
|
||||||
|
match = (/8=FIX.4.29=5735=A34=149=TW52=\d{8}-\d{2}:\d{2}:\d{2}56=ISLD98=0108=3010=005/ === str)
|
||||||
|
assert(match != nil)
|
||||||
|
|
||||||
|
str = "8=FIX.4.29=5735=A34=149=TW52=<TIME>56=ISLD98=0" +
|
||||||
|
"108=3060=<TIME>10=005"
|
||||||
|
reflector.timify!(str)
|
||||||
|
match = (/8=FIX.4.29=5735=A34=149=TW52=\d{8}-\d{2}:\d{2}:\d{2}56=ISLD98=0108=3060=\d{8}-\d{2}:\d{2}:\d{2}10=005/ === str)
|
||||||
|
assert(match != nil)
|
||||||
|
|
||||||
|
str = "8=FIX.4.235=D34=249=PATS52=<TIME>56=RCG1=acct111=121=138=240=154=155=ESU2" +
|
||||||
|
"60=<TIME>167=FUT204=1207=CME9701=omni19702=19706=E9707=1239708=G9710=PEA"
|
||||||
|
reflector.timify!(str)
|
||||||
|
match = (/8=FIX.4.235=D34=249=PATS52=\d{8}-\d{2}:\d{2}:\d{2}56=RCG1=acct111=121=138=240=154=155=ESU260=\d{8}-\d{2}:\d{2}:\d{2}167=FUT204=1207=CME9701=omni19702=19706=E9707=1239708=G9710=PEA/ === str)
|
||||||
|
assert(match != nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_identifyFile
|
||||||
|
reflector = Reflector.new
|
||||||
|
messages = "E8=1\nI8=2\n\nI8=3\nE8=4\n#foo\nE8=5\nE8=6\nI8=7\niCONNECT\neDISCONNECT\neCONNECT\niDISCONNECT\nE2,8=8\n"
|
||||||
|
cum = ""
|
||||||
|
|
||||||
|
def reflector.ini=(i)
|
||||||
|
@ini = i
|
||||||
|
end
|
||||||
|
def reflector.ini
|
||||||
|
return @ini
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.cum=(c)
|
||||||
|
@cum = c
|
||||||
|
end
|
||||||
|
def reflector.cum
|
||||||
|
return @cum
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.exp=(e)
|
||||||
|
@exp = e
|
||||||
|
end
|
||||||
|
def reflector.exp
|
||||||
|
return @exp
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.icon=(i)
|
||||||
|
@icon = i
|
||||||
|
end
|
||||||
|
def reflector.icon
|
||||||
|
return @icon
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.idis=(i)
|
||||||
|
@idis = i
|
||||||
|
end
|
||||||
|
def reflector.idis
|
||||||
|
return @idis
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.econ=(e)
|
||||||
|
@econ = e
|
||||||
|
end
|
||||||
|
def reflector.econ
|
||||||
|
return @econ
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.edis=(e)
|
||||||
|
@edis = e
|
||||||
|
end
|
||||||
|
def reflector.edis
|
||||||
|
return @edis
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.err=(e)
|
||||||
|
@err = e
|
||||||
|
end
|
||||||
|
def reflector.err
|
||||||
|
return @err
|
||||||
|
end
|
||||||
|
|
||||||
|
reflector.ini = ""; reflector.cum = "";
|
||||||
|
reflector.exp = ""; reflector.icon = "";
|
||||||
|
reflector.idis = ""; reflector.econ = "";
|
||||||
|
reflector.edis = ""; reflector.err = "";
|
||||||
|
|
||||||
|
def reflector.initiateAction(msg, cid)
|
||||||
|
@cum += cid.to_s + "," + msg + "|"
|
||||||
|
@ini += cid.to_s + "," + msg + "|"
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.expectedAction(msg, cid)
|
||||||
|
@cum += cid.to_s + "," + msg + "|"
|
||||||
|
@exp += cid.to_s + "," + msg + "|"
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.connectAction(cid)
|
||||||
|
@cum += cid.to_s + "," + "iCONNECT" + "|"
|
||||||
|
@icon += cid.to_s + "," + "iCONNECT" + "|"
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.disconnectAction(cid)
|
||||||
|
@cum += cid.to_s + "," + "iDISCONNECT" + "|"
|
||||||
|
@idis += cid.to_s + "," + "iDISCONNECT" + "|"
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.waitConnectAction(cid)
|
||||||
|
@cum += cid.to_s + "," + "eCONNECT" + "|"
|
||||||
|
@econ += cid.to_s + "," + "eCONNECT" + "|"
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.waitDisconnectAction(cid)
|
||||||
|
@cum += cid.to_s + "," + "eDISCONNECT" + "|"
|
||||||
|
@edis += cid.to_s + "," + "eDISCONNECT" + "|"
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflector.errorAction(lineNum, msg)
|
||||||
|
@cum += msg + "|"
|
||||||
|
@err += msg + "|"
|
||||||
|
end
|
||||||
|
|
||||||
|
reflector.processFile(messages)
|
||||||
|
|
||||||
|
#messages = "E8=1\nI8=2\n\nI8=3\nE8=4\n#foo\nE8=5\nE8=6\nI8=7\niCONNECT\neDISCONNECT\neCONNECT\niDISCONNECT\nE2,8=8\n"
|
||||||
|
|
||||||
|
assert_equals("1,8=1|1,8=2|1,8=3|1,8=4|1,8=5|1,8=6|1,8=7|" +
|
||||||
|
"1,iCONNECT|1,eDISCONNECT|1,eCONNECT|1,iDISCONNECT|2,8=8|",
|
||||||
|
reflector.cum)
|
||||||
|
assert_equals("1,8=2|1,8=3|1,8=7|", reflector.ini)
|
||||||
|
assert_equals("1,8=1|1,8=4|1,8=5|1,8=6|2,8=8|", reflector.exp)
|
||||||
|
assert_equals("1,iCONNECT|", reflector.icon)
|
||||||
|
assert_equals("1,iDISCONNECT|", reflector.idis)
|
||||||
|
assert_equals("1,eCONNECT|", reflector.econ)
|
||||||
|
assert_equals("1,eDISCONNECT|", reflector.edis)
|
||||||
|
end
|
||||||
|
end
|
||||||
144
quickfix/_test/Runner.rb
Normal file
144
quickfix/_test/Runner.rb
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#****************************************************************************
|
||||||
|
# Copyright (c) quickfixengine.org All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is part of the QuickFIX FIX Engine
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#****************************************************************************
|
||||||
|
|
||||||
|
require 'ReflectorClient'
|
||||||
|
require 'Comparator'
|
||||||
|
|
||||||
|
def extendProcess(c)
|
||||||
|
|
||||||
|
def c.errorAction(lineNum, line)
|
||||||
|
report = " " + $!.to_s + "\n"
|
||||||
|
report += " <line>" + lineNum.to_s + "</line>\n"
|
||||||
|
raise report
|
||||||
|
end
|
||||||
|
|
||||||
|
def c.compareAction(e, a)
|
||||||
|
if( !defined? @patterns )
|
||||||
|
@patterns = "10=\\d{1,3}\n52=\\d{8}-\\d{2}:\\d{2}:\\d{2}\n";
|
||||||
|
end
|
||||||
|
if( !defined? @comp )
|
||||||
|
@comp = Comparator.new(@patterns)
|
||||||
|
end
|
||||||
|
|
||||||
|
if( !@comp.compare(e,a) )
|
||||||
|
e.tr!("\001", "*")
|
||||||
|
a.tr!("\001", "*")
|
||||||
|
report = @comp.reason + "\n"
|
||||||
|
report += " <expected><![CDATA[" + e + "]]></expected>\n"
|
||||||
|
report += " <received><![CDATA[" + a + "]]></received>"
|
||||||
|
raise report
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def c.patterns=(p)
|
||||||
|
@patterns = p
|
||||||
|
end
|
||||||
|
|
||||||
|
c.patterns = File.open("definitions/fields.fmt", "r")
|
||||||
|
end
|
||||||
|
|
||||||
|
def printResult(test, exception)
|
||||||
|
print "<test name='", test, "' result='"
|
||||||
|
if exception == nil then
|
||||||
|
print "success'/>\n"
|
||||||
|
else
|
||||||
|
print "failure' >\n"
|
||||||
|
print " <message>\n", $!, " </message>\n"
|
||||||
|
#print " <trace><![CDATA["
|
||||||
|
#print $!.backtrace.join("]]></trace>\n <trace><![CDATA[")
|
||||||
|
#print " ]]></trace>\n"
|
||||||
|
print "</test>\n"
|
||||||
|
end
|
||||||
|
STDOUT.flush
|
||||||
|
end
|
||||||
|
|
||||||
|
def createProcess(file, address, port)
|
||||||
|
newarray = [1,2,3,4,5,6,7,8,9,10]
|
||||||
|
newarray.each do
|
||||||
|
| num |
|
||||||
|
begin
|
||||||
|
socket = TCPSocket.open(address, port);
|
||||||
|
rescue
|
||||||
|
end
|
||||||
|
if socket == nil
|
||||||
|
sleep 3
|
||||||
|
next
|
||||||
|
else
|
||||||
|
socket.close
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
file.each_line do
|
||||||
|
| line |
|
||||||
|
if line =~ /^i\d*,?CONNECT/ then
|
||||||
|
return ReflectorClient.new(file, address, port)
|
||||||
|
elsif line =~ /^e\d*,?CONNECT/ then
|
||||||
|
return ReflectorServer.new(file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
newarray = ARGV[2, ARGV.length-2]
|
||||||
|
exitValue = 0
|
||||||
|
total = 0
|
||||||
|
failures = 0
|
||||||
|
|
||||||
|
begin
|
||||||
|
print "<at>\n"
|
||||||
|
newarray.each do
|
||||||
|
| v |
|
||||||
|
file = File.open(v, "r")
|
||||||
|
process = createProcess(file, ARGV[0], ARGV[1])
|
||||||
|
if process.nil? then
|
||||||
|
print " <test name='", v, "' result='", "failure' >\n"
|
||||||
|
print " <message><![CDATA[Test definition did "
|
||||||
|
print "not contain iCONNECT or eCONNECT]]></message>\n"
|
||||||
|
print " </test>\n"
|
||||||
|
exitValue += 1
|
||||||
|
next
|
||||||
|
end
|
||||||
|
file.rewind
|
||||||
|
extendProcess(process)
|
||||||
|
|
||||||
|
sleep(0.1)
|
||||||
|
total += 1
|
||||||
|
begin
|
||||||
|
process.start
|
||||||
|
printResult(v, nil)
|
||||||
|
process.stop
|
||||||
|
rescue
|
||||||
|
failures += 1
|
||||||
|
exitValue += 1
|
||||||
|
printResult(v, $!)
|
||||||
|
process.stop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
print "\n<results total='", total, "' failures='", failures, "'/>\n"
|
||||||
|
print "</at>\n"
|
||||||
|
rescue
|
||||||
|
print " ",$!,"\n"
|
||||||
|
print "</at>\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
exit exitValue
|
||||||
|
|
||||||
|
if not Object.respond_to?("is_testing") or not Object.is_testing then
|
||||||
|
end
|
||||||
21
quickfix/_test/RunnerTestCase.rb
Normal file
21
quickfix/_test/RunnerTestCase.rb
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
require 'Runner'
|
||||||
|
require 'runit/testcase'
|
||||||
|
|
||||||
|
class RunnerTestCase < RUNIT::TestCase
|
||||||
|
def test_createProcess
|
||||||
|
process = createProcess("foo\nbar\niCONNECT\nbaz", "localhost", 39333)
|
||||||
|
assert process.kind_of?(ReflectorClient)
|
||||||
|
process = createProcess("iCONNECT\nfoo\nbar\nbaz", "localhost", 39333)
|
||||||
|
assert process.kind_of?(ReflectorClient)
|
||||||
|
process = createProcess("foo\nbar\neCONNECT\nbaz", "localhost", 39333)
|
||||||
|
assert process.kind_of?(ReflectorServer)
|
||||||
|
process = createProcess("eCONNECT\nfoo\nbar\nbaz", "localhost", 39333)
|
||||||
|
assert process.kind_of?(ReflectorServer)
|
||||||
|
process = createProcess("foo\nbar\nbaz", "localhost", 39333)
|
||||||
|
assert process.nil?
|
||||||
|
process = createProcess("foo\nbar\nbazeCONNECT", "localhost", 39333)
|
||||||
|
assert process.nil?
|
||||||
|
process = createProcess("", "localhost", 39333)
|
||||||
|
assert process.nil?
|
||||||
|
end
|
||||||
|
end
|
||||||
57
quickfix/_test/SocketServer.rb
Normal file
57
quickfix/_test/SocketServer.rb
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#****************************************************************************
|
||||||
|
# Copyright (c) quickfixengine.org All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is part of the QuickFIX FIX Engine
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#****************************************************************************
|
||||||
|
|
||||||
|
require "socket"
|
||||||
|
|
||||||
|
class SocketServer
|
||||||
|
|
||||||
|
def listen(port)
|
||||||
|
|
||||||
|
@gs = TCPServer.open(port)
|
||||||
|
addr = @gs.addr
|
||||||
|
addr.shift
|
||||||
|
|
||||||
|
while !@gs.closed?
|
||||||
|
ns = @gs.accept
|
||||||
|
Thread.start do
|
||||||
|
s = ns
|
||||||
|
connectAction(s)
|
||||||
|
receiveAction(s)
|
||||||
|
s.close
|
||||||
|
disconnectAction(s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def stop
|
||||||
|
if not @gs.nil?
|
||||||
|
@gs.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def closed?
|
||||||
|
return @gs.closed?
|
||||||
|
end
|
||||||
|
|
||||||
|
def wait
|
||||||
|
while( closed? )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
68
quickfix/_test/SocketServerTestCase.rb
Normal file
68
quickfix/_test/SocketServerTestCase.rb
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
require 'SocketServer'
|
||||||
|
require 'runit/testcase'
|
||||||
|
require "thread"
|
||||||
|
|
||||||
|
class SocketServerTestCase < RUNIT::TestCase
|
||||||
|
|
||||||
|
def test_listen
|
||||||
|
socketServer = SocketServer.new
|
||||||
|
connectQueue = Queue.new
|
||||||
|
receiveQueue = Queue.new
|
||||||
|
disconnectQueue = Queue.new
|
||||||
|
|
||||||
|
def socketServer.connectQueue=(q)
|
||||||
|
@connectQueue = q
|
||||||
|
end
|
||||||
|
def socketServer.connectQueue
|
||||||
|
return @connectQueue
|
||||||
|
end
|
||||||
|
|
||||||
|
def socketServer.receiveQueue=(q)
|
||||||
|
@receiveQueue = q
|
||||||
|
end
|
||||||
|
def socketServer.receiveQueue
|
||||||
|
return @receiveQueue
|
||||||
|
end
|
||||||
|
|
||||||
|
def socketServer.disconnectQueue=(q)
|
||||||
|
@disconnectQueue = q
|
||||||
|
end
|
||||||
|
def socketServer.disconnectQueue
|
||||||
|
return @disconnectQueue
|
||||||
|
end
|
||||||
|
|
||||||
|
def socketServer.connectAction(s)
|
||||||
|
@connectQueue.push(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def socketServer.disconnectAction(s)
|
||||||
|
@disconnectQueue.push(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def socketServer.receiveAction(s)
|
||||||
|
while( str = s.gets )
|
||||||
|
@receiveQueue.push(str)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
socketServer.connectQueue = connectQueue
|
||||||
|
socketServer.receiveQueue = receiveQueue
|
||||||
|
socketServer.disconnectQueue = disconnectQueue
|
||||||
|
|
||||||
|
Thread.start do
|
||||||
|
socketServer.listen(RUNIT::TestCase.port)
|
||||||
|
end
|
||||||
|
socketServer.wait
|
||||||
|
|
||||||
|
s = TCPSocket.open("localhost", RUNIT::TestCase.port)
|
||||||
|
assert(connectQueue.pop)
|
||||||
|
s.write("test\r\n")
|
||||||
|
s.write("test2\r\n")
|
||||||
|
assert_equals("test\r\n", receiveQueue.pop)
|
||||||
|
assert_equals("test2\r\n", receiveQueue.pop)
|
||||||
|
s.close
|
||||||
|
assert(disconnectQueue.pop)
|
||||||
|
socketServer.stop()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
10
quickfix/_test/atfixturerun.rb
Normal file
10
quickfix/_test/atfixturerun.rb
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
$kidpid = fork;
|
||||||
|
|
||||||
|
if($kidpid == 0) {
|
||||||
|
chdir("..");
|
||||||
|
exec("debug/quickfix -t server -f cfg/at_server_test.cfg");
|
||||||
|
}
|
||||||
|
sleep(6000);
|
||||||
|
`bash -c "./runall"`;
|
||||||
|
|
||||||
|
kill($kidpid);
|
||||||
11
quickfix/_test/cfg/lastseqnumprocessed/fix42.cfg
Normal file
11
quickfix/_test/cfg/lastseqnumprocessed/fix42.cfg
Normal file
@ -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
|
||||||
11
quickfix/_test/cfg/lastseqnumprocessed/fix43.cfg
Normal file
11
quickfix/_test/cfg/lastseqnumprocessed/fix43.cfg
Normal file
@ -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
|
||||||
11
quickfix/_test/cfg/lastseqnumprocessed/fix44.cfg
Normal file
11
quickfix/_test/cfg/lastseqnumprocessed/fix44.cfg
Normal file
@ -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
|
||||||
14
quickfix/_test/cfg/lastseqnumprocessed/fix50.cfg
Normal file
14
quickfix/_test/cfg/lastseqnumprocessed/fix50.cfg
Normal file
@ -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
|
||||||
14
quickfix/_test/cfg/lastseqnumprocessed/fix50sp1.cfg
Normal file
14
quickfix/_test/cfg/lastseqnumprocessed/fix50sp1.cfg
Normal file
@ -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
|
||||||
14
quickfix/_test/cfg/lastseqnumprocessed/fix50sp2.cfg
Normal file
14
quickfix/_test/cfg/lastseqnumprocessed/fix50sp2.cfg
Normal file
@ -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
|
||||||
10
quickfix/_test/cfg/nextexpectedseqnum/fix44.cfg
Normal file
10
quickfix/_test/cfg/nextexpectedseqnum/fix44.cfg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
SocketAcceptPort=5005
|
||||||
|
SenderCompID=ISLD
|
||||||
|
TargetCompID=TW
|
||||||
|
FileLogPath=tmp
|
||||||
|
|
||||||
|
[SESSION]
|
||||||
|
BeginString=FIX.4.4
|
||||||
|
DataDictionary=../spec/FIX44.xml
|
||||||
|
EnableNextExpectedMsgSeqNum=Y
|
||||||
12
quickfix/_test/cfg/nextexpectedseqnum/fix50.cfg
Normal file
12
quickfix/_test/cfg/nextexpectedseqnum/fix50.cfg
Normal file
@ -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
|
||||||
12
quickfix/_test/cfg/nextexpectedseqnum/fix50sp1.cfg
Normal file
12
quickfix/_test/cfg/nextexpectedseqnum/fix50sp1.cfg
Normal file
@ -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
|
||||||
12
quickfix/_test/cfg/nextexpectedseqnum/fix50sp2.cfg
Normal file
12
quickfix/_test/cfg/nextexpectedseqnum/fix50sp2.cfg
Normal file
@ -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
|
||||||
11
quickfix/_test/cfg/resendreqchunksize/fix40.cfg
Normal file
11
quickfix/_test/cfg/resendreqchunksize/fix40.cfg
Normal file
@ -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
|
||||||
11
quickfix/_test/cfg/resendreqchunksize/fix41.cfg
Normal file
11
quickfix/_test/cfg/resendreqchunksize/fix41.cfg
Normal file
@ -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
|
||||||
11
quickfix/_test/cfg/resendreqchunksize/fix42.cfg
Normal file
11
quickfix/_test/cfg/resendreqchunksize/fix42.cfg
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
SocketAcceptPort=5003
|
||||||
|
SenderCompID=ISLD
|
||||||
|
TargetCompID=TW
|
||||||
|
ResetOnLogon=Y
|
||||||
|
FileLogPath=tmp
|
||||||
|
|
||||||
|
[SESSION]
|
||||||
|
BeginString=FIX.4.2
|
||||||
|
DataDictionary=../spec/FIX42.xml
|
||||||
|
ResendRequestChunkSize=5
|
||||||
11
quickfix/_test/cfg/resendreqchunksize/fix43.cfg
Normal file
11
quickfix/_test/cfg/resendreqchunksize/fix43.cfg
Normal file
@ -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
|
||||||
11
quickfix/_test/cfg/resendreqchunksize/fix44.cfg
Normal file
11
quickfix/_test/cfg/resendreqchunksize/fix44.cfg
Normal file
@ -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
|
||||||
14
quickfix/_test/cfg/resendreqchunksize/fix50.cfg
Normal file
14
quickfix/_test/cfg/resendreqchunksize/fix50.cfg
Normal file
@ -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
|
||||||
14
quickfix/_test/cfg/resendreqchunksize/fix50sp1.cfg
Normal file
14
quickfix/_test/cfg/resendreqchunksize/fix50sp1.cfg
Normal file
@ -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
|
||||||
14
quickfix/_test/cfg/resendreqchunksize/fix50sp2.cfg
Normal file
14
quickfix/_test/cfg/resendreqchunksize/fix50sp2.cfg
Normal file
@ -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
|
||||||
10
quickfix/_test/cfg/server/fix40.cfg
Normal file
10
quickfix/_test/cfg/server/fix40.cfg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
SocketAcceptPort=5001
|
||||||
|
SenderCompID=ISLD
|
||||||
|
TargetCompID=TW
|
||||||
|
ResetOnLogon=Y
|
||||||
|
FileLogPath=tmp
|
||||||
|
|
||||||
|
[SESSION]
|
||||||
|
BeginString=FIX.4.0
|
||||||
|
DataDictionary=../spec/FIX40.xml
|
||||||
10
quickfix/_test/cfg/server/fix41.cfg
Normal file
10
quickfix/_test/cfg/server/fix41.cfg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
SocketAcceptPort=5002
|
||||||
|
SenderCompID=ISLD
|
||||||
|
TargetCompID=TW
|
||||||
|
ResetOnLogon=Y
|
||||||
|
FileLogPath=tmp
|
||||||
|
|
||||||
|
[SESSION]
|
||||||
|
BeginString=FIX.4.1
|
||||||
|
DataDictionary=../spec/FIX41.xml
|
||||||
10
quickfix/_test/cfg/server/fix42.cfg
Normal file
10
quickfix/_test/cfg/server/fix42.cfg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
SocketAcceptPort=5003
|
||||||
|
SenderCompID=ISLD
|
||||||
|
TargetCompID=TW
|
||||||
|
ResetOnLogon=Y
|
||||||
|
FileLogPath=tmp
|
||||||
|
|
||||||
|
[SESSION]
|
||||||
|
BeginString=FIX.4.2
|
||||||
|
DataDictionary=../spec/FIX42.xml
|
||||||
10
quickfix/_test/cfg/server/fix43.cfg
Normal file
10
quickfix/_test/cfg/server/fix43.cfg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
SocketAcceptPort=5004
|
||||||
|
SenderCompID=ISLD
|
||||||
|
TargetCompID=TW
|
||||||
|
ResetOnLogon=Y
|
||||||
|
FileLogPath=tmp
|
||||||
|
|
||||||
|
[SESSION]
|
||||||
|
BeginString=FIX.4.3
|
||||||
|
DataDictionary=../spec/FIX43.xml
|
||||||
10
quickfix/_test/cfg/server/fix44.cfg
Normal file
10
quickfix/_test/cfg/server/fix44.cfg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
SocketAcceptPort=5005
|
||||||
|
SenderCompID=ISLD
|
||||||
|
TargetCompID=TW
|
||||||
|
ResetOnLogon=Y
|
||||||
|
FileLogPath=tmp
|
||||||
|
|
||||||
|
[SESSION]
|
||||||
|
BeginString=FIX.4.4
|
||||||
|
DataDictionary=../spec/FIX44.xml
|
||||||
13
quickfix/_test/cfg/server/fix50.cfg
Normal file
13
quickfix/_test/cfg/server/fix50.cfg
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[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
|
||||||
13
quickfix/_test/cfg/server/fix50sp1.cfg
Normal file
13
quickfix/_test/cfg/server/fix50sp1.cfg
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[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
|
||||||
13
quickfix/_test/cfg/server/fix50sp2.cfg
Normal file
13
quickfix/_test/cfg/server/fix50sp2.cfg
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[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
|
||||||
5
quickfix/_test/definitions/fields.fmt
Normal file
5
quickfix/_test/definitions/fields.fmt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
10=\d{3}
|
||||||
|
42=\d{8}-\d{2}:\d{2}:\d{2}
|
||||||
|
52=\d{8}-\d{2}:\d{2}:\d{2}|\d{8}-\d{2}:\d{2}:\d{2}[.]\d{3}
|
||||||
|
60=\d{8}-\d{2}:\d{2}:\d{2}
|
||||||
|
122=\d{8}-\d{2}:\d{2}:\d{2}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
iCONNECT
|
||||||
|
|
||||||
|
I8=FIX.4.235=A34=149=TW52=<TIME>56=ISLD369=098=0108=2
|
||||||
|
E8=FIX.4.29=6635=A34=149=ISLD52=00000000-00:00:00.00056=TW369=198=0108=210=0
|
||||||
|
|
||||||
|
I8=FIX.4.235=134=249=TW52=<TIME>56=ISLD369=1112=HELLO
|
||||||
|
E8=FIX.4.29=6535=034=249=ISLD52=00000000-00:00:00.00056=TW369=2112=HELLO10=0
|
||||||
|
|
||||||
|
I8=FIX.4.235=034=349=TW52=<TIME>56=ISLD369=2
|
||||||
|
|
||||||
|
I8=FIX.4.235=034=449=TW52=<TIME>56=ISLD369=2
|
||||||
|
|
||||||
|
E8=FIX.4.29=5535=034=349=ISLD52=00000000-00:00:00.00056=TW369=410=0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# logout message and response
|
||||||
|
I8=FIX.4.235=534=549=TW52=<TIME>56=ISLD369=3
|
||||||
|
E8=FIX.4.29=5535=534=449=ISLD52=00000000-00:00:00.00056=TW369=510=0
|
||||||
|
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
iCONNECT
|
||||||
|
|
||||||
|
I8=FIX.4.335=A34=149=TW52=<TIME>56=ISLD369=098=0108=2
|
||||||
|
E8=FIX.4.39=6635=A34=149=ISLD52=00000000-00:00:00.00056=TW369=198=0108=210=0
|
||||||
|
|
||||||
|
I8=FIX.4.335=134=249=TW52=<TIME>56=ISLD369=1112=HELLO
|
||||||
|
E8=FIX.4.39=6535=034=249=ISLD52=00000000-00:00:00.00056=TW369=2112=HELLO10=0
|
||||||
|
|
||||||
|
I8=FIX.4.335=034=349=TW52=<TIME>56=ISLD369=2
|
||||||
|
|
||||||
|
I8=FIX.4.335=034=449=TW52=<TIME>56=ISLD369=2
|
||||||
|
|
||||||
|
E8=FIX.4.39=5535=034=349=ISLD52=00000000-00:00:00.00056=TW369=410=0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# logout message and response
|
||||||
|
I8=FIX.4.335=534=549=TW52=<TIME>56=ISLD369=3
|
||||||
|
E8=FIX.4.39=5535=534=449=ISLD52=00000000-00:00:00.00056=TW369=510=0
|
||||||
|
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
iCONNECT
|
||||||
|
|
||||||
|
I8=FIX.4.435=A34=149=TW52=<TIME>56=ISLD369=098=0108=2
|
||||||
|
E8=FIX.4.49=6635=A34=149=ISLD52=00000000-00:00:00.00056=TW369=198=0108=210=0
|
||||||
|
|
||||||
|
I8=FIX.4.435=134=249=TW52=<TIME>56=ISLD369=1112=HELLO
|
||||||
|
E8=FIX.4.49=6535=034=249=ISLD52=00000000-00:00:00.00056=TW369=2112=HELLO10=0
|
||||||
|
|
||||||
|
I8=FIX.4.435=034=349=TW52=<TIME>56=ISLD369=2
|
||||||
|
|
||||||
|
I8=FIX.4.435=034=449=TW52=<TIME>56=ISLD369=2
|
||||||
|
|
||||||
|
E8=FIX.4.49=5535=034=349=ISLD52=00000000-00:00:00.00056=TW369=410=0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# logout message and response
|
||||||
|
I8=FIX.4.435=534=549=TW52=<TIME>56=ISLD369=3
|
||||||
|
E8=FIX.4.49=5535=534=449=ISLD52=00000000-00:00:00.00056=TW369=510=0
|
||||||
|
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
iCONNECT
|
||||||
|
|
||||||
|
I8=FIXT.1.135=A34=149=TW52=<TIME>56=ISLD369=098=0108=21137=7
|
||||||
|
E8=FIXT.1.19=7335=A34=149=ISLD52=00000000-00:00:00.00056=TW369=198=0108=21137=710=0
|
||||||
|
|
||||||
|
I8=FIXT.1.135=134=249=TW52=<TIME>56=ISLD369=1112=HELLO
|
||||||
|
E8=FIXT.1.19=6535=034=249=ISLD52=00000000-00:00:00.00056=TW369=2112=HELLO10=0
|
||||||
|
|
||||||
|
I8=FIXT.1.135=034=349=TW52=<TIME>56=ISLD369=2
|
||||||
|
|
||||||
|
I8=FIXT.1.135=034=449=TW52=<TIME>56=ISLD369=2
|
||||||
|
|
||||||
|
E8=FIXT.1.19=5535=034=349=ISLD52=00000000-00:00:00.00056=TW369=410=0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# logout message and response
|
||||||
|
I8=FIXT.1.135=534=549=TW52=<TIME>56=ISLD369=3
|
||||||
|
E8=FIXT.1.19=5535=534=449=ISLD52=00000000-00:00:00.00056=TW369=510=0
|
||||||
|
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
iCONNECT
|
||||||
|
|
||||||
|
I8=FIXT.1.135=A34=149=TW52=<TIME>56=ISLD369=098=0108=21137=8
|
||||||
|
E8=FIXT.1.19=7335=A34=149=ISLD52=00000000-00:00:00.00056=TW369=198=0108=21137=810=0
|
||||||
|
|
||||||
|
I8=FIXT.1.135=134=249=TW52=<TIME>56=ISLD369=1112=HELLO
|
||||||
|
E8=FIXT.1.19=6535=034=249=ISLD52=00000000-00:00:00.00056=TW369=2112=HELLO10=0
|
||||||
|
|
||||||
|
I8=FIXT.1.135=034=349=TW52=<TIME>56=ISLD369=2
|
||||||
|
|
||||||
|
I8=FIXT.1.135=034=449=TW52=<TIME>56=ISLD369=2
|
||||||
|
|
||||||
|
E8=FIXT.1.19=5535=034=349=ISLD52=00000000-00:00:00.00056=TW369=410=0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# logout message and response
|
||||||
|
I8=FIXT.1.135=534=549=TW52=<TIME>56=ISLD369=3
|
||||||
|
E8=FIXT.1.19=5535=534=449=ISLD52=00000000-00:00:00.00056=TW369=510=0
|
||||||
|
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
iCONNECT
|
||||||
|
|
||||||
|
I8=FIXT.1.135=A34=149=TW52=<TIME>56=ISLD369=098=0108=21137=9
|
||||||
|
E8=FIXT.1.19=7335=A34=149=ISLD52=00000000-00:00:00.00056=TW369=198=0108=21137=910=0
|
||||||
|
|
||||||
|
I8=FIXT.1.135=134=249=TW52=<TIME>56=ISLD369=1112=HELLO
|
||||||
|
E8=FIXT.1.19=6535=034=249=ISLD52=00000000-00:00:00.00056=TW369=2112=HELLO10=0
|
||||||
|
|
||||||
|
I8=FIXT.1.135=034=349=TW52=<TIME>56=ISLD369=2
|
||||||
|
|
||||||
|
I8=FIXT.1.135=034=449=TW52=<TIME>56=ISLD369=2
|
||||||
|
|
||||||
|
E8=FIXT.1.19=5535=034=349=ISLD52=00000000-00:00:00.00056=TW369=410=0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# logout message and response
|
||||||
|
I8=FIXT.1.135=534=549=TW52=<TIME>56=ISLD369=3
|
||||||
|
E8=FIXT.1.19=5535=534=449=ISLD52=00000000-00:00:00.00056=TW369=510=0
|
||||||
|
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
iCONNECT
|
||||||
|
|
||||||
|
#------------------------
|
||||||
|
# logon message and response
|
||||||
|
# send logon with sequence number equals to 1
|
||||||
|
# expect for a logon response with NextExpectedMsgSeqNum field equals to 2
|
||||||
|
#------------------------
|
||||||
|
|
||||||
|
I8=FIX.4.435=A34=149=TW52=<TIME>56=ISLD98=0789=1108=2
|
||||||
|
E8=FIX.4.49=6635=A34=149=ISLD52=00000000-00:00:00.00056=TW98=0108=2789=210=0
|
||||||
|
|
||||||
|
# logout message and response
|
||||||
|
I8=FIX.4.435=534=249=TW52=<TIME>56=ISLD
|
||||||
|
E8=FIX.4.49=4935=534=249=ISLD52=00000000-00:00:00.00056=TW10=0
|
||||||
|
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
# If message NextExpectedMsgSeqNum field is too high, we must disconnect
|
||||||
|
|
||||||
|
iCONNECT
|
||||||
|
iSET_SESSION FIX.4.4:ISLD->TW NEXTSENDERSEQNUM=1
|
||||||
|
iSET_SESSION FIX.4.4:ISLD->TW NEXTTARGETSEQNUM=1
|
||||||
|
|
||||||
|
I8=FIX.4.435=A34=100049=TW52=<TIME>56=ISLD98=0789=1200108=30
|
||||||
|
|
||||||
|
E8=FIX.4.49=13535=534=149=ISLD52=00000000-00:00:00.00056=TW58=Tag 789 (NextExpectedMsgSeqNum) is higher than expected. Expected 1, Received 120010=0
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
iCONNECT
|
||||||
|
iSET_SESSION FIX.4.4:ISLD->TW NEXTSENDERSEQNUM=2000
|
||||||
|
iSET_SESSION FIX.4.4:ISLD->TW NEXTTARGETSEQNUM=1
|
||||||
|
|
||||||
|
I8=FIX.4.435=A34=149=TW52=<TIME>56=ISLD98=0789=1108=30
|
||||||
|
|
||||||
|
E8=FIX.4.49=7035=A34=200049=ISLD52=00000000-00:00:00.00056=TW98=0108=30789=210=0
|
||||||
|
E8=FIX.4.49=9435=434=143=Y49=ISLD52=<TIME>56=TW122=<TIME>36=2001123=Y
|
||||||
|
|
||||||
|
# logout message and response
|
||||||
|
I8=FIX.4.435=534=249=TW52=<TIME>56=ISLD
|
||||||
|
E8=FIX.4.49=5235=534=200149=ISLD52=00000000-00:00:00.00056=TW10=0
|
||||||
|
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
# FIX Logon using tag 141/ResetSeqNumFlag and tag 789/NextExpectedSeqMsgNum
|
||||||
|
|
||||||
|
iCONNECT
|
||||||
|
iSET_SESSION FIX.4.4:ISLD->TW NEXTSENDERSEQNUM=2000
|
||||||
|
iSET_SESSION FIX.4.4:ISLD->TW NEXTTARGETSEQNUM=2000
|
||||||
|
|
||||||
|
I8=FIX.4.435=A34=149=TW52=<TIME>56=ISLD98=0789=1141=Y108=30
|
||||||
|
E8=FIX.4.49=7335=A34=149=ISLD52=00000000-00:00:00.00056=TW98=0108=30141=Y789=210=0
|
||||||
|
|
||||||
|
# logout message and response
|
||||||
|
I8=FIX.4.435=534=249=TW52=<TIME>56=ISLD
|
||||||
|
E8=FIX.4.49=4935=534=249=ISLD52=00000000-00:00:0056=TW10=0
|
||||||
|
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
iCONNECT
|
||||||
|
|
||||||
|
#------------------------
|
||||||
|
# logon message and response
|
||||||
|
# send logon with sequence number equals to 1
|
||||||
|
# expect for a logon response with NextExpectedMsgSeqNum field equals to 2
|
||||||
|
#------------------------
|
||||||
|
|
||||||
|
I8=FIXT.1.135=A34=149=TW52=<TIME>56=ISLD98=0789=11137=7108=2
|
||||||
|
E8=FIXT.1.19=7335=A34=149=ISLD52=00000000-00:00:00.00056=TW98=0108=2789=21137=710=0
|
||||||
|
|
||||||
|
# logout message and response
|
||||||
|
I8=FIXT.1.135=534=249=TW52=<TIME>56=ISLD
|
||||||
|
E8=FIXT.1.19=4935=534=249=ISLD52=00000000-00:00:00.00056=TW10=0
|
||||||
|
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
# If message NextExpectedMsgSeqNum field is too high, we must disconnect
|
||||||
|
|
||||||
|
iCONNECT
|
||||||
|
iSET_SESSION FIXT.1.1:ISLD->TW NEXTSENDERSEQNUM=1
|
||||||
|
iSET_SESSION FIXT.1.1:ISLD->TW NEXTTARGETSEQNUM=1
|
||||||
|
I8=FIXT.1.135=A34=100049=TW52=<TIME>56=ISLD98=0789=12001137=7108=30
|
||||||
|
|
||||||
|
E8=FIXT.1.19=13535=534=149=ISLD52=00000000-00:00:00.00056=TW58=Tag 789 (NextExpectedMsgSeqNum) is higher than expected. Expected 1, Received 120010=0
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
iCONNECT
|
||||||
|
iSET_SESSION FIXT.1.1:ISLD->TW NEXTSENDERSEQNUM=2000
|
||||||
|
iSET_SESSION FIXT.1.1:ISLD->TW NEXTTARGETSEQNUM=1
|
||||||
|
|
||||||
|
I8=FIXT.1.135=A34=149=TW52=<TIME>56=ISLD98=0789=11137=7108=30
|
||||||
|
|
||||||
|
E8=FIXT.1.19=7735=A34=200049=ISLD52=00000000-00:00:00.00056=TW98=0108=30789=21137=710=0
|
||||||
|
E8=FIXT.1.19=9435=434=143=Y49=ISLD52=<TIME>56=TW122=<TIME>36=2001123=Y
|
||||||
|
|
||||||
|
# logout message and response
|
||||||
|
I8=FIXT.1.135=534=249=TW52=<TIME>56=ISLD
|
||||||
|
E8=FIXT.1.19=5235=534=200149=ISLD52=00000000-00:00:00.00056=TW10=0
|
||||||
|
|
||||||
|
eDISCONNECT
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
# FIX Logon using tag 141/ResetSeqNumFlag and tag 789/NextExpectedSeqMsgNum
|
||||||
|
|
||||||
|
iCONNECT
|
||||||
|
iSET_SESSION FIXT.1.1:ISLD->TW NEXTSENDERSEQNUM=2000
|
||||||
|
iSET_SESSION FIXT.1.1:ISLD->TW NEXTTARGETSEQNUM=2000
|
||||||
|
|
||||||
|
I8=FIXT.1.135=A34=149=TW52=<TIME>56=ISLD98=0789=1141=Y1137=7108=30
|
||||||
|
E8=FIXT.1.19=8035=A34=149=ISLD52=00000000-00:00:00.00056=TW98=0108=30141=Y789=21137=710=0
|
||||||
|
|
||||||
|
# logout message and response
|
||||||
|
I8=FIXT.1.135=534=249=TW52=<TIME>56=ISLD
|
||||||
|
E8=FIXT.1.19=4935=534=249=ISLD52=00000000-00:00:00.00056=TW10=0
|
||||||
|
|
||||||
|
eDISCONNECT
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user