Skip to content

Commit f64f9f5

Browse files
committed
Refactor HTTP client and API handler***
***Adjust concurrency management based on metrics
1 parent 25ac658 commit f64f9f5

File tree

6 files changed

+26
-77
lines changed

6 files changed

+26
-77
lines changed

internal/apihandlers/jamfpro/jamfpro_api_handler.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ import (
4949

5050
_ "embed"
5151

52-
"github.com/deploymenttheory/go-api-http-client/internal/httpclient"
5352
"github.com/deploymenttheory/go-api-http-client/internal/logger"
5453
"go.uber.org/zap"
5554
)
@@ -258,7 +257,7 @@ func (u *JamfAPIHandler) UnmarshalResponse(resp *http.Response, out interface{},
258257
if strings.Contains(contentType, "text/html") {
259258
errMsg := ExtractErrorMessageFromHTML(string(bodyBytes))
260259
log.Warn("Received HTML content", zap.String("error_message", errMsg), zap.Int("status_code", resp.StatusCode))
261-
return &httpclient.APIError{
260+
return &APIError{
262261
StatusCode: resp.StatusCode,
263262
Message: errMsg,
264263
}

internal/httpclient/http_error_handling.go renamed to internal/errors/http_error_handling.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// http_error_handling.go
22
// This package provides utility functions and structures for handling and categorizing HTTP error responses.
3-
package httpclient
3+
package errors
44

55
import (
66
"encoding/json"
@@ -25,7 +25,7 @@ type StructuredError struct {
2525
}
2626

2727
// HandleAPIError handles error responses from the API, converting them into a structured error if possible.
28-
func (c *Client) HandleAPIError(resp *http.Response) error {
28+
func HandleAPIError(logger Logger, resp *http.Response) error {
2929
var structuredErr StructuredError
3030
err := json.NewDecoder(resp.Body).Decode(&structuredErr)
3131
if err == nil && structuredErr.Error.Message != "" {

internal/httpclient/http_client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ func BuildClient(config Config) (*Client, error) {
157157
}
158158

159159
// Authenticate and check token validity.
160-
_, err = client.ValidAuthTokenCheck()
160+
_, err = client.ValidAuthTokenCheck(client.Logger)
161161
if err != nil {
162162
return nil, log.Error("Failed to validate or obtain auth token", zap.Error(err))
163163
}

internal/httpclient/http_client_auth_token_management.go

Lines changed: 14 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
package httpclient
33

44
import (
5-
"fmt"
65
"time"
76

7+
"github.com/deploymenttheory/go-api-http-client/internal/logger"
88
"go.uber.org/zap"
99
)
1010

@@ -14,72 +14,23 @@ type TokenResponse struct {
1414
Expires time.Time `json:"expires"`
1515
}
1616

17-
/*
1817
// ValidAuthTokenCheck checks if the current token is valid and not close to expiry.
1918
// If the token is invalid, it tries to refresh it.
2019
// It returns a boolean indicating the validity of the token and an error if there's a failure.
21-
func (c *Client) ValidAuthTokenCheck() (bool, error) {
22-
20+
func (c *Client) ValidAuthTokenCheck(log logger.Logger) (bool, error) {
2321
if c.Token == "" {
22+
c.Logger.Debug("No token found, attempting to obtain a new one")
2423
if c.AuthMethod == "bearer" {
2524
err := c.ObtainToken()
2625
if err != nil {
27-
return false, fmt.Errorf("failed to obtain bearer token: %w", err)
26+
return false, c.Logger.Error("Failed to obtain bearer token", zap.Error(err))
2827
}
2928
} else if c.AuthMethod == "oauth" {
30-
err := c.ObtainOAuthToken(c.config.Auth)
31-
if err != nil {
32-
return false, fmt.Errorf("failed to obtain OAuth token: %w", err)
33-
}
34-
} else {
35-
return false, fmt.Errorf("no valid credentials provided. Unable to obtain a token")
36-
}
37-
}
38-
39-
// If token exists and is close to expiry or already expired
40-
if time.Until(c.Expiry) < c.config.TokenRefreshBufferPeriod {
41-
var err error
42-
if c.BearerTokenAuthCredentials.Username != "" && c.BearerTokenAuthCredentials.Password != "" {
43-
err = c.RefreshToken()
44-
} else if c.OAuthCredentials.ClientID != "" && c.OAuthCredentials.ClientSecret != "" {
45-
err = c.ObtainOAuthToken(c.config.Auth)
46-
} else {
47-
return false, fmt.Errorf("unknown auth method: %s", c.AuthMethod)
48-
}
49-
50-
if err != nil {
51-
return false, fmt.Errorf("failed to refresh token: %w", err)
52-
}
53-
}
54-
55-
if time.Until(c.Expiry) < c.config.TokenRefreshBufferPeriod {
56-
return false, fmt.Errorf("token lifetime setting less than buffer. Buffer setting: %v, Time (seconds) until Exp: %v", c.config.TokenRefreshBufferPeriod, time.Until(c.Expiry))
57-
}
58-
return true, nil
59-
}
60-
*/
61-
62-
// ValidAuthTokenCheck checks if the current token is valid and not close to expiry.
63-
// If the token is invalid, it tries to refresh it.
64-
// It returns a boolean indicating the validity of the token and an error if there's a failure.
65-
func (c *Client) ValidAuthTokenCheck() (bool, error) {
66-
if c.Token == "" {
67-
if c.AuthMethod == "bearer" {
68-
err := c.ObtainToken()
69-
if err != nil {
70-
c.logger.Error("Failed to obtain bearer token", zap.Error(err))
71-
return false, fmt.Errorf("failed to obtain bearer token: %w", err)
72-
}
73-
} else if c.AuthMethod == "oauth" {
74-
err := c.ObtainOAuthToken(c.config.Auth)
75-
if err != nil {
76-
c.logger.Error("Failed to obtain OAuth token", zap.Error(err))
77-
return false, fmt.Errorf("failed to obtain OAuth token: %w", err)
29+
if err := c.ObtainOAuthToken(c.config.Auth); err != nil {
30+
return false, c.Logger.Error("Failed to obtain OAuth token", zap.Error(err))
7831
}
7932
} else {
80-
err := fmt.Errorf("no valid credentials provided. Unable to obtain a token")
81-
c.logger.Error("No valid credentials provided", zap.Error(err))
82-
return false, err
33+
return false, c.Logger.Error("No valid credentials provided. Unable to obtain a token", zap.String("authMethod", c.AuthMethod))
8334
}
8435
}
8536

@@ -90,21 +41,20 @@ func (c *Client) ValidAuthTokenCheck() (bool, error) {
9041
} else if c.OAuthCredentials.ClientID != "" && c.OAuthCredentials.ClientSecret != "" {
9142
err = c.ObtainOAuthToken(c.config.Auth)
9243
} else {
93-
err = fmt.Errorf("unknown auth method: %s", c.AuthMethod)
94-
c.logger.Error("Unknown auth method", zap.String("auth_method", c.AuthMethod), zap.Error(err))
95-
return false, err
44+
return false, c.Logger.Error("Unknown auth method", zap.String("authMethod", c.AuthMethod))
9645
}
9746

9847
if err != nil {
99-
c.logger.Error("Failed to refresh token", zap.Error(err))
100-
return false, fmt.Errorf("failed to refresh token: %w", err)
48+
return false, c.Logger.Error("Failed to refresh token", zap.Error(err))
10149
}
10250
}
10351

10452
if time.Until(c.Expiry) < c.config.TokenRefreshBufferPeriod {
105-
err := fmt.Errorf("token lifetime setting less than buffer. Buffer setting: %v, Time (seconds) until Exp: %v", c.config.TokenRefreshBufferPeriod, time.Until(c.Expiry))
106-
c.logger.Error("Token lifetime less than buffer", zap.Duration("buffer_period", c.config.TokenRefreshBufferPeriod), zap.Duration("time_until_expiry", time.Until(c.Expiry)), zap.Error(err))
107-
return false, err
53+
return false, c.Logger.Error(
54+
"Token lifetime setting less than buffer",
55+
zap.Duration("buffer_period", c.config.TokenRefreshBufferPeriod),
56+
zap.Duration("time_until_expiry", time.Until(c.Expiry)),
57+
)
10858
}
10959

11060
return true, nil

internal/httpclient/http_concurrency_management.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"sync"
99
"time"
1010

11+
"github.com/deploymenttheory/go-api-http-client/internal/logger"
1112
"github.com/google/uuid"
1213
"go.uber.org/zap"
1314
)
@@ -23,7 +24,7 @@ const (
2324
// ConcurrencyManager controls the number of concurrent HTTP requests.
2425
type ConcurrencyManager struct {
2526
sem chan struct{}
26-
logger Logger
27+
logger logger.Logger
2728
debugMode bool
2829
AcquisitionTimes []time.Duration
2930
lock sync.Mutex
@@ -37,10 +38,7 @@ type requestIDKey struct{}
3738
// NewConcurrencyManager initializes a new ConcurrencyManager with the given concurrency limit, logger, and debug mode.
3839
// The ConcurrencyManager ensures no more than a certain number of concurrent requests are made.
3940
// It uses a semaphore to control concurrency.
40-
func NewConcurrencyManager(limit int, logger Logger, debugMode bool) *ConcurrencyManager {
41-
if logger == nil {
42-
logger = &defaultLogger{} // Assuming this is the default logger implementation
43-
}
41+
func NewConcurrencyManager(limit int, logger logger.Logger, debugMode bool) *ConcurrencyManager {
4442
return &ConcurrencyManager{
4543
sem: make(chan struct{}, limit),
4644
logger: logger,
@@ -209,7 +207,7 @@ func (c *Client) AdjustConcurrencyBasedOnMetrics() {
209207
if newLimit != currentLimit {
210208
c.ConcurrencyMgr.AdjustConcurrencyLimit(newLimit)
211209

212-
c.logger.Debug("Adjusted concurrency",
210+
c.Logger.Debug("Adjusted concurrency",
213211
zap.Int("OldLimit", currentLimit),
214212
zap.Int("NewLimit", newLimit),
215213
zap.String("Reason", "Based on average acquisition time"),

internal/httpclient/http_headers.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package httpclient
22

33
import (
44
"net/http"
5+
6+
"github.com/deploymenttheory/go-api-http-client/internal/logger"
57
)
68

79
// LogHTTPHeaders logs the HTTP headers of an HTTP request or response, with an option to hide sensitive information like the token in secure mode.
8-
func LogHTTPHeaders(logger Logger, headers http.Header, secureMode bool) {
10+
func LogHTTPHeaders(log logger.Logger, headers http.Header, secureMode bool) {
911
var keysAndValues []interface{}
1012
if secureMode {
1113
for key, values := range headers {
@@ -23,6 +25,6 @@ func LogHTTPHeaders(logger Logger, headers http.Header, secureMode bool) {
2325

2426
// Log the headers using the logger from the httpclient package
2527
if len(keysAndValues) > 0 {
26-
logger.Debug("HTTP Headers", keysAndValues...)
28+
log.Debug("HTTP Headers", keysAndValues...)
2729
}
2830
}

0 commit comments

Comments
 (0)