Skip to content

Commit ceebf75

Browse files
authored
add "Get" method for es client (#81)
1 parent 5c2d664 commit ceebf75

File tree

4 files changed

+222
-12
lines changed

4 files changed

+222
-12
lines changed

go/v1beta1/storage/esutil/client.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import (
2525
"go.uber.org/zap"
2626
"google.golang.org/protobuf/encoding/protojson"
2727
"google.golang.org/protobuf/proto"
28+
"net/http"
29+
"net/url"
2830
)
2931

3032
type CreateRequest struct {
@@ -50,6 +52,11 @@ type MultiSearchRequest struct {
5052
Searches []*EsSearch
5153
}
5254

55+
type GetRequest struct {
56+
Index string
57+
DocumentId string
58+
}
59+
5360
type MultiGetRequest struct {
5461
Index string
5562
DocumentIds []string
@@ -93,6 +100,7 @@ type Client interface {
93100
BulkCreate(ctx context.Context, request *BulkCreateRequest) (*EsBulkResponse, error)
94101
Search(ctx context.Context, request *SearchRequest) (*SearchResponse, error)
95102
MultiSearch(ctx context.Context, request *MultiSearchRequest) (*EsMultiSearchResponse, error)
103+
Get(ctx context.Context, request *GetRequest) (*EsGetResponse, error)
96104
MultiGet(ctx context.Context, request *MultiGetRequest) (*EsMultiGetResponse, error)
97105
Update(ctx context.Context, request *UpdateRequest) error
98106
Delete(ctx context.Context, request *DeleteRequest) error
@@ -350,6 +358,31 @@ func (c *client) MultiSearch(ctx context.Context, request *MultiSearchRequest) (
350358
return &response, nil
351359
}
352360

361+
func (c *client) Get(ctx context.Context, request *GetRequest) (*EsGetResponse, error) {
362+
log := c.logger.Named("Get").With(zap.String("index", request.Index), zap.String("documentId", request.DocumentId))
363+
364+
res, err := c.esClient.Get(
365+
request.Index,
366+
url.QueryEscape(request.DocumentId),
367+
c.esClient.Get.WithContext(ctx),
368+
)
369+
if err != nil {
370+
return nil, err
371+
}
372+
if res.IsError() && res.StatusCode != http.StatusNotFound {
373+
return nil, fmt.Errorf("unexpected response from elasticsearch: %s", res.String())
374+
}
375+
376+
var response EsGetResponse
377+
if err = DecodeResponse(res.Body, &response); err != nil {
378+
return nil, err
379+
}
380+
381+
log.Debug("elasticsearch response", zap.Any("response", response))
382+
383+
return &response, nil
384+
}
385+
353386
func (c *client) MultiGet(ctx context.Context, request *MultiGetRequest) (*EsMultiGetResponse, error) {
354387
log := c.logger.Named("MultiGet")
355388

go/v1beta1/storage/esutil/client_test.go

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"io"
3434
"io/ioutil"
3535
"net/http"
36+
"net/url"
3637
"strconv"
3738
"strings"
3839
)
@@ -605,6 +606,97 @@ var _ = Describe("elasticsearch client", func() {
605606
})
606607
})
607608

609+
Context("Get", func() {
610+
var (
611+
expectedDocumentId string
612+
expectedIndex string
613+
614+
expectedGetRequest *GetRequest
615+
expectedGetResponse *EsGetResponse
616+
617+
actualGetResponse *EsGetResponse
618+
actualErr error
619+
)
620+
621+
BeforeEach(func() {
622+
expectedDocumentId = fake.LetterN(10)
623+
expectedIndex = fake.LetterN(10)
624+
625+
expectedGetRequest = &GetRequest{
626+
Index: expectedIndex,
627+
DocumentId: expectedDocumentId,
628+
}
629+
630+
expectedOccurrence := createRandomOccurrence()
631+
expectedOccurrenceJson, _ := protojson.Marshal(protov1.MessageV2(expectedOccurrence))
632+
633+
expectedGetResponse = &EsGetResponse{
634+
Id: expectedDocumentId,
635+
Found: true,
636+
Source: expectedOccurrenceJson,
637+
}
638+
639+
transport.PreparedHttpResponses = []*http.Response{
640+
{
641+
StatusCode: http.StatusOK,
642+
Body: structToJsonBody(expectedGetResponse),
643+
},
644+
}
645+
})
646+
647+
JustBeforeEach(func() {
648+
actualGetResponse, actualErr = client.Get(ctx, expectedGetRequest)
649+
})
650+
651+
It("should send the get request to ES", func() {
652+
Expect(transport.ReceivedHttpRequests[0].Method).To(Equal(http.MethodGet))
653+
Expect(transport.ReceivedHttpRequests[0].URL.Path).To(Equal(fmt.Sprintf("/%s/_doc/%s", expectedIndex, expectedDocumentId)))
654+
})
655+
656+
It("should return the response and no error", func() {
657+
Expect(actualErr).ToNot(HaveOccurred())
658+
Expect(actualGetResponse).To(Equal(expectedGetResponse))
659+
})
660+
661+
When("the get operation fails", func() {
662+
BeforeEach(func() {
663+
transport.PreparedHttpResponses = []*http.Response{
664+
{
665+
StatusCode: http.StatusInternalServerError,
666+
},
667+
}
668+
})
669+
670+
It("should return an error", func() {
671+
Expect(actualErr).To(HaveOccurred())
672+
Expect(actualGetResponse).To(BeNil())
673+
})
674+
})
675+
676+
When("the get operation can't find the document", func() {
677+
BeforeEach(func() {
678+
transport.PreparedHttpResponses[0].StatusCode = http.StatusNotFound
679+
})
680+
681+
It("should return the response and no error", func() {
682+
Expect(actualErr).ToNot(HaveOccurred())
683+
Expect(actualGetResponse).To(Equal(expectedGetResponse))
684+
})
685+
})
686+
687+
When("the document id is a url", func() {
688+
BeforeEach(func() {
689+
expectedDocumentId = fake.URL()
690+
expectedGetRequest.DocumentId = expectedDocumentId
691+
})
692+
693+
It("should query escape the document id", func() {
694+
Expect(transport.ReceivedHttpRequests[0].Method).To(Equal(http.MethodGet))
695+
Expect(transport.ReceivedHttpRequests[0].URL.RawPath).To(ContainSubstring(url.QueryEscape(expectedDocumentId)))
696+
})
697+
})
698+
})
699+
608700
Context("MultiGet", func() {
609701
var (
610702
expectedDocumentIds []string
@@ -625,12 +717,13 @@ var _ = Describe("elasticsearch client", func() {
625717
}
626718

627719
expectedMultiGetResponse = &EsMultiGetResponse{
628-
Docs: []*EsMultiGetDocument{},
720+
Docs: []*EsGetResponse{},
629721
}
630722
for _, id := range expectedDocumentIds {
631-
expectedMultiGetResponse.Docs = append(expectedMultiGetResponse.Docs, &EsMultiGetDocument{
632-
ID: id,
633-
Found: fake.Bool(),
723+
expectedMultiGetResponse.Docs = append(expectedMultiGetResponse.Docs, &EsGetResponse{
724+
Id: id,
725+
Found: fake.Bool(),
726+
Source: []byte("null"),
634727
})
635728
}
636729

@@ -662,8 +755,10 @@ var _ = Describe("elasticsearch client", func() {
662755

663756
When("the multiget operation fails", func() {
664757
BeforeEach(func() {
665-
transport.PreparedHttpResponses[0] = &http.Response{
666-
StatusCode: http.StatusInternalServerError,
758+
transport.PreparedHttpResponses = []*http.Response{
759+
{
760+
StatusCode: http.StatusInternalServerError,
761+
},
667762
}
668763
})
669764

go/v1beta1/storage/esutil/esutilfakes/fake_client.go

Lines changed: 81 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/v1beta1/storage/esutil/types.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -249,17 +249,18 @@ type ESMeta struct {
249249
Type string `json:"type,omitempty"`
250250
}
251251

252-
type EsMultiGetRequest struct {
253-
IDs []string `json:"ids"`
252+
type EsGetResponse struct {
253+
Id string `json:"_id"`
254+
Found bool `json:"found"`
255+
Source json.RawMessage `json:"_source"`
254256
}
255257

256-
type EsMultiGetDocument struct {
257-
ID string `json:"_id"`
258-
Found bool `json:"found"`
258+
type EsMultiGetRequest struct {
259+
IDs []string `json:"ids"`
259260
}
260261

261262
type EsMultiGetResponse struct {
262-
Docs []*EsMultiGetDocument `json:"docs"`
263+
Docs []*EsGetResponse `json:"docs"`
263264
}
264265

265266
// response for index creation

0 commit comments

Comments
 (0)