package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "os" "strings" "time" ) func required(name string) string { value := os.Getenv(name); if value == "" { panic("Set " + name) }; return value } func getenv(name, fallback string) string { if value := os.Getenv(name); value != "" { return value }; return fallback } func postJSON(url string, payload any, token string, correlationId string) ([]byte, error) { body, _ := json.Marshal(payload) req, _ := http.NewRequest("POST", url, bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") if token != "" { req.Header.Set("Authorization", "Bearer "+token) } if correlationId != "" { req.Header.Set("X-Correlation-Id", correlationId) } return send(req) } func optional(name, fallback string) string { value := os.Getenv(name) if value == "" { return fallback } return value } func getJSON(url string, token string, correlationId string) ([]byte, error) { req, _ := http.NewRequest("GET", url, nil) req.Header.Set("Authorization", "Bearer "+token) req.Header.Set("X-Correlation-Id", correlationId) return send(req) } func send(req *http.Request) ([]byte, error) { client := &http.Client{Timeout: 45 * time.Second} resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() result, _ := io.ReadAll(resp.Body) if resp.StatusCode < 200 || resp.StatusCode >= 300 { return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(result)) } return result, nil } func values(proximity, certification, load, safety, rating float64) map[string]float64 { return map[string]float64{ "proximity_score": proximity, "certification_match_score": certification, "current_job_load": load, "safety_history_score": safety, "customer_rating_score": rating } } func main() { identityURL := getenv("DECISIOQ_IDENTITY_URL", "https://identity.vinquery.com/connect/token") catalogURL := strings.TrimRight(getenv("DECISIOQ_DKS_URL", "https://dks.vinquery.com"), "/") decisionServiceURL := strings.TrimRight(getenv("DECISIOQ_DDE_URL", "https://dde.vinquery.com"), "/") correlationID := fmt.Sprintf("auto-tow-019-go-%d", time.Now().Unix()) tokenBody, err := postJSON(identityURL, map[string]string{ "clientId": required("DECISIOQ_CLIENT_ID"), "clientSecret": required("DECISIOQ_CLIENT_SECRET"), "audience": optional("DECISIOQ_AUDIENCE", "vinquery:api:decisioq"), }, "", "") if err != nil { panic(err) } var token struct{ JwtToken string `json:"jwtToken"` } json.Unmarshal(tokenBody, &token) if _, err = getJSON(catalogURL+"/decisioncatalog/decisions/AUTO-TOW-019", token.JwtToken, correlationID); err != nil { panic(err) } executionRequest := map[string]any{ "decisionId": "AUTO-TOW-019", "profileId": "balanced", "scenarioId": "standard", "algorithm": "TOPSIS", "weightStrategy": "Expert", "runSensitivity": false, "requestContext": map[string]string{"correlationId": correlationID}, "options": []map[string]any{ {"optionId": "OPTION-001", "name": "Operator North Zone", "values": values(88, 88, 1, 88, 88)}, {"optionId": "OPTION-002", "name": "Operator Central Zone", "values": values(80, 80, 3, 80, 80)}, {"optionId": "OPTION-003", "name": "Operator East Zone", "values": values(72, 72, 5, 72, 72)}, }, } result, err := postJSON(decisionServiceURL+"/api/v1/decide", executionRequest, token.JwtToken, correlationID) if err != nil { panic(err) } os.Stdout.Write(result) }