From ff454b2700d621438020b511aba62585c5609a20 Mon Sep 17 00:00:00 2001 From: Kristi Burnette Date: Fri, 23 Feb 2024 12:42:40 -0700 Subject: [PATCH 1/8] Enable fedach and fedwire download from proxy --- cmd/server/reader.go | 24 ++++++------- pkg/download/download.go | 20 ++++++++--- pkg/download/download_test.go | 67 +++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 18 deletions(-) diff --git a/cmd/server/reader.go b/cmd/server/reader.go index b2997beb..a7f841dd 100644 --- a/cmd/server/reader.go +++ b/cmd/server/reader.go @@ -51,20 +51,18 @@ func fedWireDataFile(logger log.Logger) (io.Reader, error) { func attemptFileDownload(logger log.Logger, listName string) (io.Reader, error) { routingNumber := os.Getenv("FRB_ROUTING_NUMBER") downloadCode := os.Getenv("FRB_DOWNLOAD_CODE") - - if routingNumber != "" && downloadCode != "" { - logger.Logf("download: attempting %s", listName) - client, err := download.NewClient(&download.ClientOpts{ - RoutingNumber: routingNumber, - DownloadCode: downloadCode, - }) - if err != nil { - return nil, fmt.Errorf("client setup: %v", err) - } - return client.GetList(listName) + downloadURL := os.Getenv("CUSTOM_DOWNLOAD_URL") + + logger.Logf("download: attempting %s", listName) + client, err := download.NewClient(&download.ClientOpts{ + RoutingNumber: routingNumber, + DownloadCode: downloadCode, + DownloadURL: downloadURL, + }) + if err != nil { + return nil, fmt.Errorf("client setup: %v", err) } - - return nil, nil + return client.GetList(listName) } func readDataFilepath(env, fallback string) string { diff --git a/pkg/download/download.go b/pkg/download/download.go index f0876e11..6b7b06ae 100644 --- a/pkg/download/download.go +++ b/pkg/download/download.go @@ -19,11 +19,13 @@ type Client struct { routingNumber string // X_FRB_EPAYMENTS_DIRECTORY_ORG_ID header downloadCode string // X_FRB_EPAYMENTS_DIRECTORY_DOWNLOAD_CD + downloadURL string // defaults to "https://frbservices.org/EPaymentsDirectory/directories/%s?format=json" where %s is the list name + } type ClientOpts struct { - HTTPClient *http.Client - RoutingNumber, DownloadCode string + HTTPClient *http.Client + RoutingNumber, DownloadCode, DownloadURL string } func NewClient(opts *ClientOpts) (*Client, error) { @@ -45,17 +47,22 @@ func NewClient(opts *ClientOpts) (*Client, error) { return nil, errors.New("missing download code") } + if opts.DownloadURL == "" { + opts.DownloadURL = "https://frbservices.org/EPaymentsDirectory/directories/%s?format=json" + } + return &Client{ httpClient: opts.HTTPClient, routingNumber: opts.RoutingNumber, downloadCode: opts.DownloadCode, + downloadURL: opts.DownloadURL, }, nil } // GetList downloads an FRB list and saves it into an io.Reader. // Example listName values: fedach, fedwire func (c *Client) GetList(listName string) (io.Reader, error) { - where, err := url.Parse(fmt.Sprintf("https://frbservices.org/EPaymentsDirectory/directories/%s?format=json", listName)) + where, err := url.Parse(fmt.Sprintf(c.downloadURL, listName)) if err != nil { return nil, fmt.Errorf("url: %v", err) } @@ -64,8 +71,11 @@ func (c *Client) GetList(listName string) (io.Reader, error) { if err != nil { return nil, fmt.Errorf("building %s url: %v", listName, err) } - req.Header.Set("X_FRB_EPAYMENTS_DIRECTORY_ORG_ID", c.routingNumber) - req.Header.Set("X_FRB_EPAYMENTS_DIRECTORY_DOWNLOAD_CD", c.downloadCode) + + if c.downloadCode != "" && c.routingNumber != "" { + req.Header.Set("X_FRB_EPAYMENTS_DIRECTORY_ORG_ID", c.routingNumber) + req.Header.Set("X_FRB_EPAYMENTS_DIRECTORY_DOWNLOAD_CD", c.downloadCode) + } // perform our request resp, err := c.httpClient.Do(req) diff --git a/pkg/download/download_test.go b/pkg/download/download_test.go index 1709591d..7acddd67 100644 --- a/pkg/download/download_test.go +++ b/pkg/download/download_test.go @@ -6,7 +6,10 @@ package download import ( "bytes" + "fmt" "io" + "net/http" + "net/http/httptest" "os" "testing" @@ -34,6 +37,38 @@ func TestClient__fedach(t *testing.T) { } } +func TestClient__fedach_custom_url(t *testing.T) { + byteArray := make([]byte, 1024) + mockHTTPServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + fmt.Fprint(writer, string(byteArray)) + })) + defer mockHTTPServer.Close() + + err := os.Setenv("CUSTOM_DOWNLOAD_URL", mockHTTPServer.URL+"/%s") + err = os.Setenv("FRB_ROUTING_NUMBER", "123456789") + err = os.Setenv("FRB_DOWNLOAD_CODE", "a1b2c3d4-123b-9876-1234-z1x2y3a1b2c3") + require.NoError(t, err) + + client := setupClient(t) + + fedach, err := client.GetList("fedach") + if err != nil { + t.Fatal(err) + } + + buf, ok := fedach.(*bytes.Buffer) + require.True(t, ok) + + if n := buf.Len(); n < 1024 { + t.Errorf("unexpected size of %d bytes", n) + } + + bs, _ := io.ReadAll(io.LimitReader(fedach, 10024)) + if !bytes.Equal(bs, byteArray) { + t.Errorf("unexpected output:\n%s \n%s", string(bs), byteArray) + } +} + func TestClient__fedwire(t *testing.T) { client := setupClient(t) @@ -55,6 +90,38 @@ func TestClient__fedwire(t *testing.T) { } } +func TestClient__wire_custom_url(t *testing.T) { + byteArray := make([]byte, 1024) + mockHTTPServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + fmt.Fprint(writer, string(byteArray)) + })) + defer mockHTTPServer.Close() + + err := os.Setenv("CUSTOM_DOWNLOAD_URL", mockHTTPServer.URL+"/%s") + err = os.Setenv("FRB_ROUTING_NUMBER", "123456789") + err = os.Setenv("FRB_DOWNLOAD_CODE", "a1b2c3d4-123b-9876-1234-z1x2y3a1b2c3") + require.NoError(t, err) + + client := setupClient(t) + + fedach, err := client.GetList("fedwire") + if err != nil { + t.Fatal(err) + } + + buf, ok := fedach.(*bytes.Buffer) + require.True(t, ok) + + if n := buf.Len(); n < 1024 { + t.Errorf("unexpected size of %d bytes", n) + } + + bs, _ := io.ReadAll(io.LimitReader(fedach, 10024)) + if !bytes.Equal(bs, byteArray) { + t.Errorf("unexpected output:\n%s", string(bs)) + } +} + func setupClient(t *testing.T) *Client { t.Helper() From 26dc914a54160575c9e6c5f96cdf41f2cf2179cc Mon Sep 17 00:00:00 2001 From: Kristi Burnette Date: Fri, 23 Feb 2024 13:09:20 -0700 Subject: [PATCH 2/8] fix: rename environment variable --- cmd/server/reader.go | 2 +- pkg/download/download_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/server/reader.go b/cmd/server/reader.go index a7f841dd..549f9df5 100644 --- a/cmd/server/reader.go +++ b/cmd/server/reader.go @@ -51,7 +51,7 @@ func fedWireDataFile(logger log.Logger) (io.Reader, error) { func attemptFileDownload(logger log.Logger, listName string) (io.Reader, error) { routingNumber := os.Getenv("FRB_ROUTING_NUMBER") downloadCode := os.Getenv("FRB_DOWNLOAD_CODE") - downloadURL := os.Getenv("CUSTOM_DOWNLOAD_URL") + downloadURL := os.Getenv("FRB_DOWNLOAD_URL_TEMPLATE") logger.Logf("download: attempting %s", listName) client, err := download.NewClient(&download.ClientOpts{ diff --git a/pkg/download/download_test.go b/pkg/download/download_test.go index 7acddd67..615a685c 100644 --- a/pkg/download/download_test.go +++ b/pkg/download/download_test.go @@ -44,7 +44,7 @@ func TestClient__fedach_custom_url(t *testing.T) { })) defer mockHTTPServer.Close() - err := os.Setenv("CUSTOM_DOWNLOAD_URL", mockHTTPServer.URL+"/%s") + err := os.Setenv("FRB_DOWNLOAD_URL_TEMPLATE", mockHTTPServer.URL+"/%s") err = os.Setenv("FRB_ROUTING_NUMBER", "123456789") err = os.Setenv("FRB_DOWNLOAD_CODE", "a1b2c3d4-123b-9876-1234-z1x2y3a1b2c3") require.NoError(t, err) @@ -97,7 +97,7 @@ func TestClient__wire_custom_url(t *testing.T) { })) defer mockHTTPServer.Close() - err := os.Setenv("CUSTOM_DOWNLOAD_URL", mockHTTPServer.URL+"/%s") + err := os.Setenv("FRB_DOWNLOAD_URL_TEMPLATE", mockHTTPServer.URL+"/%s") err = os.Setenv("FRB_ROUTING_NUMBER", "123456789") err = os.Setenv("FRB_DOWNLOAD_CODE", "a1b2c3d4-123b-9876-1234-z1x2y3a1b2c3") require.NoError(t, err) From b62ca83eccb36532ccf703c495eed1e054761690 Mon Sep 17 00:00:00 2001 From: Kristi Burnette Date: Fri, 23 Feb 2024 13:37:14 -0700 Subject: [PATCH 3/8] fix: stream file into test --- pkg/download/download_test.go | 38 +++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/pkg/download/download_test.go b/pkg/download/download_test.go index 615a685c..7d0c0fec 100644 --- a/pkg/download/download_test.go +++ b/pkg/download/download_test.go @@ -11,6 +11,7 @@ import ( "net/http" "net/http/httptest" "os" + "path/filepath" "testing" "github.com/stretchr/testify/require" @@ -38,16 +39,19 @@ func TestClient__fedach(t *testing.T) { } func TestClient__fedach_custom_url(t *testing.T) { - byteArray := make([]byte, 1024) + file, err := os.ReadFile(filepath.Join("..", "..", "data", "fedachdir.json")) + if err != nil { + t.Fatal(err) + } + mockHTTPServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { - fmt.Fprint(writer, string(byteArray)) + fmt.Fprint(writer, string(file)) })) defer mockHTTPServer.Close() - err := os.Setenv("FRB_DOWNLOAD_URL_TEMPLATE", mockHTTPServer.URL+"/%s") - err = os.Setenv("FRB_ROUTING_NUMBER", "123456789") - err = os.Setenv("FRB_DOWNLOAD_CODE", "a1b2c3d4-123b-9876-1234-z1x2y3a1b2c3") - require.NoError(t, err) + t.Setenv("FRB_DOWNLOAD_URL_TEMPLATE", mockHTTPServer.URL+"/%s") + t.Setenv("FRB_ROUTING_NUMBER", "123456789") + t.Setenv("FRB_DOWNLOAD_CODE", "a1b2c3d4-123b-9876-1234-z1x2y3a1b2c3") client := setupClient(t) @@ -64,8 +68,8 @@ func TestClient__fedach_custom_url(t *testing.T) { } bs, _ := io.ReadAll(io.LimitReader(fedach, 10024)) - if !bytes.Equal(bs, byteArray) { - t.Errorf("unexpected output:\n%s \n%s", string(bs), byteArray) + if !bytes.Equal(bs, file) { + t.Errorf("unexpected output:\n%s", string(bs)) } } @@ -91,16 +95,18 @@ func TestClient__fedwire(t *testing.T) { } func TestClient__wire_custom_url(t *testing.T) { - byteArray := make([]byte, 1024) + file, err := os.ReadFile(filepath.Join("..", "..", "data", "fedachdir.json")) + if err != nil { + t.Fatal(err) + } mockHTTPServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { - fmt.Fprint(writer, string(byteArray)) + fmt.Fprint(writer, string(file)) })) defer mockHTTPServer.Close() - err := os.Setenv("FRB_DOWNLOAD_URL_TEMPLATE", mockHTTPServer.URL+"/%s") - err = os.Setenv("FRB_ROUTING_NUMBER", "123456789") - err = os.Setenv("FRB_DOWNLOAD_CODE", "a1b2c3d4-123b-9876-1234-z1x2y3a1b2c3") - require.NoError(t, err) + t.Setenv("FRB_DOWNLOAD_URL_TEMPLATE", mockHTTPServer.URL+"/%s") + t.Setenv("FRB_ROUTING_NUMBER", "123456789") + t.Setenv("FRB_DOWNLOAD_CODE", "a1b2c3d4-123b-9876-1234-z1x2y3a1b2c3") client := setupClient(t) @@ -117,7 +123,7 @@ func TestClient__wire_custom_url(t *testing.T) { } bs, _ := io.ReadAll(io.LimitReader(fedach, 10024)) - if !bytes.Equal(bs, byteArray) { + if !bytes.Equal(bs, file) { t.Errorf("unexpected output:\n%s", string(bs)) } } @@ -127,6 +133,7 @@ func setupClient(t *testing.T) *Client { routingNumber := os.Getenv("FRB_ROUTING_NUMBER") downloadCode := os.Getenv("FRB_DOWNLOAD_CODE") + downloadURL := os.Getenv("FRB_DOWNLOAD_URL_TEMPLATE") if routingNumber == "" || downloadCode == "" { t.Skip("missing FRB routing number or download code") } @@ -134,6 +141,7 @@ func setupClient(t *testing.T) *Client { client, err := NewClient(&ClientOpts{ RoutingNumber: routingNumber, DownloadCode: downloadCode, + DownloadURL: downloadURL, }) if err != nil { t.Fatal(err) From eadc364cad7e186ea73c85195300d17670c5fc36 Mon Sep 17 00:00:00 2001 From: Kristi Burnette Date: Fri, 23 Feb 2024 14:28:46 -0700 Subject: [PATCH 4/8] If client fails to setup due to missing environment variables, try reading from disk --- cmd/server/reader.go | 23 +++++++++++++++-------- pkg/download/download.go | 9 +++++++-- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/cmd/server/reader.go b/cmd/server/reader.go index 549f9df5..82cf0b69 100644 --- a/cmd/server/reader.go +++ b/cmd/server/reader.go @@ -8,6 +8,7 @@ import ( "fmt" "io" "os" + "strings" "github.com/moov-io/base/log" "github.com/moov-io/fed" @@ -15,16 +16,19 @@ import ( ) func fedACHDataFile(logger log.Logger) (io.Reader, error) { - if file, err := attemptFileDownload(logger, "fedach"); file != nil { - return file, nil - } else if err != nil { + file, err := attemptFileDownload(logger, "fedach") + if err != nil && !strings.Contains(err.Error(), download.MissingRoutingNumberErr) && !strings.Contains(err.Error(), download.MissingDownloadCodeErr) { return nil, fmt.Errorf("problem downloading fedach: %v", err) } + if file != nil { + return file, nil + } + path := readDataFilepath("FEDACH_DATA_PATH", "./data/FedACHdir.txt") logger.Logf("search: loading %s for ACH data", path) - file, err := os.Open(path) + file, err = os.Open(path) if err != nil { return nil, fmt.Errorf("problem opening %s: %v", path, err) } @@ -32,16 +36,19 @@ func fedACHDataFile(logger log.Logger) (io.Reader, error) { } func fedWireDataFile(logger log.Logger) (io.Reader, error) { - if file, err := attemptFileDownload(logger, "fedwire"); file != nil { + file, err := attemptFileDownload(logger, "fedach") + if err != nil && !strings.Contains(err.Error(), download.MissingRoutingNumberErr) && !strings.Contains(err.Error(), download.MissingDownloadCodeErr) { + return nil, fmt.Errorf("problem downloading fedach: %v", err) + } + + if file != nil { return file, nil - } else if err != nil { - return nil, fmt.Errorf("problem downloading fedwire: %v", err) } path := readDataFilepath("FEDWIRE_DATA_PATH", "./data/fpddir.txt") logger.Logf("search: loading %s for Wire data", path) - file, err := os.Open(path) + file, err = os.Open(path) if err != nil { return nil, fmt.Errorf("problem opening %s: %v", path, err) } diff --git a/pkg/download/download.go b/pkg/download/download.go index 6b7b06ae..fe95ade2 100644 --- a/pkg/download/download.go +++ b/pkg/download/download.go @@ -14,6 +14,9 @@ import ( "time" ) +var MissingRoutingNumberErr = "missing routing number" +var MissingDownloadCodeErr = "missing download code" + type Client struct { httpClient *http.Client @@ -40,11 +43,13 @@ func NewClient(opts *ClientOpts) (*Client, error) { } } + // the client needs either routing number && download code OR download URL + if opts.RoutingNumber == "" { - return nil, errors.New("missing routing number") + return nil, errors.New(MissingRoutingNumberErr) } if opts.DownloadCode == "" { - return nil, errors.New("missing download code") + return nil, errors.New(MissingDownloadCodeErr) } if opts.DownloadURL == "" { From f6415d0a89f0127b3175ca15aa11232847e5bf0c Mon Sep 17 00:00:00 2001 From: Kristi Burnette Date: Fri, 23 Feb 2024 17:03:13 -0700 Subject: [PATCH 5/8] Use errors.Is to filter out missing environment variable error --- cmd/server/reader.go | 13 ++++++------- pkg/download/download.go | 7 +++---- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/cmd/server/reader.go b/cmd/server/reader.go index 82cf0b69..4742429e 100644 --- a/cmd/server/reader.go +++ b/cmd/server/reader.go @@ -5,19 +5,18 @@ package main import ( + "errors" "fmt" - "io" - "os" - "strings" - "github.com/moov-io/base/log" "github.com/moov-io/fed" "github.com/moov-io/fed/pkg/download" + "io" + "os" ) func fedACHDataFile(logger log.Logger) (io.Reader, error) { file, err := attemptFileDownload(logger, "fedach") - if err != nil && !strings.Contains(err.Error(), download.MissingRoutingNumberErr) && !strings.Contains(err.Error(), download.MissingDownloadCodeErr) { + if err != nil && !errors.Is(err, download.ErrMissingData) { return nil, fmt.Errorf("problem downloading fedach: %v", err) } @@ -37,7 +36,7 @@ func fedACHDataFile(logger log.Logger) (io.Reader, error) { func fedWireDataFile(logger log.Logger) (io.Reader, error) { file, err := attemptFileDownload(logger, "fedach") - if err != nil && !strings.Contains(err.Error(), download.MissingRoutingNumberErr) && !strings.Contains(err.Error(), download.MissingDownloadCodeErr) { + if err != nil && !errors.Is(err, download.ErrMissingData) { return nil, fmt.Errorf("problem downloading fedach: %v", err) } @@ -67,7 +66,7 @@ func attemptFileDownload(logger log.Logger, listName string) (io.Reader, error) DownloadURL: downloadURL, }) if err != nil { - return nil, fmt.Errorf("client setup: %v", err) + return nil, fmt.Errorf("client setup: %w", err) } return client.GetList(listName) } diff --git a/pkg/download/download.go b/pkg/download/download.go index fe95ade2..6b77b6ba 100644 --- a/pkg/download/download.go +++ b/pkg/download/download.go @@ -14,8 +14,7 @@ import ( "time" ) -var MissingRoutingNumberErr = "missing routing number" -var MissingDownloadCodeErr = "missing download code" +var ErrMissingData = errors.New("missing data") type Client struct { httpClient *http.Client @@ -46,10 +45,10 @@ func NewClient(opts *ClientOpts) (*Client, error) { // the client needs either routing number && download code OR download URL if opts.RoutingNumber == "" { - return nil, errors.New(MissingRoutingNumberErr) + return nil, ErrMissingData } if opts.DownloadCode == "" { - return nil, errors.New(MissingDownloadCodeErr) + return nil, ErrMissingData } if opts.DownloadURL == "" { From 4771676e61b216713cf2fc57af03ea8da61e9bc3 Mon Sep 17 00:00:00 2001 From: Kristi Burnette Date: Mon, 26 Feb 2024 16:00:36 -0700 Subject: [PATCH 6/8] Improve error messaging when config values are missing --- cmd/server/reader.go | 4 ++-- pkg/download/download.go | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/cmd/server/reader.go b/cmd/server/reader.go index 4742429e..7c9d7cc7 100644 --- a/cmd/server/reader.go +++ b/cmd/server/reader.go @@ -16,7 +16,7 @@ import ( func fedACHDataFile(logger log.Logger) (io.Reader, error) { file, err := attemptFileDownload(logger, "fedach") - if err != nil && !errors.Is(err, download.ErrMissingData) { + if err != nil && !errors.Is(err, download.ErrMissingConfigValue) { return nil, fmt.Errorf("problem downloading fedach: %v", err) } @@ -36,7 +36,7 @@ func fedACHDataFile(logger log.Logger) (io.Reader, error) { func fedWireDataFile(logger log.Logger) (io.Reader, error) { file, err := attemptFileDownload(logger, "fedach") - if err != nil && !errors.Is(err, download.ErrMissingData) { + if err != nil && !errors.Is(err, download.ErrMissingConfigValue) { return nil, fmt.Errorf("problem downloading fedach: %v", err) } diff --git a/pkg/download/download.go b/pkg/download/download.go index 6b77b6ba..eeab7fde 100644 --- a/pkg/download/download.go +++ b/pkg/download/download.go @@ -14,7 +14,13 @@ import ( "time" ) -var ErrMissingData = errors.New("missing data") +const DefaultFRBDownloadURLTemplate = "https://frbservices.org/EPaymentsDirectory/directories/%s?format=json" + +var ( + ErrMissingConfigValue = errors.New("missing config value") + ErrMissingRoutingNumber = errors.New("missing routing number") + ErrMissingDownloadCD = errors.New("missing download code") +) type Client struct { httpClient *http.Client @@ -42,17 +48,16 @@ func NewClient(opts *ClientOpts) (*Client, error) { } } - // the client needs either routing number && download code OR download URL - if opts.RoutingNumber == "" { - return nil, ErrMissingData + return nil, fmt.Errorf("%w: %w", ErrMissingConfigValue, ErrMissingRoutingNumber) } - if opts.DownloadCode == "" { - return nil, ErrMissingData + + if opts.RoutingNumber == "" { + return nil, fmt.Errorf("%w: %w", ErrMissingConfigValue, ErrMissingDownloadCD) } if opts.DownloadURL == "" { - opts.DownloadURL = "https://frbservices.org/EPaymentsDirectory/directories/%s?format=json" + opts.DownloadURL = DefaultFRBDownloadURLTemplate } return &Client{ From c48a47ca2797975433dbebbd628c2691cd0eec1e Mon Sep 17 00:00:00 2001 From: Kristi Burnette Date: Mon, 26 Feb 2024 16:17:29 -0700 Subject: [PATCH 7/8] Update README to include docs regarding downloading files from proxy --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 45bf5845..0fcde9a1 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,14 @@ FRB_ROUTING_NUMBER=123456780 FRB_DOWNLOAD_CODE=86cfa5a9-1ab9-4af5-bd89-0f84d546de13 ``` +#### Download files from proxy + +Fed can download the files from a proxy or other HTTP resources. The optional URL template is configured as an environment variable. If the URL template is not configured, Fed will download the files directly from FRB eServices by default. This value is considered a template because when preparing the request Fed replaces `%s` in the path with the requested list name(`fedach` or `fedwire`). + +``` +FRB_DOWNLOAD_URL_TEMPLATE=https://my.example.com/files/%s?format=json +``` + ### Docker We publish a [public Docker image `moov/fed`](https://hub.docker.com/r/moov/fed/) from Docker Hub or use this repository. No configuration is required to serve on `:8086` and metrics at `:9096/metrics` in Prometheus format. We also have Docker images for [OpenShift](https://quay.io/repository/moov/fed?tab=tags) published as `quay.io/moov/fed`. From 32b30825d2d306100a4dec79134427d7f07151e4 Mon Sep 17 00:00:00 2001 From: Kristi Burnette Date: Tue, 27 Feb 2024 09:36:50 -0700 Subject: [PATCH 8/8] Add new environment variable to configuration settings section --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0fcde9a1..d868853a 100644 --- a/README.md +++ b/README.md @@ -189,17 +189,18 @@ PONG ### Configuration settings -| Environmental Variable | Description | Default | -|-----|-----|-----| -| `FEDACH_DATA_PATH` | Filepath to FedACH data file | `./data/FedACHdir.txt` | -| `FEDWIRE_DATA_PATH` | Filepath to Fedwire data file | `./data/fpddir.txt` | -| `FRB_ROUTING_NUMBER` | Federal Reserve Board eServices (ABA) routing number used to download FedACH and FedWire files | Empty | -| `FRB_DOWNLOAD_CODE` | Federal Reserve Board eServices (ABA) download code used to download FedACH and FedWire files | Empty | -| `LOG_FORMAT` | Format for logging lines to be written as. | Options: `json`, `plain` - Default: `plain` | -| `HTTP_BIND_ADDRESS` | Address for Fed to bind its HTTP server on. This overrides the command-line flag `-http.addr`. | Default: `:8086` | -| `HTTP_ADMIN_BIND_ADDRESS` | Address for Fed to bind its admin HTTP server on. This overrides the command-line flag `-admin.addr`. | Default: `:9096` | +| Environmental Variable | Description | Default | +|-----|-------------------------------------------------------------------------------------------------------------------------------------|-----| +| `FEDACH_DATA_PATH` | Filepath to FedACH data file | `./data/FedACHdir.txt` | +| `FEDWIRE_DATA_PATH` | Filepath to Fedwire data file | `./data/fpddir.txt` | +| `FRB_ROUTING_NUMBER` | Federal Reserve Board eServices (ABA) routing number used to download FedACH and FedWire files | Empty | +| `FRB_DOWNLOAD_CODE` | Federal Reserve Board eServices (ABA) download code used to download FedACH and FedWire files | Empty | +| `FRB_DOWNLOAD_URL_TEMPLATE` | URL Template for downloading files from alternate source | `https://frbservices.org/EPaymentsDirectory/directories/%s?format=json`| +| `LOG_FORMAT` | Format for logging lines to be written as. | Options: `json`, `plain` - Default: `plain` | +| `HTTP_BIND_ADDRESS` | Address for Fed to bind its HTTP server on. This overrides the command-line flag `-http.addr`. | Default: `:8086` | +| `HTTP_ADMIN_BIND_ADDRESS` | Address for Fed to bind its admin HTTP server on. This overrides the command-line flag `-admin.addr`. | Default: `:9096` | | `HTTPS_CERT_FILE` | Filepath containing a certificate (or intermediate chain) to be served by the HTTP server. Requires all traffic be over secure HTTP. | Empty | -| `HTTPS_KEY_FILE` | Filepath of a private key matching the leaf certificate from `HTTPS_CERT_FILE`. | Empty | +| `HTTPS_KEY_FILE` | Filepath of a private key matching the leaf certificate from `HTTPS_CERT_FILE`. | Empty | #### Logos