Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 60 additions & 13 deletions nexus3/pkg/client/client.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package client

import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"time"
Expand Down Expand Up @@ -91,8 +91,12 @@ func (c *Client) ContentTypeTextPlain() {
}

func (c *Client) NewRequest(method string, endpoint string, body io.Reader) (req *http.Request, err error) {
return c.NewRequestContext(context.Background(), method, endpoint, body)
}

func (c *Client) NewRequestContext(ctx context.Context, method string, endpoint string, body io.Reader) (req *http.Request, err error) {
url := fmt.Sprintf("%s/%s", c.config.URL, endpoint)
req, err = http.NewRequest(method, url, body)
req, err = http.NewRequestWithContext(ctx, method, url, body)
if err != nil {
return req, err
}
Expand All @@ -104,34 +108,77 @@ func (c *Client) NewRequest(method string, endpoint string, body io.Reader) (req
return req, nil
}

func (c *Client) execute(method string, endpoint string, payload io.Reader) ([]byte, *http.Response, error) {
req, err := c.NewRequest(method, endpoint, payload)
if err != nil {
return nil, nil, err
}

func (c *Client) execute(req *http.Request) ([]byte, *http.Response, error) {
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, nil, err
}
defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
return body, resp, err
}

func (c *Client) Get(endpoint string, payload io.Reader) ([]byte, *http.Response, error) {
return c.execute(http.MethodGet, endpoint, payload)
if req, err := c.NewRequest(http.MethodGet, endpoint, payload); err != nil {
return nil, nil, err
} else {
return c.execute(req)
}
}

func (c *Client) Post(endpoint string, payload io.Reader) ([]byte, *http.Response, error) {
return c.execute(http.MethodPost, endpoint, payload)
if req, err := c.NewRequest(http.MethodPost, endpoint, payload); err != nil {
return nil, nil, err
} else {
return c.execute(req)
}
}

func (c *Client) Put(endpoint string, payload io.Reader) ([]byte, *http.Response, error) {
return c.execute(http.MethodPut, endpoint, payload)
if req, err := c.NewRequest(http.MethodPut, endpoint, payload); err != nil {
return nil, nil, err
} else {
return c.execute(req)
}
}

func (c *Client) Delete(endpoint string) ([]byte, *http.Response, error) {
return c.execute(http.MethodDelete, endpoint, nil)
if req, err := c.NewRequest(http.MethodDelete, endpoint, nil); err != nil {
return nil, nil, err
} else {
return c.execute(req)
}
}

func (c *Client) GetContext(ctx context.Context, endpoint string, payload io.Reader) ([]byte, *http.Response, error) {
if req, err := c.NewRequestContext(ctx, http.MethodGet, endpoint, payload); err != nil {
return nil, nil, err
} else {
return c.execute(req)
}
}

func (c *Client) PostContext(ctx context.Context, endpoint string, payload io.Reader) ([]byte, *http.Response, error) {
if req, err := c.NewRequestContext(ctx, http.MethodPost, endpoint, payload); err != nil {
return nil, nil, err
} else {
return c.execute(req)
}
}

func (c *Client) PutContext(ctx context.Context, endpoint string, payload io.Reader) ([]byte, *http.Response, error) {
if req, err := c.NewRequestContext(ctx, http.MethodPut, endpoint, payload); err != nil {
return nil, nil, err
} else {
return c.execute(req)
}
}

func (c *Client) DeleteContext(ctx context.Context, endpoint string) ([]byte, *http.Response, error) {
if req, err := c.NewRequestContext(ctx, http.MethodDelete, endpoint, nil); err != nil {
return nil, nil, err
} else {
return c.execute(req)
}
}
7 changes: 6 additions & 1 deletion nexus3/pkg/repository/common/common.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package common

import (
"context"
"encoding/json"
"fmt"
"net/http"
Expand All @@ -14,7 +15,11 @@ const (
)

func DeleteRepository(client *client.Client, id string) error {
body, resp, err := client.Delete(fmt.Sprintf("%s/%s", RepositoryAPIEndpoint, id))
return DeleteRepositoryContext(context.Background(), client, id)
}

func DeleteRepositoryContext(ctx context.Context, client *client.Client, id string) error {
body, resp, err := client.DeleteContext(ctx, fmt.Sprintf("%s/%s", RepositoryAPIEndpoint, id))
if err != nil {
return err
}
Expand Down
26 changes: 22 additions & 4 deletions nexus3/pkg/repository/common/service.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package common

import (
"context"
"encoding/json"
"fmt"
"net/http"
Expand All @@ -22,11 +23,16 @@ func NewRepositoryService[R any](ep string, c *client.Client) *RepositoryService
}

func (s *RepositoryService[R]) Create(repo R) error {
return s.CreateContext(context.Background(), repo)

@dungdm93 dungdm93 May 12, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anmoel Because it's shorter than duplicate code with CreateContext like this:

func (s *RepositoryService[R]) Create(ctx context.Context, repo R) error {
	data, err := tools.JsonMarshalInterfaceToIOReader(repo)
	if err != nil {
		return err
	}
	body, resp, err := s.client.Post(s.endpoint, data)
	if err != nil {
		return err
	}
	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
		return fmt.Errorf("could not create repository %v: HTTP: %d, %s", repo, resp.StatusCode, string(body))
	}
	return nil
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i mean, why you want to manage the context? in our old code, we don't manage the context. we used the http client functions without context.

@dungdm93 dungdm93 Jun 13, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To support request cancellation, timeout and so on.

An example use-case is terraform-provider-nexus: All Resource.Create|Delete|Exists|Read|Update methods are deprecated in favor of XContext counterparts

// Deprecated: Use CreateContext or CreateWithoutTimeout instead. This
// implementation does not support request cancellation initiated by
// Terraform, such as a system or practitioner sending SIGINT (Ctrl-c).
// This implementation also does not support warning diagnostics.
Create [CreateFunc](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema@v2.36.1#CreateFunc)

}

func (s *RepositoryService[R]) CreateContext(ctx context.Context, repo R) error {

data, err := tools.JsonMarshalInterfaceToIOReader(repo)
if err != nil {
return err
}
body, resp, err := s.client.Post(s.endpoint, data)
body, resp, err := s.client.PostContext(ctx, s.endpoint, data)
if err != nil {
return err
}
Expand All @@ -37,8 +43,12 @@ func (s *RepositoryService[R]) Create(repo R) error {
}

func (s *RepositoryService[R]) Get(id string) (*R, error) {
return s.GetContext(context.Background(), id)
}

func (s *RepositoryService[R]) GetContext(ctx context.Context, id string) (*R, error) {
repo := new(R)
body, resp, err := s.client.Get(fmt.Sprintf("%s/%s", s.endpoint, id), nil)
body, resp, err := s.client.GetContext(ctx, fmt.Sprintf("%s/%s", s.endpoint, id), nil)
if err != nil {
return nil, err
}
Expand All @@ -52,11 +62,15 @@ func (s *RepositoryService[R]) Get(id string) (*R, error) {
}

func (s *RepositoryService[R]) Update(id string, repo R) error {
return s.UpdateContext(context.Background(), id, repo)
}

func (s *RepositoryService[R]) UpdateContext(ctx context.Context, id string, repo R) error {
data, err := tools.JsonMarshalInterfaceToIOReader(repo)
if err != nil {
return err
}
body, resp, err := s.client.Put(fmt.Sprintf("%s/%s", s.endpoint, id), data)
body, resp, err := s.client.PutContext(ctx, fmt.Sprintf("%s/%s", s.endpoint, id), data)
if err != nil {
return err
}
Expand All @@ -67,5 +81,9 @@ func (s *RepositoryService[R]) Update(id string, repo R) error {
}

func (s *RepositoryService[R]) Delete(id string) error {
return DeleteRepository(s.client, id)
return s.DeleteContext(context.Background(), id)
}

func (s *RepositoryService[R]) DeleteContext(ctx context.Context, id string) error {
return DeleteRepositoryContext(ctx, s.client, id)
}