Skip to content

Commit

Permalink
Enhanced pkg http client impl and also using it for search documents …
Browse files Browse the repository at this point in the history
…in portal
  • Loading branch information
matskramer committed Dec 19, 2024
1 parent a7e669a commit 0c53c32
Show file tree
Hide file tree
Showing 16 changed files with 99 additions and 55 deletions.
27 changes: 2 additions & 25 deletions internal/apigw/apiv1/handlers_datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,31 +480,8 @@ func (c *Client) RevokeDocument(ctx context.Context, req *RevokeDocumentRequest)
return nil
}

// SearchDocumentsRequest the request to search for documents
type SearchDocumentsRequest struct {
AuthenticSource string `json:"authentic_source,omitempty"`
DocumentType string `json:"document_type,omitempty"`
DocumentID string `json:"document_id,omitempty"`
CollectID string `json:"collect_id,omitempty"`

AuthenticSourcePersonID string `json:"authentic_source_person_id,omitempty"`
FamilyName string `json:"family_name,omitempty"`
GivenName string `json:"given_name,omitempty"`
BirthDate string `json:"birth_date,omitempty"`

Limit int64 `json:"limit,omitempty"`
Fields []string `json:"fields,omitempty"`
SortFields map[string]int `json:"sort_fields,omitempty"`
}

// SearchDocumentsReply the reply from search documents
type SearchDocumentsReply struct {
Documents []*model.CompleteDocument `json:"documents"`
HasMoreResults bool `json:"has_more_results"`
}

// SearchDocuments search for documents
func (c *Client) SearchDocuments(ctx context.Context, req *SearchDocumentsRequest) (*SearchDocumentsReply, error) {
func (c *Client) SearchDocuments(ctx context.Context, req *model.SearchDocumentsRequest) (*model.SearchDocumentsReply, error) {
docs, hasMore, err := c.db.VCDatastoreColl.SearchDocuments(ctx, &db.SearchDocumentsQuery{
AuthenticSource: req.AuthenticSource,
DocumentType: req.DocumentType,
Expand All @@ -520,7 +497,7 @@ func (c *Client) SearchDocuments(ctx context.Context, req *SearchDocumentsReques
if err != nil {
return nil, err
}
resp := &SearchDocumentsReply{
resp := &model.SearchDocumentsReply{
Documents: docs,
HasMoreResults: hasMore,
}
Expand Down
2 changes: 1 addition & 1 deletion internal/apigw/httpserver/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type Apiv1 interface {
GetConsent(ctx context.Context, req *apiv1.GetConsentRequest) (*model.Consent, error)

// datastore endpoints - disabled in production
SearchDocuments(ctx context.Context, req *apiv1.SearchDocumentsRequest) (*apiv1.SearchDocumentsReply, error)
SearchDocuments(ctx context.Context, req *model.SearchDocumentsRequest) (*model.SearchDocumentsReply, error)

// credential endpoints
Revoke(ctx context.Context, req *apiv1.RevokeRequest) (*apiv1.RevokeReply, error)
Expand Down
3 changes: 2 additions & 1 deletion internal/apigw/httpserver/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"vc/internal/apigw/apiv1"
"vc/internal/gen/status/apiv1_status"
"vc/pkg/model"

"go.opentelemetry.io/otel/codes"

Expand Down Expand Up @@ -106,7 +107,7 @@ func (s *Service) endpointSearchDocuments(ctx context.Context, c *gin.Context) (
ctx, span := s.tracer.Start(ctx, "httpserver:endpointSearchDocuments")
defer span.End()

request := &apiv1.SearchDocumentsRequest{}
request := &model.SearchDocumentsRequest{}
if err := s.httpHelpers.Binding.Request(ctx, c, request); err != nil {
span.SetStatus(codes.Error, err.Error())
return nil, err
Expand Down
5 changes: 2 additions & 3 deletions internal/portal/apiv1/apigw_client.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package apiv1

import (
apiv1_apigw "vc/internal/apigw/apiv1"
"vc/pkg/logger"
"vc/pkg/model"
"vc/pkg/trace"
Expand All @@ -20,8 +19,8 @@ func NewAPIGWClient(cfg *model.Cfg, tracer *trace.Tracer, logger *logger.Log) *A
}

// SearchDocuments sends POST to /api/v1/document/search
func (c *APIGWClient) SearchDocuments(req *apiv1_apigw.SearchDocumentsRequest) (*apiv1_apigw.SearchDocumentsReply, error) {
reply, err := DoPostJSONGeneric[apiv1_apigw.SearchDocumentsReply](c.VCBaseClient, "/api/v1/document/search", req)
func (c *APIGWClient) SearchDocuments(req *model.SearchDocumentsRequest) (*model.SearchDocumentsReply, error) {
reply, err := DoPostJSONGeneric[model.SearchDocumentsReply](c.VCBaseClient, "/api/v1/document/search", req)
if err != nil {
return nil, err
}
Expand Down
10 changes: 9 additions & 1 deletion internal/portal/apiv1/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package apiv1

import (
"context"
"vc/pkg/datastoreclient"
"vc/pkg/logger"
"vc/pkg/model"
"vc/pkg/trace"
Expand All @@ -13,7 +14,8 @@ type Client struct {
log *logger.Log
tracer *trace.Tracer

apigwClient *APIGWClient
apigwClient *APIGWClient
datastoreClient *datastoreclient.Client
}

// New creates a new instance of the public api
Expand All @@ -25,6 +27,12 @@ func New(ctx context.Context, tracer *trace.Tracer, cfg *model.Cfg, log *logger.
apigwClient: NewAPIGWClient(cfg, tracer, log.New("apiwg_client")),
}

var err error
c.datastoreClient, err = datastoreclient.New(&datastoreclient.Config{URL: cfg.Portal.Services.APIGW.BaseURL})
if err != nil {
return nil, err
}

c.log.Info("Started")

return c, nil
Expand Down
11 changes: 8 additions & 3 deletions internal/portal/apiv1/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package apiv1

import (
"context"
apiv1_apigw "vc/internal/apigw/apiv1"
"errors"
"net/http"
"vc/internal/gen/status/apiv1_status"
"vc/pkg/model"
)
Expand All @@ -17,10 +18,14 @@ func (c *Client) Status(ctx context.Context, req *apiv1_status.StatusRequest) (*
}

// SearchDocuments search for documents
func (c *Client) SearchDocuments(ctx context.Context, req *apiv1_apigw.SearchDocumentsRequest) (*apiv1_apigw.SearchDocumentsReply, error) {
reply, err := c.apigwClient.SearchDocuments(req)
func (c *Client) SearchDocuments(ctx context.Context, req *model.SearchDocumentsRequest) (*model.SearchDocumentsReply, error) {
//reply, err := c.apigwClient.SearchDocuments(req)
reply, httpResponse, err := c.datastoreClient.Document.Search(ctx, req)
if err != nil {
return nil, err
}
if httpResponse.StatusCode != http.StatusOK {
return nil, errors.New(httpResponse.Status)
}
return reply, nil
}
4 changes: 2 additions & 2 deletions internal/portal/httpserver/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package httpserver

import (
"context"
apiv1_apigw "vc/internal/apigw/apiv1"
"vc/internal/gen/status/apiv1_status"
"vc/pkg/model"
)

// Apiv1 interface
type Apiv1 interface {
Status(ctx context.Context, req *apiv1_status.StatusRequest) (*apiv1_status.StatusReply, error)

SearchDocuments(ctx context.Context, request *apiv1_apigw.SearchDocumentsRequest) (*apiv1_apigw.SearchDocumentsReply, error)
SearchDocuments(ctx context.Context, request *model.SearchDocumentsRequest) (*model.SearchDocumentsReply, error)
}
4 changes: 2 additions & 2 deletions internal/portal/httpserver/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package httpserver

import (
"context"
apiv1_apigw "vc/internal/apigw/apiv1"
"vc/internal/gen/status/apiv1_status"
"vc/pkg/model"

"github.com/gin-gonic/gin"
)
Expand All @@ -18,7 +18,7 @@ func (s *Service) endpointHealth(ctx context.Context, c *gin.Context) (any, erro
}

func (s *Service) endpointSearchDocuments(ctx context.Context, c *gin.Context) (any, error) {
request := &apiv1_apigw.SearchDocumentsRequest{}
request := &model.SearchDocumentsRequest{}
if err := s.httpHelpers.Binding.Request(ctx, c, request); err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions internal/ui/apiv1/apigw_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ func (c *APIGWClient) Notification(req *NotificationRequest) (any, error) {
}

// SearchDocuments sends POST to /api/v1/document/search
func (c *APIGWClient) SearchDocuments(req *apiv1_apigw.SearchDocumentsRequest) (*apiv1_apigw.SearchDocumentsReply, error) {
reply, err := DoPostJSONGeneric[apiv1_apigw.SearchDocumentsReply](c.VCBaseClient, "/api/v1/document/search", req)
func (c *APIGWClient) SearchDocuments(req *model.SearchDocumentsRequest) (*model.SearchDocumentsReply, error) {
reply, err := DoPostJSONGeneric[model.SearchDocumentsReply](c.VCBaseClient, "/api/v1/document/search", req)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/ui/apiv1/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func (c *Client) DecodeCredential(ctx context.Context, req *apiv1_verifier.Decod
return reply, nil
}

func (c *Client) SearchDocuments(ctx context.Context, req *apiv1_apigw.SearchDocumentsRequest) (*apiv1_apigw.SearchDocumentsReply, error) {
func (c *Client) SearchDocuments(ctx context.Context, req *model.SearchDocumentsRequest) (*model.SearchDocumentsReply, error) {
reply, err := c.apigwClient.SearchDocuments(req)
if err != nil {
return nil, err
Expand Down
3 changes: 2 additions & 1 deletion internal/ui/httpserver/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
apiv1_mockas "vc/internal/mockas/apiv1"
"vc/internal/ui/apiv1"
apiv1_verifier "vc/internal/verifier/apiv1"
"vc/pkg/model"
)

type Apiv1 interface {
Expand All @@ -23,7 +24,7 @@ type Apiv1 interface {
Credential(ctx context.Context, request *apiv1.CredentialRequest) (any, error)
GetDocument(ctx context.Context, request *apiv1.GetDocumentRequest) (any, error)
Notification(ctx context.Context, reguest *apiv1.NotificationRequest) (any, error)
SearchDocuments(ctx context.Context, request *apiv1_apigw.SearchDocumentsRequest) (*apiv1_apigw.SearchDocumentsReply, error)
SearchDocuments(ctx context.Context, request *model.SearchDocumentsRequest) (*model.SearchDocumentsReply, error)
DeleteDocument(ctx context.Context, request *apiv1_apigw.DeleteDocumentRequest) error

// mockas
Expand Down
3 changes: 2 additions & 1 deletion internal/ui/httpserver/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
apiv1_mockas "vc/internal/mockas/apiv1"
"vc/internal/ui/apiv1"
apiv1_verifier "vc/internal/verifier/apiv1"
"vc/pkg/model"

"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
Expand Down Expand Up @@ -218,7 +219,7 @@ func (s *Service) endpointDecodeCredential(ctx context.Context, c *gin.Context)
}

func (s *Service) endpointSearchDocuments(ctx context.Context, c *gin.Context) (any, error) {
request := &apiv1_apigw.SearchDocumentsRequest{}
request := &model.SearchDocumentsRequest{}
if err := s.httpHelpers.Binding.Request(ctx, c, request); err != nil {
return nil, err
}
Expand Down
31 changes: 23 additions & 8 deletions pkg/datastoreclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (c *Client) newRequest(ctx context.Context, method, path string, body any)
}

// Do does the new request
func (c *Client) do(ctx context.Context, req *http.Request, reply any) (*http.Response, error) {
func (c *Client) do(ctx context.Context, req *http.Request, reply any, prefixReplyJsonWithData bool) (*http.Response, error) {
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
Expand All @@ -100,18 +100,33 @@ func (c *Client) do(ctx context.Context, req *http.Request, reply any) (*http.Re
return nil, err
}

r := struct {
Data any `json:"data"`
}{
Data: reply,
var r any
if prefixReplyJsonWithData {
r = &struct {
Data any `json:"data"`
}{
Data: reply,
}
} else {
r = &reply
}

if err := json.NewDecoder(resp.Body).Decode(&r); err != nil {
if err := json.NewDecoder(resp.Body).Decode(r); err != nil {
c.log.Error(err, "failed to decode response")
return nil, err
}

return resp, nil

}

// read body and make it reusable
func readBody(body io.ReadCloser) ([]byte, error) {
buf := &bytes.Buffer{}
if _, err := buf.ReadFrom(body); err != nil {
return nil, err
}
return buf.Bytes(), nil
}

func checkResponse(r *http.Response) error {
Expand All @@ -127,7 +142,7 @@ func checkResponse(r *http.Response) error {
return ErrInvalidRequest
}

func (c *Client) call(ctx context.Context, method, url string, body, reply any) (*http.Response, error) {
func (c *Client) call(ctx context.Context, method, url string, body, reply any, prefixReplyJsonWithData bool) (*http.Response, error) {
request, err := c.newRequest(
ctx,
method,
Expand All @@ -138,7 +153,7 @@ func (c *Client) call(ctx context.Context, method, url string, body, reply any)
return nil, err
}

resp, err := c.do(ctx, request, reply)
resp, err := c.do(ctx, request, reply, prefixReplyJsonWithData)
if err != nil {
return resp, err
}
Expand Down
20 changes: 17 additions & 3 deletions pkg/datastoreclient/endpoints_document.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type DocumentGetQuery struct {
func (s *documentHandler) Get(ctx context.Context, query *DocumentGetQuery) (*model.Document, *http.Response, error) {
url := fmt.Sprintf("%s", s.service)
reply := &model.Document{}
resp, err := s.client.call(ctx, http.MethodPost, url, nil, reply)
resp, err := s.client.call(ctx, http.MethodPost, url, nil, reply, true)
if err != nil {
return nil, resp, err
}
Expand All @@ -46,7 +46,7 @@ func (s *documentHandler) List(ctx context.Context, query *DocumentListQuery) ([

url := fmt.Sprintf("%s/%s", s.service, "list")
reply := []model.DocumentList{}
resp, err := s.client.call(ctx, http.MethodPost, url, nil, reply)
resp, err := s.client.call(ctx, http.MethodPost, url, nil, reply, true)
if err != nil {
return nil, resp, err
}
Expand All @@ -71,7 +71,21 @@ func (s *documentHandler) CollectID(ctx context.Context, query *DocumentCollectI

url := fmt.Sprintf("%s/%s", s.service, "collect_id")
reply := &model.Document{}
resp, err := s.client.call(ctx, http.MethodPost, url, query, reply)
resp, err := s.client.call(ctx, http.MethodPost, url, query, reply, true)
if err != nil {
return nil, resp, err
}
return reply, resp, nil
}

func (s *documentHandler) Search(ctx context.Context, query *model.SearchDocumentsRequest) (*model.SearchDocumentsReply, *http.Response, error) {
s.log.Debug("Search (Documents)")

url := fmt.Sprintf("%s/%s", s.service, "search")
reply := &model.SearchDocumentsReply{
Documents: []*model.CompleteDocument{},
}
resp, err := s.client.call(ctx, http.MethodPost, url, query, reply, false)
if err != nil {
return nil, resp, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/datastoreclient/endpoints_identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (s *identityHandler) Mapping(ctx context.Context, query *IdentityMappingQue

url := fmt.Sprintf("%s/%s", s.service, "mapping")
reply := ""
resp, err := s.client.call(ctx, http.MethodPost, url, nil, reply)
resp, err := s.client.call(ctx, http.MethodPost, url, nil, reply, true)
if err != nil {
return "", resp, err
}
Expand Down
23 changes: 23 additions & 0 deletions pkg/model/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,3 +384,26 @@ type QR struct {
// required: true
CredentialOfferURL string `json:"credential_offer,omitempty" bson:"credential_offer"`
}

// SearchDocumentsReply the reply from search documents
type SearchDocumentsReply struct {
Documents []*CompleteDocument `json:"documents"`
HasMoreResults bool `json:"has_more_results"`
}

// SearchDocumentsRequest the request to search for documents
type SearchDocumentsRequest struct {
AuthenticSource string `json:"authentic_source,omitempty"`
DocumentType string `json:"document_type,omitempty"`
DocumentID string `json:"document_id,omitempty"`
CollectID string `json:"collect_id,omitempty"`

AuthenticSourcePersonID string `json:"authentic_source_person_id,omitempty"`
FamilyName string `json:"family_name,omitempty"`
GivenName string `json:"given_name,omitempty"`
BirthDate string `json:"birth_date,omitempty"`

Limit int64 `json:"limit,omitempty"`
Fields []string `json:"fields,omitempty"`
SortFields map[string]int `json:"sort_fields,omitempty"`
}

0 comments on commit 0c53c32

Please sign in to comment.