Implement CheckCle Microservice Operation
A Go-based microservice for service operations including ICMP ping, DNS resolution, and TCP connectivity
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
|
||||
package operations
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"service-operation/types"
|
||||
)
|
||||
|
||||
type HTTPOperation struct {
|
||||
timeout time.Duration
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
func NewHTTPOperation(timeout time.Duration) *HTTPOperation {
|
||||
return &HTTPOperation{
|
||||
timeout: timeout,
|
||||
client: &http.Client{
|
||||
Timeout: timeout,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HTTPOperation) Execute(url, method string) (*types.OperationResult, error) {
|
||||
result := &types.OperationResult{
|
||||
Type: types.OperationHTTP,
|
||||
StartTime: time.Now(),
|
||||
HTTPMethod: method,
|
||||
}
|
||||
|
||||
// Default to GET if no method specified
|
||||
if method == "" {
|
||||
method = "GET"
|
||||
result.HTTPMethod = "GET"
|
||||
}
|
||||
|
||||
// Ensure URL has protocol
|
||||
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
|
||||
url = "https://" + url
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
|
||||
req, err := http.NewRequest(method, url, nil)
|
||||
if err != nil {
|
||||
result.Error = fmt.Sprintf("Failed to create request: %v", err)
|
||||
result.Success = false
|
||||
result.EndTime = time.Now()
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Set a user agent
|
||||
req.Header.Set("User-Agent", "ServiceOperation/1.0")
|
||||
|
||||
resp, err := h.client.Do(req)
|
||||
|
||||
result.ResponseTime = time.Since(start)
|
||||
result.EndTime = time.Now()
|
||||
|
||||
if err != nil {
|
||||
// More detailed error messages
|
||||
if strings.Contains(err.Error(), "timeout") {
|
||||
result.Error = fmt.Sprintf("🕐 Request timeout after %.2fs - Server did not respond within the expected time", h.timeout.Seconds())
|
||||
} else if strings.Contains(err.Error(), "connection refused") {
|
||||
result.Error = "🚫 Connection refused - Server is not accepting connections on this port"
|
||||
} else if strings.Contains(err.Error(), "no such host") {
|
||||
result.Error = "🌐 DNS resolution failed - Host not found"
|
||||
} else if strings.Contains(err.Error(), "certificate") {
|
||||
result.Error = "🔒 SSL/TLS certificate error - Certificate verification failed"
|
||||
} else {
|
||||
result.Error = fmt.Sprintf("🔌 Connection error: %v", err)
|
||||
}
|
||||
result.Success = false
|
||||
return result, nil
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
result.HTTPStatusCode = resp.StatusCode
|
||||
result.ContentLength = resp.ContentLength
|
||||
result.Success = resp.StatusCode >= 200 && resp.StatusCode < 400
|
||||
|
||||
// Capture important headers
|
||||
result.HTTPHeaders = make(map[string]string)
|
||||
for key, values := range resp.Header {
|
||||
if len(values) > 0 {
|
||||
switch strings.ToLower(key) {
|
||||
case "content-type", "server", "cache-control", "content-encoding", "x-powered-by":
|
||||
result.HTTPHeaders[key] = values[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read response body for keyword checking and additional details
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err == nil && len(body) > 0 {
|
||||
result.ResponseBody = string(body)
|
||||
// Update content length if not set by server
|
||||
if result.ContentLength <= 0 {
|
||||
result.ContentLength = int64(len(body))
|
||||
}
|
||||
}
|
||||
|
||||
// Create detailed status message with emoji
|
||||
if !result.Success {
|
||||
switch {
|
||||
case resp.StatusCode >= 500:
|
||||
result.Error = fmt.Sprintf("🔥 Server Error (HTTP %d): %s - The server encountered an internal error", resp.StatusCode, resp.Status)
|
||||
case resp.StatusCode >= 400:
|
||||
result.Error = fmt.Sprintf("❌ Client Error (HTTP %d): %s - The request was invalid or unauthorized", resp.StatusCode, resp.Status)
|
||||
case resp.StatusCode >= 300:
|
||||
result.Error = fmt.Sprintf("↩️ Redirect (HTTP %d): %s - Resource has moved", resp.StatusCode, resp.Status)
|
||||
default:
|
||||
result.Error = fmt.Sprintf("⚠️ Unexpected Status (HTTP %d): %s", resp.StatusCode, resp.Status)
|
||||
}
|
||||
} else {
|
||||
// Success message with emoji
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
result.Error = "✅ OK - Request successful"
|
||||
case 201:
|
||||
result.Error = "🆕 Created - Resource created successfully"
|
||||
case 202:
|
||||
result.Error = "⏳ Accepted - Request accepted for processing"
|
||||
case 204:
|
||||
result.Error = "📭 No Content - Request successful, no content returned"
|
||||
default:
|
||||
result.Error = fmt.Sprintf("✅ Success (HTTP %d): %s", resp.StatusCode, resp.Status)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
Reference in New Issue
Block a user