Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/expose full url on fail #37

Open
wants to merge 40 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
7a76a4a
feat(pvo-344): make pipes sync. add nodeID. fixture on odds change
g-mugnaini-pvotal Aug 5, 2023
c1c5107
feat(pvo-344): remove idea. gitignore
g-mugnaini-pvotal Aug 5, 2023
ce6706b
feat(pvo-344): remove idea. gitignore
g-mugnaini-pvotal Aug 5, 2023
3e510c1
feat(pvo-344): change imports and go.mod
g-mugnaini-pvotal Aug 5, 2023
86ae3e3
Merge pull request #1 from pvotal-tech/feature/sync-pipes_node-id_fix…
g-mugnaini-pvotal Aug 7, 2023
be7952c
feat(PVO-311): add specifier parsing
c-ganga-pvotal Aug 7, 2023
124b8ec
chore: rename files
c-ganga-pvotal Aug 7, 2023
f95f32f
chore: remove comment
c-ganga-pvotal Aug 7, 2023
11961c8
Merge pull request #2 from pvotal-tech/feat/PVO-311
c-ganga-pvotal Aug 7, 2023
3447877
fix(PVO-311): handle floats in specifiers
c-ganga-pvotal Aug 7, 2023
992ca8b
Merge pull request #3 from pvotal-tech/feat/PVO-311
g-mugnaini-pvotal Aug 7, 2023
1768883
feat(PVO-311): fix competitor parsing
c-ganga-pvotal Aug 8, 2023
087e3e1
chore: fix typo
c-ganga-pvotal Aug 8, 2023
57a3648
Merge pull request #4 from pvotal-tech/feat/PVO-311
g-mugnaini-pvotal Aug 8, 2023
248c333
feat(pvo-344): market player pipes sync
g-mugnaini-pvotal Aug 8, 2023
01da12c
Merge pull request #5 from pvotal-tech/feature/market-player-sync
g-mugnaini-pvotal Aug 8, 2023
f0d474f
fix: remove prefix player urn specifier
g-mugnaini-pvotal Aug 8, 2023
d46dce3
Merge pull request #6 from pvotal-tech/fix/remove-prefix-player-urn-s…
g-mugnaini-pvotal Aug 8, 2023
bedebb1
fix: add market 368 case
g-mugnaini-pvotal Aug 8, 2023
ee54938
Merge pull request #7 from pvotal-tech/fix/market-edge-case
g-mugnaini-pvotal Aug 8, 2023
21be386
feat: custom server config
g-mugnaini-pvotal Aug 9, 2023
7ff66a9
Merge pull request #8 from pvotal-tech/feature/custom-server-config
g-mugnaini-pvotal Aug 9, 2023
793763c
feat(pvo-399): tls select amqp
g-mugnaini-pvotal Aug 9, 2023
9689977
Merge pull request #9 from pvotal-tech/feat/tls-select-amqp
g-mugnaini-pvotal Aug 10, 2023
a65b6f6
fix(PVO-66): Skip TLS verify for betradar http client
m-guesnon-pvotal Aug 11, 2023
44ead68
feat(pvo-66): upgrade amqp lib
g-mugnaini-pvotal Aug 17, 2023
a7a8975
Merge pull request #10 from pvotal-tech/feat/upgrade-amqp-lib
g-mugnaini-pvotal Aug 17, 2023
7536134
feat(pvo-604): add event recovery endpoints
g-mugnaini-pvotal Sep 14, 2023
095e305
feat(pvo-604): improved concurrency
g-mugnaini-pvotal Sep 14, 2023
460a68e
feat(pvo-604): improved concurrency
g-mugnaini-pvotal Sep 19, 2023
9dd984a
feat(pvo-604): improved concurrency
g-mugnaini-pvotal Sep 19, 2023
c7960f0
feat(pvo-604): improved concurrency
g-mugnaini-pvotal Sep 19, 2023
ad9abe1
Merge pull request #14 from pvotal-tech/feat/event-recovery
g-mugnaini-pvotal Sep 19, 2023
5f013a2
feat(pvo-476): new fields. type changes
g-mugnaini-pvotal Sep 20, 2023
b1e1d4c
Merge pull request #15 from pvotal-tech/feat/new-fields-mts
g-mugnaini-pvotal Sep 21, 2023
416a5ec
feat(pvo-927): player pipe concurrency flag
g-mugnaini-pvotal Sep 27, 2023
ef4a678
Merge pull request #16 from pvotal-tech/feat/player-fetch-concurrency
g-mugnaini-pvotal Sep 29, 2023
7889eb7
fix(pvo-1177): reduce liveoods recovery window
g-mugnaini-pvotal Oct 17, 2023
5561572
Merge pull request #17 from pvotal-tech/fix/liveodds-recovery-window
g-mugnaini-pvotal Oct 17, 2023
2248f4a
fix(pvo-1225): print full addr on dial error
g-mugnaini-pvotal Oct 20, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
coverage.html

.vscode

.idea

2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
language: go
go_import_path: github.com/minus5/go-uof-sdk
go_import_path: github.com/pvotal-tech/go-uof-sdk
os:
- linux
- osx
Expand Down
61 changes: 39 additions & 22 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ package api
import (
"bytes"
"context"
"crypto/tls"
"encoding/xml"
"fmt"
"io/ioutil"
"net/http"
"text/template"
"time"

"github.com/hashicorp/go-retryablehttp"
"github.com/minus5/go-uof-sdk"
"github.com/pvotal-tech/go-uof-sdk"
)

const (
Expand Down Expand Up @@ -78,8 +80,23 @@ func ProductionGlobal(exitSig context.Context, token string) (*API, error) {
return a, a.Ping()
}

// DialCustom connects to a custom system
func DialCustom(exitSig context.Context, customServer, token string) (*API, error) {
a := &API{
server: customServer,
token: token,
exitSig: exitSig,
client: client(),
}
return a, a.Ping()
}

func client() *retryablehttp.Client {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
c := retryablehttp.NewClient()
c.HTTPClient.Transport = tr
c.Logger = nil
c.RetryWaitMin = 1 * time.Second
c.RetryWaitMax = 16 * time.Second
Expand All @@ -88,42 +105,41 @@ func client() *retryablehttp.Client {
}

const (
recovery = "/v1/{{.Producer}}/recovery/initiate_request?after={{.Timestamp}}&request_id={{.RequestID}}"
fullRecovery = "/v1/{{.Producer}}/recovery/initiate_request?request_id={{.RequestID}}"
ping = "/v1/users/whoami.xml"
recovery = "/v1/{{.Producer}}/recovery/initiate_request?after={{.Timestamp}}&request_id={{.RequestID}}&node_id={{.NodeID}}"
fullRecovery = "/v1/{{.Producer}}/recovery/initiate_request?request_id={{.RequestID}}&node_id={{.NodeID}}"
sportEventRecovery = "/v1/{{.Producer}}/odds/events/{{.EventURN}}/initiate_request?request_id={{.RequestID}}&node_id={{.NodeID}}"
sportEventStatefulRecovery = "/v1/{{.Producer}}/stateful_messages/events/{{.EventURN}}/initiate_request?request_id={{.RequestID}}&node_id={{.NodeID}}"
ping = "/v1/users/whoami.xml"
)

func (a *API) RequestRecovery(producer uof.Producer, timestamp int, requestID int) error {
func (a *API) RequestRecovery(producer uof.Producer, timestamp, requestID, nodeID int) error {
if timestamp <= 0 {
return a.RequestFullOddsRecovery(producer, requestID)
return a.RequestFullOddsRecovery(producer, requestID, nodeID)
}
return a.RequestRecoverySinceTimestamp(producer, timestamp, requestID)
return a.RequestRecoverySinceTimestamp(producer, timestamp, requestID, nodeID)
}

// RequestRecoverySinceTimestamp does recovery of odds and stateful messages
// over the feed since after timestamp. Subscribes client to feed messages.
func (a *API) RequestRecoverySinceTimestamp(producer uof.Producer, timestamp int, requestID int) error {
return a.post(recovery, &params{Producer: producer, Timestamp: timestamp, RequestID: requestID})
func (a *API) RequestRecoverySinceTimestamp(producer uof.Producer, timestamp, requestID, nodeID int) error {
return a.post(recovery, &params{Producer: producer, Timestamp: timestamp, RequestID: requestID, NodeID: nodeID})
}

// RequestFullOddsRecovery does recovery of odds over the feed. Subscribes
// client to feed messages.
func (a *API) RequestFullOddsRecovery(producer uof.Producer, requestID int) error {
return a.post(fullRecovery, &params{Producer: producer, RequestID: requestID})
func (a *API) RequestFullOddsRecovery(producer uof.Producer, requestID, nodeID int) error {
return a.post(fullRecovery, &params{Producer: producer, RequestID: requestID, NodeID: nodeID})
}

// // RecoverSportEvent requests to resend all odds for all markets for a sport
// // event.
// func (a *Api) RecoverSportEvent(product, eventID string) error {
// return a.post(fmt.Sprintf("/v1/%s/events/%s/initiate_request", product, eventID))
// }
// RecoverSportEvent requests to resend all odds for all markets for a sport event.
func (a *API) RecoverSportEvent(producer uof.Producer, eventURN uof.URN, requestID, nodeID int) error {
return a.post(sportEventRecovery, &params{Producer: producer, EventURN: eventURN, RequestID: requestID, NodeID: nodeID})
}

// // RecoverStatefulForSportEvent requests to resend all stateful-messages
// // (BetSettlement, RollbackBetSettlement, BetCancel, UndoBetCancel) for a sport
// // event.
// func (a *Api) RecoverStatefulForSportEvent(product, eventID string) error {
// return a.post(fmt.Sprintf("/v1/%s/stateful_messages/events/%s/initiate_request", product, eventID))
// }
// RecoverStatefulForSportEvent requests to resend all stateful-messages (BetSettlement, RollbackBetSettlement, BetCancel, UndoBetCancel) for a sport event.
func (a *API) RecoverStatefulForSportEvent(producer uof.Producer, eventURN uof.URN, requestID, nodeID int) error {
return a.post(sportEventStatefulRecovery, &params{Producer: producer, EventURN: eventURN, RequestID: requestID, NodeID: nodeID})
}

func (a *API) Ping() error {
_, err := a.get(ping, nil)
Expand Down Expand Up @@ -207,6 +223,7 @@ type params struct {
UseReplayTimestamp bool
Lang uof.Lang
Producer uof.Producer
NodeID int
}

func runTemplate(def string, p *params) string {
Expand Down
2 changes: 1 addition & 1 deletion api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"testing"
"time"

"github.com/minus5/go-uof-sdk"
"github.com/pvotal-tech/go-uof-sdk"
"github.com/stretchr/testify/assert"
)

Expand Down
2 changes: 1 addition & 1 deletion api/replay.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package api
import (
"context"

"github.com/minus5/go-uof-sdk"
"github.com/pvotal-tech/go-uof-sdk"
)

// replay api paths
Expand Down
2 changes: 1 addition & 1 deletion api/sports.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"encoding/xml"
"time"

"github.com/minus5/go-uof-sdk"
"github.com/pvotal-tech/go-uof-sdk"
)

const (
Expand Down
24 changes: 14 additions & 10 deletions bet_settlement.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ type BetSettlement struct {
}

type BetSettlementMarket struct {
ID int `xml:"id,attr" json:"id"`
LineID int `json:"lineID"`
Specifiers map[string]string `json:"specifiers,omitempty"`
ID int `xml:"id,attr" json:"id"`
LineID int `json:"lineID"`
Specifiers map[string]string `json:"specifiers,omitempty"`
AllSpecifiers string `json:"allSpecifiers,omitempty"`
// Describes the reason for voiding certain outcomes for a particular market.
// Only set if at least one of the outcomes have a void_factor. A list of void
// reasons can be found above this table or by using the API at
Expand Down Expand Up @@ -81,7 +82,8 @@ func (t *BetSettlementMarket) UnmarshalXML(d *xml.Decoder, start xml.StartElemen
if err := d.DecodeElement(&overlay, &start); err != nil {
return err
}
t.Specifiers = toSpecifiers(overlay.Specifiers, overlay.ExtendedSpecifiers)
t.AllSpecifiers = getAllSpecifiers(overlay.Specifiers, overlay.ExtendedSpecifiers)
t.Specifiers = toSpecifiers(t.AllSpecifiers)
t.LineID = toLineID(overlay.Specifiers)
return nil
}
Expand All @@ -108,12 +110,14 @@ func (t *BetSettlementOutcome) UnmarshalXML(d *xml.Decoder, start xml.StartEleme
return nil
}

//The following list includes all possible combinations of outcome (result) and void_factor:
// result="0" and no void_factor: Lose entire bet
// result="1" and no void_factor: Win entire bet
// result="0" and void_factor="1": Refund entire bet
// result="1" and void_factor="0.5": Refund half bet and win other half
// result="0" and void_factor="0.5": Refund half bet and lose other half.
// The following list includes all possible combinations of outcome (result) and void_factor:
//
// result="0" and no void_factor: Lose entire bet
// result="1" and no void_factor: Win entire bet
// result="0" and void_factor="1": Refund entire bet
// result="1" and void_factor="0.5": Refund half bet and win other half
// result="0" and void_factor="0.5": Refund half bet and lose other half.
//
// If the bet on an outcome should be refunded completely void-factor is set to
// 1.0. If half of the bet on an outcome should be refunded void_factor is set
// to 0.5.
Expand Down
73 changes: 49 additions & 24 deletions cmd/client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/pvotal-tech/go-uof-sdk"
"github.com/pvotal-tech/go-uof-sdk/sdk"
"log"
"net/http"
_ "net/http/pprof"
"os"
"os/signal"
"syscall"
"time"

"github.com/minus5/go-uof-sdk"
"github.com/minus5/go-uof-sdk/pipe"
"github.com/minus5/go-uof-sdk/sdk"
)

const (
Expand All @@ -32,16 +30,6 @@ func env(name string) string {
return e
}

var (
bookmakerID string
token string
)

func init() {
token = env(EnvToken)
bookmakerID = env(EnvBookmakerID)
}

func debugHTTP() {
if err := http.ListenAndServe("localhost:8124", nil); err != nil {
log.Fatal(err)
Expand All @@ -61,24 +49,30 @@ func exitSignal() context.Context {
}

func main() {
go func() {
_ = http.ListenAndServe(fmt.Sprintf(":%d", 6060), nil)
}()
go debugHTTP()

preloadTo := time.Now().Add(24 * time.Hour)
//preloadTo := time.Now().Add(24 * time.Hour)

timestamp := uof.CurrentTimestamp() - 5*60*1000 // -5 minutes
timestamp := uof.CurrentTimestamp() - 12*60*60*1000 // -5 minutes
var pc uof.ProducersChange
pc.Add(uof.ProducerPrematch, timestamp)
pc.Add(uof.ProducerLiveOdds, timestamp)
pc.Add(uof.ProducerBetPal, timestamp)
pc.Add(uof.ProducerPremiumCricket, timestamp)

err := sdk.Run(exitSignal(),
sdk.Credentials(bookmakerID, token),
sdk.Credentials(123456, "token_goes_here", 123),
sdk.Staging(),
sdk.Recovery(pc),
sdk.Fixtures(preloadTo),
sdk.Languages(uof.Languages("en,de,hr")),
sdk.BufferedConsumer(pipe.FileStore("./tmp"), 1024),
sdk.ConfigThrottle(true),
//sdk.Fixtures(preloadTo),
sdk.Languages(uof.Languages("en")),
//sdk.BufferedConsumer(pipe.FileStore("./tmp"), 1024),
sdk.Consumer(logMessages),
sdk.ListenErrors(listenSDKErrors),
//sdk.ListenErrors(listenSDKErrors),
)
if err != nil {
log.Fatal(err)
Expand All @@ -88,12 +82,32 @@ func main() {
// consumer of incoming messages
func logMessages(in <-chan *uof.Message) error {
for m := range in {
logMessage(m)
processMessage(m)
}
return nil
}

func logMessage(m *uof.Message) {
func processMessage(m *uof.Message) {
var pendingCount, p, requestID, sport string
if m.External {
pendingCount = fmt.Sprintf("pending=%d", m.PendingMsgCount)
p = fmt.Sprintf("producer=%s", m.Producer.Code())
if m.Type == uof.MessageTypeBetSettlement {
if m.BetSettlement.RequestID != nil {
requestID = fmt.Sprintf("requestID=%d", *m.BetSettlement.RequestID)
}
sport = fmt.Sprintf("sportID=%d", m.SportID)
}
if m.Type == uof.MessageTypeOddsChange {
if m.OddsChange.RequestID != nil {
requestID = fmt.Sprintf("requestID=%d", *m.OddsChange.RequestID)
}
sport = fmt.Sprintf("sportID=%d", m.SportID)
}
}
fmt.Printf("%-60s %-20s %-20s %-20s %-20s %-20s\n", time.Now().String(), m.Type, pendingCount, p, requestID, sport)
time.Sleep(time.Millisecond * 200)
return
switch m.Type {
case uof.MessageTypeConnection:
fmt.Printf("%-25s status: %s, server: %s, local: %s, network: %s, tls: %s\n", m.Type, m.Connection.Status, m.Connection.ServerName, m.Connection.LocalAddr, m.Connection.Network, m.Connection.TLSVersionToString())
Expand All @@ -105,8 +119,19 @@ func logMessage(m *uof.Message) {
if m.Alive.Subscribed != 0 {
fmt.Printf("%-25s producer: %s, timestamp: %d\n", m.Type, m.Alive.Producer, m.Alive.Timestamp)
}
case uof.MessageTypeBetSettlement:
for _, v := range m.BetSettlement.Markets {
fmt.Printf("BET SETTLEMENT producer=%v eventID=%d marketID=%v status=%v\n", m.Producer, m.BetSettlement.EventURN.ID(), v.ID, v.Result)
}
case uof.MessageTypeBetStop:
for _, v := range m.BetStop.MarketIDs {
fmt.Printf("BET STOP producer=%v eventID=%d marketID=%v status=%v\n", m.Producer, m.BetStop.EventURN.ID(), v, m.BetStop.Status)
}
case uof.MessageTypeOddsChange:
fmt.Printf("%-25s event: %s, markets: %d\n", m.Type, m.EventURN, len(m.OddsChange.Markets))
fmt.Printf("ODDS CHANGE producer=%v eventID=%d eventStatus=%v\n", m.Producer, m.OddsChange.EventURN.ID(), m.OddsChange.EventStatus)
for _, v := range m.OddsChange.Markets {
fmt.Printf("ODDS CHANGE producer=%v eventID=%d marketID=%v status=%v\n", m.Producer, m.OddsChange.EventURN.ID(), v.ID, v.Status)
}
default:
var b []byte
if false && m.Raw != nil {
Expand Down
20 changes: 6 additions & 14 deletions cmd/replay/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,10 @@ import (
"net/http"
_ "net/http/pprof"

"github.com/minus5/go-uof-sdk"
"github.com/minus5/go-uof-sdk/api"
"github.com/minus5/go-uof-sdk/pipe"
"github.com/minus5/go-uof-sdk/sdk"
)

const (
EnvBookmakerID = "UOF_BOOKMAKER_ID"
EnvToken = "UOF_TOKEN"
"github.com/pvotal-tech/go-uof-sdk"
"github.com/pvotal-tech/go-uof-sdk/api"
"github.com/pvotal-tech/go-uof-sdk/pipe"
"github.com/pvotal-tech/go-uof-sdk/sdk"
)

func env(name string) string {
Expand All @@ -32,7 +27,7 @@ func env(name string) string {
}

var (
bookmakerID string
bookmakerID int
token string
scenarioID int
eventURN uof.URN
Expand All @@ -56,9 +51,6 @@ func init() {
log.Printf("no event or scenario found, will replay sample event %s", event)
}
eventURN.Parse(event)

token = env(EnvToken)
bookmakerID = env(EnvBookmakerID)
}

func debugHTTP() {
Expand All @@ -84,7 +76,7 @@ func main() {
go debugHTTP()

err := sdk.Run(exitSignal(),
sdk.Credentials(bookmakerID, token),
sdk.Credentials(bookmakerID, token, 123),
sdk.Languages(uof.Languages("en,de,hr")),
sdk.BufferedConsumer(pipe.FileStore(outputFolder), 1024),
sdk.Callback(progress),
Expand Down
Loading