From 2f3b565f27815c1ba65515987d8111716932e6d9 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 14 Apr 2026 17:31:29 +0200 Subject: [PATCH 01/21] CROSSLINK-250 multiple symbols per tenant --- broker/api/symbol_checker.go | 86 ++++++++++++ broker/api/symbol_checker_test.go | 122 ++++++++++++++++++ broker/app/app.go | 6 +- broker/patron_request/api/api-handler.go | 74 ++++++----- broker/patron_request/api/api-handler_test.go | 71 +++++----- 5 files changed, 291 insertions(+), 68 deletions(-) create mode 100644 broker/api/symbol_checker.go create mode 100644 broker/api/symbol_checker_test.go diff --git a/broker/api/symbol_checker.go b/broker/api/symbol_checker.go new file mode 100644 index 00000000..5d21cb84 --- /dev/null +++ b/broker/api/symbol_checker.go @@ -0,0 +1,86 @@ +package api + +import ( + "errors" + "net/http" + "strings" + + "github.com/indexdata/crosslink/broker/adapter" + "github.com/indexdata/crosslink/broker/common" + "github.com/indexdata/crosslink/broker/ill_db" +) + +type SymbolChecker struct { + illRepo *ill_db.IllRepo + directoryLookupAdapter adapter.DirectoryLookupAdapter + tenantResolver common.Tenant +} + +func NewSymbolChecker(tenantResolver common.Tenant) *SymbolChecker { + return &SymbolChecker{ + tenantResolver: tenantResolver, + } +} + +func (s *SymbolChecker) WithRepoCheck(illRepo ill_db.IllRepo) *SymbolChecker { + s.illRepo = &illRepo + return s +} + +func (s *SymbolChecker) WithLookupAdapter(directoryLookupAdapter adapter.DirectoryLookupAdapter) *SymbolChecker { + s.directoryLookupAdapter = directoryLookupAdapter + return s +} + +func (s *SymbolChecker) Check(ctx common.ExtendedContext, isBroker bool, tenant *string, symbol *string) (string, error) { + var mainSymbol string + if isBroker { + if !s.tenantResolver.IsSpecified() { + return "", errors.New("tenant mapping must be specified") + } + if tenant == nil { + return "", errors.New("X-Okapi-Tenant must be specified") + } + mainSymbol = s.tenantResolver.GetSymbol(*tenant) + } else { + if symbol == nil || *symbol == "" { + return "", errors.New("symbol must be specified") + } + mainSymbol = *symbol + } + if s.illRepo == nil { + return mainSymbol, nil + } + peers, _, err := (*s.illRepo).GetCachedPeersBySymbols(ctx, []string{mainSymbol}, s.directoryLookupAdapter) + if err != nil { + return "", err + } + if len(peers) == 0 { + ctx.Logger().Error("no peers for symbol", "symbol", mainSymbol) + return "", errors.New("no peers for symbol") + } + if symbol == nil || *symbol == mainSymbol { + return mainSymbol, nil + } + found := false + for _, peer := range peers { + branchSymbols, err := (*s.illRepo).GetBranchSymbolsByPeerId(ctx, peer.ID) + if err != nil { + return "", err + } + for _, branchSymbol := range branchSymbols { + if *symbol == branchSymbol.SymbolValue { + found = true + break + } + } + } + if !found { + return "", errors.New("symbol does not match any branch symbols for tenant") + } + return *symbol, nil +} + +func (s *SymbolChecker) GetSymbolForRequest(ctx common.ExtendedContext, r *http.Request, tenant *string, symbol *string) (string, error) { + return s.Check(ctx, strings.Contains(r.RequestURI, "/broker/"), tenant, symbol) +} diff --git a/broker/api/symbol_checker_test.go b/broker/api/symbol_checker_test.go new file mode 100644 index 00000000..e78a0a91 --- /dev/null +++ b/broker/api/symbol_checker_test.go @@ -0,0 +1,122 @@ +package api + +import ( + "context" + "strings" + "testing" + + "github.com/indexdata/crosslink/broker/adapter" + "github.com/indexdata/crosslink/broker/common" + "github.com/indexdata/crosslink/broker/ill_db" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +func TestSymbolChecker(t *testing.T) { + tenantResolver := common.NewTenant("") + symbolChecker := NewSymbolChecker(tenantResolver) + + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) + _, err := symbolChecker.Check(ctx, false, nil, nil) + assert.Error(t, err) + assert.Equal(t, "symbol must be specified", err.Error()) + + requestSymbol := "symbol2" + symbol, err := symbolChecker.Check(ctx, false, nil, &requestSymbol) + assert.NoError(t, err) + assert.Equal(t, requestSymbol, symbol) + + _, err = symbolChecker.Check(ctx, true, nil, nil) + assert.Error(t, err) + assert.Equal(t, "tenant mapping must be specified", err.Error()) + + tenantResolver = common.NewTenant("{tenant}") + symbolChecker = NewSymbolChecker(tenantResolver) + _, err = symbolChecker.Check(ctx, true, nil, nil) + assert.Error(t, err) + assert.Equal(t, "X-Okapi-Tenant must be specified", err.Error()) + + tenant := "tenant1" + symbol, err = symbolChecker.Check(ctx, true, &tenant, nil) + assert.NoError(t, err) + assert.Equal(t, strings.ToUpper(tenant), symbol) +} + +type MockDirectoryLookupAdapter struct { + mock.Mock + adapter.DirectoryLookupAdapter +} + +type MockIllRepo struct { + mock.Mock + ill_db.IllRepo +} + +func (r *MockIllRepo) GetCachedPeersBySymbols(ctx common.ExtendedContext, symbols []string, directoryAdapter adapter.DirectoryLookupAdapter) ([]ill_db.Peer, string, error) { + args := r.Called(ctx, symbols, directoryAdapter) + return args.Get(0).([]ill_db.Peer), args.String(1), args.Error(2) +} + +func (r *MockIllRepo) GetBranchSymbolsByPeerId(ctx common.ExtendedContext, peerId string) ([]ill_db.BranchSymbol, error) { + args := r.Called(ctx, peerId) + return args.Get(0).([]ill_db.BranchSymbol), args.Error(1) +} + +func TestSymbolCheckerRepoNoPeer(t *testing.T) { + tenantResolver := common.NewTenant("{tenant}") + + mockIllRepo := new(MockIllRepo) + mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{}, "", nil) + + symbolChecker := NewSymbolChecker(tenantResolver).WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithRepoCheck(mockIllRepo) + + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) + requestSymbol := "SYMBOL2" + _, err := symbolChecker.Check(ctx, false, nil, &requestSymbol) + assert.Error(t, err) + assert.Equal(t, "no peers for symbol", err.Error()) +} + +func TestSymbolCheckerRepoOK(t *testing.T) { + tenantResolver := common.NewTenant("{tenant}") + + mockIllRepo := new(MockIllRepo) + mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{{ID: "SYMBOL"}}, "", nil) + mockIllRepo.On("GetBranchSymbolsByPeerId", mock.Anything, mock.Anything).Return([]ill_db.BranchSymbol{{SymbolValue: "LIB"}}, nil) + + symbolChecker := NewSymbolChecker(tenantResolver).WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithRepoCheck(mockIllRepo) + + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) + requestSymbol := "SYMBOL" + symbol, err := symbolChecker.Check(ctx, false, nil, &requestSymbol) + assert.NoError(t, err) + assert.Equal(t, requestSymbol, symbol) + + requestSymbol = "LIB" + tenant := "SYMBOL" + symbol, err = symbolChecker.Check(ctx, true, &tenant, &requestSymbol) + assert.NoError(t, err) + assert.Equal(t, requestSymbol, symbol) +} + +func TestSymbolCheckerRepoBranches(t *testing.T) { + tenantResolver := common.NewTenant("{tenant}") + + mockIllRepo := new(MockIllRepo) + mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{{ID: "SYMBOL"}}, "", nil) + mockIllRepo.On("GetBranchSymbolsByPeerId", mock.Anything, mock.Anything).Return([]ill_db.BranchSymbol{}, nil) + + symbolChecker := NewSymbolChecker(tenantResolver).WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithRepoCheck(mockIllRepo) + + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) + requestSymbol := "SYMBOL" + symbol, err := symbolChecker.Check(ctx, false, nil, &requestSymbol) + assert.NoError(t, err) + assert.Equal(t, requestSymbol, symbol) + + requestSymbol = "LIB" + tenant := "SYMBOL" + _, err = symbolChecker.Check(ctx, true, &tenant, &requestSymbol) + assert.Error(t, err) + assert.Equal(t, "symbol does not match any branch symbols for tenant", err.Error()) +} diff --git a/broker/app/app.go b/broker/app/app.go index 63bd595f..6a165425 100644 --- a/broker/app/app.go +++ b/broker/app/app.go @@ -166,11 +166,13 @@ func Init(ctx context.Context) (Context, error) { iso18626Client := client.CreateIso18626Client(eventBus, illRepo, prMessageHandler, MAX_MESSAGE_SIZE, delay) supplierLocator := service.CreateSupplierLocator(eventBus, illRepo, dirAdapter, holdingsAdapter) workflowManager := service.CreateWorkflowManager(eventBus, illRepo, service.WorkflowConfig{}) - prApiHandler := prapi.NewPrApiHandler(prRepo, eventBus, eventRepo, common.NewTenant(TENANT_TO_SYMBOL), API_PAGE_SIZE) + tenant := common.NewTenant(TENANT_TO_SYMBOL) + apiSymbolChecker := api.NewSymbolChecker(tenant).WithRepoCheck(illRepo).WithLookupAdapter(dirAdapter) + prApiHandler := prapi.NewPrApiHandler(prRepo, eventBus, eventRepo, apiSymbolChecker, API_PAGE_SIZE) prApiHandler.SetAutoActionRunner(prActionService) prApiHandler.SetActionTaskProcessor(prActionService) - sseBroker := api.NewSseBroker(appCtx, common.NewTenant(TENANT_TO_SYMBOL)) + sseBroker := api.NewSseBroker(appCtx, tenant) AddDefaultHandlers(eventBus, iso18626Client, supplierLocator, workflowManager, iso18626Handler, *prActionService, prApiHandler, sseBroker) err = StartEventBus(ctx, eventBus) diff --git a/broker/patron_request/api/api-handler.go b/broker/patron_request/api/api-handler.go index 1a8bdcce..95a5f56e 100644 --- a/broker/patron_request/api/api-handler.go +++ b/broker/patron_request/api/api-handler.go @@ -43,18 +43,18 @@ type PatronRequestApiHandler struct { actionMappingService prservice.ActionMappingService autoActionRunner prservice.AutoActionRunner actionTaskProcessor ActionTaskProcessor - tenant common.Tenant + symbolChecker *api.SymbolChecker } func NewPrApiHandler(prRepo pr_db.PrRepo, eventBus events.EventBus, - eventRepo events.EventRepo, tenant common.Tenant, limitDefault int32) PatronRequestApiHandler { + eventRepo events.EventRepo, symbolChecker *api.SymbolChecker, limitDefault int32) PatronRequestApiHandler { return PatronRequestApiHandler{ limitDefault: limitDefault, prRepo: prRepo, eventBus: eventBus, eventRepo: eventRepo, actionMappingService: prservice.ActionMappingService{SMService: &prservice.StateModelService{}}, - tenant: tenant, + symbolChecker: symbolChecker, } } @@ -87,18 +87,19 @@ func (a *PatronRequestApiHandler) GetStateModelCapabilities(w http.ResponseWrite } func (a *PatronRequestApiHandler) GetPatronRequests(w http.ResponseWriter, r *http.Request, params proapi.GetPatronRequestsParams) { - symbol, err := api.GetSymbolForRequest(r, a.tenant, params.XOkapiTenant, params.Symbol) - logParams := map[string]string{"method": "GetPatronRequests", "symbol": symbol} + logParams := map[string]string{"method": "GetPatronRequests"} if params.Side != nil { logParams["side"] = *params.Side } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ - Other: logParams, - }) + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return } + logParams["symbol"] = symbol + ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + limit := a.limitDefault if params.Limit != nil { limit = *params.Limit @@ -189,20 +190,21 @@ func addOwnerRestriction(queryBuilder *cqlbuilder.QueryBuilder, symbol string, s } func (a *PatronRequestApiHandler) PostPatronRequests(w http.ResponseWriter, r *http.Request, params proapi.PostPatronRequestsParams) { - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ - Other: map[string]string{"method": "PostPatronRequests"}, - }) + logParams := map[string]string{"method": "PostPatronRequests"} + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) var newPr proapi.CreatePatronRequest err := json.NewDecoder(r.Body).Decode(&newPr) if err != nil { addBadRequestError(ctx, w, err) return } - symbol, err := api.GetSymbolForRequest(r, a.tenant, params.XOkapiTenant, newPr.RequesterSymbol) + symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, newPr.RequesterSymbol) if err != nil { addBadRequestError(ctx, w, err) return } + logParams["symbol"] = symbol + ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) newPr.RequesterSymbol = &symbol creationTime := pgtype.Timestamp{Valid: true, Time: time.Now()} illRequest, requesterReqId, err := a.parseAndValidateIllRequest(ctx, &newPr, creationTime.Time) @@ -244,17 +246,18 @@ func (a *PatronRequestApiHandler) PostPatronRequests(w http.ResponseWriter, r *h } func (a *PatronRequestApiHandler) DeletePatronRequestsId(w http.ResponseWriter, r *http.Request, id string, params proapi.DeletePatronRequestsIdParams) { - symbol, err := api.GetSymbolForRequest(r, a.tenant, params.XOkapiTenant, params.Symbol) - logParams := map[string]string{"method": "DeletePatronRequestsId", "id": id, "symbol": symbol} + logParams := map[string]string{"method": "DeletePatronRequestsId", "id": id} if params.Side != nil { logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - + symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return } + logParams["symbol"] = symbol + ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return @@ -296,17 +299,18 @@ func isOwner(pr pr_db.PatronRequest, symbol string) bool { } func (a *PatronRequestApiHandler) GetPatronRequestsId(w http.ResponseWriter, r *http.Request, id string, params proapi.GetPatronRequestsIdParams) { - symbol, err := api.GetSymbolForRequest(r, a.tenant, params.XOkapiTenant, params.Symbol) - logParams := map[string]string{"method": "GetPatronRequestsId", "id": id, "symbol": symbol} + logParams := map[string]string{"method": "GetPatronRequestsId", "id": id} if params.Side != nil { logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - + symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return } + logParams["symbol"] = symbol + ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return @@ -315,17 +319,20 @@ func (a *PatronRequestApiHandler) GetPatronRequestsId(w http.ResponseWriter, r * } func (a *PatronRequestApiHandler) GetPatronRequestsIdActions(w http.ResponseWriter, r *http.Request, id string, params proapi.GetPatronRequestsIdActionsParams) { - symbol, err := api.GetSymbolForRequest(r, a.tenant, params.XOkapiTenant, params.Symbol) - logParams := map[string]string{"method": "GetPatronRequestsIdActions", "id": id, "symbol": symbol} + logParams := map[string]string{"method": "GetPatronRequestsIdActions", "id": id} if params.Side != nil { logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + if err != nil { addBadRequestError(ctx, w, err) return } + logParams["symbol"] = symbol + ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return @@ -340,17 +347,19 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdActions(w http.ResponseWrit } func (a *PatronRequestApiHandler) PostPatronRequestsIdAction(w http.ResponseWriter, r *http.Request, id string, params proapi.PostPatronRequestsIdActionParams) { - symbol, err := api.GetSymbolForRequest(r, a.tenant, params.XOkapiTenant, params.Symbol) - logParams := map[string]string{"method": "PostPatronRequestsIdAction", "id": id, "symbol": symbol} + logParams := map[string]string{"method": "PostPatronRequestsIdAction", "id": id} if params.Side != nil { logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return } + logParams["symbol"] = symbol + ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return @@ -415,18 +424,19 @@ func (a *PatronRequestApiHandler) PostPatronRequestsIdAction(w http.ResponseWrit } func (a *PatronRequestApiHandler) GetPatronRequestsIdEvents(w http.ResponseWriter, r *http.Request, id string, params proapi.GetPatronRequestsIdEventsParams) { - symbol, err := api.GetSymbolForRequest(r, a.tenant, params.XOkapiTenant, params.Symbol) - logParams := map[string]string{"method": "GetPatronRequestsIdEvents", "id": id, "symbol": symbol} - + logParams := map[string]string{"method": "GetPatronRequestsIdEvents", "id": id} if params.Side != nil { logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return } + logParams["symbol"] = symbol + ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return @@ -445,18 +455,19 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdEvents(w http.ResponseWrite } func (a *PatronRequestApiHandler) GetPatronRequestsIdItems(w http.ResponseWriter, r *http.Request, id string, params proapi.GetPatronRequestsIdItemsParams) { - symbol, err := api.GetSymbolForRequest(r, a.tenant, params.XOkapiTenant, params.Symbol) - logParams := map[string]string{"method": "GetPatronRequestsIdItems", "id": id, "symbol": symbol} - + logParams := map[string]string{"method": "GetPatronRequestsIdItems", "id": id} if params.Side != nil { logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return } + logParams["symbol"] = symbol + ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return @@ -475,18 +486,19 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdItems(w http.ResponseWriter } func (a *PatronRequestApiHandler) GetPatronRequestsIdNotifications(w http.ResponseWriter, r *http.Request, id string, params proapi.GetPatronRequestsIdNotificationsParams) { - symbol, err := api.GetSymbolForRequest(r, a.tenant, params.XOkapiTenant, params.Symbol) - logParams := map[string]string{"method": "GetPatronRequestsIdNotifications", "id": id, "symbol": symbol} - + logParams := map[string]string{"method": "GetPatronRequestsIdNotifications", "id": id} if params.Side != nil { logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return } + logParams["symbol"] = symbol + ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return diff --git a/broker/patron_request/api/api-handler_test.go b/broker/patron_request/api/api-handler_test.go index be76e54a..37fb2333 100644 --- a/broker/patron_request/api/api-handler_test.go +++ b/broker/patron_request/api/api-handler_test.go @@ -13,6 +13,7 @@ import ( "time" "github.com/google/uuid" + "github.com/indexdata/crosslink/broker/api" "github.com/indexdata/crosslink/broker/common" "github.com/indexdata/crosslink/broker/events" pr_db "github.com/indexdata/crosslink/broker/patron_request/db" @@ -48,7 +49,7 @@ func TestGetDbText(t *testing.T) { } func TestGetPatronRequests(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() params := proapi.GetPatronRequestsParams{ @@ -61,7 +62,7 @@ func TestGetPatronRequests(t *testing.T) { } func TestGetPatronRequestsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() params := proapi.GetPatronRequestsParams{ @@ -73,7 +74,7 @@ func TestGetPatronRequestsNoSymbol(t *testing.T) { } func TestGetPatronRequestsWithLimits(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() offset := proapi.Offset(10) @@ -93,7 +94,7 @@ func TestGetPatronRequestsWithLimits(t *testing.T) { func TestGetPatronRequestsWithRequesterReqId(t *testing.T) { repo := new(PrRepoCapture) - handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() requesterReqID := "req-123" @@ -112,7 +113,7 @@ func TestGetPatronRequestsWithRequesterReqId(t *testing.T) { } func TestPostPatronRequests(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) id := "1" toCreate := proapi.CreatePatronRequest{ Id: &id, @@ -138,7 +139,7 @@ func TestPostPatronRequests(t *testing.T) { } func TestPostPatronRequestsMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) toCreate := proapi.PatronRequest{Id: "1"} jsonBytes, err := json.Marshal(toCreate) assert.NoError(t, err, "failed to marshal patron request") @@ -152,7 +153,7 @@ func TestPostPatronRequestsMissingSymbol(t *testing.T) { } func TestPostPatronRequestsInvalidJson(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("POST", "/", bytes.NewBuffer([]byte("a\": v\""))) rr := httptest.NewRecorder() tenant := proapi.Tenant("test-lib") @@ -162,7 +163,7 @@ func TestPostPatronRequestsInvalidJson(t *testing.T) { } func TestPostPatronRequestsInvalidIllRequestShape(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) toCreate := proapi.CreatePatronRequest{ Id: ptr("1"), RequesterSymbol: &symbol, @@ -182,7 +183,7 @@ func TestPostPatronRequestsInvalidIllRequestShape(t *testing.T) { } func TestDeletePatronRequestsIdNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "2", proapi.DeletePatronRequestsIdParams{Symbol: &symbol}) @@ -190,7 +191,7 @@ func TestDeletePatronRequestsIdNotFound(t *testing.T) { } func TestDeletePatronRequestsIdMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "2", proapi.DeletePatronRequestsIdParams{}) @@ -199,7 +200,7 @@ func TestDeletePatronRequestsIdMissingSymbol(t *testing.T) { } func TestDeletePatronRequestsIdError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "1", proapi.DeletePatronRequestsIdParams{Symbol: &symbol}) @@ -208,7 +209,7 @@ func TestDeletePatronRequestsIdError(t *testing.T) { } func TestDeletePatronRequestsId(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "3", proapi.DeletePatronRequestsIdParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -217,7 +218,7 @@ func TestDeletePatronRequestsId(t *testing.T) { } func TestDeletePatronRequestsIdDeleted(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "4", proapi.DeletePatronRequestsIdParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -225,7 +226,7 @@ func TestDeletePatronRequestsIdDeleted(t *testing.T) { } func TestGetPatronRequestsIdMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "2", proapi.GetPatronRequestsIdParams{}) @@ -234,7 +235,7 @@ func TestGetPatronRequestsIdMissingSymbol(t *testing.T) { } func TestGetPatronRequestsIdNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "2", proapi.GetPatronRequestsIdParams{Symbol: &symbol}) @@ -242,7 +243,7 @@ func TestGetPatronRequestsIdNotFound(t *testing.T) { } func TestGetPatronRequestsId(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "1", proapi.GetPatronRequestsIdParams{Symbol: &symbol}) @@ -251,7 +252,7 @@ func TestGetPatronRequestsId(t *testing.T) { } func TestGetPatronRequestsIdActions(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -260,7 +261,7 @@ func TestGetPatronRequestsIdActions(t *testing.T) { } func TestGetPatronRequestsIdActionsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Side: &proapiBorrowingSide}) @@ -269,7 +270,7 @@ func TestGetPatronRequestsIdActionsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdActionsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "1", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -278,7 +279,7 @@ func TestGetPatronRequestsIdActionsDbError(t *testing.T) { } func TestGetPatronRequestsIdActionsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -287,7 +288,7 @@ func TestGetPatronRequestsIdActionsNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdActionNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Side: &proapiBorrowingSide}) @@ -296,7 +297,7 @@ func TestPostPatronRequestsIdActionNoSymbol(t *testing.T) { } func TestPostPatronRequestsIdActionDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "1", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -305,7 +306,7 @@ func TestPostPatronRequestsIdActionDbError(t *testing.T) { } func TestPostPatronRequestsIdActionNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -314,7 +315,7 @@ func TestPostPatronRequestsIdActionNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdActionErrorParsing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", strings.NewReader("{")) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -323,7 +324,7 @@ func TestPostPatronRequestsIdActionErrorParsing(t *testing.T) { } func TestGetPatronRequestsIdEventsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Side: &proapiBorrowingSide}) @@ -332,7 +333,7 @@ func TestGetPatronRequestsIdEventsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdEventsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "1", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -341,7 +342,7 @@ func TestGetPatronRequestsIdEventsDbError(t *testing.T) { } func TestGetPatronRequestsIdEventsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -350,7 +351,7 @@ func TestGetPatronRequestsIdEventsNotFoundBecauseOfSide(t *testing.T) { } func TestGetPatronRequestsIdEventsErrorGettingEvents(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -359,7 +360,7 @@ func TestGetPatronRequestsIdEventsErrorGettingEvents(t *testing.T) { } func TestGetPatronRequestsIdNotificationsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Side: &proapiBorrowingSide}) @@ -368,7 +369,7 @@ func TestGetPatronRequestsIdNotificationsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdNotificationsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "1", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -377,7 +378,7 @@ func TestGetPatronRequestsIdNotificationsDbError(t *testing.T) { } func TestGetPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -386,7 +387,7 @@ func TestGetPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { } func TestGetPatronRequestsIdNotificationsErrorGettingEvents(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -395,7 +396,7 @@ func TestGetPatronRequestsIdNotificationsErrorGettingEvents(t *testing.T) { } func TestParseAndValidateIllRequestAndBuildDbPatronRequest(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) creationTime := time.Now() id := uuid.NewString() @@ -429,7 +430,7 @@ func TestParseAndValidateIllRequestAndBuildDbPatronRequest(t *testing.T) { } func TestParseAndValidateIllRequestInvalidRequesterSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) invalidSymbol := "REQ" @@ -439,7 +440,7 @@ func TestParseAndValidateIllRequestInvalidRequesterSymbol(t *testing.T) { } func TestParseAndValidateIllRequestInvalidBrokerSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, common.NewTenant(""), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) previousBrokerSymbol := brokerSymbol brokerSymbol = "BROKER" From c10cca0ed98fb6d4e5ed6c500bb610ade1ffc302 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 14 Apr 2026 22:05:48 +0200 Subject: [PATCH 02/21] SymbolChecker used in regular broker API --- broker/api/api-handler.go | 45 +++++++++++++++++------------ broker/api/common.go | 22 -------------- broker/api/common_test.go | 27 ----------------- broker/api/symbol_checker.go | 35 ++++++++++++++++++++++ broker/app/app.go | 10 +++++-- broker/test/api/api-handler_test.go | 2 +- 6 files changed, 70 insertions(+), 71 deletions(-) delete mode 100644 broker/api/common_test.go diff --git a/broker/api/api-handler.go b/broker/api/api-handler.go index 6e1b9148..ead79ed6 100644 --- a/broker/api/api-handler.go +++ b/broker/api/api-handler.go @@ -37,32 +37,38 @@ var LIMIT_DEFAULT int32 = 10 var ARCHIVE_PROCESS_STARTED = "Archive process started" type ApiHandler struct { - limitDefault int32 - eventRepo events.EventRepo - illRepo ill_db.IllRepo - tenant common.Tenant + limitDefault int32 + eventRepo events.EventRepo + illRepo ill_db.IllRepo + symbolChecker SymbolChecker } -func NewApiHandler(eventRepo events.EventRepo, illRepo ill_db.IllRepo, tenant common.Tenant, limitDefault int32) ApiHandler { +func NewApiHandler(eventRepo events.EventRepo, illRepo ill_db.IllRepo, symbolChecker SymbolChecker, limitDefault int32) ApiHandler { return ApiHandler{ - eventRepo: eventRepo, - illRepo: illRepo, - tenant: tenant, - limitDefault: limitDefault, + eventRepo: eventRepo, + illRepo: illRepo, + symbolChecker: symbolChecker, + limitDefault: limitDefault, } } -func (a *ApiHandler) isOwner(trans *ill_db.IllTransaction, tenant *string, requesterSymbol *string) bool { +func (a *ApiHandler) isOwner(ctx common.ExtendedContext, trans *ill_db.IllTransaction, tenant *string, requesterSymbol *string) bool { if tenant == nil && requesterSymbol != nil { return trans.RequesterSymbol.String == *requesterSymbol } - if !a.tenant.IsSpecified() { + if !a.symbolChecker.tenantResolver.IsSpecified() { return true } if tenant == nil { return false } - return trans.RequesterSymbol.String == a.tenant.GetSymbol(*tenant) + syms := a.symbolChecker.GetSymbolsForTenant(ctx, *tenant) + for _, sym := range syms { + if trans.RequesterSymbol.String == sym { + return true + } + } + return false } func (a *ApiHandler) getIllTranFromParams(ctx common.ExtendedContext, w http.ResponseWriter, @@ -89,7 +95,7 @@ func (a *ApiHandler) getIllTranFromParams(ctx common.ExtendedContext, w http.Res addInternalError(ctx, w, err) return nil, err } - if !a.isOwner(&tran, okapiTenant, requesterSymbol) { + if !a.isOwner(ctx, &tran, okapiTenant, requesterSymbol) { return nil, nil } return &tran, nil @@ -168,22 +174,23 @@ func (a *ApiHandler) GetIllTransactions(w http.ResponseWriter, r *http.Request, fullCount = 1 resp.Items = append(resp.Items, toApiIllTransaction(r, *tran)) } - } else if a.tenant.IsSpecified() { - var symbol string + } else if a.symbolChecker.tenantResolver.IsSpecified() { + var symbols []string if params.XOkapiTenant != nil { - symbol = a.tenant.GetSymbol(*params.XOkapiTenant) + symbols = a.symbolChecker.GetSymbolsForTenant(ctx, *params.XOkapiTenant) } else if params.RequesterSymbol != nil { - symbol = *params.RequesterSymbol + symbols = []string{*params.RequesterSymbol} } - if symbol == "" { + if len(symbols) == 0 { writeJsonResponse(w, resp) return } + // TODO handle multiple symbols properly instead of just using the first one in the list dbparams := ill_db.GetIllTransactionsByRequesterSymbolParams{ Limit: limit, Offset: offset, RequesterSymbol: pgtype.Text{ - String: symbol, + String: symbols[0], Valid: true, }, } diff --git a/broker/api/common.go b/broker/api/common.go index 1a6285ad..4b47642d 100644 --- a/broker/api/common.go +++ b/broker/api/common.go @@ -1,13 +1,11 @@ package api import ( - "errors" "net/http" "net/url" "strconv" "strings" - "github.com/indexdata/crosslink/broker/common" "github.com/indexdata/crosslink/broker/oapi" ) @@ -83,23 +81,3 @@ func CollectAboutData(fullCount int64, offset int32, limit int32, r *http.Reques } return about } - -func GetSymbolForRequest(r *http.Request, tenantResolver common.Tenant, tenant *string, symbol *string) (string, error) { - if strings.Contains(r.RequestURI, "/broker/") { - if tenantResolver.IsSpecified() { - if tenant == nil { - return "", errors.New("X-Okapi-Tenant must be specified") - } else { - return tenantResolver.GetSymbol(*tenant), nil - } - } else { - return "", errors.New("tenant mapping must be specified") - } - } else { - if symbol == nil || *symbol == "" { - return "", errors.New("symbol must be specified") - } else { - return *symbol, nil - } - } -} diff --git a/broker/api/common_test.go b/broker/api/common_test.go deleted file mode 100644 index 0e7ed713..00000000 --- a/broker/api/common_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package api - -import ( - "net/http" - "strings" - "testing" - - "github.com/indexdata/crosslink/broker/common" - "github.com/stretchr/testify/assert" -) - -func TestGetSymbolForRequest(t *testing.T) { - req, _ := http.NewRequest("GET", "/broker/patron_request", strings.NewReader("{")) - req.RequestURI = "/broker/patron_request" - tenant := "req" - resolved, err := GetSymbolForRequest(req, common.NewTenant("ISIL:{tenant}"), &tenant, nil) - assert.NoError(t, err) - assert.Equal(t, "ISIL:REQ", resolved) - - resolved, err = GetSymbolForRequest(req, common.NewTenant("ISIL:{tenant}"), nil, nil) - assert.Equal(t, "X-Okapi-Tenant must be specified", err.Error()) - assert.Equal(t, "", resolved) - - resolved, err = GetSymbolForRequest(req, common.NewTenant(""), &tenant, nil) - assert.Equal(t, "tenant mapping must be specified", err.Error()) - assert.Equal(t, "", resolved) -} diff --git a/broker/api/symbol_checker.go b/broker/api/symbol_checker.go index 5d21cb84..aa115b40 100644 --- a/broker/api/symbol_checker.go +++ b/broker/api/symbol_checker.go @@ -81,6 +81,41 @@ func (s *SymbolChecker) Check(ctx common.ExtendedContext, isBroker bool, tenant return *symbol, nil } +func (s *SymbolChecker) GetSymbolsForTenant(ctx common.ExtendedContext, tenant string) []string { + if !s.tenantResolver.IsSpecified() { + return []string{} + } + if tenant == "" { + return []string{} + } + mainSymbol := s.tenantResolver.GetSymbol(tenant) + if s.illRepo == nil { + return []string{mainSymbol} + } + if s.illRepo == nil { + return []string{mainSymbol} + } + peers, _, err := (*s.illRepo).GetCachedPeersBySymbols(ctx, []string{mainSymbol}, s.directoryLookupAdapter) + if err != nil { + return []string{} + } + if len(peers) == 0 { + ctx.Logger().Error("no peers for symbol", "symbol", mainSymbol) + return []string{} + } + symbols := []string{mainSymbol} + for _, peer := range peers { + branchSymbols, err := (*s.illRepo).GetBranchSymbolsByPeerId(ctx, peer.ID) + if err != nil { + return []string{} + } + for _, branchSymbol := range branchSymbols { + symbols = append(symbols, branchSymbol.SymbolValue) + } + } + return symbols +} + func (s *SymbolChecker) GetSymbolForRequest(ctx common.ExtendedContext, r *http.Request, tenant *string, symbol *string) (string, error) { return s.Check(ctx, strings.Contains(r.RequestURI, "/broker/"), tenant, symbol) } diff --git a/broker/app/app.go b/broker/app/app.go index 6a165425..776dc3cf 100644 --- a/broker/app/app.go +++ b/broker/app/app.go @@ -211,11 +211,17 @@ func StartServer(ctx Context) error { _, _ = w.Write(oapi.OpenAPISpecYAML) }) - apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, common.NewTenant(""), API_PAGE_SIZE) + tenant := common.NewTenant("") + symbolChecker := api.NewSymbolChecker(tenant).WithRepoCheck(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter) + + apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, *symbolChecker, API_PAGE_SIZE) oapi.HandlerFromMux(&apiHandler, ServeMux) proapi.HandlerFromMux(&ctx.PrApiHandler, ServeMux) if TENANT_TO_SYMBOL != "" { - apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, common.NewTenant(TENANT_TO_SYMBOL), API_PAGE_SIZE) + tenant = common.NewTenant(TENANT_TO_SYMBOL) + symbolChecker = api.NewSymbolChecker(tenant).WithRepoCheck(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter) + + apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, *symbolChecker, API_PAGE_SIZE) oapi.HandlerFromMuxWithBaseURL(&apiHandler, ServeMux, "/broker") proapi.HandlerFromMuxWithBaseURL(&ctx.PrApiHandler, ServeMux, "/broker") } diff --git a/broker/test/api/api-handler_test.go b/broker/test/api/api-handler_test.go index 2fb41707..420d5670 100644 --- a/broker/test/api/api-handler_test.go +++ b/broker/test/api/api-handler_test.go @@ -43,7 +43,7 @@ var eventRepo events.EventRepo var sseBroker *api.SseBroker var mockIllRepoError = new(mocks.MockIllRepositoryError) var mockEventRepoError = new(mocks.MockEventRepositoryError) -var handlerMock = api.NewApiHandler(mockEventRepoError, mockIllRepoError, common.NewTenant(""), api.LIMIT_DEFAULT) +var handlerMock = api.NewApiHandler(mockEventRepoError, mockIllRepoError, *api.NewSymbolChecker(common.NewTenant("")), api.LIMIT_DEFAULT) func TestMain(m *testing.M) { app.TENANT_TO_SYMBOL = "ISIL:DK-{tenant}" From ce2d12536fbd5b36f3bc75b10b93c7cdf19b8c8a Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 15 Apr 2026 15:08:29 +0200 Subject: [PATCH 03/21] SymbolChecker used for sse as well --- broker/api/sse_broker.go | 41 ++++++++++++++++-------------- broker/api/symbol_checker.go | 6 ++--- broker/api/symbol_checker_test.go | 14 ++++++++-- broker/app/app.go | 3 ++- broker/test/api/sse_broker_test.go | 4 +-- 5 files changed, 41 insertions(+), 27 deletions(-) diff --git a/broker/api/sse_broker.go b/broker/api/sse_broker.go index 7b084f10..7766a87d 100644 --- a/broker/api/sse_broker.go +++ b/broker/api/sse_broker.go @@ -1,6 +1,7 @@ package api import ( + "context" "encoding/json" "fmt" "net/http" @@ -14,19 +15,19 @@ import ( ) type SseBroker struct { - input chan SseMessage - clients map[string]map[chan string]bool - mu sync.Mutex - ctx common.ExtendedContext - tenant common.Tenant + input chan SseMessage + clients map[string]map[chan string]bool + mu sync.Mutex + ctx common.ExtendedContext + symbolChecker SymbolChecker } -func NewSseBroker(ctx common.ExtendedContext, tenant common.Tenant) (broker *SseBroker) { +func NewSseBroker(ctx common.ExtendedContext, symbolChecker SymbolChecker) (broker *SseBroker) { broker = &SseBroker{ - input: make(chan SseMessage), - clients: make(map[string]map[chan string]bool), - ctx: ctx, - tenant: tenant, + input: make(chan SseMessage), + clients: make(map[string]map[chan string]bool), + ctx: ctx, + symbolChecker: symbolChecker, } // Start the single broadcaster goroutine @@ -67,24 +68,26 @@ func (b *SseBroker) removeClient(receiver string, clientChannel chan string) { // ServeHTTP implements the http.Handler interface for the SSE endpoint. func (b *SseBroker) ServeHTTP(w http.ResponseWriter, r *http.Request) { - clientChannel := make(chan string, 10) + logParams := map[string]string{"method": "ServeHTTP"} + ectx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + tenant := r.Header.Get("X-Okapi-Tenant") - var symbol string - if b.tenant.IsSpecified() && tenant != "" { - symbol = b.tenant.GetSymbol(tenant) - } else { - symbol = r.URL.Query().Get("symbol") + suppliedSymbol := r.URL.Query().Get("symbol") + symbol, err := b.symbolChecker.GetSymbolForRequest(ectx, r, &tenant, &suppliedSymbol) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return } - side := r.URL.Query().Get("side") - if side == "" || symbol == "" { - http.Error(w, "query parameter 'side' and 'symbol' must be specified", http.StatusBadRequest) + if side == "" { + http.Error(w, "query parameter 'side' must be specified", http.StatusBadRequest) return } if side != string(prservice.SideBorrowing) && side != string(prservice.SideLending) { http.Error(w, fmt.Sprintf("query parameter 'side' must be %s or %s", prservice.SideBorrowing, prservice.SideLending), http.StatusBadRequest) return } + clientChannel := make(chan string, 10) b.mu.Lock() receiver := side + symbol clients := b.clients[receiver] diff --git a/broker/api/symbol_checker.go b/broker/api/symbol_checker.go index aa115b40..efd0fbde 100644 --- a/broker/api/symbol_checker.go +++ b/broker/api/symbol_checker.go @@ -32,13 +32,13 @@ func (s *SymbolChecker) WithLookupAdapter(directoryLookupAdapter adapter.Directo return s } -func (s *SymbolChecker) Check(ctx common.ExtendedContext, isBroker bool, tenant *string, symbol *string) (string, error) { +func (s *SymbolChecker) Check(ctx common.ExtendedContext, isBrokerPrefix bool, tenant *string, symbol *string) (string, error) { var mainSymbol string - if isBroker { + if isBrokerPrefix { if !s.tenantResolver.IsSpecified() { return "", errors.New("tenant mapping must be specified") } - if tenant == nil { + if tenant == nil || *tenant == "" { return "", errors.New("X-Okapi-Tenant must be specified") } mainSymbol = s.tenantResolver.GetSymbol(*tenant) diff --git a/broker/api/symbol_checker_test.go b/broker/api/symbol_checker_test.go index e78a0a91..1a73b89a 100644 --- a/broker/api/symbol_checker_test.go +++ b/broker/api/symbol_checker_test.go @@ -21,7 +21,12 @@ func TestSymbolChecker(t *testing.T) { assert.Error(t, err) assert.Equal(t, "symbol must be specified", err.Error()) - requestSymbol := "symbol2" + requestSymbol := "" + _, err = symbolChecker.Check(ctx, false, nil, &requestSymbol) + assert.Error(t, err) + assert.Equal(t, "symbol must be specified", err.Error()) + + requestSymbol = "symbol2" symbol, err := symbolChecker.Check(ctx, false, nil, &requestSymbol) assert.NoError(t, err) assert.Equal(t, requestSymbol, symbol) @@ -36,7 +41,12 @@ func TestSymbolChecker(t *testing.T) { assert.Error(t, err) assert.Equal(t, "X-Okapi-Tenant must be specified", err.Error()) - tenant := "tenant1" + tenant := "" + _, err = symbolChecker.Check(ctx, true, &tenant, nil) + assert.Error(t, err) + assert.Equal(t, "X-Okapi-Tenant must be specified", err.Error()) + + tenant = "tenant1" symbol, err = symbolChecker.Check(ctx, true, &tenant, nil) assert.NoError(t, err) assert.Equal(t, strings.ToUpper(tenant), symbol) diff --git a/broker/app/app.go b/broker/app/app.go index 776dc3cf..61da844c 100644 --- a/broker/app/app.go +++ b/broker/app/app.go @@ -172,7 +172,7 @@ func Init(ctx context.Context) (Context, error) { prApiHandler.SetAutoActionRunner(prActionService) prApiHandler.SetActionTaskProcessor(prActionService) - sseBroker := api.NewSseBroker(appCtx, tenant) + sseBroker := api.NewSseBroker(appCtx, *apiSymbolChecker) AddDefaultHandlers(eventBus, iso18626Client, supplierLocator, workflowManager, iso18626Handler, *prActionService, prApiHandler, sseBroker) err = StartEventBus(ctx, eventBus) @@ -220,6 +220,7 @@ func StartServer(ctx Context) error { if TENANT_TO_SYMBOL != "" { tenant = common.NewTenant(TENANT_TO_SYMBOL) symbolChecker = api.NewSymbolChecker(tenant).WithRepoCheck(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter) + ServeMux.HandleFunc("/broker/sse/events", ctx.SseBroker.ServeHTTP) apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, *symbolChecker, API_PAGE_SIZE) oapi.HandlerFromMuxWithBaseURL(&apiHandler, ServeMux, "/broker") diff --git a/broker/test/api/sse_broker_test.go b/broker/test/api/sse_broker_test.go index 629b9e60..d57b8a86 100644 --- a/broker/test/api/sse_broker_test.go +++ b/broker/test/api/sse_broker_test.go @@ -101,7 +101,7 @@ func TestSseEndpointNoSide(t *testing.T) { bodyBytes, err := io.ReadAll(resp.Body) assert.NoError(t, err) assert.Equal(t, 400, resp.StatusCode) - assert.Equal(t, "query parameter 'side' and 'symbol' must be specified\n", string(bodyBytes)) + assert.Equal(t, "query parameter 'side' must be specified\n", string(bodyBytes)) } func TestSseEndpointNoSymbol(t *testing.T) { @@ -110,7 +110,7 @@ func TestSseEndpointNoSymbol(t *testing.T) { bodyBytes, err := io.ReadAll(resp.Body) assert.NoError(t, err) assert.Equal(t, 400, resp.StatusCode) - assert.Equal(t, "query parameter 'side' and 'symbol' must be specified\n", string(bodyBytes)) + assert.Equal(t, "symbol must be specified\n", string(bodyBytes)) } func executeTask(t time.Time) { From 7358b719f8e77307f52e7e0e252e94a609e7979e Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 15 Apr 2026 16:05:31 +0200 Subject: [PATCH 04/21] Better check for okapi mode /broker prefix --- broker/api/symbol_checker.go | 2 +- broker/test/api/sse_broker_test.go | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/broker/api/symbol_checker.go b/broker/api/symbol_checker.go index c4a66c38..acfd2e7c 100644 --- a/broker/api/symbol_checker.go +++ b/broker/api/symbol_checker.go @@ -117,5 +117,5 @@ func (s *SymbolChecker) GetSymbolsForTenant(ctx common.ExtendedContext, tenant s } func (s *SymbolChecker) GetSymbolForRequest(ctx common.ExtendedContext, r *http.Request, tenant *string, symbol *string) (string, error) { - return s.Check(ctx, strings.Contains(r.RequestURI, "/broker/"), tenant, symbol) + return s.Check(ctx, strings.HasPrefix(r.URL.Path, "/broker/"), tenant, symbol) } diff --git a/broker/test/api/sse_broker_test.go b/broker/test/api/sse_broker_test.go index d57b8a86..983e3f9f 100644 --- a/broker/test/api/sse_broker_test.go +++ b/broker/test/api/sse_broker_test.go @@ -105,7 +105,7 @@ func TestSseEndpointNoSide(t *testing.T) { } func TestSseEndpointNoSymbol(t *testing.T) { - resp, err := http.Get(getLocalhostWithPort() + "/sse/events?side=borrowing") + resp, err := http.Get(getLocalhostWithPort() + "/sse/events?side=/broker/") assert.NoError(t, err) bodyBytes, err := io.ReadAll(resp.Body) assert.NoError(t, err) @@ -113,6 +113,15 @@ func TestSseEndpointNoSymbol(t *testing.T) { assert.Equal(t, "symbol must be specified\n", string(bodyBytes)) } +func TestSseEndpointNoTenant(t *testing.T) { + resp, err := http.Get(getLocalhostWithPort() + "/broker/sse/events?side=borrowing") + assert.NoError(t, err) + bodyBytes, err := io.ReadAll(resp.Body) + assert.NoError(t, err) + assert.Equal(t, 400, resp.StatusCode) + assert.Equal(t, "X-Okapi-Tenant must be specified\n", string(bodyBytes)) +} + func executeTask(t time.Time) { ctx := common.CreateExtCtxWithArgs(context.Background(), nil) var message = iso18626.NewISO18626Message() From 135e9539471077124e1934669fb5481907f02493 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 15 Apr 2026 16:24:07 +0200 Subject: [PATCH 05/21] SymbolChecker fixes --- broker/api/symbol_checker.go | 5 +---- broker/api/symbol_checker_test.go | 7 ++++++- broker/test/api/sse_broker_test.go | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/broker/api/symbol_checker.go b/broker/api/symbol_checker.go index acfd2e7c..7a7f84ba 100644 --- a/broker/api/symbol_checker.go +++ b/broker/api/symbol_checker.go @@ -59,7 +59,7 @@ func (s *SymbolChecker) Check(ctx common.ExtendedContext, isBrokerPrefix bool, t ctx.Logger().Error("no peers for symbol", "symbol", mainSymbol) return "", errors.New("no peers for symbol") } - if symbol == nil || *symbol == mainSymbol { + if symbol == nil || *symbol == "" || *symbol == mainSymbol { return mainSymbol, nil } found := false @@ -92,9 +92,6 @@ func (s *SymbolChecker) GetSymbolsForTenant(ctx common.ExtendedContext, tenant s if s.illRepo == nil { return []string{mainSymbol} } - if s.illRepo == nil { - return []string{mainSymbol} - } peers, _, err := (*s.illRepo).GetCachedPeersBySymbols(ctx, []string{mainSymbol}, s.directoryLookupAdapter) if err != nil { return []string{} diff --git a/broker/api/symbol_checker_test.go b/broker/api/symbol_checker_test.go index 38a11e25..710915b4 100644 --- a/broker/api/symbol_checker_test.go +++ b/broker/api/symbol_checker_test.go @@ -103,10 +103,15 @@ func TestSymbolCheckerRepoOK(t *testing.T) { assert.Equal(t, requestSymbol, symbol) requestSymbol = "LIB" - tenant := "SYMBOL" + tenant := "symbol" symbol, err = symbolChecker.Check(ctx, true, &tenant, &requestSymbol) assert.NoError(t, err) assert.Equal(t, requestSymbol, symbol) + + requestSymbol = "" + symbol, err = symbolChecker.Check(ctx, true, &tenant, &requestSymbol) + assert.NoError(t, err) + assert.Equal(t, strings.ToUpper(tenant), symbol) } func TestSymbolCheckerRepoBranches(t *testing.T) { diff --git a/broker/test/api/sse_broker_test.go b/broker/test/api/sse_broker_test.go index 983e3f9f..fb3e8eeb 100644 --- a/broker/test/api/sse_broker_test.go +++ b/broker/test/api/sse_broker_test.go @@ -105,7 +105,7 @@ func TestSseEndpointNoSide(t *testing.T) { } func TestSseEndpointNoSymbol(t *testing.T) { - resp, err := http.Get(getLocalhostWithPort() + "/sse/events?side=/broker/") + resp, err := http.Get(getLocalhostWithPort() + "/sse/events?side=borrowwing&other=/broker/") assert.NoError(t, err) bodyBytes, err := io.ReadAll(resp.Body) assert.NoError(t, err) From b56dc4441039d2126ea0387df817f36cf3d91315 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 15 Apr 2026 16:38:14 +0200 Subject: [PATCH 06/21] takes api.symbolChecker --- broker/app/app.go | 2 +- broker/patron_request/api/api-handler.go | 4 +- broker/patron_request/api/api-handler_test.go | 102 +++++++++--------- 3 files changed, 54 insertions(+), 54 deletions(-) diff --git a/broker/app/app.go b/broker/app/app.go index c38642b1..bd98753a 100644 --- a/broker/app/app.go +++ b/broker/app/app.go @@ -168,7 +168,7 @@ func Init(ctx context.Context) (Context, error) { workflowManager := service.CreateWorkflowManager(eventBus, illRepo, service.WorkflowConfig{}) tenant := common.NewTenant(TENANT_TO_SYMBOL) apiSymbolChecker := api.NewSymbolChecker(tenant).WithIllRepo(illRepo).WithLookupAdapter(dirAdapter) - prApiHandler := prapi.NewPrApiHandler(prRepo, eventBus, eventRepo, apiSymbolChecker, &iso18626Handler, API_PAGE_SIZE) + prApiHandler := prapi.NewPrApiHandler(prRepo, eventBus, eventRepo, *apiSymbolChecker, &iso18626Handler, API_PAGE_SIZE) prApiHandler.SetAutoActionRunner(prActionService) prApiHandler.SetActionTaskProcessor(prActionService) diff --git a/broker/patron_request/api/api-handler.go b/broker/patron_request/api/api-handler.go index e5ac0d8e..a3fa0f31 100644 --- a/broker/patron_request/api/api-handler.go +++ b/broker/patron_request/api/api-handler.go @@ -50,14 +50,14 @@ type PatronRequestApiHandler struct { } func NewPrApiHandler(prRepo pr_db.PrRepo, eventBus events.EventBus, - eventRepo events.EventRepo, symbolChecker *api.SymbolChecker, iso18626Handler handler.Iso18626HandlerInterface, limitDefault int32) PatronRequestApiHandler { + eventRepo events.EventRepo, symbolChecker api.SymbolChecker, iso18626Handler handler.Iso18626HandlerInterface, limitDefault int32) PatronRequestApiHandler { return PatronRequestApiHandler{ limitDefault: limitDefault, prRepo: prRepo, eventBus: eventBus, eventRepo: eventRepo, actionMappingService: prservice.ActionMappingService{SMService: &prservice.StateModelService{}}, - symbolChecker: *symbolChecker, + symbolChecker: symbolChecker, notificationSender: *prservice.CreatePatronRequestNotificationService(prRepo, eventBus, iso18626Handler), } } diff --git a/broker/patron_request/api/api-handler_test.go b/broker/patron_request/api/api-handler_test.go index e0428aac..7586f1b2 100644 --- a/broker/patron_request/api/api-handler_test.go +++ b/broker/patron_request/api/api-handler_test.go @@ -62,7 +62,7 @@ func TestGetDbText(t *testing.T) { } func TestGetPatronRequests(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() params := proapi.GetPatronRequestsParams{ @@ -75,7 +75,7 @@ func TestGetPatronRequests(t *testing.T) { } func TestGetPatronRequestsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() params := proapi.GetPatronRequestsParams{ @@ -87,7 +87,7 @@ func TestGetPatronRequestsNoSymbol(t *testing.T) { } func TestGetPatronRequestsWithLimits(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() offset := proapi.Offset(10) @@ -107,7 +107,7 @@ func TestGetPatronRequestsWithLimits(t *testing.T) { func TestGetPatronRequestsWithRequesterReqId(t *testing.T) { repo := new(PrRepoCapture) - handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() requesterReqID := "req-123" @@ -126,7 +126,7 @@ func TestGetPatronRequestsWithRequesterReqId(t *testing.T) { } func TestPostPatronRequests(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) id := "1" toCreate := proapi.CreatePatronRequest{ Id: &id, @@ -145,7 +145,7 @@ func TestPostPatronRequests(t *testing.T) { } func TestPostPatronRequestsMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) toCreate := proapi.PatronRequest{Id: "1"} jsonBytes, err := json.Marshal(toCreate) assert.NoError(t, err, "failed to marshal patron request") @@ -159,7 +159,7 @@ func TestPostPatronRequestsMissingSymbol(t *testing.T) { } func TestPostPatronRequestsInvalidJson(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("POST", "/", bytes.NewBuffer([]byte("a\": v\""))) rr := httptest.NewRecorder() tenant := proapi.Tenant("test-lib") @@ -169,7 +169,7 @@ func TestPostPatronRequestsInvalidJson(t *testing.T) { } func TestPostPatronRequestsInvalidIllRequestShape(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) jsonBytes := []byte(`{ "id":"1", "requesterSymbol":"` + symbol + `", @@ -185,7 +185,7 @@ func TestPostPatronRequestsInvalidIllRequestShape(t *testing.T) { } func TestDeletePatronRequestsIdNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "2", proapi.DeletePatronRequestsIdParams{Symbol: &symbol}) @@ -193,7 +193,7 @@ func TestDeletePatronRequestsIdNotFound(t *testing.T) { } func TestDeletePatronRequestsIdMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "2", proapi.DeletePatronRequestsIdParams{}) @@ -202,7 +202,7 @@ func TestDeletePatronRequestsIdMissingSymbol(t *testing.T) { } func TestDeletePatronRequestsIdError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "1", proapi.DeletePatronRequestsIdParams{Symbol: &symbol}) @@ -211,7 +211,7 @@ func TestDeletePatronRequestsIdError(t *testing.T) { } func TestDeletePatronRequestsId(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "3", proapi.DeletePatronRequestsIdParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -220,7 +220,7 @@ func TestDeletePatronRequestsId(t *testing.T) { } func TestDeletePatronRequestsIdDeleted(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "4", proapi.DeletePatronRequestsIdParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -228,7 +228,7 @@ func TestDeletePatronRequestsIdDeleted(t *testing.T) { } func TestGetPatronRequestsIdMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "2", proapi.GetPatronRequestsIdParams{}) @@ -237,7 +237,7 @@ func TestGetPatronRequestsIdMissingSymbol(t *testing.T) { } func TestGetPatronRequestsIdNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "2", proapi.GetPatronRequestsIdParams{Symbol: &symbol}) @@ -245,7 +245,7 @@ func TestGetPatronRequestsIdNotFound(t *testing.T) { } func TestGetPatronRequestsId(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "1", proapi.GetPatronRequestsIdParams{Symbol: &symbol}) @@ -254,7 +254,7 @@ func TestGetPatronRequestsId(t *testing.T) { } func TestGetPatronRequestsIdActions(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -263,7 +263,7 @@ func TestGetPatronRequestsIdActions(t *testing.T) { } func TestGetPatronRequestsIdActionsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Side: &proapiBorrowingSide}) @@ -272,7 +272,7 @@ func TestGetPatronRequestsIdActionsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdActionsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "1", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -281,7 +281,7 @@ func TestGetPatronRequestsIdActionsDbError(t *testing.T) { } func TestGetPatronRequestsIdActionsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -290,7 +290,7 @@ func TestGetPatronRequestsIdActionsNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdActionNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Side: &proapiBorrowingSide}) @@ -299,7 +299,7 @@ func TestPostPatronRequestsIdActionNoSymbol(t *testing.T) { } func TestPostPatronRequestsIdActionDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "1", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -308,7 +308,7 @@ func TestPostPatronRequestsIdActionDbError(t *testing.T) { } func TestPostPatronRequestsIdActionNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -317,7 +317,7 @@ func TestPostPatronRequestsIdActionNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdActionErrorParsing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", strings.NewReader("{")) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -326,7 +326,7 @@ func TestPostPatronRequestsIdActionErrorParsing(t *testing.T) { } func TestGetPatronRequestsIdEventsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Side: &proapiBorrowingSide}) @@ -335,7 +335,7 @@ func TestGetPatronRequestsIdEventsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdEventsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "1", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -344,7 +344,7 @@ func TestGetPatronRequestsIdEventsDbError(t *testing.T) { } func TestGetPatronRequestsIdEventsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -353,7 +353,7 @@ func TestGetPatronRequestsIdEventsNotFoundBecauseOfSide(t *testing.T) { } func TestGetPatronRequestsIdEventsErrorGettingEvents(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -362,7 +362,7 @@ func TestGetPatronRequestsIdEventsErrorGettingEvents(t *testing.T) { } func TestGetPatronRequestsIdNotificationsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Side: &proapiBorrowingSide}) @@ -371,7 +371,7 @@ func TestGetPatronRequestsIdNotificationsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdNotificationsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "1", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -380,7 +380,7 @@ func TestGetPatronRequestsIdNotificationsDbError(t *testing.T) { } func TestGetPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -389,7 +389,7 @@ func TestGetPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { } func TestGetPatronRequestsIdNotificationsErrorGettingEvents(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -398,7 +398,7 @@ func TestGetPatronRequestsIdNotificationsErrorGettingEvents(t *testing.T) { } func TestParseAndValidateIllRequestAndBuildDbPatronRequest(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) creationTime := time.Now() id := uuid.NewString() @@ -425,7 +425,7 @@ func TestParseAndValidateIllRequestAndBuildDbPatronRequest(t *testing.T) { } func TestParseAndValidateIllRequestInvalidRequesterSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) invalidSymbol := "REQ" @@ -435,7 +435,7 @@ func TestParseAndValidateIllRequestInvalidRequesterSymbol(t *testing.T) { } func TestParseAndValidateIllRequestInvalidBrokerSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) previousBrokerSymbol := brokerSymbol brokerSymbol = "BROKER" @@ -452,7 +452,7 @@ func TestParseAndValidateIllRequestInvalidBrokerSymbol(t *testing.T) { } func TestPostPatronRequestsIdNotificationsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdNotifications(rr, req, "3", proapi.PostPatronRequestsIdNotificationsParams{Side: &proapiBorrowingSide}) @@ -461,7 +461,7 @@ func TestPostPatronRequestsIdNotificationsNoSymbol(t *testing.T) { } func TestPostPatronRequestsIdNotificationsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -471,7 +471,7 @@ func TestPostPatronRequestsIdNotificationsDbError(t *testing.T) { } func TestPostPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -481,7 +481,7 @@ func TestPostPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdNotificationsErrorSavingNotification(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -491,7 +491,7 @@ func TestPostPatronRequestsIdNotificationsErrorSavingNotification(t *testing.T) } func TestPostPatronRequestsIdNotificationsErrorBecauseOfBodyMissing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdNotifications(rr, req, "3", proapi.PostPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -500,7 +500,7 @@ func TestPostPatronRequestsIdNotificationsErrorBecauseOfBodyMissing(t *testing.T } func TestPostPatronRequestsIdNotificationsErrorBecauseOfBody(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) body := "{\"note" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -510,7 +510,7 @@ func TestPostPatronRequestsIdNotificationsErrorBecauseOfBody(t *testing.T) { } func TestPostPatronRequestsIdNotificationsErrorFailedSendOnlyLogged(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositorySuccess), api.NewSymbolChecker(common.NewTenant("")), new(MockIso18626Handler), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositorySuccess), *api.NewSymbolChecker(common.NewTenant("")), new(MockIso18626Handler), 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -520,7 +520,7 @@ func TestPostPatronRequestsIdNotificationsErrorFailedSendOnlyLogged(t *testing.T } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("PUT", "/", nil) rr := httptest.NewRecorder() handler.PutPatronRequestsIdNotificationsNotificationIdReceipt(rr, req, "3", "n1", proapi.PutPatronRequestsIdNotificationsNotificationIdReceiptParams{Side: &proapiBorrowingSide}) @@ -529,7 +529,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNoSymbol(t *testin } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -539,7 +539,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptDbError(t *testing } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -549,7 +549,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFoundBecauseOfS } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorReadingNotification(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -559,7 +559,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorReadingNotifi } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -569,7 +569,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFound(t *testin } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBodyMissing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) req, _ := http.NewRequest("PUT", "/", nil) rr := httptest.NewRecorder() handler.PutPatronRequestsIdNotificationsNotificationIdReceipt(rr, req, "3", "n1", proapi.PutPatronRequestsIdNotificationsNotificationIdReceiptParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -578,7 +578,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBody } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBody(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) body := "{\"receipt" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -588,7 +588,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBody } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptPrDoesNotOwn(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -598,7 +598,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptPrDoesNotOwn(t *te } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptFailedToSave(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() From 3c43bdca6f139d1cb5c88120406a28d6f76fbc65 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 15 Apr 2026 20:40:32 +0200 Subject: [PATCH 07/21] common.Tenant gone --- broker/api/api-handler.go | 4 +- broker/api/symbol_checker.go | 39 ++++--- broker/api/symbol_checker_test.go | 46 ++++---- broker/app/app.go | 9 +- broker/common/tenant.go | 21 ---- broker/patron_request/api/api-handler_test.go | 102 +++++++++--------- broker/test/api/api-handler_test.go | 2 +- 7 files changed, 102 insertions(+), 121 deletions(-) delete mode 100644 broker/common/tenant.go diff --git a/broker/api/api-handler.go b/broker/api/api-handler.go index 13b10dc0..d8e4702d 100644 --- a/broker/api/api-handler.go +++ b/broker/api/api-handler.go @@ -54,7 +54,7 @@ func (a *ApiHandler) isOwner(ctx common.ExtendedContext, trans *ill_db.IllTransa if tenant == nil && requesterSymbol != nil { return trans.RequesterSymbol.String == *requesterSymbol } - if !a.symbolChecker.tenantResolver.IsSpecified() { + if !a.symbolChecker.IsSpecified() { return true } if tenant == nil { @@ -172,7 +172,7 @@ func (a *ApiHandler) GetIllTransactions(w http.ResponseWriter, r *http.Request, fullCount = 1 resp.Items = append(resp.Items, toApiIllTransaction(r, *tran)) } - } else if a.symbolChecker.tenantResolver.IsSpecified() { + } else if a.symbolChecker.IsSpecified() { var symbols []string if params.XOkapiTenant != nil { symbols = a.symbolChecker.GetSymbolsForTenant(ctx, *params.XOkapiTenant) diff --git a/broker/api/symbol_checker.go b/broker/api/symbol_checker.go index 7a7f84ba..ae7994cb 100644 --- a/broker/api/symbol_checker.go +++ b/broker/api/symbol_checker.go @@ -13,13 +13,16 @@ import ( type SymbolChecker struct { illRepo *ill_db.IllRepo directoryLookupAdapter adapter.DirectoryLookupAdapter - tenantResolver common.Tenant + tenantSymbolMap string } -func NewSymbolChecker(tenantResolver common.Tenant) *SymbolChecker { - return &SymbolChecker{ - tenantResolver: tenantResolver, - } +func NewSymbolChecker() *SymbolChecker { + return &SymbolChecker{} +} + +func (s *SymbolChecker) WithTenantSymbol(tenantSymbol string) *SymbolChecker { + s.tenantSymbolMap = tenantSymbol + return s } func (s *SymbolChecker) WithIllRepo(illRepo ill_db.IllRepo) *SymbolChecker { @@ -32,16 +35,24 @@ func (s *SymbolChecker) WithLookupAdapter(directoryLookupAdapter adapter.Directo return s } -func (s *SymbolChecker) Check(ctx common.ExtendedContext, isBrokerPrefix bool, tenant *string, symbol *string) (string, error) { +func (s *SymbolChecker) IsSpecified() bool { + return s.tenantSymbolMap != "" +} + +func (s *SymbolChecker) getSymbol(tenant string) string { + return strings.ReplaceAll(s.tenantSymbolMap, "{tenant}", strings.ToUpper(tenant)) +} + +func (s *SymbolChecker) symbolForRequest(ctx common.ExtendedContext, isBrokerPrefix bool, tenant *string, symbol *string) (string, error) { var mainSymbol string if isBrokerPrefix { - if !s.tenantResolver.IsSpecified() { + if !s.IsSpecified() { return "", errors.New("tenant mapping must be specified") } if tenant == nil || *tenant == "" { return "", errors.New("X-Okapi-Tenant must be specified") } - mainSymbol = s.tenantResolver.GetSymbol(*tenant) + mainSymbol = s.getSymbol(*tenant) } else { if symbol == nil || *symbol == "" { return "", errors.New("symbol must be specified") @@ -81,14 +92,18 @@ func (s *SymbolChecker) Check(ctx common.ExtendedContext, isBrokerPrefix bool, t return *symbol, nil } +func (s *SymbolChecker) GetSymbolForRequest(ctx common.ExtendedContext, r *http.Request, tenant *string, symbol *string) (string, error) { + return s.symbolForRequest(ctx, strings.HasPrefix(r.URL.Path, "/broker/"), tenant, symbol) +} + func (s *SymbolChecker) GetSymbolsForTenant(ctx common.ExtendedContext, tenant string) []string { - if !s.tenantResolver.IsSpecified() { + if !s.IsSpecified() { return []string{} } if tenant == "" { return []string{} } - mainSymbol := s.tenantResolver.GetSymbol(tenant) + mainSymbol := s.getSymbol(tenant) if s.illRepo == nil { return []string{mainSymbol} } @@ -112,7 +127,3 @@ func (s *SymbolChecker) GetSymbolsForTenant(ctx common.ExtendedContext, tenant s } return symbols } - -func (s *SymbolChecker) GetSymbolForRequest(ctx common.ExtendedContext, r *http.Request, tenant *string, symbol *string) (string, error) { - return s.Check(ctx, strings.HasPrefix(r.URL.Path, "/broker/"), tenant, symbol) -} diff --git a/broker/api/symbol_checker_test.go b/broker/api/symbol_checker_test.go index 710915b4..1d761a18 100644 --- a/broker/api/symbol_checker_test.go +++ b/broker/api/symbol_checker_test.go @@ -13,41 +13,41 @@ import ( ) func TestSymbolChecker(t *testing.T) { - tenantResolver := common.NewTenant("") - symbolChecker := NewSymbolChecker(tenantResolver) + symbolChecker := NewSymbolChecker() + assert.False(t, symbolChecker.IsSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) - _, err := symbolChecker.Check(ctx, false, nil, nil) + _, err := symbolChecker.symbolForRequest(ctx, false, nil, nil) assert.Error(t, err) assert.Equal(t, "symbol must be specified", err.Error()) requestSymbol := "" - _, err = symbolChecker.Check(ctx, false, nil, &requestSymbol) + _, err = symbolChecker.symbolForRequest(ctx, false, nil, &requestSymbol) assert.Error(t, err) assert.Equal(t, "symbol must be specified", err.Error()) requestSymbol = "symbol2" - symbol, err := symbolChecker.Check(ctx, false, nil, &requestSymbol) + symbol, err := symbolChecker.symbolForRequest(ctx, false, nil, &requestSymbol) assert.NoError(t, err) assert.Equal(t, requestSymbol, symbol) - _, err = symbolChecker.Check(ctx, true, nil, nil) + _, err = symbolChecker.symbolForRequest(ctx, true, nil, nil) assert.Error(t, err) assert.Equal(t, "tenant mapping must be specified", err.Error()) - tenantResolver = common.NewTenant("{tenant}") - symbolChecker = NewSymbolChecker(tenantResolver) - _, err = symbolChecker.Check(ctx, true, nil, nil) + symbolChecker = NewSymbolChecker().WithTenantSymbol("{tenant}") + assert.True(t, symbolChecker.IsSpecified()) + _, err = symbolChecker.symbolForRequest(ctx, true, nil, nil) assert.Error(t, err) assert.Equal(t, "X-Okapi-Tenant must be specified", err.Error()) tenant := "" - _, err = symbolChecker.Check(ctx, true, &tenant, nil) + _, err = symbolChecker.symbolForRequest(ctx, true, &tenant, nil) assert.Error(t, err) assert.Equal(t, "X-Okapi-Tenant must be specified", err.Error()) tenant = "tenant1" - symbol, err = symbolChecker.Check(ctx, true, &tenant, nil) + symbol, err = symbolChecker.symbolForRequest(ctx, true, &tenant, nil) assert.NoError(t, err) assert.Equal(t, strings.ToUpper(tenant), symbol) } @@ -73,65 +73,59 @@ func (r *MockIllRepo) GetBranchSymbolsByPeerId(ctx common.ExtendedContext, peerI } func TestSymbolCheckerRepoNoPeer(t *testing.T) { - tenantResolver := common.NewTenant("{tenant}") - mockIllRepo := new(MockIllRepo) mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{}, "", nil) - symbolChecker := NewSymbolChecker(tenantResolver).WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) + symbolChecker := NewSymbolChecker().WithTenantSymbol("{tenant}").WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) requestSymbol := "SYMBOL2" - _, err := symbolChecker.Check(ctx, false, nil, &requestSymbol) + _, err := symbolChecker.symbolForRequest(ctx, false, nil, &requestSymbol) assert.Error(t, err) assert.Equal(t, "no peers for symbol", err.Error()) } func TestSymbolCheckerRepoOK(t *testing.T) { - tenantResolver := common.NewTenant("{tenant}") - mockIllRepo := new(MockIllRepo) mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{{ID: "SYMBOL"}}, "", nil) mockIllRepo.On("GetBranchSymbolsByPeerId", mock.Anything, mock.Anything).Return([]ill_db.BranchSymbol{{SymbolValue: "LIB"}}, nil) - symbolChecker := NewSymbolChecker(tenantResolver).WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) + symbolChecker := NewSymbolChecker().WithTenantSymbol("{tenant}").WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) requestSymbol := "SYMBOL" - symbol, err := symbolChecker.Check(ctx, false, nil, &requestSymbol) + symbol, err := symbolChecker.symbolForRequest(ctx, false, nil, &requestSymbol) assert.NoError(t, err) assert.Equal(t, requestSymbol, symbol) requestSymbol = "LIB" tenant := "symbol" - symbol, err = symbolChecker.Check(ctx, true, &tenant, &requestSymbol) + symbol, err = symbolChecker.symbolForRequest(ctx, true, &tenant, &requestSymbol) assert.NoError(t, err) assert.Equal(t, requestSymbol, symbol) requestSymbol = "" - symbol, err = symbolChecker.Check(ctx, true, &tenant, &requestSymbol) + symbol, err = symbolChecker.symbolForRequest(ctx, true, &tenant, &requestSymbol) assert.NoError(t, err) assert.Equal(t, strings.ToUpper(tenant), symbol) } func TestSymbolCheckerRepoBranches(t *testing.T) { - tenantResolver := common.NewTenant("{tenant}") - mockIllRepo := new(MockIllRepo) mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{{ID: "SYMBOL"}}, "", nil) mockIllRepo.On("GetBranchSymbolsByPeerId", mock.Anything, mock.Anything).Return([]ill_db.BranchSymbol{}, nil) - symbolChecker := NewSymbolChecker(tenantResolver).WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) + symbolChecker := NewSymbolChecker().WithTenantSymbol("{tenant}").WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) requestSymbol := "SYMBOL" - symbol, err := symbolChecker.Check(ctx, false, nil, &requestSymbol) + symbol, err := symbolChecker.symbolForRequest(ctx, false, nil, &requestSymbol) assert.NoError(t, err) assert.Equal(t, requestSymbol, symbol) requestSymbol = "LIB" tenant := "SYMBOL" - _, err = symbolChecker.Check(ctx, true, &tenant, &requestSymbol) + _, err = symbolChecker.symbolForRequest(ctx, true, &tenant, &requestSymbol) assert.Error(t, err) assert.Equal(t, "symbol does not match any branch symbols for tenant", err.Error()) } diff --git a/broker/app/app.go b/broker/app/app.go index bd98753a..1adebf98 100644 --- a/broker/app/app.go +++ b/broker/app/app.go @@ -166,8 +166,7 @@ func Init(ctx context.Context) (Context, error) { iso18626Client := client.CreateIso18626Client(eventBus, illRepo, prMessageHandler, MAX_MESSAGE_SIZE, delay) supplierLocator := service.CreateSupplierLocator(eventBus, illRepo, dirAdapter, holdingsAdapter) workflowManager := service.CreateWorkflowManager(eventBus, illRepo, service.WorkflowConfig{}) - tenant := common.NewTenant(TENANT_TO_SYMBOL) - apiSymbolChecker := api.NewSymbolChecker(tenant).WithIllRepo(illRepo).WithLookupAdapter(dirAdapter) + apiSymbolChecker := api.NewSymbolChecker().WithIllRepo(illRepo).WithLookupAdapter(dirAdapter).WithTenantSymbol(TENANT_TO_SYMBOL) prApiHandler := prapi.NewPrApiHandler(prRepo, eventBus, eventRepo, *apiSymbolChecker, &iso18626Handler, API_PAGE_SIZE) prApiHandler.SetAutoActionRunner(prActionService) prApiHandler.SetActionTaskProcessor(prActionService) @@ -211,15 +210,13 @@ func StartServer(ctx Context) error { _, _ = w.Write(oapi.OpenAPISpecYAML) }) - tenant := common.NewTenant("") - symbolChecker := api.NewSymbolChecker(tenant).WithIllRepo(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter) + symbolChecker := api.NewSymbolChecker().WithIllRepo(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter) apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, *symbolChecker, API_PAGE_SIZE) oapi.HandlerFromMux(&apiHandler, ServeMux) proapi.HandlerFromMux(&ctx.PrApiHandler, ServeMux) if TENANT_TO_SYMBOL != "" { - tenant = common.NewTenant(TENANT_TO_SYMBOL) - symbolChecker = api.NewSymbolChecker(tenant).WithIllRepo(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter) + symbolChecker = api.NewSymbolChecker().WithIllRepo(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter).WithTenantSymbol(TENANT_TO_SYMBOL) ServeMux.HandleFunc("/broker/sse/events", ctx.SseBroker.ServeHTTP) apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, *symbolChecker, API_PAGE_SIZE) diff --git a/broker/common/tenant.go b/broker/common/tenant.go deleted file mode 100644 index 9e17acc9..00000000 --- a/broker/common/tenant.go +++ /dev/null @@ -1,21 +0,0 @@ -package common - -import ( - "strings" -) - -type Tenant struct { - mapping string -} - -func NewTenant(tenantSymbol string) Tenant { - return Tenant{mapping: tenantSymbol} -} - -func (t *Tenant) IsSpecified() bool { - return t.mapping != "" -} - -func (t *Tenant) GetSymbol(tenant string) string { - return strings.ReplaceAll(t.mapping, "{tenant}", strings.ToUpper(tenant)) -} diff --git a/broker/patron_request/api/api-handler_test.go b/broker/patron_request/api/api-handler_test.go index 7586f1b2..a1ad8e11 100644 --- a/broker/patron_request/api/api-handler_test.go +++ b/broker/patron_request/api/api-handler_test.go @@ -62,7 +62,7 @@ func TestGetDbText(t *testing.T) { } func TestGetPatronRequests(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() params := proapi.GetPatronRequestsParams{ @@ -75,7 +75,7 @@ func TestGetPatronRequests(t *testing.T) { } func TestGetPatronRequestsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() params := proapi.GetPatronRequestsParams{ @@ -87,7 +87,7 @@ func TestGetPatronRequestsNoSymbol(t *testing.T) { } func TestGetPatronRequestsWithLimits(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() offset := proapi.Offset(10) @@ -107,7 +107,7 @@ func TestGetPatronRequestsWithLimits(t *testing.T) { func TestGetPatronRequestsWithRequesterReqId(t *testing.T) { repo := new(PrRepoCapture) - handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() requesterReqID := "req-123" @@ -126,7 +126,7 @@ func TestGetPatronRequestsWithRequesterReqId(t *testing.T) { } func TestPostPatronRequests(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) id := "1" toCreate := proapi.CreatePatronRequest{ Id: &id, @@ -145,7 +145,7 @@ func TestPostPatronRequests(t *testing.T) { } func TestPostPatronRequestsMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) toCreate := proapi.PatronRequest{Id: "1"} jsonBytes, err := json.Marshal(toCreate) assert.NoError(t, err, "failed to marshal patron request") @@ -159,7 +159,7 @@ func TestPostPatronRequestsMissingSymbol(t *testing.T) { } func TestPostPatronRequestsInvalidJson(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("POST", "/", bytes.NewBuffer([]byte("a\": v\""))) rr := httptest.NewRecorder() tenant := proapi.Tenant("test-lib") @@ -169,7 +169,7 @@ func TestPostPatronRequestsInvalidJson(t *testing.T) { } func TestPostPatronRequestsInvalidIllRequestShape(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) jsonBytes := []byte(`{ "id":"1", "requesterSymbol":"` + symbol + `", @@ -185,7 +185,7 @@ func TestPostPatronRequestsInvalidIllRequestShape(t *testing.T) { } func TestDeletePatronRequestsIdNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "2", proapi.DeletePatronRequestsIdParams{Symbol: &symbol}) @@ -193,7 +193,7 @@ func TestDeletePatronRequestsIdNotFound(t *testing.T) { } func TestDeletePatronRequestsIdMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "2", proapi.DeletePatronRequestsIdParams{}) @@ -202,7 +202,7 @@ func TestDeletePatronRequestsIdMissingSymbol(t *testing.T) { } func TestDeletePatronRequestsIdError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "1", proapi.DeletePatronRequestsIdParams{Symbol: &symbol}) @@ -211,7 +211,7 @@ func TestDeletePatronRequestsIdError(t *testing.T) { } func TestDeletePatronRequestsId(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "3", proapi.DeletePatronRequestsIdParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -220,7 +220,7 @@ func TestDeletePatronRequestsId(t *testing.T) { } func TestDeletePatronRequestsIdDeleted(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "4", proapi.DeletePatronRequestsIdParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -228,7 +228,7 @@ func TestDeletePatronRequestsIdDeleted(t *testing.T) { } func TestGetPatronRequestsIdMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "2", proapi.GetPatronRequestsIdParams{}) @@ -237,7 +237,7 @@ func TestGetPatronRequestsIdMissingSymbol(t *testing.T) { } func TestGetPatronRequestsIdNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "2", proapi.GetPatronRequestsIdParams{Symbol: &symbol}) @@ -245,7 +245,7 @@ func TestGetPatronRequestsIdNotFound(t *testing.T) { } func TestGetPatronRequestsId(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "1", proapi.GetPatronRequestsIdParams{Symbol: &symbol}) @@ -254,7 +254,7 @@ func TestGetPatronRequestsId(t *testing.T) { } func TestGetPatronRequestsIdActions(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -263,7 +263,7 @@ func TestGetPatronRequestsIdActions(t *testing.T) { } func TestGetPatronRequestsIdActionsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Side: &proapiBorrowingSide}) @@ -272,7 +272,7 @@ func TestGetPatronRequestsIdActionsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdActionsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "1", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -281,7 +281,7 @@ func TestGetPatronRequestsIdActionsDbError(t *testing.T) { } func TestGetPatronRequestsIdActionsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -290,7 +290,7 @@ func TestGetPatronRequestsIdActionsNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdActionNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Side: &proapiBorrowingSide}) @@ -299,7 +299,7 @@ func TestPostPatronRequestsIdActionNoSymbol(t *testing.T) { } func TestPostPatronRequestsIdActionDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "1", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -308,7 +308,7 @@ func TestPostPatronRequestsIdActionDbError(t *testing.T) { } func TestPostPatronRequestsIdActionNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -317,7 +317,7 @@ func TestPostPatronRequestsIdActionNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdActionErrorParsing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", strings.NewReader("{")) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -326,7 +326,7 @@ func TestPostPatronRequestsIdActionErrorParsing(t *testing.T) { } func TestGetPatronRequestsIdEventsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Side: &proapiBorrowingSide}) @@ -335,7 +335,7 @@ func TestGetPatronRequestsIdEventsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdEventsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "1", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -344,7 +344,7 @@ func TestGetPatronRequestsIdEventsDbError(t *testing.T) { } func TestGetPatronRequestsIdEventsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -353,7 +353,7 @@ func TestGetPatronRequestsIdEventsNotFoundBecauseOfSide(t *testing.T) { } func TestGetPatronRequestsIdEventsErrorGettingEvents(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -362,7 +362,7 @@ func TestGetPatronRequestsIdEventsErrorGettingEvents(t *testing.T) { } func TestGetPatronRequestsIdNotificationsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Side: &proapiBorrowingSide}) @@ -371,7 +371,7 @@ func TestGetPatronRequestsIdNotificationsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdNotificationsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "1", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -380,7 +380,7 @@ func TestGetPatronRequestsIdNotificationsDbError(t *testing.T) { } func TestGetPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -389,7 +389,7 @@ func TestGetPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { } func TestGetPatronRequestsIdNotificationsErrorGettingEvents(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -398,7 +398,7 @@ func TestGetPatronRequestsIdNotificationsErrorGettingEvents(t *testing.T) { } func TestParseAndValidateIllRequestAndBuildDbPatronRequest(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) creationTime := time.Now() id := uuid.NewString() @@ -425,7 +425,7 @@ func TestParseAndValidateIllRequestAndBuildDbPatronRequest(t *testing.T) { } func TestParseAndValidateIllRequestInvalidRequesterSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) invalidSymbol := "REQ" @@ -435,7 +435,7 @@ func TestParseAndValidateIllRequestInvalidRequesterSymbol(t *testing.T) { } func TestParseAndValidateIllRequestInvalidBrokerSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) previousBrokerSymbol := brokerSymbol brokerSymbol = "BROKER" @@ -452,7 +452,7 @@ func TestParseAndValidateIllRequestInvalidBrokerSymbol(t *testing.T) { } func TestPostPatronRequestsIdNotificationsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdNotifications(rr, req, "3", proapi.PostPatronRequestsIdNotificationsParams{Side: &proapiBorrowingSide}) @@ -461,7 +461,7 @@ func TestPostPatronRequestsIdNotificationsNoSymbol(t *testing.T) { } func TestPostPatronRequestsIdNotificationsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -471,7 +471,7 @@ func TestPostPatronRequestsIdNotificationsDbError(t *testing.T) { } func TestPostPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -481,7 +481,7 @@ func TestPostPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdNotificationsErrorSavingNotification(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -491,7 +491,7 @@ func TestPostPatronRequestsIdNotificationsErrorSavingNotification(t *testing.T) } func TestPostPatronRequestsIdNotificationsErrorBecauseOfBodyMissing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdNotifications(rr, req, "3", proapi.PostPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -500,7 +500,7 @@ func TestPostPatronRequestsIdNotificationsErrorBecauseOfBodyMissing(t *testing.T } func TestPostPatronRequestsIdNotificationsErrorBecauseOfBody(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) body := "{\"note" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -510,7 +510,7 @@ func TestPostPatronRequestsIdNotificationsErrorBecauseOfBody(t *testing.T) { } func TestPostPatronRequestsIdNotificationsErrorFailedSendOnlyLogged(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositorySuccess), *api.NewSymbolChecker(common.NewTenant("")), new(MockIso18626Handler), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositorySuccess), *api.NewSymbolChecker(), new(MockIso18626Handler), 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -520,7 +520,7 @@ func TestPostPatronRequestsIdNotificationsErrorFailedSendOnlyLogged(t *testing.T } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("PUT", "/", nil) rr := httptest.NewRecorder() handler.PutPatronRequestsIdNotificationsNotificationIdReceipt(rr, req, "3", "n1", proapi.PutPatronRequestsIdNotificationsNotificationIdReceiptParams{Side: &proapiBorrowingSide}) @@ -529,7 +529,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNoSymbol(t *testin } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -539,7 +539,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptDbError(t *testing } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -549,7 +549,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFoundBecauseOfS } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorReadingNotification(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -559,7 +559,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorReadingNotifi } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -569,7 +569,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFound(t *testin } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBodyMissing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("PUT", "/", nil) rr := httptest.NewRecorder() handler.PutPatronRequestsIdNotificationsNotificationIdReceipt(rr, req, "3", "n1", proapi.PutPatronRequestsIdNotificationsNotificationIdReceiptParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -578,7 +578,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBody } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBody(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) body := "{\"receipt" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -588,7 +588,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBody } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptPrDoesNotOwn(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -598,7 +598,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptPrDoesNotOwn(t *te } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptFailedToSave(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(common.NewTenant("")), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() diff --git a/broker/test/api/api-handler_test.go b/broker/test/api/api-handler_test.go index 4dd184c1..74428226 100644 --- a/broker/test/api/api-handler_test.go +++ b/broker/test/api/api-handler_test.go @@ -44,7 +44,7 @@ var eventRepo events.EventRepo var sseBroker *api.SseBroker var mockIllRepoError = new(mocks.MockIllRepositoryError) var mockEventRepoError = new(mocks.MockEventRepositoryError) -var handlerMock = api.NewApiHandler(mockEventRepoError, mockIllRepoError, *api.NewSymbolChecker(common.NewTenant("")), api.LIMIT_DEFAULT) +var handlerMock = api.NewApiHandler(mockEventRepoError, mockIllRepoError, *api.NewSymbolChecker(), api.LIMIT_DEFAULT) func TestMain(m *testing.M) { app.TENANT_TO_SYMBOL = "ISIL:DK-{tenant}" From cf699c0cf5a80bc6cca40543e9ced774a9bf1e3b Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 16 Apr 2026 09:26:27 +0200 Subject: [PATCH 08/21] No need for ptr --- broker/api/symbol_checker.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/broker/api/symbol_checker.go b/broker/api/symbol_checker.go index ae7994cb..75555a55 100644 --- a/broker/api/symbol_checker.go +++ b/broker/api/symbol_checker.go @@ -11,7 +11,7 @@ import ( ) type SymbolChecker struct { - illRepo *ill_db.IllRepo + illRepo ill_db.IllRepo directoryLookupAdapter adapter.DirectoryLookupAdapter tenantSymbolMap string } @@ -26,7 +26,7 @@ func (s *SymbolChecker) WithTenantSymbol(tenantSymbol string) *SymbolChecker { } func (s *SymbolChecker) WithIllRepo(illRepo ill_db.IllRepo) *SymbolChecker { - s.illRepo = &illRepo + s.illRepo = illRepo return s } @@ -62,7 +62,7 @@ func (s *SymbolChecker) symbolForRequest(ctx common.ExtendedContext, isBrokerPre if s.illRepo == nil { return mainSymbol, nil } - peers, _, err := (*s.illRepo).GetCachedPeersBySymbols(ctx, []string{mainSymbol}, s.directoryLookupAdapter) + peers, _, err := s.illRepo.GetCachedPeersBySymbols(ctx, []string{mainSymbol}, s.directoryLookupAdapter) if err != nil { return "", err } @@ -75,7 +75,7 @@ func (s *SymbolChecker) symbolForRequest(ctx common.ExtendedContext, isBrokerPre } found := false for _, peer := range peers { - branchSymbols, err := (*s.illRepo).GetBranchSymbolsByPeerId(ctx, peer.ID) + branchSymbols, err := s.illRepo.GetBranchSymbolsByPeerId(ctx, peer.ID) if err != nil { return "", err } @@ -107,7 +107,7 @@ func (s *SymbolChecker) GetSymbolsForTenant(ctx common.ExtendedContext, tenant s if s.illRepo == nil { return []string{mainSymbol} } - peers, _, err := (*s.illRepo).GetCachedPeersBySymbols(ctx, []string{mainSymbol}, s.directoryLookupAdapter) + peers, _, err := s.illRepo.GetCachedPeersBySymbols(ctx, []string{mainSymbol}, s.directoryLookupAdapter) if err != nil { return []string{} } @@ -117,7 +117,7 @@ func (s *SymbolChecker) GetSymbolsForTenant(ctx common.ExtendedContext, tenant s } symbols := []string{mainSymbol} for _, peer := range peers { - branchSymbols, err := (*s.illRepo).GetBranchSymbolsByPeerId(ctx, peer.ID) + branchSymbols, err := s.illRepo.GetBranchSymbolsByPeerId(ctx, peer.ID) if err != nil { return []string{} } From ae01bfe12c8f6d17062c4cc931333358b53886be Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 16 Apr 2026 10:06:24 +0200 Subject: [PATCH 09/21] Fix test --- broker/patron_request/api/api-handler_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/broker/patron_request/api/api-handler_test.go b/broker/patron_request/api/api-handler_test.go index fe8a849a..85657426 100644 --- a/broker/patron_request/api/api-handler_test.go +++ b/broker/patron_request/api/api-handler_test.go @@ -423,7 +423,7 @@ func TestGetPatronRequestsIdNotificationsWithKindFilter(t *testing.T) { }, fullCount: 1, } - handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, common.NewTenant(""), nil, 10) + handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() From 3a5e3189f00f4ec087b84a398b6ebb8d511a1d02 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 16 Apr 2026 12:43:05 +0200 Subject: [PATCH 10/21] Deal with symbols in GetIllTransactions --- broker/api/api-handler.go | 42 +++++---------- broker/ill_db/ill_cql.go | 88 +++++++++---------------------- broker/ill_db/illrepo.go | 22 ++------ broker/sqlc/ill_query.sql | 7 --- broker/test/mocks/mock_illrepo.go | 14 +---- 5 files changed, 44 insertions(+), 129 deletions(-) diff --git a/broker/api/api-handler.go b/broker/api/api-handler.go index d8e4702d..14dfe9a1 100644 --- a/broker/api/api-handler.go +++ b/broker/api/api-handler.go @@ -172,44 +172,26 @@ func (a *ApiHandler) GetIllTransactions(w http.ResponseWriter, r *http.Request, fullCount = 1 resp.Items = append(resp.Items, toApiIllTransaction(r, *tran)) } - } else if a.symbolChecker.IsSpecified() { + } else { var symbols []string - if params.XOkapiTenant != nil { - symbols = a.symbolChecker.GetSymbolsForTenant(ctx, *params.XOkapiTenant) - } else if params.RequesterSymbol != nil { - symbols = []string{*params.RequesterSymbol} - } - if len(symbols) == 0 { - writeJsonResponse(w, resp) - return - } - // TODO handle multiple symbols properly instead of just using the first one in the list - dbparams := ill_db.GetIllTransactionsByRequesterSymbolParams{ - Limit: limit, - Offset: offset, - RequesterSymbol: pgtype.Text{ - String: symbols[0], - Valid: true, - }, - } - var trans []ill_db.IllTransaction - var err error - trans, fullCount, err = a.illRepo.GetIllTransactionsByRequesterSymbol(ctx, dbparams, cql) - if err != nil { //DB error - addInternalError(ctx, w, err) - return - } - for _, t := range trans { - resp.Items = append(resp.Items, toApiIllTransaction(r, t)) + if a.symbolChecker.IsSpecified() { + if params.XOkapiTenant != nil { + symbols = a.symbolChecker.GetSymbolsForTenant(ctx, *params.XOkapiTenant) + } else if params.RequesterSymbol != nil { + symbols = []string{*params.RequesterSymbol} + } + if len(symbols) == 0 { + writeJsonResponse(w, resp) + return + } } - } else { dbparams := ill_db.ListIllTransactionsParams{ Limit: limit, Offset: offset, } var trans []ill_db.IllTransaction var err error - trans, fullCount, err = a.illRepo.ListIllTransactions(ctx, dbparams, cql) + trans, fullCount, err = a.illRepo.ListIllTransactions(ctx, dbparams, cql, symbols) if err != nil { //DB error addInternalError(ctx, w, err) return diff --git a/broker/ill_db/ill_cql.go b/broker/ill_db/ill_cql.go index 3976cef4..b6d44547 100644 --- a/broker/ill_db/ill_cql.go +++ b/broker/ill_db/ill_cql.go @@ -55,12 +55,34 @@ func handlePeersQuery(cqlString string, noBaseArgs int) (pgcql.Query, error) { } func (q *Queries) ListIllTransactionsCql(ctx context.Context, db DBTX, arg ListIllTransactionsParams, - cqlString *string) ([]ListIllTransactionsRow, error) { - if cqlString == nil { + cqlString *string, symbols []string) ([]ListIllTransactionsRow, error) { + var cql strings.Builder + for _, symbol := range symbols { + if cql.Len() > 0 { + cql.WriteString(" OR ") + } else { + cql.WriteString("(") + } + if len(symbol) == 0 || strings.ContainsAny(symbol, " *\"\\") { + return nil, fmt.Errorf("invalid symbol: %s", symbol) + } + sc := "requester_symbol=" + symbol + cql.WriteString(sc) + } + if cql.Len() > 0 { + cql.WriteString(")") + } + if cqlString != nil { + if cql.Len() > 0 { + cql.WriteString(" AND ") + } + cql.WriteString("(" + *cqlString + ")") + } + if cql.Len() == 0 { return q.ListIllTransactions(ctx, db, arg) } - noBaseArgs := 2 // weh have two base arguments: limit and offset - res, err := handleIllTransactionsQuery(*cqlString, noBaseArgs) + noBaseArgs := 2 // we have two base arguments: limit and offset + res, err := handleIllTransactionsQuery(cql.String(), noBaseArgs) if err != nil { return nil, err } @@ -111,64 +133,6 @@ func (q *Queries) ListIllTransactionsCql(ctx context.Context, db DBTX, arg ListI return items, nil } -func (q *Queries) GetIllTransactionsByRequesterSymbolCql(ctx context.Context, db DBTX, arg GetIllTransactionsByRequesterSymbolParams, - cqlString *string) ([]GetIllTransactionsByRequesterSymbolRow, error) { - if cqlString == nil { - return q.GetIllTransactionsByRequesterSymbol(ctx, db, arg) - } - noBaseArgs := 3 // we have three base arguments: requester_symbol, limit and offset - res, err := handleIllTransactionsQuery(*cqlString, noBaseArgs) - if err != nil { - return nil, err - } - whereClause := "" - if res.GetWhereClause() != "" { - whereClause = "AND (" + res.GetWhereClause() + ") " - } - orgSql := getIllTransactionsByRequesterSymbol - pos := strings.Index(orgSql, "ORDER BY") - if pos == -1 { - return nil, fmt.Errorf("CQL query must contain an ORDER BY clause") - } - sql := orgSql[:pos] + whereClause + orgSql[pos:] - sqlArguments := make([]interface{}, 0, noBaseArgs+len(res.GetQueryArguments())) - sqlArguments = append(sqlArguments, arg.RequesterSymbol, arg.Limit, arg.Offset) - sqlArguments = append(sqlArguments, res.GetQueryArguments()...) - - rows, err := db.Query(ctx, sql, sqlArguments...) - if err != nil { - return nil, err - } - defer rows.Close() - var items []GetIllTransactionsByRequesterSymbolRow - for rows.Next() { - var i GetIllTransactionsByRequesterSymbolRow - if err := rows.Scan( - &i.IllTransaction.ID, - &i.IllTransaction.Timestamp, - &i.IllTransaction.RequesterSymbol, - &i.IllTransaction.RequesterID, - &i.IllTransaction.LastRequesterAction, - &i.IllTransaction.PrevRequesterAction, - &i.IllTransaction.SupplierSymbol, - &i.IllTransaction.RequesterRequestID, - &i.IllTransaction.PrevRequesterRequestID, - &i.IllTransaction.SupplierRequestID, - &i.IllTransaction.LastSupplierStatus, - &i.IllTransaction.PrevSupplierStatus, - &i.IllTransaction.IllTransactionData, - &i.FullCount, - ); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - func (q *Queries) ListPeersCql(ctx context.Context, db DBTX, arg ListPeersParams, cqlString *string) ([]ListPeersRow, error) { if cqlString == nil { return q.ListPeers(ctx, db, arg) diff --git a/broker/ill_db/illrepo.go b/broker/ill_db/illrepo.go index 797f7bc3..5f1e9b67 100644 --- a/broker/ill_db/illrepo.go +++ b/broker/ill_db/illrepo.go @@ -22,8 +22,7 @@ type IllRepo interface { GetIllTransactionByRequesterRequestIdForUpdate(ctx common.ExtendedContext, requesterRequestID pgtype.Text) (IllTransaction, error) GetIllTransactionById(ctx common.ExtendedContext, id string) (IllTransaction, error) GetIllTransactionByIdForUpdate(ctx common.ExtendedContext, id string) (IllTransaction, error) - ListIllTransactions(ctx common.ExtendedContext, params ListIllTransactionsParams, cql *string) ([]IllTransaction, int64, error) - GetIllTransactionsByRequesterSymbol(ctx common.ExtendedContext, params GetIllTransactionsByRequesterSymbolParams, cql *string) ([]IllTransaction, int64, error) + ListIllTransactions(ctx common.ExtendedContext, params ListIllTransactionsParams, cql *string, symbols []string) ([]IllTransaction, int64, error) DeleteIllTransaction(ctx common.ExtendedContext, id string) error SavePeer(ctx common.ExtendedContext, params SavePeerParams) (Peer, error) GetPeerById(ctx common.ExtendedContext, id string) (Peer, error) @@ -101,8 +100,8 @@ func (r *PgIllRepo) GetIllTransactionByIdForUpdate(ctx common.ExtendedContext, i return row.IllTransaction, err } -func (r *PgIllRepo) ListIllTransactions(ctx common.ExtendedContext, params ListIllTransactionsParams, cql *string) ([]IllTransaction, int64, error) { - rows, err := r.queries.ListIllTransactionsCql(ctx, r.GetConnOrTx(), params, cql) +func (r *PgIllRepo) ListIllTransactions(ctx common.ExtendedContext, params ListIllTransactionsParams, cql *string, symbols []string) ([]IllTransaction, int64, error) { + rows, err := r.queries.ListIllTransactionsCql(ctx, r.GetConnOrTx(), params, cql, symbols) var transactions []IllTransaction var fullCount int64 if err == nil { @@ -115,7 +114,7 @@ func (r *PgIllRepo) ListIllTransactions(ctx common.ExtendedContext, params ListI } else { params.Limit = 1 params.Offset = 0 - rows, err = r.queries.ListIllTransactionsCql(ctx, r.GetConnOrTx(), params, cql) + rows, err = r.queries.ListIllTransactionsCql(ctx, r.GetConnOrTx(), params, cql, symbols) if err == nil && len(rows) > 0 { fullCount = rows[0].FullCount } @@ -124,19 +123,6 @@ func (r *PgIllRepo) ListIllTransactions(ctx common.ExtendedContext, params ListI return transactions, fullCount, err } -func (r *PgIllRepo) GetIllTransactionsByRequesterSymbol(ctx common.ExtendedContext, params GetIllTransactionsByRequesterSymbolParams, cql *string) ([]IllTransaction, int64, error) { - rows, err := r.queries.GetIllTransactionsByRequesterSymbolCql(ctx, r.GetConnOrTx(), params, cql) - var transactions []IllTransaction - var fullCount int64 - if err == nil { - for _, r := range rows { - fullCount = r.FullCount - transactions = append(transactions, r.IllTransaction) - } - } - return transactions, fullCount, err -} - func (r *PgIllRepo) DeleteIllTransaction(ctx common.ExtendedContext, id string) error { return r.queries.DeleteIllTransaction(ctx, r.GetConnOrTx(), id) } diff --git a/broker/sqlc/ill_query.sql b/broker/sqlc/ill_query.sql index d8755c39..7bb7d2ce 100644 --- a/broker/sqlc/ill_query.sql +++ b/broker/sqlc/ill_query.sql @@ -100,13 +100,6 @@ FROM ill_transaction ORDER BY timestamp LIMIT $1 OFFSET $2; --- name: GetIllTransactionsByRequesterSymbol :many -SELECT sqlc.embed(ill_transaction), COUNT(*) OVER () as full_count -FROM ill_transaction -WHERE requester_symbol = $1 -ORDER BY timestamp -LIMIT $2 OFFSET $3; - -- name: SaveIllTransaction :one INSERT INTO ill_transaction (id, timestamp, requester_symbol, requester_id, last_requester_action, prev_requester_action, supplier_symbol, requester_request_id, diff --git a/broker/test/mocks/mock_illrepo.go b/broker/test/mocks/mock_illrepo.go index 65b43d42..f441a5e8 100644 --- a/broker/test/mocks/mock_illrepo.go +++ b/broker/test/mocks/mock_illrepo.go @@ -101,13 +101,7 @@ func (r *MockIllRepositorySuccess) GetIllTransactionByRequesterRequestIdForUpdat }, nil } -func (r *MockIllRepositorySuccess) ListIllTransactions(ctx common.ExtendedContext, params ill_db.ListIllTransactionsParams, cql *string) ([]ill_db.IllTransaction, int64, error) { - return []ill_db.IllTransaction{{ - ID: "id", - }}, 0, nil -} - -func (r *MockIllRepositorySuccess) GetIllTransactionsByRequesterSymbol(ctx common.ExtendedContext, params ill_db.GetIllTransactionsByRequesterSymbolParams, cql *string) ([]ill_db.IllTransaction, int64, error) { +func (r *MockIllRepositorySuccess) ListIllTransactions(ctx common.ExtendedContext, params ill_db.ListIllTransactionsParams, cql *string, symbols []string) ([]ill_db.IllTransaction, int64, error) { return []ill_db.IllTransaction{{ ID: "id", }}, 0, nil @@ -263,11 +257,7 @@ func (r *MockIllRepositoryError) GetIllTransactionByRequesterRequestIdForUpdate( return ill_db.IllTransaction{}, errors.New("DB error") } -func (r *MockIllRepositoryError) ListIllTransactions(ctx common.ExtendedContext, params ill_db.ListIllTransactionsParams, cql *string) ([]ill_db.IllTransaction, int64, error) { - return []ill_db.IllTransaction{}, 0, errors.New("DB error") -} - -func (r *MockIllRepositoryError) GetIllTransactionsByRequesterSymbol(ctx common.ExtendedContext, params ill_db.GetIllTransactionsByRequesterSymbolParams, cql *string) ([]ill_db.IllTransaction, int64, error) { +func (r *MockIllRepositoryError) ListIllTransactions(ctx common.ExtendedContext, params ill_db.ListIllTransactionsParams, cql *string, symbols []string) ([]ill_db.IllTransaction, int64, error) { return []ill_db.IllTransaction{}, 0, errors.New("DB error") } From cc36ae717f5e66e89d5264d216efdbbcbf93a566 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 16 Apr 2026 13:46:19 +0200 Subject: [PATCH 11/21] Rename --- broker/api/api-handler.go | 14 +-- broker/api/sse_broker.go | 8 +- broker/api/{symbol_checker.go => tenant.go} | 22 ++-- ...{symbol_checker_test.go => tenant_test.go} | 48 ++++---- broker/app/app.go | 14 +-- broker/patron_request/api/api-handler.go | 28 ++--- broker/patron_request/api/api-handler_test.go | 104 +++++++++--------- broker/test/api/api-handler_test.go | 2 +- 8 files changed, 120 insertions(+), 120 deletions(-) rename broker/api/{symbol_checker.go => tenant.go} (81%) rename broker/api/{symbol_checker_test.go => tenant_test.go} (72%) diff --git a/broker/api/api-handler.go b/broker/api/api-handler.go index 14dfe9a1..2240494e 100644 --- a/broker/api/api-handler.go +++ b/broker/api/api-handler.go @@ -38,14 +38,14 @@ type ApiHandler struct { limitDefault int32 eventRepo events.EventRepo illRepo ill_db.IllRepo - symbolChecker SymbolChecker + tenantContext TenantContext } -func NewApiHandler(eventRepo events.EventRepo, illRepo ill_db.IllRepo, symbolChecker SymbolChecker, limitDefault int32) ApiHandler { +func NewApiHandler(eventRepo events.EventRepo, illRepo ill_db.IllRepo, tenantContext TenantContext, limitDefault int32) ApiHandler { return ApiHandler{ eventRepo: eventRepo, illRepo: illRepo, - symbolChecker: symbolChecker, + tenantContext: tenantContext, limitDefault: limitDefault, } } @@ -54,13 +54,13 @@ func (a *ApiHandler) isOwner(ctx common.ExtendedContext, trans *ill_db.IllTransa if tenant == nil && requesterSymbol != nil { return trans.RequesterSymbol.String == *requesterSymbol } - if !a.symbolChecker.IsSpecified() { + if !a.tenantContext.IsSpecified() { return true } if tenant == nil { return false } - syms := a.symbolChecker.GetSymbolsForTenant(ctx, *tenant) + syms := a.tenantContext.GetSymbolsForTenant(ctx, *tenant) for _, sym := range syms { if trans.RequesterSymbol.String == sym { return true @@ -174,9 +174,9 @@ func (a *ApiHandler) GetIllTransactions(w http.ResponseWriter, r *http.Request, } } else { var symbols []string - if a.symbolChecker.IsSpecified() { + if a.tenantContext.IsSpecified() { if params.XOkapiTenant != nil { - symbols = a.symbolChecker.GetSymbolsForTenant(ctx, *params.XOkapiTenant) + symbols = a.tenantContext.GetSymbolsForTenant(ctx, *params.XOkapiTenant) } else if params.RequesterSymbol != nil { symbols = []string{*params.RequesterSymbol} } diff --git a/broker/api/sse_broker.go b/broker/api/sse_broker.go index 7766a87d..4b8e2a06 100644 --- a/broker/api/sse_broker.go +++ b/broker/api/sse_broker.go @@ -19,15 +19,15 @@ type SseBroker struct { clients map[string]map[chan string]bool mu sync.Mutex ctx common.ExtendedContext - symbolChecker SymbolChecker + tenantContext TenantContext } -func NewSseBroker(ctx common.ExtendedContext, symbolChecker SymbolChecker) (broker *SseBroker) { +func NewSseBroker(ctx common.ExtendedContext, tenantContext TenantContext) (broker *SseBroker) { broker = &SseBroker{ input: make(chan SseMessage), clients: make(map[string]map[chan string]bool), ctx: ctx, - symbolChecker: symbolChecker, + tenantContext: tenantContext, } // Start the single broadcaster goroutine @@ -73,7 +73,7 @@ func (b *SseBroker) ServeHTTP(w http.ResponseWriter, r *http.Request) { tenant := r.Header.Get("X-Okapi-Tenant") suppliedSymbol := r.URL.Query().Get("symbol") - symbol, err := b.symbolChecker.GetSymbolForRequest(ectx, r, &tenant, &suppliedSymbol) + symbol, err := b.tenantContext.GetSymbolForRequest(ectx, r, &tenant, &suppliedSymbol) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return diff --git a/broker/api/symbol_checker.go b/broker/api/tenant.go similarity index 81% rename from broker/api/symbol_checker.go rename to broker/api/tenant.go index 75555a55..e0a099b7 100644 --- a/broker/api/symbol_checker.go +++ b/broker/api/tenant.go @@ -10,40 +10,40 @@ import ( "github.com/indexdata/crosslink/broker/ill_db" ) -type SymbolChecker struct { +type TenantContext struct { illRepo ill_db.IllRepo directoryLookupAdapter adapter.DirectoryLookupAdapter tenantSymbolMap string } -func NewSymbolChecker() *SymbolChecker { - return &SymbolChecker{} +func NewTenantContext() *TenantContext { + return &TenantContext{} } -func (s *SymbolChecker) WithTenantSymbol(tenantSymbol string) *SymbolChecker { +func (s *TenantContext) WithTenantSymbol(tenantSymbol string) *TenantContext { s.tenantSymbolMap = tenantSymbol return s } -func (s *SymbolChecker) WithIllRepo(illRepo ill_db.IllRepo) *SymbolChecker { +func (s *TenantContext) WithIllRepo(illRepo ill_db.IllRepo) *TenantContext { s.illRepo = illRepo return s } -func (s *SymbolChecker) WithLookupAdapter(directoryLookupAdapter adapter.DirectoryLookupAdapter) *SymbolChecker { +func (s *TenantContext) WithLookupAdapter(directoryLookupAdapter adapter.DirectoryLookupAdapter) *TenantContext { s.directoryLookupAdapter = directoryLookupAdapter return s } -func (s *SymbolChecker) IsSpecified() bool { +func (s *TenantContext) IsSpecified() bool { return s.tenantSymbolMap != "" } -func (s *SymbolChecker) getSymbol(tenant string) string { +func (s *TenantContext) getSymbol(tenant string) string { return strings.ReplaceAll(s.tenantSymbolMap, "{tenant}", strings.ToUpper(tenant)) } -func (s *SymbolChecker) symbolForRequest(ctx common.ExtendedContext, isBrokerPrefix bool, tenant *string, symbol *string) (string, error) { +func (s *TenantContext) symbolForRequest(ctx common.ExtendedContext, isBrokerPrefix bool, tenant *string, symbol *string) (string, error) { var mainSymbol string if isBrokerPrefix { if !s.IsSpecified() { @@ -92,11 +92,11 @@ func (s *SymbolChecker) symbolForRequest(ctx common.ExtendedContext, isBrokerPre return *symbol, nil } -func (s *SymbolChecker) GetSymbolForRequest(ctx common.ExtendedContext, r *http.Request, tenant *string, symbol *string) (string, error) { +func (s *TenantContext) GetSymbolForRequest(ctx common.ExtendedContext, r *http.Request, tenant *string, symbol *string) (string, error) { return s.symbolForRequest(ctx, strings.HasPrefix(r.URL.Path, "/broker/"), tenant, symbol) } -func (s *SymbolChecker) GetSymbolsForTenant(ctx common.ExtendedContext, tenant string) []string { +func (s *TenantContext) GetSymbolsForTenant(ctx common.ExtendedContext, tenant string) []string { if !s.IsSpecified() { return []string{} } diff --git a/broker/api/symbol_checker_test.go b/broker/api/tenant_test.go similarity index 72% rename from broker/api/symbol_checker_test.go rename to broker/api/tenant_test.go index 1d761a18..6743aacb 100644 --- a/broker/api/symbol_checker_test.go +++ b/broker/api/tenant_test.go @@ -12,42 +12,42 @@ import ( "github.com/stretchr/testify/mock" ) -func TestSymbolChecker(t *testing.T) { - symbolChecker := NewSymbolChecker() - assert.False(t, symbolChecker.IsSpecified()) +func TestTenantContext(t *testing.T) { + tenantContext := NewTenantContext() + assert.False(t, tenantContext.IsSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) - _, err := symbolChecker.symbolForRequest(ctx, false, nil, nil) + _, err := tenantContext.symbolForRequest(ctx, false, nil, nil) assert.Error(t, err) assert.Equal(t, "symbol must be specified", err.Error()) requestSymbol := "" - _, err = symbolChecker.symbolForRequest(ctx, false, nil, &requestSymbol) + _, err = tenantContext.symbolForRequest(ctx, false, nil, &requestSymbol) assert.Error(t, err) assert.Equal(t, "symbol must be specified", err.Error()) requestSymbol = "symbol2" - symbol, err := symbolChecker.symbolForRequest(ctx, false, nil, &requestSymbol) + symbol, err := tenantContext.symbolForRequest(ctx, false, nil, &requestSymbol) assert.NoError(t, err) assert.Equal(t, requestSymbol, symbol) - _, err = symbolChecker.symbolForRequest(ctx, true, nil, nil) + _, err = tenantContext.symbolForRequest(ctx, true, nil, nil) assert.Error(t, err) assert.Equal(t, "tenant mapping must be specified", err.Error()) - symbolChecker = NewSymbolChecker().WithTenantSymbol("{tenant}") - assert.True(t, symbolChecker.IsSpecified()) - _, err = symbolChecker.symbolForRequest(ctx, true, nil, nil) + tenantContext = NewTenantContext().WithTenantSymbol("{tenant}") + assert.True(t, tenantContext.IsSpecified()) + _, err = tenantContext.symbolForRequest(ctx, true, nil, nil) assert.Error(t, err) assert.Equal(t, "X-Okapi-Tenant must be specified", err.Error()) tenant := "" - _, err = symbolChecker.symbolForRequest(ctx, true, &tenant, nil) + _, err = tenantContext.symbolForRequest(ctx, true, &tenant, nil) assert.Error(t, err) assert.Equal(t, "X-Okapi-Tenant must be specified", err.Error()) tenant = "tenant1" - symbol, err = symbolChecker.symbolForRequest(ctx, true, &tenant, nil) + symbol, err = tenantContext.symbolForRequest(ctx, true, &tenant, nil) assert.NoError(t, err) assert.Equal(t, strings.ToUpper(tenant), symbol) } @@ -72,60 +72,60 @@ func (r *MockIllRepo) GetBranchSymbolsByPeerId(ctx common.ExtendedContext, peerI return args.Get(0).([]ill_db.BranchSymbol), args.Error(1) } -func TestSymbolCheckerRepoNoPeer(t *testing.T) { +func TestTenantContextRepoNoPeer(t *testing.T) { mockIllRepo := new(MockIllRepo) mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{}, "", nil) - symbolChecker := NewSymbolChecker().WithTenantSymbol("{tenant}").WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) + tenantContext := NewTenantContext().WithTenantSymbol("{tenant}").WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) requestSymbol := "SYMBOL2" - _, err := symbolChecker.symbolForRequest(ctx, false, nil, &requestSymbol) + _, err := tenantContext.symbolForRequest(ctx, false, nil, &requestSymbol) assert.Error(t, err) assert.Equal(t, "no peers for symbol", err.Error()) } -func TestSymbolCheckerRepoOK(t *testing.T) { +func TestTenantContextRepoOK(t *testing.T) { mockIllRepo := new(MockIllRepo) mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{{ID: "SYMBOL"}}, "", nil) mockIllRepo.On("GetBranchSymbolsByPeerId", mock.Anything, mock.Anything).Return([]ill_db.BranchSymbol{{SymbolValue: "LIB"}}, nil) - symbolChecker := NewSymbolChecker().WithTenantSymbol("{tenant}").WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) + tenantContext := NewTenantContext().WithTenantSymbol("{tenant}").WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) requestSymbol := "SYMBOL" - symbol, err := symbolChecker.symbolForRequest(ctx, false, nil, &requestSymbol) + symbol, err := tenantContext.symbolForRequest(ctx, false, nil, &requestSymbol) assert.NoError(t, err) assert.Equal(t, requestSymbol, symbol) requestSymbol = "LIB" tenant := "symbol" - symbol, err = symbolChecker.symbolForRequest(ctx, true, &tenant, &requestSymbol) + symbol, err = tenantContext.symbolForRequest(ctx, true, &tenant, &requestSymbol) assert.NoError(t, err) assert.Equal(t, requestSymbol, symbol) requestSymbol = "" - symbol, err = symbolChecker.symbolForRequest(ctx, true, &tenant, &requestSymbol) + symbol, err = tenantContext.symbolForRequest(ctx, true, &tenant, &requestSymbol) assert.NoError(t, err) assert.Equal(t, strings.ToUpper(tenant), symbol) } -func TestSymbolCheckerRepoBranches(t *testing.T) { +func TestTenantContextRepoBranches(t *testing.T) { mockIllRepo := new(MockIllRepo) mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{{ID: "SYMBOL"}}, "", nil) mockIllRepo.On("GetBranchSymbolsByPeerId", mock.Anything, mock.Anything).Return([]ill_db.BranchSymbol{}, nil) - symbolChecker := NewSymbolChecker().WithTenantSymbol("{tenant}").WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) + tenantContext := NewTenantContext().WithTenantSymbol("{tenant}").WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) requestSymbol := "SYMBOL" - symbol, err := symbolChecker.symbolForRequest(ctx, false, nil, &requestSymbol) + symbol, err := tenantContext.symbolForRequest(ctx, false, nil, &requestSymbol) assert.NoError(t, err) assert.Equal(t, requestSymbol, symbol) requestSymbol = "LIB" tenant := "SYMBOL" - _, err = symbolChecker.symbolForRequest(ctx, true, &tenant, &requestSymbol) + _, err = tenantContext.symbolForRequest(ctx, true, &tenant, &requestSymbol) assert.Error(t, err) assert.Equal(t, "symbol does not match any branch symbols for tenant", err.Error()) } diff --git a/broker/app/app.go b/broker/app/app.go index 1adebf98..77c2eec9 100644 --- a/broker/app/app.go +++ b/broker/app/app.go @@ -166,12 +166,12 @@ func Init(ctx context.Context) (Context, error) { iso18626Client := client.CreateIso18626Client(eventBus, illRepo, prMessageHandler, MAX_MESSAGE_SIZE, delay) supplierLocator := service.CreateSupplierLocator(eventBus, illRepo, dirAdapter, holdingsAdapter) workflowManager := service.CreateWorkflowManager(eventBus, illRepo, service.WorkflowConfig{}) - apiSymbolChecker := api.NewSymbolChecker().WithIllRepo(illRepo).WithLookupAdapter(dirAdapter).WithTenantSymbol(TENANT_TO_SYMBOL) - prApiHandler := prapi.NewPrApiHandler(prRepo, eventBus, eventRepo, *apiSymbolChecker, &iso18626Handler, API_PAGE_SIZE) + tenantContext := api.NewTenantContext().WithIllRepo(illRepo).WithLookupAdapter(dirAdapter).WithTenantSymbol(TENANT_TO_SYMBOL) + prApiHandler := prapi.NewPrApiHandler(prRepo, eventBus, eventRepo, *tenantContext, &iso18626Handler, API_PAGE_SIZE) prApiHandler.SetAutoActionRunner(prActionService) prApiHandler.SetActionTaskProcessor(prActionService) - sseBroker := api.NewSseBroker(appCtx, *apiSymbolChecker) + sseBroker := api.NewSseBroker(appCtx, *tenantContext) AddDefaultHandlers(eventBus, iso18626Client, supplierLocator, workflowManager, iso18626Handler, *prActionService, prApiHandler, sseBroker) err = StartEventBus(ctx, eventBus) @@ -210,16 +210,16 @@ func StartServer(ctx Context) error { _, _ = w.Write(oapi.OpenAPISpecYAML) }) - symbolChecker := api.NewSymbolChecker().WithIllRepo(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter) + tenantContext := api.NewTenantContext().WithIllRepo(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter) - apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, *symbolChecker, API_PAGE_SIZE) + apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, *tenantContext, API_PAGE_SIZE) oapi.HandlerFromMux(&apiHandler, ServeMux) proapi.HandlerFromMux(&ctx.PrApiHandler, ServeMux) if TENANT_TO_SYMBOL != "" { - symbolChecker = api.NewSymbolChecker().WithIllRepo(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter).WithTenantSymbol(TENANT_TO_SYMBOL) + tenantContext = api.NewTenantContext().WithIllRepo(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter).WithTenantSymbol(TENANT_TO_SYMBOL) ServeMux.HandleFunc("/broker/sse/events", ctx.SseBroker.ServeHTTP) - apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, *symbolChecker, API_PAGE_SIZE) + apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, *tenantContext, API_PAGE_SIZE) oapi.HandlerFromMuxWithBaseURL(&apiHandler, ServeMux, "/broker") proapi.HandlerFromMuxWithBaseURL(&ctx.PrApiHandler, ServeMux, "/broker") } diff --git a/broker/patron_request/api/api-handler.go b/broker/patron_request/api/api-handler.go index 808b08e9..72349090 100644 --- a/broker/patron_request/api/api-handler.go +++ b/broker/patron_request/api/api-handler.go @@ -45,19 +45,19 @@ type PatronRequestApiHandler struct { actionMappingService prservice.ActionMappingService autoActionRunner prservice.AutoActionRunner actionTaskProcessor ActionTaskProcessor - symbolChecker api.SymbolChecker + tenantContext api.TenantContext notificationSender prservice.PatronRequestNotificationService } func NewPrApiHandler(prRepo pr_db.PrRepo, eventBus events.EventBus, - eventRepo events.EventRepo, symbolChecker api.SymbolChecker, iso18626Handler handler.Iso18626HandlerInterface, limitDefault int32) PatronRequestApiHandler { + eventRepo events.EventRepo, tenantContext api.TenantContext, iso18626Handler handler.Iso18626HandlerInterface, limitDefault int32) PatronRequestApiHandler { return PatronRequestApiHandler{ limitDefault: limitDefault, prRepo: prRepo, eventBus: eventBus, eventRepo: eventRepo, actionMappingService: prservice.ActionMappingService{SMService: &prservice.StateModelService{}}, - symbolChecker: symbolChecker, + tenantContext: tenantContext, notificationSender: *prservice.CreatePatronRequestNotificationService(prRepo, eventBus, iso18626Handler), } } @@ -96,7 +96,7 @@ func (a *PatronRequestApiHandler) GetPatronRequests(w http.ResponseWriter, r *ht logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return @@ -202,7 +202,7 @@ func (a *PatronRequestApiHandler) PostPatronRequests(w http.ResponseWriter, r *h addBadRequestError(ctx, w, err) return } - symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, newPr.RequesterSymbol) + symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, newPr.RequesterSymbol) if err != nil { addBadRequestError(ctx, w, err) return @@ -255,7 +255,7 @@ func (a *PatronRequestApiHandler) DeletePatronRequestsId(w http.ResponseWriter, logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return @@ -308,7 +308,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsId(w http.ResponseWriter, r * logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return @@ -329,7 +329,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdActions(w http.ResponseWrit } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) @@ -357,7 +357,7 @@ func (a *PatronRequestApiHandler) PostPatronRequestsIdAction(w http.ResponseWrit } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return @@ -434,7 +434,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdEvents(w http.ResponseWrite } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return @@ -465,7 +465,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdItems(w http.ResponseWriter } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return @@ -496,7 +496,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdNotifications(w http.Respon } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return @@ -546,7 +546,7 @@ func (a *PatronRequestApiHandler) PostPatronRequestsIdNotifications(w http.Respo logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return @@ -599,7 +599,7 @@ func (a *PatronRequestApiHandler) PutPatronRequestsIdNotificationsNotificationId logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.symbolChecker.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) if err != nil { addBadRequestError(ctx, w, err) return diff --git a/broker/patron_request/api/api-handler_test.go b/broker/patron_request/api/api-handler_test.go index 85657426..564dac5b 100644 --- a/broker/patron_request/api/api-handler_test.go +++ b/broker/patron_request/api/api-handler_test.go @@ -62,7 +62,7 @@ func TestGetDbText(t *testing.T) { } func TestGetPatronRequests(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() params := proapi.GetPatronRequestsParams{ @@ -75,7 +75,7 @@ func TestGetPatronRequests(t *testing.T) { } func TestGetPatronRequestsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() params := proapi.GetPatronRequestsParams{ @@ -87,7 +87,7 @@ func TestGetPatronRequestsNoSymbol(t *testing.T) { } func TestGetPatronRequestsWithLimits(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() offset := proapi.Offset(10) @@ -107,7 +107,7 @@ func TestGetPatronRequestsWithLimits(t *testing.T) { func TestGetPatronRequestsWithRequesterReqId(t *testing.T) { repo := new(PrRepoCapture) - handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() requesterReqID := "req-123" @@ -126,7 +126,7 @@ func TestGetPatronRequestsWithRequesterReqId(t *testing.T) { } func TestPostPatronRequests(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) id := "1" toCreate := proapi.CreatePatronRequest{ Id: &id, @@ -145,7 +145,7 @@ func TestPostPatronRequests(t *testing.T) { } func TestPostPatronRequestsMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) toCreate := proapi.PatronRequest{Id: "1"} jsonBytes, err := json.Marshal(toCreate) assert.NoError(t, err, "failed to marshal patron request") @@ -159,7 +159,7 @@ func TestPostPatronRequestsMissingSymbol(t *testing.T) { } func TestPostPatronRequestsInvalidJson(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("POST", "/", bytes.NewBuffer([]byte("a\": v\""))) rr := httptest.NewRecorder() tenant := proapi.Tenant("test-lib") @@ -169,7 +169,7 @@ func TestPostPatronRequestsInvalidJson(t *testing.T) { } func TestPostPatronRequestsInvalidIllRequestShape(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) jsonBytes := []byte(`{ "id":"1", "requesterSymbol":"` + symbol + `", @@ -185,7 +185,7 @@ func TestPostPatronRequestsInvalidIllRequestShape(t *testing.T) { } func TestDeletePatronRequestsIdNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "2", proapi.DeletePatronRequestsIdParams{Symbol: &symbol}) @@ -193,7 +193,7 @@ func TestDeletePatronRequestsIdNotFound(t *testing.T) { } func TestDeletePatronRequestsIdMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "2", proapi.DeletePatronRequestsIdParams{}) @@ -202,7 +202,7 @@ func TestDeletePatronRequestsIdMissingSymbol(t *testing.T) { } func TestDeletePatronRequestsIdError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "1", proapi.DeletePatronRequestsIdParams{Symbol: &symbol}) @@ -211,7 +211,7 @@ func TestDeletePatronRequestsIdError(t *testing.T) { } func TestDeletePatronRequestsId(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "3", proapi.DeletePatronRequestsIdParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -220,7 +220,7 @@ func TestDeletePatronRequestsId(t *testing.T) { } func TestDeletePatronRequestsIdDeleted(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "4", proapi.DeletePatronRequestsIdParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -228,7 +228,7 @@ func TestDeletePatronRequestsIdDeleted(t *testing.T) { } func TestGetPatronRequestsIdMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "2", proapi.GetPatronRequestsIdParams{}) @@ -237,7 +237,7 @@ func TestGetPatronRequestsIdMissingSymbol(t *testing.T) { } func TestGetPatronRequestsIdNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "2", proapi.GetPatronRequestsIdParams{Symbol: &symbol}) @@ -245,7 +245,7 @@ func TestGetPatronRequestsIdNotFound(t *testing.T) { } func TestGetPatronRequestsId(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "1", proapi.GetPatronRequestsIdParams{Symbol: &symbol}) @@ -254,7 +254,7 @@ func TestGetPatronRequestsId(t *testing.T) { } func TestGetPatronRequestsIdActions(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -263,7 +263,7 @@ func TestGetPatronRequestsIdActions(t *testing.T) { } func TestGetPatronRequestsIdActionsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Side: &proapiBorrowingSide}) @@ -272,7 +272,7 @@ func TestGetPatronRequestsIdActionsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdActionsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "1", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -281,7 +281,7 @@ func TestGetPatronRequestsIdActionsDbError(t *testing.T) { } func TestGetPatronRequestsIdActionsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -290,7 +290,7 @@ func TestGetPatronRequestsIdActionsNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdActionNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Side: &proapiBorrowingSide}) @@ -299,7 +299,7 @@ func TestPostPatronRequestsIdActionNoSymbol(t *testing.T) { } func TestPostPatronRequestsIdActionDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "1", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -308,7 +308,7 @@ func TestPostPatronRequestsIdActionDbError(t *testing.T) { } func TestPostPatronRequestsIdActionNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -317,7 +317,7 @@ func TestPostPatronRequestsIdActionNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdActionErrorParsing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", strings.NewReader("{")) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -326,7 +326,7 @@ func TestPostPatronRequestsIdActionErrorParsing(t *testing.T) { } func TestGetPatronRequestsIdEventsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Side: &proapiBorrowingSide}) @@ -335,7 +335,7 @@ func TestGetPatronRequestsIdEventsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdEventsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "1", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -344,7 +344,7 @@ func TestGetPatronRequestsIdEventsDbError(t *testing.T) { } func TestGetPatronRequestsIdEventsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -353,7 +353,7 @@ func TestGetPatronRequestsIdEventsNotFoundBecauseOfSide(t *testing.T) { } func TestGetPatronRequestsIdEventsErrorGettingEvents(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -362,7 +362,7 @@ func TestGetPatronRequestsIdEventsErrorGettingEvents(t *testing.T) { } func TestGetPatronRequestsIdNotificationsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Side: &proapiBorrowingSide}) @@ -371,7 +371,7 @@ func TestGetPatronRequestsIdNotificationsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdNotificationsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "1", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -380,7 +380,7 @@ func TestGetPatronRequestsIdNotificationsDbError(t *testing.T) { } func TestGetPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -389,7 +389,7 @@ func TestGetPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { } func TestGetPatronRequestsIdNotificationsErrorGettingEvents(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -423,7 +423,7 @@ func TestGetPatronRequestsIdNotificationsWithKindFilter(t *testing.T) { }, fullCount: 1, } - handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() @@ -458,7 +458,7 @@ func TestGetPatronRequestsIdNotificationsWithKindFilter(t *testing.T) { } func TestParseAndValidateIllRequestAndBuildDbPatronRequest(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) creationTime := time.Now() id := uuid.NewString() @@ -485,7 +485,7 @@ func TestParseAndValidateIllRequestAndBuildDbPatronRequest(t *testing.T) { } func TestParseAndValidateIllRequestInvalidRequesterSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) invalidSymbol := "REQ" @@ -495,7 +495,7 @@ func TestParseAndValidateIllRequestInvalidRequesterSymbol(t *testing.T) { } func TestParseAndValidateIllRequestInvalidBrokerSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) previousBrokerSymbol := brokerSymbol brokerSymbol = "BROKER" @@ -512,7 +512,7 @@ func TestParseAndValidateIllRequestInvalidBrokerSymbol(t *testing.T) { } func TestPostPatronRequestsIdNotificationsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdNotifications(rr, req, "3", proapi.PostPatronRequestsIdNotificationsParams{Side: &proapiBorrowingSide}) @@ -521,7 +521,7 @@ func TestPostPatronRequestsIdNotificationsNoSymbol(t *testing.T) { } func TestPostPatronRequestsIdNotificationsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -531,7 +531,7 @@ func TestPostPatronRequestsIdNotificationsDbError(t *testing.T) { } func TestPostPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -541,7 +541,7 @@ func TestPostPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdNotificationsErrorSavingNotification(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -551,7 +551,7 @@ func TestPostPatronRequestsIdNotificationsErrorSavingNotification(t *testing.T) } func TestPostPatronRequestsIdNotificationsErrorBecauseOfBodyMissing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdNotifications(rr, req, "3", proapi.PostPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -560,7 +560,7 @@ func TestPostPatronRequestsIdNotificationsErrorBecauseOfBodyMissing(t *testing.T } func TestPostPatronRequestsIdNotificationsErrorBecauseOfBody(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) body := "{\"note" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -570,7 +570,7 @@ func TestPostPatronRequestsIdNotificationsErrorBecauseOfBody(t *testing.T) { } func TestPostPatronRequestsIdNotificationsErrorFailedSendOnlyLogged(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositorySuccess), *api.NewSymbolChecker(), new(MockIso18626Handler), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositorySuccess), *api.NewTenantContext(), new(MockIso18626Handler), 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -580,7 +580,7 @@ func TestPostPatronRequestsIdNotificationsErrorFailedSendOnlyLogged(t *testing.T } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("PUT", "/", nil) rr := httptest.NewRecorder() handler.PutPatronRequestsIdNotificationsNotificationIdReceipt(rr, req, "3", "n1", proapi.PutPatronRequestsIdNotificationsNotificationIdReceiptParams{Side: &proapiBorrowingSide}) @@ -589,7 +589,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNoSymbol(t *testin } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -599,7 +599,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptDbError(t *testing } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -609,7 +609,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFoundBecauseOfS } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorReadingNotification(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -619,7 +619,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorReadingNotifi } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -629,7 +629,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFound(t *testin } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBodyMissing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) req, _ := http.NewRequest("PUT", "/", nil) rr := httptest.NewRecorder() handler.PutPatronRequestsIdNotificationsNotificationIdReceipt(rr, req, "3", "n1", proapi.PutPatronRequestsIdNotificationsNotificationIdReceiptParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -638,7 +638,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBody } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBody(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) body := "{\"receipt" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -648,7 +648,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBody } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptPrDoesNotOwn(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -658,7 +658,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptPrDoesNotOwn(t *te } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptFailedToSave(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewSymbolChecker(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() diff --git a/broker/test/api/api-handler_test.go b/broker/test/api/api-handler_test.go index 74428226..ae778e93 100644 --- a/broker/test/api/api-handler_test.go +++ b/broker/test/api/api-handler_test.go @@ -44,7 +44,7 @@ var eventRepo events.EventRepo var sseBroker *api.SseBroker var mockIllRepoError = new(mocks.MockIllRepositoryError) var mockEventRepoError = new(mocks.MockEventRepositoryError) -var handlerMock = api.NewApiHandler(mockEventRepoError, mockIllRepoError, *api.NewSymbolChecker(), api.LIMIT_DEFAULT) +var handlerMock = api.NewApiHandler(mockEventRepoError, mockIllRepoError, *api.NewTenantContext(), api.LIMIT_DEFAULT) func TestMain(m *testing.M) { app.TENANT_TO_SYMBOL = "ISIL:DK-{tenant}" From 8599b18ccd4346599a7dc20b8840d37cda6cb73a Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 17 Apr 2026 15:39:01 +0200 Subject: [PATCH 12/21] Rework tenant API --- broker/api/api-handler.go | 86 +++---- broker/api/sse_broker.go | 5 +- broker/api/tenant.go | 110 +++++---- broker/api/tenant_test.go | 276 +++++++++++++++++------ broker/patron_request/api/api-handler.go | 22 +- broker/test/api/api-handler_test.go | 30 ++- broker/test/api/sse_broker_test.go | 2 +- 7 files changed, 345 insertions(+), 186 deletions(-) diff --git a/broker/api/api-handler.go b/broker/api/api-handler.go index 2240494e..782f6b10 100644 --- a/broker/api/api-handler.go +++ b/broker/api/api-handler.go @@ -50,27 +50,8 @@ func NewApiHandler(eventRepo events.EventRepo, illRepo ill_db.IllRepo, tenantCon } } -func (a *ApiHandler) isOwner(ctx common.ExtendedContext, trans *ill_db.IllTransaction, tenant *string, requesterSymbol *string) bool { - if tenant == nil && requesterSymbol != nil { - return trans.RequesterSymbol.String == *requesterSymbol - } - if !a.tenantContext.IsSpecified() { - return true - } - if tenant == nil { - return false - } - syms := a.tenantContext.GetSymbolsForTenant(ctx, *tenant) - for _, sym := range syms { - if trans.RequesterSymbol.String == sym { - return true - } - } - return false -} - func (a *ApiHandler) getIllTranFromParams(ctx common.ExtendedContext, w http.ResponseWriter, - okapiTenant *string, requesterSymbol *string, requesterReqId *oapi.RequesterRequestId, + r *http.Request, requesterSymbol *string, requesterReqId *oapi.RequesterRequestId, illTransactionId *oapi.IllTransactionId) (*ill_db.IllTransaction, error) { var tran ill_db.IllTransaction var err error @@ -93,10 +74,21 @@ func (a *ApiHandler) getIllTranFromParams(ctx common.ExtendedContext, w http.Res addInternalError(ctx, w, err) return nil, err } - if !a.isOwner(ctx, &tran, okapiTenant, requesterSymbol) { - return nil, nil + tenant := a.tenantContext.WithRequest(ctx, r, requesterSymbol) + syms, err := tenant.GetSymbols() + if err != nil { + addBadRequestError(ctx, w, err) + return nil, err + } + if syms == nil { + return &tran, nil } - return &tran, nil + for _, s := range syms { + if s == tran.RequesterSymbol.String { + return &tran, nil + } + } + return nil, nil } func (a *ApiHandler) Get(w http.ResponseWriter, r *http.Request) { @@ -119,7 +111,7 @@ func (a *ApiHandler) GetEvents(w http.ResponseWriter, r *http.Request, params oa ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ Other: logParams, }) - tran, err := a.getIllTranFromParams(ctx, w, params.XOkapiTenant, params.RequesterSymbol, + tran, err := a.getIllTranFromParams(ctx, w, r, params.RequesterSymbol, params.RequesterReqId, params.IllTransactionId) if err != nil { return @@ -163,7 +155,7 @@ func (a *ApiHandler) GetIllTransactions(w http.ResponseWriter, r *http.Request, } var fullCount int64 if params.RequesterReqId != nil { - tran, err := a.getIllTranFromParams(ctx, w, params.XOkapiTenant, params.RequesterSymbol, + tran, err := a.getIllTranFromParams(ctx, w, r, params.RequesterSymbol, params.RequesterReqId, nil) if err != nil { return @@ -173,31 +165,27 @@ func (a *ApiHandler) GetIllTransactions(w http.ResponseWriter, r *http.Request, resp.Items = append(resp.Items, toApiIllTransaction(r, *tran)) } } else { - var symbols []string - if a.tenantContext.IsSpecified() { - if params.XOkapiTenant != nil { - symbols = a.tenantContext.GetSymbolsForTenant(ctx, *params.XOkapiTenant) - } else if params.RequesterSymbol != nil { - symbols = []string{*params.RequesterSymbol} + tenant := a.tenantContext.WithRequest(ctx, r, params.RequesterSymbol) + symbols, err := tenant.GetSymbols() + if err != nil { + addBadRequestError(ctx, w, err) + return + } + if symbols == nil || len(symbols) > 0 { + dbparams := ill_db.ListIllTransactionsParams{ + Limit: limit, + Offset: offset, } - if len(symbols) == 0 { - writeJsonResponse(w, resp) + var trans []ill_db.IllTransaction + var err error + trans, fullCount, err = a.illRepo.ListIllTransactions(ctx, dbparams, cql, symbols) + if err != nil { //DB error + addInternalError(ctx, w, err) return } - } - dbparams := ill_db.ListIllTransactionsParams{ - Limit: limit, - Offset: offset, - } - var trans []ill_db.IllTransaction - var err error - trans, fullCount, err = a.illRepo.ListIllTransactions(ctx, dbparams, cql, symbols) - if err != nil { //DB error - addInternalError(ctx, w, err) - return - } - for _, t := range trans { - resp.Items = append(resp.Items, toApiIllTransaction(r, t)) + for _, t := range trans { + resp.Items = append(resp.Items, toApiIllTransaction(r, t)) + } } } resp.About = CollectAboutData(fullCount, offset, limit, r) @@ -208,7 +196,7 @@ func (a *ApiHandler) GetIllTransactionsId(w http.ResponseWriter, r *http.Request ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ Other: map[string]string{"method": "GetIllTransactionsId", "id": id}, }) - tran, err := a.getIllTranFromParams(ctx, w, params.XOkapiTenant, params.RequesterSymbol, + tran, err := a.getIllTranFromParams(ctx, w, r, params.RequesterSymbol, nil, &id) if err != nil { return @@ -561,7 +549,7 @@ func (a *ApiHandler) GetLocatedSuppliers(w http.ResponseWriter, r *http.Request, ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ Other: logParams, }) - tran, err := a.getIllTranFromParams(ctx, w, params.XOkapiTenant, params.RequesterSymbol, + tran, err := a.getIllTranFromParams(ctx, w, r, params.RequesterSymbol, params.RequesterReqId, params.IllTransactionId) if err != nil { return diff --git a/broker/api/sse_broker.go b/broker/api/sse_broker.go index 4b8e2a06..a384d22b 100644 --- a/broker/api/sse_broker.go +++ b/broker/api/sse_broker.go @@ -71,9 +71,10 @@ func (b *SseBroker) ServeHTTP(w http.ResponseWriter, r *http.Request) { logParams := map[string]string{"method": "ServeHTTP"} ectx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - tenant := r.Header.Get("X-Okapi-Tenant") suppliedSymbol := r.URL.Query().Get("symbol") - symbol, err := b.tenantContext.GetSymbolForRequest(ectx, r, &tenant, &suppliedSymbol) + // symbol, err := b.tenantContext.GetSymbolForRequest(ectx, r, &tenant, &suppliedSymbol) + symbol, err := b.tenantContext.WithRequest(ectx, r, &suppliedSymbol).GetSymbol() + if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return diff --git a/broker/api/tenant.go b/broker/api/tenant.go index e0a099b7..d2720f1a 100644 --- a/broker/api/tenant.go +++ b/broker/api/tenant.go @@ -35,7 +35,7 @@ func (s *TenantContext) WithLookupAdapter(directoryLookupAdapter adapter.Directo return s } -func (s *TenantContext) IsSpecified() bool { +func (s *TenantContext) isSpecified() bool { return s.tenantSymbolMap != "" } @@ -43,87 +43,109 @@ func (s *TenantContext) getSymbol(tenant string) string { return strings.ReplaceAll(s.tenantSymbolMap, "{tenant}", strings.ToUpper(tenant)) } -func (s *TenantContext) symbolForRequest(ctx common.ExtendedContext, isBrokerPrefix bool, tenant *string, symbol *string) (string, error) { +type Tenant struct { + tenantContext *TenantContext + ctx common.ExtendedContext + okapiEndpoint bool + tenant string + symbol string +} + +func (s *TenantContext) WithRequest(ctx common.ExtendedContext, r *http.Request, symbol *string) *Tenant { + var pSymbol string + if symbol != nil { + pSymbol = *symbol + } + t := &Tenant{ + tenantContext: s, + tenant: r.Header.Get("X-Okapi-Tenant"), + ctx: ctx, + okapiEndpoint: strings.HasPrefix(r.URL.Path, "/broker/"), + symbol: pSymbol, + } + return t +} + +func (t *Tenant) GetSymbol() (string, error) { var mainSymbol string - if isBrokerPrefix { - if !s.IsSpecified() { + if t.okapiEndpoint { + if !t.tenantContext.isSpecified() { return "", errors.New("tenant mapping must be specified") } - if tenant == nil || *tenant == "" { - return "", errors.New("X-Okapi-Tenant must be specified") + if t.tenant == "" { + return "", errors.New("header X-Okapi-Tenant must be specified") } - mainSymbol = s.getSymbol(*tenant) + mainSymbol = t.tenantContext.getSymbol(t.tenant) } else { - if symbol == nil || *symbol == "" { + if t.symbol == "" { return "", errors.New("symbol must be specified") } - mainSymbol = *symbol + mainSymbol = t.symbol } - if s.illRepo == nil { + if t.tenantContext.illRepo == nil { return mainSymbol, nil } - peers, _, err := s.illRepo.GetCachedPeersBySymbols(ctx, []string{mainSymbol}, s.directoryLookupAdapter) + peers, _, err := t.tenantContext.illRepo.GetCachedPeersBySymbols(t.ctx, []string{mainSymbol}, t.tenantContext.directoryLookupAdapter) if err != nil { return "", err } - if len(peers) == 0 { - ctx.Logger().Error("no peers for symbol", "symbol", mainSymbol) - return "", errors.New("no peers for symbol") - } - if symbol == nil || *symbol == "" || *symbol == mainSymbol { + // seems like len(peers) > 0 always, so we can't flag an error for symbol that does not exist + // if supplied symbol is the same as main symbol, we can skip the check against branch symbols, since it's valid + if t.symbol == "" || t.symbol == mainSymbol { return mainSymbol, nil } found := false for _, peer := range peers { - branchSymbols, err := s.illRepo.GetBranchSymbolsByPeerId(ctx, peer.ID) + branchSymbols, err := t.tenantContext.illRepo.GetBranchSymbolsByPeerId(t.ctx, peer.ID) if err != nil { return "", err } for _, branchSymbol := range branchSymbols { - if *symbol == branchSymbol.SymbolValue { + if t.symbol == branchSymbol.SymbolValue { found = true - break } } } if !found { return "", errors.New("symbol does not match any branch symbols for tenant") } - return *symbol, nil -} - -func (s *TenantContext) GetSymbolForRequest(ctx common.ExtendedContext, r *http.Request, tenant *string, symbol *string) (string, error) { - return s.symbolForRequest(ctx, strings.HasPrefix(r.URL.Path, "/broker/"), tenant, symbol) + return t.symbol, nil } -func (s *TenantContext) GetSymbolsForTenant(ctx common.ExtendedContext, tenant string) []string { - if !s.IsSpecified() { - return []string{} - } - if tenant == "" { - return []string{} +// GetSymbols returns the main symbol for the tenant and all branch symbols of peers associated with that symbol. +// Note that empty list and nil are used to distinguish between "no symbols" and "all symbols" (i.e. no symbol filtering). +func (t *Tenant) GetSymbols() ([]string, error) { + var mainSymbol string + if t.okapiEndpoint { + if !t.tenantContext.isSpecified() { + return nil, errors.New("tenant mapping must be specified") + } + if t.tenant == "" { + return nil, errors.New("header X-Okapi-Tenant must be specified") + } + mainSymbol = t.tenantContext.getSymbol(t.tenant) + } else { + if t.symbol == "" { + return nil, nil + } + mainSymbol = t.symbol } - mainSymbol := s.getSymbol(tenant) - if s.illRepo == nil { - return []string{mainSymbol} + allSyms := []string{mainSymbol} + if t.tenantContext.illRepo == nil { + return allSyms, nil } - peers, _, err := s.illRepo.GetCachedPeersBySymbols(ctx, []string{mainSymbol}, s.directoryLookupAdapter) + peers, _, err := t.tenantContext.illRepo.GetCachedPeersBySymbols(t.ctx, []string{mainSymbol}, t.tenantContext.directoryLookupAdapter) if err != nil { - return []string{} - } - if len(peers) == 0 { - ctx.Logger().Error("no peers for symbol", "symbol", mainSymbol) - return []string{} + return nil, err } - symbols := []string{mainSymbol} for _, peer := range peers { - branchSymbols, err := s.illRepo.GetBranchSymbolsByPeerId(ctx, peer.ID) + branchSymbols, err := t.tenantContext.illRepo.GetBranchSymbolsByPeerId(t.ctx, peer.ID) if err != nil { - return []string{} + return nil, err } for _, branchSymbol := range branchSymbols { - symbols = append(symbols, branchSymbol.SymbolValue) + allSyms = append(allSyms, branchSymbol.SymbolValue) } } - return symbols + return allSyms, nil } diff --git a/broker/api/tenant_test.go b/broker/api/tenant_test.go index 6743aacb..c08b379a 100644 --- a/broker/api/tenant_test.go +++ b/broker/api/tenant_test.go @@ -2,7 +2,8 @@ package api import ( "context" - "strings" + "net/http" + "net/url" "testing" "github.com/indexdata/crosslink/broker/adapter" @@ -12,120 +13,259 @@ import ( "github.com/stretchr/testify/mock" ) -func TestTenantContext(t *testing.T) { +type MockDirectoryLookupAdapter struct { + mock.Mock + adapter.DirectoryLookupAdapter +} + +type MockIllRepo struct { + mock.Mock + ill_db.IllRepo +} + +func (r *MockIllRepo) GetCachedPeersBySymbols(ctx common.ExtendedContext, symbols []string, directoryAdapter adapter.DirectoryLookupAdapter) ([]ill_db.Peer, string, error) { + args := r.Called(ctx, symbols, directoryAdapter) + return args.Get(0).([]ill_db.Peer), args.String(1), args.Error(2) +} + +func (r *MockIllRepo) GetBranchSymbolsByPeerId(ctx common.ExtendedContext, peerId string) ([]ill_db.BranchSymbol, error) { + args := r.Called(ctx, peerId) + return args.Get(0).([]ill_db.BranchSymbol), args.Error(1) +} + +func TestTenantNoSymbol(t *testing.T) { tenantContext := NewTenantContext() - assert.False(t, tenantContext.IsSpecified()) + assert.False(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) - _, err := tenantContext.symbolForRequest(ctx, false, nil, nil) - assert.Error(t, err) - assert.Equal(t, "symbol must be specified", err.Error()) + header := http.Header{} + url := &url.URL{Path: "/test"} + httpRequest := &http.Request{Header: header, URL: url} - requestSymbol := "" - _, err = tenantContext.symbolForRequest(ctx, false, nil, &requestSymbol) + tenant := tenantContext.WithRequest(ctx, httpRequest, nil) + _, err := tenant.GetSymbol() assert.Error(t, err) assert.Equal(t, "symbol must be specified", err.Error()) - requestSymbol = "symbol2" - symbol, err := tenantContext.symbolForRequest(ctx, false, nil, &requestSymbol) + symbols, err := tenant.GetSymbols() assert.NoError(t, err) - assert.Equal(t, requestSymbol, symbol) + assert.Nil(t, symbols) +} - _, err = tenantContext.symbolForRequest(ctx, true, nil, nil) +func TestTenantWithSymbol(t *testing.T) { + tenantContext := NewTenantContext() + assert.False(t, tenantContext.isSpecified()) + + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) + header := http.Header{} + url := &url.URL{Path: "/test"} + httpRequest := &http.Request{Header: header, URL: url} + + symbol := "LIB" + tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) + _, err := tenant.GetSymbol() + assert.NoError(t, err) + assert.Equal(t, "LIB", symbol) + + symbols, err := tenant.GetSymbols() + assert.NoError(t, err) + assert.Equal(t, []string{"LIB"}, symbols) +} + +func TestTenantNoMapping(t *testing.T) { + tenantContext := NewTenantContext() + assert.False(t, tenantContext.isSpecified()) + + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) + header := http.Header{} + url := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: url} + + tenant := tenantContext.WithRequest(ctx, httpRequest, nil) + _, err := tenant.GetSymbol() assert.Error(t, err) assert.Equal(t, "tenant mapping must be specified", err.Error()) - tenantContext = NewTenantContext().WithTenantSymbol("{tenant}") - assert.True(t, tenantContext.IsSpecified()) - _, err = tenantContext.symbolForRequest(ctx, true, nil, nil) + _, err = tenant.GetSymbols() assert.Error(t, err) - assert.Equal(t, "X-Okapi-Tenant must be specified", err.Error()) + assert.Equal(t, "tenant mapping must be specified", err.Error()) +} + +func TestTenantMissingTenant(t *testing.T) { + tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}") + assert.True(t, tenantContext.isSpecified()) - tenant := "" - _, err = tenantContext.symbolForRequest(ctx, true, &tenant, nil) + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) + header := http.Header{} + url := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: url} + + tenant := tenantContext.WithRequest(ctx, httpRequest, nil) + _, err := tenant.GetSymbol() assert.Error(t, err) - assert.Equal(t, "X-Okapi-Tenant must be specified", err.Error()) + assert.Equal(t, "header X-Okapi-Tenant must be specified", err.Error()) - tenant = "tenant1" - symbol, err = tenantContext.symbolForRequest(ctx, true, &tenant, nil) - assert.NoError(t, err) - assert.Equal(t, strings.ToUpper(tenant), symbol) + _, err = tenant.GetSymbols() + assert.Error(t, err) + assert.Equal(t, "header X-Okapi-Tenant must be specified", err.Error()) } -type MockDirectoryLookupAdapter struct { - mock.Mock - adapter.DirectoryLookupAdapter -} +func TestTenantMapOK(t *testing.T) { + tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}") + assert.True(t, tenantContext.isSpecified()) -type MockIllRepo struct { - mock.Mock - ill_db.IllRepo + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) + header := http.Header{} + header.Set("X-Okapi-Tenant", "tenant1") + url := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: url} + + tenant := tenantContext.WithRequest(ctx, httpRequest, nil) + sym, err := tenant.GetSymbol() + assert.NoError(t, err) + assert.Equal(t, "ISIL:DK-TENANT1", sym) + + symbols, err := tenant.GetSymbols() + assert.NoError(t, err) + assert.Equal(t, []string{"ISIL:DK-TENANT1"}, symbols) } -func (r *MockIllRepo) GetCachedPeersBySymbols(ctx common.ExtendedContext, symbols []string, directoryAdapter adapter.DirectoryLookupAdapter) ([]ill_db.Peer, string, error) { - args := r.Called(ctx, symbols, directoryAdapter) - return args.Get(0).([]ill_db.Peer), args.String(1), args.Error(2) +func TestTenantRepo1(t *testing.T) { + mockIllRepo := new(MockIllRepo) + mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{}, "", nil) + + tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) + assert.True(t, tenantContext.isSpecified()) + + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) + header := http.Header{} + header.Set("X-Okapi-Tenant", "tenant1") + url := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: url} + + tenant := tenantContext.WithRequest(ctx, httpRequest, nil) + sym, err := tenant.GetSymbol() + assert.NoError(t, err) + assert.Equal(t, "ISIL:DK-TENANT1", sym) + + symbols, err := tenant.GetSymbols() + assert.NoError(t, err) + assert.Equal(t, []string{"ISIL:DK-TENANT1"}, symbols) } -func (r *MockIllRepo) GetBranchSymbolsByPeerId(ctx common.ExtendedContext, peerId string) ([]ill_db.BranchSymbol, error) { - args := r.Called(ctx, peerId) - return args.Get(0).([]ill_db.BranchSymbol), args.Error(1) +func TestTenantSymIdentical(t *testing.T) { + mockIllRepo := new(MockIllRepo) + mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{}, "", nil) + + tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) + assert.True(t, tenantContext.isSpecified()) + + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) + header := http.Header{} + header.Set("X-Okapi-Tenant", "tenant1") + url := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: url} + symbol := "ISIL:DK-TENANT1" + tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) + outputSymbol, err := tenant.GetSymbol() + assert.NoError(t, err) + assert.Equal(t, "ISIL:DK-TENANT1", outputSymbol) + + symbols, err := tenant.GetSymbols() + assert.NoError(t, err) + assert.Equal(t, []string{"ISIL:DK-TENANT1"}, symbols) } -func TestTenantContextRepoNoPeer(t *testing.T) { +func TestTenantNoBranchMatch(t *testing.T) { mockIllRepo := new(MockIllRepo) mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{}, "", nil) - tenantContext := NewTenantContext().WithTenantSymbol("{tenant}").WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) + tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) + assert.True(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) - requestSymbol := "SYMBOL2" - _, err := tenantContext.symbolForRequest(ctx, false, nil, &requestSymbol) + header := http.Header{} + header.Set("X-Okapi-Tenant", "tenant1") + url := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: url} + symbol := "LIB" + tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) + _, err := tenant.GetSymbol() assert.Error(t, err) - assert.Equal(t, "no peers for symbol", err.Error()) + assert.Equal(t, "symbol does not match any branch symbols for tenant", err.Error()) + + symbols, err := tenant.GetSymbols() + assert.NoError(t, err) + assert.Equal(t, []string{"ISIL:DK-TENANT1"}, symbols) } -func TestTenantContextRepoOK(t *testing.T) { +func TestTenantBranchMatch(t *testing.T) { mockIllRepo := new(MockIllRepo) - mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{{ID: "SYMBOL"}}, "", nil) - mockIllRepo.On("GetBranchSymbolsByPeerId", mock.Anything, mock.Anything).Return([]ill_db.BranchSymbol{{SymbolValue: "LIB"}}, nil) + mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{{ID: "ISIL:DK-TENANT1"}}, "", nil) + mockIllRepo.On("GetBranchSymbolsByPeerId", mock.Anything, mock.Anything).Return([]ill_db.BranchSymbol{{SymbolValue: "ISIL:DK-DIKU"}, {SymbolValue: "ISIL:DK-LIB"}}, nil) - tenantContext := NewTenantContext().WithTenantSymbol("{tenant}").WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) + tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) + assert.True(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) - requestSymbol := "SYMBOL" - symbol, err := tenantContext.symbolForRequest(ctx, false, nil, &requestSymbol) + header := http.Header{} + header.Set("X-Okapi-Tenant", "tenant1") + url := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: url} + symbol := "ISIL:DK-LIB" + tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) + outputSymbol, err := tenant.GetSymbol() assert.NoError(t, err) - assert.Equal(t, requestSymbol, symbol) + assert.Equal(t, "ISIL:DK-LIB", outputSymbol) - requestSymbol = "LIB" - tenant := "symbol" - symbol, err = tenantContext.symbolForRequest(ctx, true, &tenant, &requestSymbol) + symbols, err := tenant.GetSymbols() assert.NoError(t, err) - assert.Equal(t, requestSymbol, symbol) + assert.Equal(t, []string{"ISIL:DK-TENANT1", "ISIL:DK-DIKU", "ISIL:DK-LIB"}, symbols) +} - requestSymbol = "" - symbol, err = tenantContext.symbolForRequest(ctx, true, &tenant, &requestSymbol) - assert.NoError(t, err) - assert.Equal(t, strings.ToUpper(tenant), symbol) +func TestTenantRepoError1(t *testing.T) { + mockIllRepo := new(MockIllRepo) + mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{}, "", assert.AnError) + + tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) + assert.True(t, tenantContext.isSpecified()) + + ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) + header := http.Header{} + header.Set("X-Okapi-Tenant", "tenant1") + url := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: url} + symbol := "ISIL:DK-LIB" + tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) + _, err := tenant.GetSymbol() + assert.Error(t, err) + assert.Equal(t, "assert.AnError general error for testing", err.Error()) + + _, err = tenant.GetSymbols() + assert.Error(t, err) + assert.Equal(t, "assert.AnError general error for testing", err.Error()) } -func TestTenantContextRepoBranches(t *testing.T) { +func TestTenantRepoError2(t *testing.T) { mockIllRepo := new(MockIllRepo) - mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{{ID: "SYMBOL"}}, "", nil) - mockIllRepo.On("GetBranchSymbolsByPeerId", mock.Anything, mock.Anything).Return([]ill_db.BranchSymbol{}, nil) + mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{{ID: "ISIL:DK-TENANT1"}}, "", nil) + mockIllRepo.On("GetBranchSymbolsByPeerId", mock.Anything, mock.Anything).Return([]ill_db.BranchSymbol{}, assert.AnError) - tenantContext := NewTenantContext().WithTenantSymbol("{tenant}").WithLookupAdapter(&MockDirectoryLookupAdapter{}).WithIllRepo(mockIllRepo) + tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) + assert.True(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) - requestSymbol := "SYMBOL" - symbol, err := tenantContext.symbolForRequest(ctx, false, nil, &requestSymbol) - assert.NoError(t, err) - assert.Equal(t, requestSymbol, symbol) + header := http.Header{} + header.Set("X-Okapi-Tenant", "tenant1") + url := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: url} + symbol := "ISIL:DK-LIB" + tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) + _, err := tenant.GetSymbol() + assert.Error(t, err) + assert.Equal(t, "assert.AnError general error for testing", err.Error()) - requestSymbol = "LIB" - tenant := "SYMBOL" - _, err = tenantContext.symbolForRequest(ctx, true, &tenant, &requestSymbol) + _, err = tenant.GetSymbols() assert.Error(t, err) - assert.Equal(t, "symbol does not match any branch symbols for tenant", err.Error()) + assert.Equal(t, "assert.AnError general error for testing", err.Error()) } diff --git a/broker/patron_request/api/api-handler.go b/broker/patron_request/api/api-handler.go index 72349090..9aab7687 100644 --- a/broker/patron_request/api/api-handler.go +++ b/broker/patron_request/api/api-handler.go @@ -96,7 +96,7 @@ func (a *PatronRequestApiHandler) GetPatronRequests(w http.ResponseWriter, r *ht logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return @@ -202,7 +202,7 @@ func (a *PatronRequestApiHandler) PostPatronRequests(w http.ResponseWriter, r *h addBadRequestError(ctx, w, err) return } - symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, newPr.RequesterSymbol) + symbol, err := a.tenantContext.WithRequest(ctx, r, newPr.RequesterSymbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return @@ -255,7 +255,7 @@ func (a *PatronRequestApiHandler) DeletePatronRequestsId(w http.ResponseWriter, logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return @@ -308,7 +308,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsId(w http.ResponseWriter, r * logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return @@ -329,7 +329,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdActions(w http.ResponseWrit } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) @@ -357,7 +357,7 @@ func (a *PatronRequestApiHandler) PostPatronRequestsIdAction(w http.ResponseWrit } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return @@ -434,7 +434,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdEvents(w http.ResponseWrite } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return @@ -465,7 +465,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdItems(w http.ResponseWriter } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return @@ -496,7 +496,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdNotifications(w http.Respon } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return @@ -546,7 +546,7 @@ func (a *PatronRequestApiHandler) PostPatronRequestsIdNotifications(w http.Respo logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return @@ -599,7 +599,7 @@ func (a *PatronRequestApiHandler) PutPatronRequestsIdNotificationsNotificationId logParams["side"] = *params.Side } ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) - symbol, err := a.tenantContext.GetSymbolForRequest(ctx, r, params.XOkapiTenant, params.Symbol) + symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return diff --git a/broker/test/api/api-handler_test.go b/broker/test/api/api-handler_test.go index ae778e93..a2dc9ca2 100644 --- a/broker/test/api/api-handler_test.go +++ b/broker/test/api/api-handler_test.go @@ -202,7 +202,8 @@ func TestGetIllTransactions(t *testing.T) { prevLink := *resp.About.PrevLink assert.Contains(t, prevLink, "offset=0") - body = getResponseBody(t, "/broker/ill_transactions?requester_symbol="+url.QueryEscape("ISIL:DK-BIB1")) + body = httpGet(t, "/broker/ill_transactions?requester_symbol="+url.QueryEscape("ISIL:DK-BIB1"), "bib1", http.StatusOK) + resp.About.NextLink = nil resp.About.PrevLink = nil err = json.Unmarshal(body, &resp) @@ -222,11 +223,10 @@ func TestGetIllTransactions(t *testing.T) { assert.Contains(t, lastLink, "requester_symbol="+url.QueryEscape("ISIL:DK-BIB1")) assert.Contains(t, lastLink, "offset=10") // we have estblished that the next link is correct, now we will check if it works - hres, err := http.Get(nextLink) // nolint:gosec - assert.NoError(t, err) - defer hres.Body.Close() - body, err = io.ReadAll(hres.Body) - assert.NoError(t, err) + + body = httpGet(t, nextLink, "", http.StatusBadRequest) + + body = httpGet(t, nextLink, "bib1", http.StatusOK) err = json.Unmarshal(body, &resp) assert.NoError(t, err) assert.NotNil(t, resp.About.PrevLink) @@ -324,9 +324,10 @@ func TestBrokerCRUD(t *testing.T) { httpGet(t, "/broker/ill_transactions/"+illId+"?requester_symbol="+url.QueryEscape("ISIL:DK-DIKU"), "diku", http.StatusOK) httpGet(t, "/broker/ill_transactions/"+illId+"?requester_symbol="+url.QueryEscape("ISIL:DK-DIKU"), "ruc", http.StatusNotFound) httpGet(t, "/broker/ill_transactions/"+illId, "ruc", http.StatusNotFound) - httpGet(t, "/broker/ill_transactions/"+illId, "", http.StatusNotFound) + httpGet(t, "/broker/ill_transactions/"+illId, "diku", http.StatusOK) + httpGet(t, "/broker/ill_transactions/"+illId, "", http.StatusBadRequest) - body = httpGet(t, "/broker/ill_transactions/"+illId+"?requester_symbol="+url.QueryEscape("ISIL:DK-DIKU"), "", http.StatusOK) + body = httpGet(t, "/broker/ill_transactions/"+illId+"?requester_symbol="+url.QueryEscape("ISIL:DK-DIKU"), "diku", http.StatusOK) err = json.Unmarshal(body, &tran) assert.NoError(t, err) assert.Equal(t, illId, tran.Id) @@ -339,7 +340,11 @@ func TestBrokerCRUD(t *testing.T) { assert.Equal(t, 0, len(httpGetTrans(t, "/broker/ill_transactions", "ruc", http.StatusOK))) - assert.Equal(t, 0, len(httpGetTrans(t, "/broker/ill_transactions", "", http.StatusOK))) + assert.Equal(t, 0, len(httpGetTrans(t, "/broker/ill_transactions", "magtic", http.StatusOK))) + + assert.Equal(t, 0, len(httpGetTrans(t, "/broker/ill_transactions", "", http.StatusBadRequest))) + + assert.True(t, len(httpGetTrans(t, "/ill_transactions", "", http.StatusOK)) >= 2) body = httpGet(t, "/broker/ill_transactions?requester_req_id="+url.QueryEscape(reqReqId), "diku", http.StatusOK) var resp oapi.IllTransactions @@ -383,7 +388,7 @@ func TestBrokerCRUD(t *testing.T) { assert.Len(t, events.Items, 1) assert.Equal(t, eventId, events.Items[0].Id) - body = httpGet(t, "/broker/events?requester_req_id="+url.QueryEscape(reqReqId)+"&requester_symbol="+url.QueryEscape("ISIL:DK-DIKU"), "", http.StatusOK) + body = httpGet(t, "/broker/events?requester_req_id="+url.QueryEscape(reqReqId)+"&requester_symbol="+url.QueryEscape("ISIL:DK-DIKU"), "diku", http.StatusOK) err = json.Unmarshal(body, &events) assert.NoError(t, err) assert.Len(t, events.Items, 1) @@ -822,7 +827,10 @@ func getResponseBody(t *testing.T, endpoint string) []byte { func httpRequest(t *testing.T, method string, uriPath string, reqbytes []byte, tenant string, expectStatus int) []byte { client := http.DefaultClient - hreq, err := http.NewRequest(method, getLocalhostWithPort()+uriPath, bytes.NewBuffer(reqbytes)) + if strings.HasPrefix(uriPath, "/") { + uriPath = getLocalhostWithPort() + uriPath + } + hreq, err := http.NewRequest(method, uriPath, bytes.NewBuffer(reqbytes)) assert.NoError(t, err) if tenant != "" { hreq.Header.Set("X-Okapi-Tenant", tenant) diff --git a/broker/test/api/sse_broker_test.go b/broker/test/api/sse_broker_test.go index fb3e8eeb..83843e58 100644 --- a/broker/test/api/sse_broker_test.go +++ b/broker/test/api/sse_broker_test.go @@ -119,7 +119,7 @@ func TestSseEndpointNoTenant(t *testing.T) { bodyBytes, err := io.ReadAll(resp.Body) assert.NoError(t, err) assert.Equal(t, 400, resp.StatusCode) - assert.Equal(t, "X-Okapi-Tenant must be specified\n", string(bodyBytes)) + assert.Equal(t, "header X-Okapi-Tenant must be specified\n", string(bodyBytes)) } func executeTask(t time.Time) { From f74a54a0ed536bf965f1df3b11551c1c3a1f1431 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 17 Apr 2026 15:41:33 +0200 Subject: [PATCH 13/21] check body --- broker/test/api/api-handler_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/broker/test/api/api-handler_test.go b/broker/test/api/api-handler_test.go index a2dc9ca2..1d11d5f7 100644 --- a/broker/test/api/api-handler_test.go +++ b/broker/test/api/api-handler_test.go @@ -222,10 +222,11 @@ func TestGetIllTransactions(t *testing.T) { assert.True(t, strings.HasPrefix(lastLink, getLocalhostWithPort()+"/broker/ill_transactions?")) assert.Contains(t, lastLink, "requester_symbol="+url.QueryEscape("ISIL:DK-BIB1")) assert.Contains(t, lastLink, "offset=10") - // we have estblished that the next link is correct, now we will check if it works + // we still need the tenant body = httpGet(t, nextLink, "", http.StatusBadRequest) - + assert.Contains(t, string(body), "header X-Okapi-Tenant must be specified") + // supply tenant now body = httpGet(t, nextLink, "bib1", http.StatusOK) err = json.Unmarshal(body, &resp) assert.NoError(t, err) From 0554300f9fdf8d1d26ed2092d5f2f178601ed265 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 17 Apr 2026 15:56:28 +0200 Subject: [PATCH 14/21] tenant in separate package --- broker/api/api-handler.go | 5 +- broker/api/sse_broker.go | 5 +- broker/app/app.go | 7 +- broker/patron_request/api/api-handler.go | 5 +- broker/patron_request/api/api-handler_test.go | 106 +++++++++--------- broker/{api => tenant}/tenant.go | 4 +- broker/{api => tenant}/tenant_test.go | 24 ++-- broker/test/api/api-handler_test.go | 3 +- 8 files changed, 82 insertions(+), 77 deletions(-) rename broker/{api => tenant}/tenant.go (98%) rename broker/{api => tenant}/tenant_test.go (91%) diff --git a/broker/api/api-handler.go b/broker/api/api-handler.go index 782f6b10..d808a26e 100644 --- a/broker/api/api-handler.go +++ b/broker/api/api-handler.go @@ -11,6 +11,7 @@ import ( "github.com/indexdata/crosslink/broker/adapter" "github.com/indexdata/crosslink/broker/service" + "github.com/indexdata/crosslink/broker/tenant" "github.com/indexdata/crosslink/directory" "github.com/google/uuid" @@ -38,10 +39,10 @@ type ApiHandler struct { limitDefault int32 eventRepo events.EventRepo illRepo ill_db.IllRepo - tenantContext TenantContext + tenantContext tenant.TenantContext } -func NewApiHandler(eventRepo events.EventRepo, illRepo ill_db.IllRepo, tenantContext TenantContext, limitDefault int32) ApiHandler { +func NewApiHandler(eventRepo events.EventRepo, illRepo ill_db.IllRepo, tenantContext tenant.TenantContext, limitDefault int32) ApiHandler { return ApiHandler{ eventRepo: eventRepo, illRepo: illRepo, diff --git a/broker/api/sse_broker.go b/broker/api/sse_broker.go index a384d22b..9bd8d17a 100644 --- a/broker/api/sse_broker.go +++ b/broker/api/sse_broker.go @@ -11,6 +11,7 @@ import ( "github.com/indexdata/crosslink/broker/events" pr_db "github.com/indexdata/crosslink/broker/patron_request/db" prservice "github.com/indexdata/crosslink/broker/patron_request/service" + "github.com/indexdata/crosslink/broker/tenant" "github.com/indexdata/crosslink/iso18626" ) @@ -19,10 +20,10 @@ type SseBroker struct { clients map[string]map[chan string]bool mu sync.Mutex ctx common.ExtendedContext - tenantContext TenantContext + tenantContext tenant.TenantContext } -func NewSseBroker(ctx common.ExtendedContext, tenantContext TenantContext) (broker *SseBroker) { +func NewSseBroker(ctx common.ExtendedContext, tenantContext tenant.TenantContext) (broker *SseBroker) { broker = &SseBroker{ input: make(chan SseMessage), clients: make(map[string]map[chan string]bool), diff --git a/broker/app/app.go b/broker/app/app.go index 7dd997fd..0d3d8e32 100644 --- a/broker/app/app.go +++ b/broker/app/app.go @@ -17,6 +17,7 @@ import ( pr_db "github.com/indexdata/crosslink/broker/patron_request/db" "github.com/indexdata/crosslink/broker/patron_request/proapi" prservice "github.com/indexdata/crosslink/broker/patron_request/service" + "github.com/indexdata/crosslink/broker/tenant" "github.com/dustin/go-humanize" "github.com/indexdata/crosslink/broker/adapter" @@ -166,7 +167,7 @@ func Init(ctx context.Context) (Context, error) { iso18626Client := client.CreateIso18626Client(eventBus, illRepo, prMessageHandler, MAX_MESSAGE_SIZE, delay) supplierLocator := service.CreateSupplierLocator(eventBus, illRepo, dirAdapter, holdingsAdapter) workflowManager := service.CreateWorkflowManager(eventBus, illRepo, service.WorkflowConfig{}) - tenantContext := api.NewTenantContext().WithIllRepo(illRepo).WithLookupAdapter(dirAdapter).WithTenantSymbol(TENANT_TO_SYMBOL) + tenantContext := tenant.NewContext().WithIllRepo(illRepo).WithLookupAdapter(dirAdapter).WithTenantSymbol(TENANT_TO_SYMBOL) prApiHandler := prapi.NewPrApiHandler(prRepo, eventBus, eventRepo, *tenantContext, &iso18626Handler, API_PAGE_SIZE) prApiHandler.SetAutoActionRunner(prActionService) prApiHandler.SetActionTaskProcessor(prActionService) @@ -210,13 +211,13 @@ func StartServer(ctx Context) error { _, _ = w.Write(oapi.OpenAPISpecYAML) }) - tenantContext := api.NewTenantContext().WithIllRepo(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter) + tenantContext := tenant.NewContext().WithIllRepo(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter) apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, *tenantContext, API_PAGE_SIZE) oapi.HandlerFromMux(&apiHandler, ServeMux) proapi.HandlerFromMux(&ctx.PrApiHandler, ServeMux) if TENANT_TO_SYMBOL != "" { - tenantContext = api.NewTenantContext().WithIllRepo(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter).WithTenantSymbol(TENANT_TO_SYMBOL) + tenantContext = tenant.NewContext().WithIllRepo(ctx.IllRepo).WithLookupAdapter(ctx.DirAdapter).WithTenantSymbol(TENANT_TO_SYMBOL) ServeMux.HandleFunc("/broker/sse/events", ctx.SseBroker.ServeHTTP) apiHandler := api.NewApiHandler(ctx.EventRepo, ctx.IllRepo, *tenantContext, API_PAGE_SIZE) diff --git a/broker/patron_request/api/api-handler.go b/broker/patron_request/api/api-handler.go index 32bbc25c..b9ab6203 100644 --- a/broker/patron_request/api/api-handler.go +++ b/broker/patron_request/api/api-handler.go @@ -21,6 +21,7 @@ import ( pr_db "github.com/indexdata/crosslink/broker/patron_request/db" "github.com/indexdata/crosslink/broker/patron_request/proapi" prservice "github.com/indexdata/crosslink/broker/patron_request/service" + "github.com/indexdata/crosslink/broker/tenant" "github.com/indexdata/crosslink/iso18626" "github.com/indexdata/go-utils/utils" "github.com/jackc/pgerrcode" @@ -45,12 +46,12 @@ type PatronRequestApiHandler struct { actionMappingService prservice.ActionMappingService autoActionRunner prservice.AutoActionRunner actionTaskProcessor ActionTaskProcessor - tenantContext api.TenantContext + tenantContext tenant.TenantContext notificationSender prservice.PatronRequestNotificationService } func NewPrApiHandler(prRepo pr_db.PrRepo, eventBus events.EventBus, - eventRepo events.EventRepo, tenantContext api.TenantContext, iso18626Handler handler.Iso18626HandlerInterface, limitDefault int32) PatronRequestApiHandler { + eventRepo events.EventRepo, tenantContext tenant.TenantContext, iso18626Handler handler.Iso18626HandlerInterface, limitDefault int32) PatronRequestApiHandler { return PatronRequestApiHandler{ limitDefault: limitDefault, prRepo: prRepo, diff --git a/broker/patron_request/api/api-handler_test.go b/broker/patron_request/api/api-handler_test.go index 9b315db0..f0d2f6af 100644 --- a/broker/patron_request/api/api-handler_test.go +++ b/broker/patron_request/api/api-handler_test.go @@ -13,13 +13,13 @@ import ( "time" "github.com/google/uuid" - "github.com/indexdata/crosslink/broker/api" "github.com/indexdata/crosslink/broker/common" "github.com/indexdata/crosslink/broker/events" "github.com/indexdata/crosslink/broker/handler" pr_db "github.com/indexdata/crosslink/broker/patron_request/db" "github.com/indexdata/crosslink/broker/patron_request/proapi" prservice "github.com/indexdata/crosslink/broker/patron_request/service" + "github.com/indexdata/crosslink/broker/tenant" "github.com/indexdata/crosslink/broker/test/mocks" "github.com/indexdata/crosslink/iso18626" "github.com/jackc/pgx/v5" @@ -62,7 +62,7 @@ func TestGetDbText(t *testing.T) { } func TestGetPatronRequests(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() params := proapi.GetPatronRequestsParams{ @@ -75,7 +75,7 @@ func TestGetPatronRequests(t *testing.T) { } func TestGetPatronRequestsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() params := proapi.GetPatronRequestsParams{ @@ -87,7 +87,7 @@ func TestGetPatronRequestsNoSymbol(t *testing.T) { } func TestGetPatronRequestsWithLimits(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() offset := proapi.Offset(10) @@ -107,7 +107,7 @@ func TestGetPatronRequestsWithLimits(t *testing.T) { func TestGetPatronRequestsWithRequesterReqId(t *testing.T) { repo := new(PrRepoCapture) - handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() requesterReqID := "req-123" @@ -126,7 +126,7 @@ func TestGetPatronRequestsWithRequesterReqId(t *testing.T) { } func TestPostPatronRequests(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) id := "1" toCreate := proapi.CreatePatronRequest{ Id: &id, @@ -145,7 +145,7 @@ func TestPostPatronRequests(t *testing.T) { } func TestPostPatronRequestsMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) toCreate := proapi.PatronRequest{Id: "1"} jsonBytes, err := json.Marshal(toCreate) assert.NoError(t, err, "failed to marshal patron request") @@ -159,7 +159,7 @@ func TestPostPatronRequestsMissingSymbol(t *testing.T) { } func TestPostPatronRequestsInvalidJson(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("POST", "/", bytes.NewBuffer([]byte("a\": v\""))) rr := httptest.NewRecorder() tenant := proapi.Tenant("test-lib") @@ -169,7 +169,7 @@ func TestPostPatronRequestsInvalidJson(t *testing.T) { } func TestPostPatronRequestsInvalidIllRequestShape(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) jsonBytes := []byte(`{ "id":"1", "requesterSymbol":"` + symbol + `", @@ -185,7 +185,7 @@ func TestPostPatronRequestsInvalidIllRequestShape(t *testing.T) { } func TestDeletePatronRequestsIdNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "2", proapi.DeletePatronRequestsIdParams{Symbol: &symbol}) @@ -193,7 +193,7 @@ func TestDeletePatronRequestsIdNotFound(t *testing.T) { } func TestDeletePatronRequestsIdMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "2", proapi.DeletePatronRequestsIdParams{}) @@ -202,7 +202,7 @@ func TestDeletePatronRequestsIdMissingSymbol(t *testing.T) { } func TestDeletePatronRequestsIdError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "1", proapi.DeletePatronRequestsIdParams{Symbol: &symbol}) @@ -211,7 +211,7 @@ func TestDeletePatronRequestsIdError(t *testing.T) { } func TestDeletePatronRequestsId(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "3", proapi.DeletePatronRequestsIdParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -220,7 +220,7 @@ func TestDeletePatronRequestsId(t *testing.T) { } func TestDeletePatronRequestsIdDeleted(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.DeletePatronRequestsId(rr, req, "4", proapi.DeletePatronRequestsIdParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -228,7 +228,7 @@ func TestDeletePatronRequestsIdDeleted(t *testing.T) { } func TestGetPatronRequestsIdMissingSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "2", proapi.GetPatronRequestsIdParams{}) @@ -237,7 +237,7 @@ func TestGetPatronRequestsIdMissingSymbol(t *testing.T) { } func TestGetPatronRequestsIdNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "2", proapi.GetPatronRequestsIdParams{Symbol: &symbol}) @@ -245,7 +245,7 @@ func TestGetPatronRequestsIdNotFound(t *testing.T) { } func TestGetPatronRequestsId(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsId(rr, req, "1", proapi.GetPatronRequestsIdParams{Symbol: &symbol}) @@ -254,7 +254,7 @@ func TestGetPatronRequestsId(t *testing.T) { } func TestGetPatronRequestsIdActions(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -263,7 +263,7 @@ func TestGetPatronRequestsIdActions(t *testing.T) { } func TestGetPatronRequestsIdActionsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Side: &proapiBorrowingSide}) @@ -272,7 +272,7 @@ func TestGetPatronRequestsIdActionsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdActionsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "1", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -281,7 +281,7 @@ func TestGetPatronRequestsIdActionsDbError(t *testing.T) { } func TestGetPatronRequestsIdActionsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdActions(rr, req, "3", proapi.GetPatronRequestsIdActionsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -290,7 +290,7 @@ func TestGetPatronRequestsIdActionsNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdActionNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Side: &proapiBorrowingSide}) @@ -299,7 +299,7 @@ func TestPostPatronRequestsIdActionNoSymbol(t *testing.T) { } func TestPostPatronRequestsIdActionDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "1", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -308,7 +308,7 @@ func TestPostPatronRequestsIdActionDbError(t *testing.T) { } func TestPostPatronRequestsIdActionNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -317,7 +317,7 @@ func TestPostPatronRequestsIdActionNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdActionErrorParsing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", strings.NewReader("{")) rr := httptest.NewRecorder() handler.PostPatronRequestsIdAction(rr, req, "3", proapi.PostPatronRequestsIdActionParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -326,7 +326,7 @@ func TestPostPatronRequestsIdActionErrorParsing(t *testing.T) { } func TestGetPatronRequestsIdEventsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Side: &proapiBorrowingSide}) @@ -335,7 +335,7 @@ func TestGetPatronRequestsIdEventsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdEventsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "1", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -344,7 +344,7 @@ func TestGetPatronRequestsIdEventsDbError(t *testing.T) { } func TestGetPatronRequestsIdEventsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -353,7 +353,7 @@ func TestGetPatronRequestsIdEventsNotFoundBecauseOfSide(t *testing.T) { } func TestGetPatronRequestsIdEventsErrorGettingEvents(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdEvents(rr, req, "3", proapi.GetPatronRequestsIdEventsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -362,7 +362,7 @@ func TestGetPatronRequestsIdEventsErrorGettingEvents(t *testing.T) { } func TestGetPatronRequestsIdNotificationsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Side: &proapiBorrowingSide}) @@ -371,7 +371,7 @@ func TestGetPatronRequestsIdNotificationsNoSymbol(t *testing.T) { } func TestGetPatronRequestsIdNotificationsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "1", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -380,7 +380,7 @@ func TestGetPatronRequestsIdNotificationsDbError(t *testing.T) { } func TestGetPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiLendingSide}) @@ -389,7 +389,7 @@ func TestGetPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { } func TestGetPatronRequestsIdNotificationsErrorGettingEvents(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() handler.GetPatronRequestsIdNotifications(rr, req, "3", proapi.GetPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -423,7 +423,7 @@ func TestGetPatronRequestsIdNotificationsWithKindFilter(t *testing.T) { }, fullCount: 1, } - handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(repo, mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("GET", "/", nil) rr := httptest.NewRecorder() @@ -458,7 +458,7 @@ func TestGetPatronRequestsIdNotificationsWithKindFilter(t *testing.T) { } func TestParseAndValidateIllRequestAndBuildDbPatronRequest(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) creationTime := time.Now() id := uuid.NewString() @@ -485,7 +485,7 @@ func TestParseAndValidateIllRequestAndBuildDbPatronRequest(t *testing.T) { } func TestParseAndValidateIllRequestInvalidRequesterSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) invalidSymbol := "REQ" @@ -495,7 +495,7 @@ func TestParseAndValidateIllRequestInvalidRequesterSymbol(t *testing.T) { } func TestParseAndValidateIllRequestInvalidBrokerSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) previousBrokerSymbol := brokerSymbol brokerSymbol = "BROKER" @@ -512,7 +512,7 @@ func TestParseAndValidateIllRequestInvalidBrokerSymbol(t *testing.T) { } func TestPostPatronRequestsIdNotificationsNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdNotifications(rr, req, "3", proapi.PostPatronRequestsIdNotificationsParams{Side: &proapiBorrowingSide}) @@ -521,7 +521,7 @@ func TestPostPatronRequestsIdNotificationsNoSymbol(t *testing.T) { } func TestPostPatronRequestsIdNotificationsDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -531,7 +531,7 @@ func TestPostPatronRequestsIdNotificationsDbError(t *testing.T) { } func TestPostPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -541,7 +541,7 @@ func TestPostPatronRequestsIdNotificationsNotFoundBecauseOfSide(t *testing.T) { } func TestPostPatronRequestsIdNotificationsErrorSavingNotification(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *tenant.NewContext(), nil, 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -551,7 +551,7 @@ func TestPostPatronRequestsIdNotificationsErrorSavingNotification(t *testing.T) } func TestPostPatronRequestsIdNotificationsErrorBecauseOfBodyMissing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("POST", "/", nil) rr := httptest.NewRecorder() handler.PostPatronRequestsIdNotifications(rr, req, "3", proapi.PostPatronRequestsIdNotificationsParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -560,7 +560,7 @@ func TestPostPatronRequestsIdNotificationsErrorBecauseOfBodyMissing(t *testing.T } func TestPostPatronRequestsIdNotificationsErrorBecauseOfBody(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *tenant.NewContext(), nil, 10) body := "{\"note" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -570,7 +570,7 @@ func TestPostPatronRequestsIdNotificationsErrorBecauseOfBody(t *testing.T) { } func TestPostPatronRequestsIdNotificationsErrorFailedSendOnlyLogged(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositorySuccess), *api.NewTenantContext(), new(MockIso18626Handler), 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositorySuccess), *tenant.NewContext(), new(MockIso18626Handler), 10) body := "{\"note\": \"Say hello\"}" req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -580,7 +580,7 @@ func TestPostPatronRequestsIdNotificationsErrorFailedSendOnlyLogged(t *testing.T } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNoSymbol(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("PUT", "/", nil) rr := httptest.NewRecorder() handler.PutPatronRequestsIdNotificationsNotificationIdReceipt(rr, req, "3", "n1", proapi.PutPatronRequestsIdNotificationsNotificationIdReceiptParams{Side: &proapiBorrowingSide}) @@ -589,7 +589,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNoSymbol(t *testin } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptDbError(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -599,7 +599,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptDbError(t *testing } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFoundBecauseOfSide(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, mockEventRepo, *tenant.NewContext(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -609,7 +609,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFoundBecauseOfS } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorReadingNotification(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *tenant.NewContext(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -619,7 +619,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorReadingNotifi } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFound(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *tenant.NewContext(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -629,7 +629,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptNotFound(t *testin } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBodyMissing(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *tenant.NewContext(), nil, 10) req, _ := http.NewRequest("PUT", "/", nil) rr := httptest.NewRecorder() handler.PutPatronRequestsIdNotificationsNotificationIdReceipt(rr, req, "3", "n1", proapi.PutPatronRequestsIdNotificationsNotificationIdReceiptParams{Symbol: &symbol, Side: &proapiBorrowingSide}) @@ -638,7 +638,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBody } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBody(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *tenant.NewContext(), nil, 10) body := "{\"receipt" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -648,7 +648,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptErrorBecauseOfBody } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptPrDoesNotOwn(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *tenant.NewContext(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() @@ -658,7 +658,7 @@ func TestPutPatronRequestsIdNotificationsNotificationIdReceiptPrDoesNotOwn(t *te } func TestPutPatronRequestsIdNotificationsNotificationIdReceiptFailedToSave(t *testing.T) { - handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *api.NewTenantContext(), nil, 10) + handler := NewPrApiHandler(new(PrRepoError), mockEventBus, new(mocks.MockEventRepositoryError), *tenant.NewContext(), nil, 10) body := "{\"receipt\": \"SEEN\"}" req, _ := http.NewRequest("PUT", "/", bytes.NewBufferString(body)) rr := httptest.NewRecorder() diff --git a/broker/api/tenant.go b/broker/tenant/tenant.go similarity index 98% rename from broker/api/tenant.go rename to broker/tenant/tenant.go index d2720f1a..c4cff9b2 100644 --- a/broker/api/tenant.go +++ b/broker/tenant/tenant.go @@ -1,4 +1,4 @@ -package api +package tenant import ( "errors" @@ -16,7 +16,7 @@ type TenantContext struct { tenantSymbolMap string } -func NewTenantContext() *TenantContext { +func NewContext() *TenantContext { return &TenantContext{} } diff --git a/broker/api/tenant_test.go b/broker/tenant/tenant_test.go similarity index 91% rename from broker/api/tenant_test.go rename to broker/tenant/tenant_test.go index c08b379a..8acf4ac0 100644 --- a/broker/api/tenant_test.go +++ b/broker/tenant/tenant_test.go @@ -1,4 +1,4 @@ -package api +package tenant import ( "context" @@ -34,7 +34,7 @@ func (r *MockIllRepo) GetBranchSymbolsByPeerId(ctx common.ExtendedContext, peerI } func TestTenantNoSymbol(t *testing.T) { - tenantContext := NewTenantContext() + tenantContext := NewContext() assert.False(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) @@ -53,7 +53,7 @@ func TestTenantNoSymbol(t *testing.T) { } func TestTenantWithSymbol(t *testing.T) { - tenantContext := NewTenantContext() + tenantContext := NewContext() assert.False(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) @@ -73,7 +73,7 @@ func TestTenantWithSymbol(t *testing.T) { } func TestTenantNoMapping(t *testing.T) { - tenantContext := NewTenantContext() + tenantContext := NewContext() assert.False(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) @@ -92,7 +92,7 @@ func TestTenantNoMapping(t *testing.T) { } func TestTenantMissingTenant(t *testing.T) { - tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}") + tenantContext := NewContext().WithTenantSymbol("ISIL:DK-{tenant}") assert.True(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) @@ -111,7 +111,7 @@ func TestTenantMissingTenant(t *testing.T) { } func TestTenantMapOK(t *testing.T) { - tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}") + tenantContext := NewContext().WithTenantSymbol("ISIL:DK-{tenant}") assert.True(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) @@ -134,7 +134,7 @@ func TestTenantRepo1(t *testing.T) { mockIllRepo := new(MockIllRepo) mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{}, "", nil) - tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) + tenantContext := NewContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) assert.True(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) @@ -157,7 +157,7 @@ func TestTenantSymIdentical(t *testing.T) { mockIllRepo := new(MockIllRepo) mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{}, "", nil) - tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) + tenantContext := NewContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) assert.True(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) @@ -180,7 +180,7 @@ func TestTenantNoBranchMatch(t *testing.T) { mockIllRepo := new(MockIllRepo) mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{}, "", nil) - tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) + tenantContext := NewContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) assert.True(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) @@ -204,7 +204,7 @@ func TestTenantBranchMatch(t *testing.T) { mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{{ID: "ISIL:DK-TENANT1"}}, "", nil) mockIllRepo.On("GetBranchSymbolsByPeerId", mock.Anything, mock.Anything).Return([]ill_db.BranchSymbol{{SymbolValue: "ISIL:DK-DIKU"}, {SymbolValue: "ISIL:DK-LIB"}}, nil) - tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) + tenantContext := NewContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) assert.True(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) @@ -227,7 +227,7 @@ func TestTenantRepoError1(t *testing.T) { mockIllRepo := new(MockIllRepo) mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{}, "", assert.AnError) - tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) + tenantContext := NewContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) assert.True(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) @@ -251,7 +251,7 @@ func TestTenantRepoError2(t *testing.T) { mockIllRepo.On("GetCachedPeersBySymbols", mock.Anything, mock.Anything, mock.Anything).Return([]ill_db.Peer{{ID: "ISIL:DK-TENANT1"}}, "", nil) mockIllRepo.On("GetBranchSymbolsByPeerId", mock.Anything, mock.Anything).Return([]ill_db.BranchSymbol{}, assert.AnError) - tenantContext := NewTenantContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) + tenantContext := NewContext().WithTenantSymbol("ISIL:DK-{tenant}").WithIllRepo(mockIllRepo) assert.True(t, tenantContext.isSpecified()) ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) diff --git a/broker/test/api/api-handler_test.go b/broker/test/api/api-handler_test.go index 1d11d5f7..03c910cf 100644 --- a/broker/test/api/api-handler_test.go +++ b/broker/test/api/api-handler_test.go @@ -18,6 +18,7 @@ import ( "github.com/jackc/pgx/v5" "github.com/indexdata/crosslink/broker/common" + "github.com/indexdata/crosslink/broker/tenant" "github.com/indexdata/crosslink/broker/vcs" "github.com/indexdata/crosslink/iso18626" "github.com/jackc/pgx/v5/pgtype" @@ -44,7 +45,7 @@ var eventRepo events.EventRepo var sseBroker *api.SseBroker var mockIllRepoError = new(mocks.MockIllRepositoryError) var mockEventRepoError = new(mocks.MockEventRepositoryError) -var handlerMock = api.NewApiHandler(mockEventRepoError, mockIllRepoError, *api.NewTenantContext(), api.LIMIT_DEFAULT) +var handlerMock = api.NewApiHandler(mockEventRepoError, mockIllRepoError, *tenant.NewContext(), api.LIMIT_DEFAULT) func TestMain(m *testing.M) { app.TENANT_TO_SYMBOL = "ISIL:DK-{tenant}" From 749ce65ba93f09ba596d9b9e6c83e3cf594c2674 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 17 Apr 2026 16:20:06 +0200 Subject: [PATCH 15/21] Avoid url as variable --- broker/tenant/tenant_test.go | 44 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/broker/tenant/tenant_test.go b/broker/tenant/tenant_test.go index 8acf4ac0..f4c049d5 100644 --- a/broker/tenant/tenant_test.go +++ b/broker/tenant/tenant_test.go @@ -39,8 +39,8 @@ func TestTenantNoSymbol(t *testing.T) { ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) header := http.Header{} - url := &url.URL{Path: "/test"} - httpRequest := &http.Request{Header: header, URL: url} + turl := &url.URL{Path: "/test"} + httpRequest := &http.Request{Header: header, URL: turl} tenant := tenantContext.WithRequest(ctx, httpRequest, nil) _, err := tenant.GetSymbol() @@ -58,8 +58,8 @@ func TestTenantWithSymbol(t *testing.T) { ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) header := http.Header{} - url := &url.URL{Path: "/test"} - httpRequest := &http.Request{Header: header, URL: url} + turl := &url.URL{Path: "/test"} + httpRequest := &http.Request{Header: header, URL: turl} symbol := "LIB" tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) @@ -78,8 +78,8 @@ func TestTenantNoMapping(t *testing.T) { ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) header := http.Header{} - url := &url.URL{Path: "/broker/"} - httpRequest := &http.Request{Header: header, URL: url} + turl := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: turl} tenant := tenantContext.WithRequest(ctx, httpRequest, nil) _, err := tenant.GetSymbol() @@ -97,8 +97,8 @@ func TestTenantMissingTenant(t *testing.T) { ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) header := http.Header{} - url := &url.URL{Path: "/broker/"} - httpRequest := &http.Request{Header: header, URL: url} + turl := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: turl} tenant := tenantContext.WithRequest(ctx, httpRequest, nil) _, err := tenant.GetSymbol() @@ -117,8 +117,8 @@ func TestTenantMapOK(t *testing.T) { ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) header := http.Header{} header.Set("X-Okapi-Tenant", "tenant1") - url := &url.URL{Path: "/broker/"} - httpRequest := &http.Request{Header: header, URL: url} + turl := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: turl} tenant := tenantContext.WithRequest(ctx, httpRequest, nil) sym, err := tenant.GetSymbol() @@ -140,8 +140,8 @@ func TestTenantRepo1(t *testing.T) { ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) header := http.Header{} header.Set("X-Okapi-Tenant", "tenant1") - url := &url.URL{Path: "/broker/"} - httpRequest := &http.Request{Header: header, URL: url} + turl := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: turl} tenant := tenantContext.WithRequest(ctx, httpRequest, nil) sym, err := tenant.GetSymbol() @@ -163,8 +163,8 @@ func TestTenantSymIdentical(t *testing.T) { ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) header := http.Header{} header.Set("X-Okapi-Tenant", "tenant1") - url := &url.URL{Path: "/broker/"} - httpRequest := &http.Request{Header: header, URL: url} + turl := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: turl} symbol := "ISIL:DK-TENANT1" tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) outputSymbol, err := tenant.GetSymbol() @@ -186,8 +186,8 @@ func TestTenantNoBranchMatch(t *testing.T) { ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) header := http.Header{} header.Set("X-Okapi-Tenant", "tenant1") - url := &url.URL{Path: "/broker/"} - httpRequest := &http.Request{Header: header, URL: url} + turl := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: turl} symbol := "LIB" tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) _, err := tenant.GetSymbol() @@ -210,8 +210,8 @@ func TestTenantBranchMatch(t *testing.T) { ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) header := http.Header{} header.Set("X-Okapi-Tenant", "tenant1") - url := &url.URL{Path: "/broker/"} - httpRequest := &http.Request{Header: header, URL: url} + turl := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: turl} symbol := "ISIL:DK-LIB" tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) outputSymbol, err := tenant.GetSymbol() @@ -233,8 +233,8 @@ func TestTenantRepoError1(t *testing.T) { ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) header := http.Header{} header.Set("X-Okapi-Tenant", "tenant1") - url := &url.URL{Path: "/broker/"} - httpRequest := &http.Request{Header: header, URL: url} + turl := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: turl} symbol := "ISIL:DK-LIB" tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) _, err := tenant.GetSymbol() @@ -257,8 +257,8 @@ func TestTenantRepoError2(t *testing.T) { ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{}) header := http.Header{} header.Set("X-Okapi-Tenant", "tenant1") - url := &url.URL{Path: "/broker/"} - httpRequest := &http.Request{Header: header, URL: url} + turl := &url.URL{Path: "/broker/"} + httpRequest := &http.Request{Header: header, URL: turl} symbol := "ISIL:DK-LIB" tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) _, err := tenant.GetSymbol() From 4d3b117d6aa724060c9ed55ff9b5b62e50bd99b8 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 17 Apr 2026 16:20:27 +0200 Subject: [PATCH 16/21] Fix typo --- broker/test/api/sse_broker_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/broker/test/api/sse_broker_test.go b/broker/test/api/sse_broker_test.go index 83843e58..047720b0 100644 --- a/broker/test/api/sse_broker_test.go +++ b/broker/test/api/sse_broker_test.go @@ -105,7 +105,7 @@ func TestSseEndpointNoSide(t *testing.T) { } func TestSseEndpointNoSymbol(t *testing.T) { - resp, err := http.Get(getLocalhostWithPort() + "/sse/events?side=borrowwing&other=/broker/") + resp, err := http.Get(getLocalhostWithPort() + "/sse/events?side=borrowing&other=/broker/") assert.NoError(t, err) bodyBytes, err := io.ReadAll(resp.Body) assert.NoError(t, err) From bd22f49ff6493e7e1885458cd65b0767ed5e7682 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 17 Apr 2026 16:21:54 +0200 Subject: [PATCH 17/21] Use r.Context for sse_broker --- broker/api/sse_broker.go | 4 +--- broker/patron_request/api/api-handler.go | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/broker/api/sse_broker.go b/broker/api/sse_broker.go index 9bd8d17a..e6cacad9 100644 --- a/broker/api/sse_broker.go +++ b/broker/api/sse_broker.go @@ -1,7 +1,6 @@ package api import ( - "context" "encoding/json" "fmt" "net/http" @@ -70,10 +69,9 @@ func (b *SseBroker) removeClient(receiver string, clientChannel chan string) { // ServeHTTP implements the http.Handler interface for the SSE endpoint. func (b *SseBroker) ServeHTTP(w http.ResponseWriter, r *http.Request) { logParams := map[string]string{"method": "ServeHTTP"} - ectx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ectx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) suppliedSymbol := r.URL.Query().Get("symbol") - // symbol, err := b.tenantContext.GetSymbolForRequest(ectx, r, &tenant, &suppliedSymbol) symbol, err := b.tenantContext.WithRequest(ectx, r, &suppliedSymbol).GetSymbol() if err != nil { diff --git a/broker/patron_request/api/api-handler.go b/broker/patron_request/api/api-handler.go index b9ab6203..3eaed64c 100644 --- a/broker/patron_request/api/api-handler.go +++ b/broker/patron_request/api/api-handler.go @@ -331,7 +331,6 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdActions(w http.ResponseWrit ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() - if err != nil { addBadRequestError(ctx, w, err) return From 191f7d14f0f305f554fff4e787af8454b3d4e164 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 17 Apr 2026 17:18:43 +0200 Subject: [PATCH 18/21] Use cqlbuilder --- broker/ill_db/ill_cql.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/broker/ill_db/ill_cql.go b/broker/ill_db/ill_cql.go index b6d44547..aeaf1403 100644 --- a/broker/ill_db/ill_cql.go +++ b/broker/ill_db/ill_cql.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/indexdata/cql-go/cql" + "github.com/indexdata/cql-go/cqlbuilder" "github.com/indexdata/cql-go/pgcql" ) @@ -63,11 +64,11 @@ func (q *Queries) ListIllTransactionsCql(ctx context.Context, db DBTX, arg ListI } else { cql.WriteString("(") } - if len(symbol) == 0 || strings.ContainsAny(symbol, " *\"\\") { - return nil, fmt.Errorf("invalid symbol: %s", symbol) + comp, err := cqlbuilder.NewQuery().Search("requester_symbol").Term(symbol).Build() + if err != nil { + return nil, fmt.Errorf("failed to build CQL query: %w", err) } - sc := "requester_symbol=" + symbol - cql.WriteString(sc) + cql.WriteString(comp.String()) } if cql.Len() > 0 { cql.WriteString(")") From 0e803fbb73012e07225338b622557d5ec2b488ae Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 17 Apr 2026 19:43:19 +0200 Subject: [PATCH 19/21] Create context from request in most cases --- broker/api/api-handler.go | 21 ++++++----- broker/patron_request/api/api-handler.go | 47 ++++++++++++------------ 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/broker/api/api-handler.go b/broker/api/api-handler.go index d808a26e..fb4c94bd 100644 --- a/broker/api/api-handler.go +++ b/broker/api/api-handler.go @@ -109,7 +109,7 @@ func (a *ApiHandler) GetEvents(w http.ResponseWriter, r *http.Request, params oa if params.IllTransactionId != nil { logParams["IllTransactionId"] = *params.IllTransactionId } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{ Other: logParams, }) tran, err := a.getIllTranFromParams(ctx, w, r, params.RequesterSymbol, @@ -138,7 +138,7 @@ func (a *ApiHandler) GetEvents(w http.ResponseWriter, r *http.Request, params oa } func (a *ApiHandler) GetIllTransactions(w http.ResponseWriter, r *http.Request, params oapi.GetIllTransactionsParams) { - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{ Other: map[string]string{"method": "GetIllTransactions"}, }) var resp oapi.IllTransactions @@ -194,7 +194,7 @@ func (a *ApiHandler) GetIllTransactions(w http.ResponseWriter, r *http.Request, } func (a *ApiHandler) GetIllTransactionsId(w http.ResponseWriter, r *http.Request, id string, params oapi.GetIllTransactionsIdParams) { - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{ Other: map[string]string{"method": "GetIllTransactionsId", "id": id}, }) tran, err := a.getIllTranFromParams(ctx, w, r, params.RequesterSymbol, @@ -210,7 +210,7 @@ func (a *ApiHandler) GetIllTransactionsId(w http.ResponseWriter, r *http.Request } func (a *ApiHandler) DeleteIllTransactionsId(w http.ResponseWriter, r *http.Request, id string) { - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{ Other: map[string]string{"method": "DeleteIllTransactionsId", "id": id}, }) trans, err := a.illRepo.GetIllTransactionById(ctx, id) @@ -248,7 +248,7 @@ func (a *ApiHandler) returnHttpError(ctx common.ExtendedContext, w http.Response } func (a *ApiHandler) GetPeers(w http.ResponseWriter, r *http.Request, params oapi.GetPeersParams) { - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{ Other: map[string]string{"method": "GetPeers"}, }) dbparams := ill_db.ListPeersParams{ @@ -287,7 +287,7 @@ func (a *ApiHandler) GetPeers(w http.ResponseWriter, r *http.Request, params oap } func (a *ApiHandler) PostPeers(w http.ResponseWriter, r *http.Request) { - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{ Other: map[string]string{"method": "PostPeers"}, }) var newPeer oapi.Peer @@ -355,7 +355,7 @@ func (a *ApiHandler) PostPeers(w http.ResponseWriter, r *http.Request) { } func (a *ApiHandler) DeletePeersId(w http.ResponseWriter, r *http.Request, id string) { - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{ Other: map[string]string{"method": "DeletePeersSymbol", "id": id}, }) err := a.illRepo.WithTxFunc(ctx, func(repo ill_db.IllRepo) error { @@ -413,7 +413,7 @@ func (a *ApiHandler) DeletePeersId(w http.ResponseWriter, r *http.Request, id st } func (a *ApiHandler) GetPeersId(w http.ResponseWriter, r *http.Request, id string) { - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{ Other: map[string]string{"method": "GetPeersSymbol", "id": id}, }) peer, err := a.illRepo.GetPeerById(ctx, id) @@ -441,7 +441,7 @@ func (a *ApiHandler) GetPeersId(w http.ResponseWriter, r *http.Request, id strin } func (a *ApiHandler) PutPeersId(w http.ResponseWriter, r *http.Request, id string) { - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{ Other: map[string]string{"method": "PutPeersSymbol", "id": id}, }) peer, err := a.illRepo.GetPeerById(ctx, id) @@ -547,7 +547,7 @@ func (a *ApiHandler) GetLocatedSuppliers(w http.ResponseWriter, r *http.Request, if params.IllTransactionId != nil { logParams["IllTransactionId"] = *params.IllTransactionId } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{ Other: logParams, }) tran, err := a.getIllTranFromParams(ctx, w, r, params.RequesterSymbol, @@ -577,6 +577,7 @@ func (a *ApiHandler) GetLocatedSuppliers(w http.ResponseWriter, r *http.Request, func (a *ApiHandler) PostArchiveIllTransactions(w http.ResponseWriter, r *http.Request, params oapi.PostArchiveIllTransactionsParams) { logParams := map[string]string{"method": "PostArchiveIllTransactions", "ArchiveDelay": params.ArchiveDelay, "ArchiveStatus": params.ArchiveStatus} + // a background process so use background context instead of request context to avoid cancellation when request is finished ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ Other: logParams, }) diff --git a/broker/patron_request/api/api-handler.go b/broker/patron_request/api/api-handler.go index 3eaed64c..b442fdaa 100644 --- a/broker/patron_request/api/api-handler.go +++ b/broker/patron_request/api/api-handler.go @@ -1,7 +1,6 @@ package prapi import ( - "context" "encoding/json" "errors" "fmt" @@ -74,7 +73,7 @@ func (a *PatronRequestApiHandler) SetActionTaskProcessor(actionTaskProcessor Act func (a *PatronRequestApiHandler) GetStateModelModelsModel(w http.ResponseWriter, r *http.Request, model string, params proapi.GetStateModelModelsModelParams) { stateModel, err := a.actionMappingService.GetStateModel(model) if err != nil { - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{ + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{ Other: map[string]string{"method": "GetStateModelModelsModel", "model": model}, }) addInternalError(ctx, w, err) @@ -96,14 +95,14 @@ func (a *PatronRequestApiHandler) GetPatronRequests(w http.ResponseWriter, r *ht if params.Side != nil { logParams["side"] = *params.Side } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return } logParams["symbol"] = symbol - ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx = common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) limit := a.limitDefault if params.Limit != nil { @@ -196,7 +195,7 @@ func addOwnerRestriction(queryBuilder *cqlbuilder.QueryBuilder, symbol string, s func (a *PatronRequestApiHandler) PostPatronRequests(w http.ResponseWriter, r *http.Request, params proapi.PostPatronRequestsParams) { logParams := map[string]string{"method": "PostPatronRequests"} - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) var newPr proapi.CreatePatronRequest err := json.NewDecoder(r.Body).Decode(&newPr) if err != nil { @@ -209,7 +208,7 @@ func (a *PatronRequestApiHandler) PostPatronRequests(w http.ResponseWriter, r *h return } logParams["symbol"] = symbol - ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx = common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) newPr.RequesterSymbol = &symbol creationTime := pgtype.Timestamp{Valid: true, Time: time.Now()} illRequest, requesterReqId, err := a.parseAndValidateIllRequest(ctx, &newPr, creationTime.Time) @@ -255,14 +254,14 @@ func (a *PatronRequestApiHandler) DeletePatronRequestsId(w http.ResponseWriter, if params.Side != nil { logParams["side"] = *params.Side } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return } logParams["symbol"] = symbol - ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx = common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return @@ -308,14 +307,14 @@ func (a *PatronRequestApiHandler) GetPatronRequestsId(w http.ResponseWriter, r * if params.Side != nil { logParams["side"] = *params.Side } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return } logParams["symbol"] = symbol - ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx = common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return @@ -328,7 +327,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdActions(w http.ResponseWrit if params.Side != nil { logParams["side"] = *params.Side } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { @@ -336,7 +335,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdActions(w http.ResponseWrit return } logParams["symbol"] = symbol - ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx = common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return @@ -355,7 +354,7 @@ func (a *PatronRequestApiHandler) PostPatronRequestsIdAction(w http.ResponseWrit if params.Side != nil { logParams["side"] = *params.Side } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { @@ -363,7 +362,7 @@ func (a *PatronRequestApiHandler) PostPatronRequestsIdAction(w http.ResponseWrit return } logParams["symbol"] = symbol - ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx = common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return @@ -432,7 +431,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdEvents(w http.ResponseWrite if params.Side != nil { logParams["side"] = *params.Side } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { @@ -440,7 +439,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdEvents(w http.ResponseWrite return } logParams["symbol"] = symbol - ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx = common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return @@ -463,7 +462,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdItems(w http.ResponseWriter if params.Side != nil { logParams["side"] = *params.Side } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { @@ -471,7 +470,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdItems(w http.ResponseWriter return } logParams["symbol"] = symbol - ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx = common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) pr := a.getPatronRequestById(w, ctx, id, params.Side, symbol) if pr == nil { return @@ -494,7 +493,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdNotifications(w http.Respon if params.Side != nil { logParams["side"] = *params.Side } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { @@ -502,7 +501,7 @@ func (a *PatronRequestApiHandler) GetPatronRequestsIdNotifications(w http.Respon return } logParams["symbol"] = symbol - ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx = common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) limit := a.limitDefault if params.Limit != nil { limit = *params.Limit @@ -545,14 +544,14 @@ func (a *PatronRequestApiHandler) PostPatronRequestsIdNotifications(w http.Respo if params.Side != nil { logParams["side"] = *params.Side } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return } logParams["symbol"] = symbol - ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx = common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) if r.Body == nil { addBadRequestError(ctx, w, errors.New("body is required")) return @@ -598,14 +597,14 @@ func (a *PatronRequestApiHandler) PutPatronRequestsIdNotificationsNotificationId if params.Side != nil { logParams["side"] = *params.Side } - ctx := common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx := common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) symbol, err := a.tenantContext.WithRequest(ctx, r, params.Symbol).GetSymbol() if err != nil { addBadRequestError(ctx, w, err) return } logParams["symbol"] = symbol - ctx = common.CreateExtCtxWithArgs(context.Background(), &common.LoggerArgs{Other: logParams}) + ctx = common.CreateExtCtxWithArgs(r.Context(), &common.LoggerArgs{Other: logParams}) if r.Body == nil { addBadRequestError(ctx, w, errors.New("body is required")) return From 4d39c98078c5359e140de3c682cf0351a0f88c38 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 17 Apr 2026 20:07:22 +0200 Subject: [PATCH 20/21] Do not call GetCachedPeersBySymbols if tenant sym == supplied syml --- broker/tenant/tenant.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/broker/tenant/tenant.go b/broker/tenant/tenant.go index c4cff9b2..73135fbe 100644 --- a/broker/tenant/tenant.go +++ b/broker/tenant/tenant.go @@ -85,15 +85,16 @@ func (t *Tenant) GetSymbol() (string, error) { if t.tenantContext.illRepo == nil { return mainSymbol, nil } - peers, _, err := t.tenantContext.illRepo.GetCachedPeersBySymbols(t.ctx, []string{mainSymbol}, t.tenantContext.directoryLookupAdapter) - if err != nil { - return "", err - } - // seems like len(peers) > 0 always, so we can't flag an error for symbol that does not exist // if supplied symbol is the same as main symbol, we can skip the check against branch symbols, since it's valid + // we do not check even if only one symbol because GetCachedPeersBySymbols() creates a peer for the main symbol if it does not exist, + // so we would not be able to distinguish between "symbol does not exist" and "symbol exists but has no peers" if t.symbol == "" || t.symbol == mainSymbol { return mainSymbol, nil } + peers, _, err := t.tenantContext.illRepo.GetCachedPeersBySymbols(t.ctx, []string{mainSymbol}, t.tenantContext.directoryLookupAdapter) + if err != nil { + return "", err + } found := false for _, peer := range peers { branchSymbols, err := t.tenantContext.illRepo.GetBranchSymbolsByPeerId(t.ctx, peer.ID) @@ -113,7 +114,8 @@ func (t *Tenant) GetSymbol() (string, error) { } // GetSymbols returns the main symbol for the tenant and all branch symbols of peers associated with that symbol. -// Note that empty list and nil are used to distinguish between "no symbols" and "all symbols" (i.e. no symbol filtering). +// A nil slice means no symbol filtering should be applied. Otherwise, the returned slice contains at least the +// main symbol and may include associated branch symbols. func (t *Tenant) GetSymbols() ([]string, error) { var mainSymbol string if t.okapiEndpoint { From 731f2e7f829323c1941d585048f1daf7958ce877 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 17 Apr 2026 20:07:35 +0200 Subject: [PATCH 21/21] Minor adjustments to testing --- broker/tenant/tenant_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/broker/tenant/tenant_test.go b/broker/tenant/tenant_test.go index f4c049d5..1657ae88 100644 --- a/broker/tenant/tenant_test.go +++ b/broker/tenant/tenant_test.go @@ -63,9 +63,9 @@ func TestTenantWithSymbol(t *testing.T) { symbol := "LIB" tenant := tenantContext.WithRequest(ctx, httpRequest, &symbol) - _, err := tenant.GetSymbol() + outputSymbol, err := tenant.GetSymbol() assert.NoError(t, err) - assert.Equal(t, "LIB", symbol) + assert.Equal(t, "LIB", outputSymbol) symbols, err := tenant.GetSymbols() assert.NoError(t, err) @@ -121,9 +121,9 @@ func TestTenantMapOK(t *testing.T) { httpRequest := &http.Request{Header: header, URL: turl} tenant := tenantContext.WithRequest(ctx, httpRequest, nil) - sym, err := tenant.GetSymbol() + outputSymbol, err := tenant.GetSymbol() assert.NoError(t, err) - assert.Equal(t, "ISIL:DK-TENANT1", sym) + assert.Equal(t, "ISIL:DK-TENANT1", outputSymbol) symbols, err := tenant.GetSymbols() assert.NoError(t, err) @@ -144,9 +144,9 @@ func TestTenantRepo1(t *testing.T) { httpRequest := &http.Request{Header: header, URL: turl} tenant := tenantContext.WithRequest(ctx, httpRequest, nil) - sym, err := tenant.GetSymbol() + outputSymbol, err := tenant.GetSymbol() assert.NoError(t, err) - assert.Equal(t, "ISIL:DK-TENANT1", sym) + assert.Equal(t, "ISIL:DK-TENANT1", outputSymbol) symbols, err := tenant.GetSymbols() assert.NoError(t, err)