http_client

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 16, 2024 License: MIT Imports: 20 Imported by: 0

README

jamf_api_negotiation.go.

The file jamf_api_negotiation.go handles the content type negotiation and response decoding for different types of JAMF APIs.

Constants and Types:

ContentType: A type alias for a string that represents the content type. JSON and XML: Constants representing the "application/json" and "application/xml" content types, respectively. Functions:

determineAPIType: Determines the type of API (Classic or JamfPro) based on the endpoint string. It logs a warning if it's unable to determine the API type and defaults to "Unknown". DetermineContentType: Determines the content type (JSON or XML) based on the API type and the HTTP method. By default, it returns JSON. UnmarshalResponse: Decodes the response body based on the JAMF API type and the HTTP method. It can handle both JSON and XML responses depending on the API type and method. Now, I'll move on to the next file, http_request.go, to understand its contents and how it relates to the issue you mentioned.

http_request.go

The file http_request.go handles the construction and execution of HTTP requests.

Comments:

constructRequest: This function determines the API type and content type based on the endpoint and method, marshals the request body to the appropriate format (JSON or XML) based on the content type, and sends the HTTP request. doRequest: This function calls constructRequest to send the HTTP request, uses UnmarshalResponse to decode the response into the desired format based on the API type and method, and handles the decision for retries based on the response status code. doRequestWithRetry: This function retries the request if a rate limit error is encountered and implements a backoff strategy to avoid overloading the API server. Functions:

constructRequest: Constructs and sends an HTTP request. It first determines the API type and content type, then marshals the request body based on the content type, and finally constructs and sends the HTTP request. The snippet provided seems to be truncated, and I haven't yet seen the implementations of doRequest and doRequestWithRetry.

Functions (Continued from constructRequest): constructRequest (continued): After constructing the HTTP request, the function adds necessary headers, including the authorization token. If the token is invalid, it attempts to refresh it. It then sends the request and logs any errors.

DoRequest: This function sends an HTTP request and handles retries if necessary.

Starts by logging the initiation of the request if in DebugMode. Checks the HTTP method to decide if it should use retries or send the request directly. Some methods (POST and PUT) are set to send directly without retries. Calls constructRequest to send the actual request. Uses UnmarshalResponse to decode the response based on the API type and HTTP method. If the HTTP method is in the directMethods map or if the response status code indicates success (200-299 range), it returns the response. Otherwise, it seems to indicate that the request might need to be retried, but the logic is truncated. From the provided portion, I see that the DoRequest method returns the response and any error that occurs during the request. This function seems to be the one called in the ssoFailover.go file, which you mentioned earlier.

http_methods.go

The http_methods.go file provides convenient methods for making various HTTP requests (GET, POST, PUT, DELETE) using the Client type. Here's a brief overview:

Methods: Get: Sends a GET request to the specified endpoint and unmarshals the response into the provided out variable. The caller is responsible for closing the response body. Post: Sends a POST request to the specified endpoint with the provided body and unmarshals the response into the out variable. Put: Sends a PUT request to the specified endpoint with the provided body and unmarshals the response into the out variable. Delete: Sends a DELETE request to the specified endpoint and unmarshals the response into the out variable. (The implementation seems to be truncated in the provided snippet.) Each of these methods logs the request details if the client is in DebugMode. They all use the DoRequest method from the http_request.go file to actually send the request and handle the response.

With this understanding, I'll proceed to the next file, http_logging.go, to further understand the client's behavior and functionalities.

http_logging.go

The http_logging.go file is focused on logging functionalities. Here's a breakdown:

Logger Interface:

Logger is an interface that defines methods for different logging levels: Trace, Debug, Info, Warn, Error, and Fatal. Default Logger:

defaultLogger is a struct that implements the Logger interface using Go's standard log package. Each method (e.g., Trace, Debug, Info, etc.) logs messages with corresponding prefixes like "[TRACE]", "[DEBUG]", etc. The Fatal method logs the message and then calls log.Fatalln, which will exit the program. Function:

NewDefaultLogger: This function returns a new instance of the default logger. This file provides a standardized way to handle logging throughout the client's codebase. The use of an interface (Logger) allows for flexibility in terms of using other logging libraries or custom logging mechanisms if needed.

http_helpers.go

The http_helpers.go file contains utility functions to assist with HTTP operations. Here's a summary:

Functions: ParseISO8601Date: Tries to parse a string date in ISO 8601 format using the RFC3339 format. It returns a time.Time object and an error.

EnsureHTTPScheme: Ensures that a given URL string is prefixed with either "http://" or "https://". If neither prefix is present, it defaults to adding "http://".

These helper functions are used throughout the client code to handle specific tasks related to HTTP operations and data manipulation.

http_error_handling.go

The http_error_handling.go file seems to focus on handling API errors and converting them into structured errors when possible. Here's a summary:

Types:

APIError: Represents a structured API error response with fields for status code and an error message. Methods & Functions:

handleAPIError: Handles error responses from the API and tries to convert them into a structured error. If the error response from the API is structured (contains an error message and code), it logs and returns a structured APIError. If the error response isn't structured, it tries to decode the error message directly from the response body. If this also fails, it defaults to using the HTTP status message as the error message.

Error: This method on the APIError type returns a string representation of the error, combining the status code and the error message.

translateStatusCode: Provides human-readable messages for various HTTP status codes. It uses a map to match status codes to their corresponding messages.

Given the focus on error handling in this file, it provides context on how the client processes and presents API errors to the user or caller.

http_client.go

The http_client.go file provides core functionalities and structures related to the HTTP client's behavior. Methods:

NewClient: Creates a new instance of the Client. If no logger is provided, it defaults to the defaultLogger. It applies any additional options provided to it. SetAuthMethod: Sets the authentication method for the client. Supported methods are "bearer" and "oauth". constructAPIEndpoint: Constructs the full URL for a given API endpoint path. ObtainToken: Fetches and sets an authentication token using the provided username and password. The method constructs the authentication URL, sends a POST request with basic authentication, handles potential deprecation warnings, checks the response status, and then decodes the token from the response. If successful, it sets the token and expiry time on the client. Error Handling:

In the ObtainToken method, if the response status code isn't http.StatusOK, it logs a warning and invokes c.handleAPIError(resp) to handle the error.

http_client_auth.go

The http_client_auth.go file focuses on authentication functionalities, particularly around handling OAuth tokens. Here's a summary:

Types:

ClientAuthConfig: Represents the structure to read authentication details from a JSON configuration file. It includes fields for BaseURL, Username, Password, ClientID, and ClientSecret. OAuthResponse: Represents the response structure when obtaining an OAuth access token. Fields include AccessToken, ExpiresIn, TokenType, RefreshToken, and Error. OAuthCredentials: Contains the client ID and client secret required for OAuth authentication. Functions & Methods:

LoadAuthConfig: Reads a JSON configuration file and decodes it into a ClientAuthConfig struct. It retrieves authentication details like BaseURL, Username, and Password for the client. SetOAuthCredentials: Sets the OAuth credentials (Client ID and Client Secret) for the client instance. These credentials are used for obtaining and refreshing OAuth tokens for authentication. ObtainOAuthToken: Fetches an OAuth access token using the provided OAuthCredentials (Client ID and Client Secret). The file provides functionalities for loading authentication configurations, setting OAuth credentials, and obtaining OAuth tokens, which are crucial for interacting with protected endpoints.

Documentation

Overview

http_client.go

The `http_client` package provides a configurable HTTP client tailored for interacting with specific APIs.

It supports different authentication methods, including "bearer" and "oauth". The client is designed with a focus on concurrency management, structured error handling, and flexible configuration options. The package offers a default timeout, custom backoff strategies, dynamic rate limiting, and detailed logging capabilities. The main `Client` structure encapsulates all necessary components, like the baseURL, authentication details, and an embedded standard HTTP client.

http_client_auth_token_management.go

http_client_bearer_token_auth.go

The http_client_auth package focuses on authentication mechanisms for an HTTP client.

It provides structures and methods for handling both basic and bearer token based authentication

http_client_oauth.go

The http_client_auth package focuses on authentication mechanisms for an HTTP client.

It provides structures and methods for handling OAuth-based authentication

http_concurrency_management.go Package http_client provides utilities to manage HTTP client interactions, including concurrency control. The Concurrency Manager ensures no more than a certain number of concurrent requests (e.g., 5 for Jamf Pro) are sent at the same time. This is managed using a semaphore

http_error_handling.go This package provides utility functions and structures for handling and categorizing HTTP error responses.

http_helpers.go

http_logging.go

http_methods.go

http_request.go

jamfpro_api_handler.go

------------------------------Summary----------------------------------------

This is a api handler module for the http_client to accommodate specifics of jamf's api(s). It handles the encoding (marshalling) and decoding (unmarshalling) of data. It also sets the correct content headers for the various http methods.

This module integrates with the http_client logger for wrapped error handling for human readable return codes. It also supports the http_client tiered logging functionality for logging support.

The logic of this module is defined as follows: Classic API:

For requests (GET, POST, PUT, DELETE): - Encoding (Marshalling): Use XML format. For responses (GET, POST, PUT): - Decoding (Unmarshalling): Use XML format. For responses (DELETE): - Handle response codes as response body lacks anything useful. Headers - Sets accept headers based on weighting. XML out weighs JSON to ensure XML is returned - Sets content header as application/xml with edge case exceptions based on need.

JamfPro API:

For requests (GET, POST, PUT, DELETE): - Encoding (Marshalling): Use JSON format. For responses (GET, POST, PUT): - Decoding (Unmarshalling): Use JSON format. For responses (DELETE): - Handle response codes as response body lacks anything useful. Headers - Sets accept headers based on weighting. Jamf Pro API doesn't support XML, so MIME type is skipped and returns JSON - Set content header as application/json with edge case exceptions based on need.

sdk_version.go

Index

Constants

View Source
const (
	DefaultLogLevel                  = LogLevelInfo
	DefaultMaxRetryAttempts          = 3
	DefaultEnableDynamicRateLimiting = true
	DefaultMaxConcurrentRequests     = 5
	DefaultTokenBufferPeriod         = 5 * time.Minute
	DefaultTotalRetryDuration        = 5 * time.Minute
	DefaultTimeout                   = 10 * time.Second
)
View Source
const (
	MaxConcurrency     = 10              // Maximum allowed concurrent requests
	MinConcurrency     = 1               // Minimum allowed concurrent requests
	EvaluationInterval = 1 * time.Minute // Time interval for evaluating metrics and adjusting concurrency
)
View Source
const (
	DefaultBaseDomain       = ".jamfcloud.com"                // DefaultBaseDomain: represents the base domain for the jamf instance.
	OAuthTokenEndpoint      = "/api/oauth/token"              // OAuthTokenEndpoint: The endpoint to obtain an OAuth token.
	BearerTokenEndpoint     = "/api/v1/auth/token"            // BearerTokenEndpoint: The endpoint to obtain a bearer token.
	TokenRefreshEndpoint    = "/api/v1/auth/keep-alive"       // TokenRefreshEndpoint: The endpoint to refresh an existing token.
	TokenInvalidateEndpoint = "/api/v1/auth/invalidate-token" // TokenInvalidateEndpoint: The endpoint to invalidate an active token.
)

Endpoint constants represent the URL suffixes used for Jamf API token interactions.

View Source
const (
	SDKVersion    = "1.0.0"
	UserAgentBase = "go-jamfpro-api-sdk"
)

Variables

This section is empty.

Functions

func CheckDeprecationHeader

func CheckDeprecationHeader(resp *http.Response, logger Logger)

CheckDeprecationHeader checks the response headers for the Deprecation header and logs a warning if present.

func EnsureHTTPScheme

func EnsureHTTPScheme(url string) string

EnsureHTTPScheme prefixes a URL with "http://" it defaults to "https://" doesn't already have an "https://".

func ExtractErrorMessageFromHTML

func ExtractErrorMessageFromHTML(htmlContent string) string

ExtractErrorMessageFromHTML attempts to parse an HTML error page and extract a human-readable error message.

func GetUserAgentHeader

func GetUserAgentHeader() string

func IsNonRetryableError

func IsNonRetryableError(resp *http.Response) bool

IsNonRetryableError checks if the provided response indicates a non-retryable error.

func IsRateLimitError

func IsRateLimitError(resp *http.Response) bool

IsRateLimitError checks if the provided response indicates a rate limit error.

func IsTransientError

func IsTransientError(resp *http.Response) bool

IsTransientError checks if an error or HTTP response indicates a transient error.

func LoadUserConfig

func LoadUserConfig(filename string) error

LoadUserConfig allows users to apply their own configuration by providing a JSON file. The custom configuration will override the default settings previously loaded. It reads the file from the provided filename path and unmarshals its content into the configMap. If reading or unmarshalling fails, an error is returned.

func Min

func Min(a, b int) int

Min returns the smaller of the two integers.

func ParseISO8601Date

func ParseISO8601Date(dateStr string) (time.Time, error)

ParseISO8601Date attempts to parse a string date in ISO 8601 format.

func ParseJSONErrorResponse

func ParseJSONErrorResponse(body []byte) (string, error)

ParseJSONErrorResponse parses the JSON error message from the response body.

func TranslateStatusCode

func TranslateStatusCode(statusCode int) string

TranslateStatusCode provides a human-readable message for HTTP status codes.

Types

type APIError

type APIError struct {
	StatusCode int
	Message    string
}

APIError represents a structured API error response.

func (*APIError) Error

func (e *APIError) Error() string

Error returns a string representation of the APIError.

type APIHandler

type APIHandler interface {
	MarshalRequest(body interface{}, method string, endpoint string) ([]byte, error)
	MarshalMultipartRequest(fields map[string]string, files map[string]string) ([]byte, string, error) // New method for multipart
	UnmarshalResponse(resp *http.Response, out interface{}) error
	GetContentTypeHeader(method string) string
	GetAcceptHeader() string
	SetLogger(logger Logger)
}

APIHandler is an interface for encoding, decoding, and determining content types for different API implementations. It encapsulates behavior for encoding and decoding requests and responses.

func GetAPIHandler

func GetAPIHandler(config Config) APIHandler

GetAPIHandler initializes and returns an APIHandler with a configured logger.

type AuthConfig

type AuthConfig struct {
	InstanceName       string `json:"instanceName,omitempty"`
	OverrideBaseDomain string `json:"overrideBaseDomain,omitempty"`
	Username           string `json:"username,omitempty"`
	Password           string `json:"password,omitempty"`
	ClientID           string `json:"clientID,omitempty"`
	ClientSecret       string `json:"clientSecret,omitempty"`
}

ClientAuthConfig represents the structure to read authentication details from a JSON configuration file.

func LoadAuthConfig

func LoadAuthConfig(filename string) (*AuthConfig, error)

LoadAuthConfig reads a JSON configuration file and decodes it into a ClientAuthConfig struct. It is used to retrieve authentication details like BaseURL, Username, and Password for the client.

type BearerTokenAuthCredentials

type BearerTokenAuthCredentials struct {
	Username string
	Password string
}

BearerTokenAuthCredentials represents the username and password for basic authentication.

type Client

type Client struct {
	InstanceName               string                     // Website Instance name without the root domain
	AuthMethod                 string                     // Specifies the authentication method: "bearer" or "oauth"
	Token                      string                     // Authentication Token
	OverrideBaseDomain         string                     // Base domain override used when the default in the api handler isn't suitable
	OAuthCredentials           OAuthCredentials           // ClientID / Client Secret
	BearerTokenAuthCredentials BearerTokenAuthCredentials // Username and Password for Basic Authentication
	Expiry                     time.Time                  // Expiry time set for the auth token

	ConcurrencyMgr *ConcurrencyManager
	PerfMetrics    PerformanceMetrics
	// contains filtered or unexported fields
}

Client represents an HTTP client to interact with a specific API.

func NewClient

func NewClient(config Config) (*Client, error)

NewClient creates a new HTTP client with the provided configuration.

func (*Client) AdjustConcurrencyBasedOnMetrics

func (c *Client) AdjustConcurrencyBasedOnMetrics()

AdjustConcurrencyBasedOnMetrics evaluates the current metrics and adjusts the concurrency limit if required. It checks metrics like average token acquisition time and decides on a new concurrency limit. The method ensures that the new limit respects the minimum and maximum allowed concurrency bounds.

func (*Client) AverageAcquisitionTime

func (c *Client) AverageAcquisitionTime() time.Duration

Returns the average Acquisition Time to get a token from the semaphore

func (*Client) ConstructAPIAuthEndpoint

func (c *Client) ConstructAPIAuthEndpoint(endpointPath string) string

ConstructAPIAuthEndpoint returns the full URL for a Jamf API auth endpoint path.

func (*Client) ConstructAPIResourceEndpoint

func (c *Client) ConstructAPIResourceEndpoint(endpointPath string) string

ConstructAPIResourceEndpoint returns the full URL for a Jamf API resource endpoint path.

func (*Client) Delete

func (c *Client) Delete(endpoint string, out interface{}) (*http.Response, error)

Delete sends a DELETE request to the specified endpoint and unmarshals the response into 'out'. The caller is responsible for closing the response body.

func (*Client) DoMultipartRequest

func (c *Client) DoMultipartRequest(method, endpoint string, fields map[string]string, files map[string]string, out interface{}) (*http.Response, error)

DoMultipartRequest creates and executes a multipart HTTP request. It is used for sending files and form fields in a single request. This method handles the construction of the multipart message body, setting the appropriate headers, and sending the request to the given endpoint.

Parameters: - method: The HTTP method to use (e.g., POST, PUT). - endpoint: The API endpoint to which the request will be sent. - fields: A map of form fields and their values to include in the multipart message. - files: A map of file field names to file paths that will be included as file attachments. - out: A pointer to a variable where the unmarshaled response will be stored.

Returns: - A pointer to the http.Response received from the server. - An error if the request could not be sent or the response could not be processed.

The function first validates the authentication token, then constructs the multipart request body based on the provided fields and files. It then constructs the full URL for the request, sets the required headers (including Authorization and Content-Type), and sends the request.

If debug mode is enabled, the function logs all the request headers before sending the request. After the request is sent, the function checks the response status code. If the response is not within the success range (200-299), it logs an error and returns the response and an error. If the response is successful, it attempts to unmarshal the response body into the 'out' parameter.

Note: The caller should handle closing the response body when successful.

func (*Client) DoRequest

func (c *Client) DoRequest(method, endpoint string, body, out interface{}) (*http.Response, error)

DoRequest constructs and executes a standard HTTP request with support for retry logic. It is intended for operations that can be encoded in a single JSON or XML body such as creating or updating resources. This method includes token validation, concurrency control, performance metrics, dynamic header setting, and structured error handling.

Parameters: - method: The HTTP method to use (e.g., GET, POST, PUT, DELETE, PATCH). - endpoint: The API endpoint to which the request will be sent. - body: The payload to send in the request, which will be marshaled based on the API handler rules. - out: A pointer to a variable where the unmarshaled response will be stored.

Returns: - A pointer to the http.Response received from the server. - An error if the request could not be sent, the response could not be processed, or if retry attempts fail.

The function starts by validating the client's authentication token and managing concurrency using a token system. It then determines the appropriate API handler for marshaling the request body and setting headers. The request is sent to the constructed URL with all necessary headers including authorization, content type, and user agent.

If configured for debug logging, the function logs all request headers before sending. The function then enters a loop to handle retryable HTTP methods, implementing a retry mechanism for transient errors, rate limits, and other retryable conditions based on response status codes.

The function also updates performance metrics to track total request count and cumulative response time. After processing the response, it handles any API errors and unmarshals the response body into the provided 'out' parameter if the response is successful.

Note: The function assumes that retryable HTTP methods have been properly defined in the retryableHTTPMethods map. It is the caller's responsibility to close the response body when the request is successful to avoid resource leaks.

func (*Client) EvaluateMetricsAndAdjustConcurrency

func (c *Client) EvaluateMetricsAndAdjustConcurrency()

EvaluateMetricsAndAdjustConcurrency evaluates the performance metrics and makes necessary adjustments to the concurrency limit. The method assesses the average response time and adjusts the concurrency based on how it compares to the historical average acquisition time. If the average response time has significantly increased compared to the historical average, the concurrency limit is decreased, and vice versa. The method ensures that the concurrency limit remains within the bounds defined by the system's best practices.

func (*Client) Get

func (c *Client) Get(endpoint string, out interface{}) (*http.Response, error)

Get sends a GET request to the specified endpoint and unmarshals the response into 'out'. The caller is responsible for closing the response body.

func (*Client) GetBaseDomain

func (c *Client) GetBaseDomain() string

GetBaseDomain returns the appropriate base domain for URL construction. It uses OverrideBaseDomain if set, otherwise falls back to DefaultBaseDomain.

func (*Client) GetBearerAuthCredentials

func (c *Client) GetBearerAuthCredentials() BearerTokenAuthCredentials

GetBearerAuthCredentials retrieves the current bearer auth credentials (Username and Password) set for the client instance. Used for test cases.

func (*Client) GetOAuthCredentials

func (c *Client) GetOAuthCredentials() OAuthCredentials

GetOAuthCredentials retrieves the current OAuth credentials (Client ID and Client Secret) set for the client instance. Used for test cases.

func (*Client) GetPerformanceMetrics

func (c *Client) GetPerformanceMetrics() *PerformanceMetrics

Returns performance metrics from the http client

func (*Client) HandleAPIError

func (c *Client) HandleAPIError(resp *http.Response) error

HandleAPIError handles error responses from the API, converting them into a structured error if possible.

func (*Client) HistoricalAverageAcquisitionTime

func (c *Client) HistoricalAverageAcquisitionTime() time.Duration

func (*Client) InvalidateOAuthToken

func (c *Client) InvalidateOAuthToken() error

InvalidateOAuthToken invalidates the current OAuth access token. After invalidation, the token cannot be used for further API requests.

func (*Client) ObtainOAuthToken

func (c *Client) ObtainOAuthToken(credentials AuthConfig) error

ObtainOAuthToken fetches an OAuth access token using the provided OAuthCredentials (Client ID and Client Secret). It updates the client's Token and Expiry fields with the obtained values.

func (*Client) ObtainToken

func (c *Client) ObtainToken() error

ObtainToken fetches and sets an authentication token using the stored basic authentication credentials.

func (*Client) Patch

func (c *Client) Patch(endpoint string, body, out interface{}) (*http.Response, error)

Patch sends a PATCH request to the specified endpoint with the provided body and unmarshals the response into 'out'. The caller is responsible for closing the response body.

func (*Client) Post

func (c *Client) Post(endpoint string, body, out interface{}) (*http.Response, error)

Post sends a POST request to the specified endpoint with the provided body and unmarshals the response into 'out'. The caller is responsible for closing the response body.

func (*Client) Put

func (c *Client) Put(endpoint string, body, out interface{}) (*http.Response, error)

Put sends a PUT request to the specified endpoint with the provided body and unmarshals the response into 'out'. The caller is responsible for closing the response body.

func (*Client) RefreshToken

func (c *Client) RefreshToken() error

RefreshToken refreshes the current authentication token.

func (*Client) SetAuthenticationCredentials

func (c *Client) SetAuthenticationCredentials(creds map[string]string)

SetAuthenticationCredentials interprets and sets the credentials for the Client.

func (*Client) SetBearerTokenAuthCredentials

func (c *Client) SetBearerTokenAuthCredentials(credentials BearerTokenAuthCredentials)

SetBearerTokenAuthCredentials sets the BearerTokenAuthCredentials (Username and Password) for the client instance. These credentials are used for obtaining and refreshing bearer tokens for authentication.

func (*Client) SetOAuthCredentials

func (c *Client) SetOAuthCredentials(credentials OAuthCredentials)

SetOAuthCredentials sets the OAuth credentials (Client ID and Client Secret) for the client instance. These credentials are used for obtaining and refreshing OAuth tokens for authentication.

func (*Client) StartConcurrencyAdjustment

func (c *Client) StartConcurrencyAdjustment()

StartConcurrencyAdjustment launches a periodic checker that evaluates current metrics and adjusts concurrency limits if needed. It uses a ticker to periodically trigger the adjustment logic.

func (*Client) StartMetricEvaluation

func (c *Client) StartMetricEvaluation()

StartMetricEvaluation continuously monitors the client's interactions with the API and adjusts the concurrency limits dynamically. The function evaluates metrics at regular intervals to detect burst activity patterns. If a burst activity is detected (e.g., many requests in a short period), the evaluation interval is reduced for more frequent checks. Otherwise, it reverts to a default interval for regular checks. After each evaluation, the function calls EvaluateMetricsAndAdjustConcurrency to potentially adjust the concurrency based on observed metrics.

The evaluation process works as follows: 1. Sleep for the defined evaluation interval. 2. Check if there's a burst in activity using the isBurstActivity method. 3. If a burst is detected, the evaluation interval is shortened to more frequently monitor and adjust the concurrency. 4. If no burst is detected, it maintains the default evaluation interval. 5. It then evaluates the metrics and adjusts the concurrency accordingly.

func (*Client) ValidAuthTokenCheck

func (c *Client) ValidAuthTokenCheck() (bool, error)

ValidAuthTokenCheck checks if the current token is valid and not close to expiry. If the token is invalid, it tries to refresh it. It returns a boolean indicating the validity of the token and an error if there's a failure.

type ConcurrencyManager

type ConcurrencyManager struct {
	AcquisitionTimes []time.Duration
	// contains filtered or unexported fields
}

ConcurrencyManager controls the number of concurrent HTTP requests.

func NewConcurrencyManager

func NewConcurrencyManager(limit int, logger Logger, debugMode bool) *ConcurrencyManager

NewConcurrencyManager initializes a new ConcurrencyManager with the given concurrency limit, logger, and debug mode. The ConcurrencyManager ensures no more than a certain number of concurrent requests are made. It uses a semaphore to control concurrency.

func (*ConcurrencyManager) Acquire

func (c *ConcurrencyManager) Acquire(ctx context.Context) (uuid.UUID, error)

Acquire attempts to get a token to allow an HTTP request to proceed. It blocks until a token is available or the context expires. Returns a unique request ID upon successful acquisition.

func (*ConcurrencyManager) AdjustConcurrencyLimit

func (c *ConcurrencyManager) AdjustConcurrencyLimit(newLimit int)

AdjustConcurrencyLimit dynamically modifies the maximum concurrency limit based on the newLimit provided. This function helps in adjusting the concurrency limit in real-time based on observed system performance and other metrics. It transfers the tokens from the old semaphore to the new one, ensuring that there's no loss of tokens during the transition.

func (*ConcurrencyManager) AverageAcquisitionTime

func (c *ConcurrencyManager) AverageAcquisitionTime() time.Duration

AverageAcquisitionTime computes the average time taken to acquire a token from the semaphore. It helps in understanding the contention for tokens and can be used to adjust concurrency limits.

func (*ConcurrencyManager) HistoricalAverageAcquisitionTime

func (c *ConcurrencyManager) HistoricalAverageAcquisitionTime() time.Duration

HistoricalAverageAcquisitionTime computes the average time taken to acquire a token from the semaphore over a historical period (e.g., the last 5 minutes). It helps in understanding the historical contention for tokens and can be used to adjust concurrency limits.

func (*ConcurrencyManager) Release

func (c *ConcurrencyManager) Release(requestID uuid.UUID)

Release returns a token back to the pool, allowing other requests to proceed. It uses the provided requestID for logging and debugging purposes.

type Config

type Config struct {
	// Required
	InstanceName string
	Auth         AuthConfig // User can either supply these values manually or pass from LoadAuthConfig/Env vars

	// Optional
	LogLevel                  LogLevel // Field for defining tiered logging level.
	MaxRetryAttempts          int      // Config item defines the max number of retry request attempts for retryable HTTP methods.
	EnableDynamicRateLimiting bool
	Logger                    Logger // Field for the packages initailzed logger
	MaxConcurrentRequests     int    // Field for defining the maximum number of concurrent requests allowed in the semaphore
	TokenRefreshBufferPeriod  time.Duration
	TotalRetryDuration        time.Duration
	CustomTimeout             time.Duration
}

Config holds configuration options for the HTTP Client.

type ConfigMap

type ConfigMap map[string]EndpointConfig

ConfigMap is a map that associates endpoint URL patterns with their corresponding configurations. The map's keys are strings that identify the endpoint, and the values are EndpointConfig structs that hold the configuration for that endpoint.

type EndpointConfig

type EndpointConfig struct {
	Accept      string  `json:"accept"`       // Accept specifies the MIME type the endpoint can handle in responses.
	ContentType *string `json:"content_type"` // ContentType, if not nil, specifies the MIME type to set for requests sent to the endpoint. A pointer is used to distinguish between a missing field and an empty string.
}

EndpointConfig is a struct that holds configuration details for a specific API endpoint. It includes what type of content it can accept and what content type it should send.

type LogLevel

type LogLevel int
const (
	LogLevelNone LogLevel = iota
	LogLevelWarning
	LogLevelInfo
	LogLevelDebug
)

type Logger

type Logger interface {
	SetLevel(level LogLevel)
	Trace(msg string, keysAndValues ...interface{}) // For very detailed logs
	Debug(msg string, keysAndValues ...interface{}) // For development and troubleshooting
	Info(msg string, keysAndValues ...interface{})  // Informational messages
	Warn(msg string, keysAndValues ...interface{})  // For potentially problematic situations
	Error(msg string, keysAndValues ...interface{}) // For errors that might still allow the app to continue running
	Fatal(msg string, keysAndValues ...interface{}) // For errors that might prevent the app from continuing
}

Logger is an interface for logging within the SDK.

func NewDefaultLogger

func NewDefaultLogger() Logger

NewDefaultLogger now initializes a defaultLogger with a default log level.

type OAuthCredentials

type OAuthCredentials struct {
	ClientID     string
	ClientSecret string
}

OAuthCredentials contains the client ID and client secret required for OAuth authentication.

type OAuthResponse

type OAuthResponse struct {
	AccessToken  string `json:"access_token"`
	ExpiresIn    int64  `json:"expires_in"`
	TokenType    string `json:"token_type"`
	RefreshToken string `json:"refresh_token,omitempty"`
	Error        string `json:"error,omitempty"`
}

OAuthResponse represents the response structure when obtaining an OAuth access token.

type PerformanceMetrics

type PerformanceMetrics struct {
	TotalRequests        int64
	TotalRetries         int64
	TotalRateLimitErrors int64
	TotalResponseTime    time.Duration
	TokenWaitTime        time.Duration
	// contains filtered or unexported fields
}

ClientPerformanceMetrics captures various metrics related to the client's interactions with the API, providing insights into its performance and behavior.

type StructuredError

type StructuredError struct {
	Error struct {
		Code    string `json:"code"`
		Message string `json:"message"`
	} `json:"error"`
}

StructuredError represents a structured error response from the API.

type TokenResponse

type TokenResponse struct {
	Token   string    `json:"token"`
	Expires time.Time `json:"expires"`
}

TokenResponse represents the structure of a token response from the API.

type UnifiedJamfAPIHandler

type UnifiedJamfAPIHandler struct {
	// contains filtered or unexported fields
}

UnifiedAPIHandler is a struct that implements the APIHandler interface. It holds a Logger instance to facilitate logging across various API handling methods. This handler is responsible for encoding and decoding request and response data, determining content types, and other API interactions as defined by the APIHandler interface.

func (*UnifiedJamfAPIHandler) GetAcceptHeader

func (u *UnifiedJamfAPIHandler) GetAcceptHeader() string

GetAcceptHeader constructs and returns a weighted Accept header string for HTTP requests. The Accept header indicates the MIME types that the client can process and prioritizes them based on the quality factor (q) parameter. Higher q-values signal greater preference. This function specifies a range of MIME types with their respective weights, ensuring that the server is informed of the client's versatile content handling capabilities while indicating a preference for XML. The specified MIME types cover common content formats like images, JSON, XML, HTML, plain text, and certificates, with a fallback option for all other types.

func (*UnifiedJamfAPIHandler) GetContentTypeHeader

func (u *UnifiedJamfAPIHandler) GetContentTypeHeader(endpoint string) string

GetContentTypeHeader determines the appropriate Content-Type header for a given API endpoint. It attempts to find a content type that matches the endpoint prefix in the global configMap. If a match is found and the content type is defined (not nil), it returns the specified content type. If the content type is nil or no match is found in configMap, it falls back to default behaviors: - For url endpoints starting with "/JSSResource", it defaults to "application/xml" for the Classic API. - For url endpoints starting with "/api", it defaults to "application/json" for the JamfPro API. If the endpoint does not match any of the predefined patterns, "application/json" is used as a fallback. This method logs the decision process at various stages for debugging purposes.

func (*UnifiedJamfAPIHandler) MarshalMultipartRequest

func (u *UnifiedJamfAPIHandler) MarshalMultipartRequest(fields map[string]string, files map[string]string) ([]byte, string, error)

MarshalMultipartFormData takes a map with form fields and file paths and returns the encoded body and content type.

func (*UnifiedJamfAPIHandler) MarshalRequest

func (u *UnifiedJamfAPIHandler) MarshalRequest(body interface{}, method string, endpoint string) ([]byte, error)

MarshalRequest encodes the request body according to the endpoint for the API.

func (*UnifiedJamfAPIHandler) SetLogger

func (u *UnifiedJamfAPIHandler) SetLogger(logger Logger)

SetLogger assigns a Logger instance to the UnifiedAPIHandler. This allows for logging throughout the handler's operations, enabling consistent logging that follows the configuration of the provided Logger.

func (*UnifiedJamfAPIHandler) UnmarshalResponse

func (u *UnifiedJamfAPIHandler) UnmarshalResponse(resp *http.Response, out interface{}) error

UnmarshalResponse decodes the response body from XML or JSON format depending on the Content-Type header.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL