@@ -14,6 +14,112 @@ import (
1414 "go.uber.org/zap"
1515)
1616
17+ // DoRequestV2 constructs and executes an HTTP request, choosing the execution path based on the idempotency of the HTTP method.
18+ func (c * Client ) DoRequestV2 (method , endpoint string , body , out interface {}, log logger.Logger ) (* http.Response , error ) {
19+ if IsIdempotentHTTPMethod (method ) {
20+ return c .executeRequestWithRetries (method , endpoint , body , out , log )
21+ } else if IsNonIdempotentHTTPMethod (method ) {
22+ return c .executeRequest (method , endpoint , body , out , log )
23+ } else {
24+ return nil , log .Error ("HTTP method not supported" , zap .String ("method" , method ))
25+ }
26+ }
27+
28+ // executeRequestWithRetries handles the execution of non-idempotent HTTP requests with appropriate retry logic.
29+ // GET / PUT / DELETE
30+ func (c * Client ) executeRequestWithRetries (method , endpoint string , body , out interface {}, log logger.Logger ) (* http.Response , error ) {
31+ // Include the core logic for handling non-idempotent requests with retries here.
32+ log .Debug ("Executing non-idempotent request with retries" , zap .String ("method" , method ), zap .String ("endpoint" , endpoint ))
33+
34+ // Placeholder for actual implementation
35+ return nil , log .Error ("executeRequestWithRetries function is not implemented yet" )
36+ }
37+
38+ // executeRequest handles the execution of idempotent HTTP requests without retry logic.
39+ // POST / PATCH
40+ func (c * Client ) executeRequest (method , endpoint string , body , out interface {}, log logger.Logger ) (* http.Response , error ) {
41+ // Include the core logic for handling idempotent requests here.
42+ log .Debug ("Executing idempotent request" , zap .String ("method" , method ), zap .String ("endpoint" , endpoint ))
43+
44+ // Auth Token validation check
45+ valid , err := c .ValidAuthTokenCheck (log )
46+ if err != nil || ! valid {
47+ return nil , err
48+ }
49+
50+ // Acquire a token for concurrency management
51+ ctx , err := c .AcquireConcurrencyToken (context .Background (), log )
52+ if err != nil {
53+ return nil , err
54+ }
55+ defer func () {
56+ // Extract the requestID from the context and release the concurrency token
57+ if requestID , ok := ctx .Value (requestIDKey {}).(uuid.UUID ); ok {
58+ c .ConcurrencyMgr .Release (requestID )
59+ }
60+ }()
61+
62+ // Determine which set of encoding and content-type request rules to use
63+ apiHandler := c .APIHandler
64+
65+ // Marshal Request with correct encoding
66+ requestData , err := apiHandler .MarshalRequest (body , method , endpoint , log )
67+ if err != nil {
68+ return nil , err
69+ }
70+
71+ // Construct URL using the ConstructAPIResourceEndpoint function
72+ url := c .APIHandler .ConstructAPIResourceEndpoint (c .InstanceName , endpoint , log )
73+
74+ // Initialize total request counter
75+ c .PerfMetrics .lock .Lock ()
76+ c .PerfMetrics .TotalRequests ++
77+ c .PerfMetrics .lock .Unlock ()
78+
79+ // Perform Request
80+ req , err := http .NewRequest (method , url , bytes .NewBuffer (requestData ))
81+ if err != nil {
82+ return nil , err
83+ }
84+
85+ // Set request headers
86+ headerManager := NewHeaderManager (req , log , c .APIHandler , c .Token )
87+ headerManager .SetRequestHeaders (endpoint )
88+ headerManager .LogHeaders (c )
89+
90+ // Start response time measurement
91+ responseTimeStart := time .Now ()
92+ // For non-retryable HTTP Methods (POST - Create)
93+ req = req .WithContext (ctx )
94+
95+ // Execute the HTTP request
96+ resp , err := c .executeHTTPRequest (req , log , method , endpoint )
97+ if err != nil {
98+ return nil , err
99+ }
100+
101+ // After each request, compute and update response time
102+ responseDuration := time .Since (responseTimeStart )
103+ c .updatePerformanceMetrics (responseDuration )
104+
105+ // Checks for the presence of a deprecation header in the HTTP response and logs if found.
106+ CheckDeprecationHeader (resp , log )
107+
108+ // Handle the response
109+ if err := c .APIHandler .UnmarshalResponse (resp , out , log ); err != nil {
110+ // Error handling, including logging and type assertion for APIError
111+ return resp , err // Error is already logged in UnmarshalResponse
112+ }
113+
114+ // Successful execution and response handling
115+ log .Info ("HTTP request executed successfully" ,
116+ zap .String ("method" , method ),
117+ zap .String ("endpoint" , endpoint ),
118+ zap .Int ("status_code" , resp .StatusCode ))
119+
120+ return resp , nil
121+ }
122+
17123// executeHTTPRequest sends an HTTP request using the client's HTTP client. It logs the request and error details, if any, using structured logging with zap fields.
18124//
19125// Parameters:
0 commit comments