Skip to content

Commit

Permalink
feat: Archivista HTTP client
Browse files Browse the repository at this point in the history
add a pkg with a HTTP client for Archivista using the pkg API

Signed-off-by: Kairo Araujo <[email protected]>
  • Loading branch information
kairoaraujo committed Nov 20, 2024
1 parent 589ea08 commit b9f3d19
Show file tree
Hide file tree
Showing 2 changed files with 501 additions and 0 deletions.
181 changes: 181 additions & 0 deletions pkg/http-client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// Copyright 2024 The Archivista Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package httpclient

import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"

"github.com/in-toto/archivista/pkg/api"
"github.com/in-toto/go-witness/dsse"
)

type ArchivistaClient struct {
BaseURL string
GraphQLURL string
*http.Client
}

func CreateArchivistaClient(httpClient *http.Client, baseURL string) (*ArchivistaClient, error) {
client := ArchivistaClient{
BaseURL: baseURL,
Client: http.DefaultClient,
}
if httpClient != nil {
client.Client = httpClient
}
var err error
client.GraphQLURL, err = url.JoinPath(client.BaseURL, "query")
if err != nil {
return nil, err
}

Check warning on line 49 in pkg/http-client/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/http-client/client.go#L48-L49

Added lines #L48 - L49 were not covered by tests
return &client, nil
}

func (ac *ArchivistaClient) DownloadDSSE(ctx context.Context, gitoid string) (dsse.Envelope, error) {
reader, err := api.DownloadReadCloserWithHTTPClient(ctx, ac.Client, ac.BaseURL, gitoid)
if err != nil {
return dsse.Envelope{}, err
}

Check warning on line 57 in pkg/http-client/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/http-client/client.go#L56-L57

Added lines #L56 - L57 were not covered by tests
env := dsse.Envelope{}
if err := json.NewDecoder(reader).Decode(&env); err != nil {
return dsse.Envelope{}, err
}

Check warning on line 61 in pkg/http-client/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/http-client/client.go#L60-L61

Added lines #L60 - L61 were not covered by tests
return env, nil
}

func (ac *ArchivistaClient) DownloadReadCloser(ctx context.Context, gitoid string) (io.ReadCloser, error) {
return api.DownloadReadCloserWithHTTPClient(ctx, ac.Client, ac.BaseURL, gitoid)
}

func (ac *ArchivistaClient) DownloadWithWriter(ctx context.Context, gitoid string, dst io.Writer) error {
return api.DownloadWithWriterWithHTTPClient(ctx, ac.Client, ac.BaseURL, gitoid, dst)
}

func (ac *ArchivistaClient) Store(ctx context.Context, envelope dsse.Envelope) (api.StoreResponse, error) {

Check failure on line 73 in pkg/http-client/client.go

View workflow job for this annotation

GitHub Actions / lint

SA1019: api.StoreResponse is deprecated: Use UploadResponse instead. It will be removed in version >= v0.6.0 (staticcheck)
return api.Store(ctx, ac.BaseURL, envelope)
}

func (ac *ArchivistaClient) StoreWithReader(ctx context.Context, r io.Reader) (api.StoreResponse, error) {

Check failure on line 77 in pkg/http-client/client.go

View workflow job for this annotation

GitHub Actions / lint

SA1019: api.StoreResponse is deprecated: Use UploadResponse instead. It will be removed in version >= v0.6.0 (staticcheck)
return api.StoreWithReader(ctx, ac.BaseURL, r)
}

type GraphQLRequestBodyInterface struct {
Query string `json:"query"`
Variables interface{} `json:"variables,omitempty"`
}

type GraphQLResponseInterface struct {
Data interface{}
Errors []api.GraphQLError `json:"errors,omitempty"`
}

func (ac *ArchivistaClient) GraphQLRetrieveSubjectResults(
ctx context.Context,
gitoid string,
) (api.RetrieveSubjectResults, error) {
return api.GraphQlQuery[api.RetrieveSubjectResults](
ctx,
ac.BaseURL,
api.RetrieveSubjectsQuery,
api.RetrieveSubjectVars{Gitoid: gitoid},
)
}

func (ac *ArchivistaClient) GraphQLRetrieveSearchResults(
ctx context.Context,
algo string,
digest string,
) (api.SearchResults, error) {
return api.GraphQlQuery[api.SearchResults](
ctx,
ac.BaseURL,
api.SearchQuery,
api.SearchVars{Algorithm: algo, Digest: digest},
)
}

func (ac *ArchivistaClient) GraphQLQueryIface(
ctx context.Context,
query string,
variables interface{},
) (*GraphQLResponseInterface, error) {
reader, err := ac.GraphQLQueryReadCloser(ctx, query, variables)
if err != nil {
return nil, err
}
defer reader.Close()
gqlRes := GraphQLResponseInterface{}
dec := json.NewDecoder(reader)
if err := dec.Decode(&gqlRes); err != nil {
return nil, err
}
if len(gqlRes.Errors) > 0 {
return nil, fmt.Errorf("graph ql query failed: %v", gqlRes.Errors)
}
return &gqlRes, nil

Check warning on line 134 in pkg/http-client/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/http-client/client.go#L120-L134

Added lines #L120 - L134 were not covered by tests
}

func (ac *ArchivistaClient) GraphQLQueryToDst(ctx context.Context, query string, variables interface{}, dst interface{}) error {
reader, err := ac.GraphQLQueryReadCloser(ctx, query, variables)
if err != nil {
return err
}
defer reader.Close()
dec := json.NewDecoder(reader)
if err := dec.Decode(&dst); err != nil {
return err
}
return nil

Check warning on line 147 in pkg/http-client/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/http-client/client.go#L137-L147

Added lines #L137 - L147 were not covered by tests
}

func (ac *ArchivistaClient) GraphQLQueryReadCloser(
ctx context.Context,
query string,
variables interface{},
) (io.ReadCloser, error) {
requestBodyMap := GraphQLRequestBodyInterface{
Query: query,
Variables: variables,
}
requestBodyJSON, err := json.Marshal(requestBodyMap)
if err != nil {
return nil, err
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, ac.GraphQLURL, bytes.NewReader(requestBodyJSON))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
res, err := ac.Do(req)
if err != nil {
return nil, err
}
if res.StatusCode != http.StatusOK {
defer res.Body.Close()
errMsg, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
return nil, errors.New(string(errMsg))

Check warning on line 178 in pkg/http-client/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/http-client/client.go#L154-L178

Added lines #L154 - L178 were not covered by tests
}
return res.Body, nil

Check warning on line 180 in pkg/http-client/client.go

View check run for this annotation

Codecov / codecov/patch

pkg/http-client/client.go#L180

Added line #L180 was not covered by tests
}
Loading

0 comments on commit b9f3d19

Please sign in to comment.