Skip to content

Commit e6c8a89

Browse files
authored
Merge pull request #39 from moov-io/intro-request-id-generator
add RequestIDGenerator interface to allow custom implementations
2 parents fe9f74e + 96a20ae commit e6c8a89

File tree

3 files changed

+57
-28
lines changed

3 files changed

+57
-28
lines changed

connection.go

+2-22
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ func (c *Connection) Send(message *iso8583.Message) (*iso8583.Message, error) {
348348
}
349349

350350
// prepare request
351-
reqID, err := requestID(message)
351+
reqID, err := c.Opts.RequestIDGenerator.GenerateRequestID(message)
352352
if err != nil {
353353
return nil, fmt.Errorf("creating request ID: %w", err)
354354
}
@@ -451,26 +451,6 @@ func (c *Connection) Reply(message *iso8583.Message) error {
451451
return err
452452
}
453453

454-
// requestID is a unique identifier for a request. responses from the server
455-
// are not guaranteed to return in order so we must have an id to reference the
456-
// original req. built from stan and datetime
457-
func requestID(message *iso8583.Message) (string, error) {
458-
if message == nil {
459-
return "", fmt.Errorf("message required")
460-
}
461-
462-
stan, err := message.GetString(11)
463-
if err != nil {
464-
return "", fmt.Errorf("getting STAN (field 11) of the message: %w", err)
465-
}
466-
467-
if stan == "" {
468-
return "", errors.New("STAN is missing")
469-
}
470-
471-
return stan, nil
472-
}
473-
474454
const (
475455
// position of the MTI specifies the message function which
476456
// defines how the message should flow within the system.
@@ -620,7 +600,7 @@ func (c *Connection) handleResponse(rawMessage []byte) {
620600
}
621601

622602
if isResponse(message) {
623-
reqID, err := requestID(message)
603+
reqID, err := c.Opts.RequestIDGenerator.GenerateRequestID(message)
624604
if err != nil {
625605
c.handleError(fmt.Errorf("creating request ID: %w", err))
626606
return

options.go

+19-6
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,23 @@ type Options struct {
6060

6161
// OnClose is called synchronously before a connection is closed
6262
OnClose func(c *Connection) error
63+
64+
// RequestIDGenerator is used to generate a unique identifier for a request
65+
// so that responses from the server can be matched to the original request.
66+
RequestIDGenerator RequestIDGenerator
6367
}
6468

6569
type Option func(*Options) error
6670

6771
func GetDefaultOptions() Options {
6872
return Options{
69-
ConnectTimeout: 10 * time.Second,
70-
SendTimeout: 30 * time.Second,
71-
IdleTime: 5 * time.Second,
72-
ReadTimeout: 60 * time.Second,
73-
PingHandler: nil,
74-
TLSConfig: nil,
73+
ConnectTimeout: 10 * time.Second,
74+
SendTimeout: 30 * time.Second,
75+
IdleTime: 5 * time.Second,
76+
ReadTimeout: 60 * time.Second,
77+
PingHandler: nil,
78+
TLSConfig: nil,
79+
RequestIDGenerator: &defaultRequestIDGenerator{},
7580
}
7681
}
7782

@@ -231,3 +236,11 @@ func SetTLSConfig(cfg func(*tls.Config)) Option {
231236
return nil
232237
}
233238
}
239+
240+
// RequestIDGenerator sets a RequestIDGenerator option
241+
func SetRequestIDGenerator(g RequestIDGenerator) Option {
242+
return func(o *Options) error {
243+
o.RequestIDGenerator = g
244+
return nil
245+
}
246+
}

request_id_generator.go

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package connection
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
7+
"github.com/moov-io/iso8583"
8+
)
9+
10+
// RequestIDGenerator is an interface that generates a unique identifier for a
11+
// request so that responses from the server can be matched to the original
12+
// request.
13+
type RequestIDGenerator interface {
14+
GenerateRequestID(msg *iso8583.Message) (string, error)
15+
}
16+
17+
// defaultRequestIDGenerator is the default implementation of RequestIDGenerator
18+
// that uses the STAN (field 11) of the message as the request ID.
19+
type defaultRequestIDGenerator struct{}
20+
21+
func (d *defaultRequestIDGenerator) GenerateRequestID(message *iso8583.Message) (string, error) {
22+
if message == nil {
23+
return "", fmt.Errorf("message required")
24+
}
25+
26+
stan, err := message.GetString(11)
27+
if err != nil {
28+
return "", fmt.Errorf("getting STAN (field 11) of the message: %w", err)
29+
}
30+
31+
if stan == "" {
32+
return "", errors.New("STAN is missing")
33+
}
34+
35+
return stan, nil
36+
}

0 commit comments

Comments
 (0)