diff --git a/cmd/import.go b/cmd/import.go index 2747151..4751803 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -16,6 +16,7 @@ package cmd import ( + "context" "fmt" "os" "strconv" @@ -65,7 +66,7 @@ func NewImportCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command // Create client with server address. mc = connectors.NewMicrocksClient(globalClientOpts.ServerAddr) - keycloakURL, err := mc.GetKeycloakURL() + keycloakURL, err := mc.GetKeycloakURL(context.Background()) if err != nil { fmt.Printf("Got error when invoking Microcks client retrieving config: %s", err) os.Exit(1) @@ -76,7 +77,7 @@ func NewImportCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command // If Keycloak is enabled, retrieve an OAuth token using Keycloak Client. kc := connectors.NewKeycloakClient(keycloakURL, globalClientOpts.ClientId, globalClientOpts.ClientSecret) - oauthToken, err = kc.ConnectAndGetToken() + oauthToken, err = kc.ConnectAndGetToken(context.Background()) if err != nil { fmt.Printf("Got error when invoking Keycloack client: %s", err) os.Exit(1) @@ -132,7 +133,7 @@ func NewImportCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command } // Try uploading this artifact. - msg, err := mc.UploadArtifact(f, mainArtifact) + msg, err := mc.UploadArtifact(context.Background(), f, mainArtifact) if err != nil { fmt.Printf("Got error when invoking Microcks client importing Artifact: %s", err) os.Exit(1) diff --git a/cmd/importDir.go b/cmd/importDir.go index 16a9157..f7154df 100644 --- a/cmd/importDir.go +++ b/cmd/importDir.go @@ -16,6 +16,7 @@ package cmd import ( + "context" "fmt" "os" "path/filepath" @@ -28,7 +29,7 @@ import ( // MicrocksClient interface for dependency injection type MicrocksClient interface { - UploadArtifact(file string, main bool) (string, error) + UploadArtifact(ctx context.Context, file string, main bool) (string, error) } type FileType struct { @@ -159,7 +160,7 @@ func NewImportDirCommand(globalClientOpts *connectors.ClientOptions) *cobra.Comm } // Execute business logic - result, err := ImportDirectory(mc, fs, dirPath, importConfig) + result, err := ImportDirectory(context.Background(), mc, fs, dirPath, importConfig) if err != nil { if validationErr, ok := err.(*ValidationError); ok { fmt.Println(validationErr.Message) @@ -207,7 +208,7 @@ func NewImportDirCommand(globalClientOpts *connectors.ClientOptions) *cobra.Comm return importDirCmd } -func ImportDirectory(client MicrocksClient, fs FileSystem, dirPath string, config ImportConfig) (ImportResult, error) { +func ImportDirectory(ctx context.Context, client MicrocksClient, fs FileSystem, dirPath string, config ImportConfig) (ImportResult, error) { if err := validateDirectory(fs, dirPath); err != nil { return ImportResult{}, err } @@ -231,7 +232,7 @@ func ImportDirectory(client MicrocksClient, fs FileSystem, dirPath string, confi for _, file := range files { fileType := detectFileType(file) - msg, err := client.UploadArtifact(file, fileType.IsPrimary) + msg, err := client.UploadArtifact(ctx, file, fileType.IsPrimary) if err != nil { result.FailedCount++ result.FailedFiles = append(result.FailedFiles, file) diff --git a/cmd/importDir_test.go b/cmd/importDir_test.go index 5693880..e762f79 100644 --- a/cmd/importDir_test.go +++ b/cmd/importDir_test.go @@ -16,6 +16,7 @@ package cmd import ( + "context" "fmt" "os" "path/filepath" @@ -33,7 +34,7 @@ type MockMicrocksClient struct { UploadCalls int } -func (m *MockMicrocksClient) UploadArtifact(file string, main bool) (string, error) { +func (m *MockMicrocksClient) UploadArtifact(ctx context.Context, file string, main bool) (string, error) { m.UploadCalls++ m.Uploaded = append(m.Uploaded, file) @@ -189,7 +190,7 @@ func TestImportDirectory(t *testing.T) { } // Execute - result, err := ImportDirectory(mockClient, mockFS, "/test", tt.config) + result, err := ImportDirectory(context.Background(), mockClient, mockFS, "/test", tt.config) // Assertions if tt.expectError { @@ -417,7 +418,7 @@ func BenchmarkImportDirectory(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - _, err := ImportDirectory(mockClient, mockFS, "/test", config) + _, err := ImportDirectory(context.Background(), mockClient, mockFS, "/test", config) require.NoError(b, err) } } diff --git a/cmd/importURL.go b/cmd/importURL.go index 442e7e2..5c762bb 100644 --- a/cmd/importURL.go +++ b/cmd/importURL.go @@ -17,6 +17,7 @@ package cmd import ( + "context" "fmt" "os" "strconv" @@ -51,7 +52,7 @@ func NewImportURLCommand(globalClientOpts *connectors.ClientOptions) *cobra.Comm // create client with server address mc = connectors.NewMicrocksClient(globalClientOpts.ServerAddr) - keycloakURL, err := mc.GetKeycloakURL() + keycloakURL, err := mc.GetKeycloakURL(context.Background()) if err != nil { fmt.Printf("Got error when invoking Microcks client retrieving config: %s", err) os.Exit(1) @@ -62,7 +63,7 @@ func NewImportURLCommand(globalClientOpts *connectors.ClientOptions) *cobra.Comm // If Keycloak is enabled, retrieve an OAuth token using Keycloak Client. kc := connectors.NewKeycloakClient(keycloakURL, globalClientOpts.ClientId, globalClientOpts.ClientSecret) - oauthToken, err = kc.ConnectAndGetToken() + oauthToken, err = kc.ConnectAndGetToken(context.Background()) if err != nil { fmt.Printf("Got error when invoking Keycloack client: %s", err) os.Exit(1) @@ -118,7 +119,7 @@ func NewImportURLCommand(globalClientOpts *connectors.ClientOptions) *cobra.Comm } // Try downloading the artifcat - msg, err := mc.DownloadArtifact(f, mainArtifact, secret) + msg, err := mc.DownloadArtifact(context.Background(), f, mainArtifact, secret) if err != nil { fmt.Printf("Got error when invoking Microcks client importing Artifact: %s", err) os.Exit(1) diff --git a/cmd/login.go b/cmd/login.go index 2b624f7..1882e86 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -73,7 +73,7 @@ microcks login http://localhost:8080 --sso --sso-launch-browser=false server = args[0] mc := connectors.NewMicrocksClient(server) - keycloakUrl, err := mc.GetKeycloakURL() + keycloakUrl, err := mc.GetKeycloakURL(ctx) if err != nil { log.Fatal(err) @@ -120,14 +120,14 @@ microcks login http://localhost:8080 --sso --sso-launch-browser=false os.Exit(1) } //Perform login and retrive tokens - authToken, refreshToken = passwordLogin(keycloakUrl, clientID, clientSecret, username, password) + authToken, refreshToken = passwordLogin(ctx, keycloakUrl, clientID, clientSecret, username, password) authCfg.ClientId = clientID authCfg.ClientSecret = clientSecret } else { httpClient := mc.HttpClient() ctx = oidc.ClientContext(ctx, httpClient) kc := connectors.NewKeycloakClient(keycloakUrl, "", "") - oauth2conf, err := kc.GetOIDCConfig() + oauth2conf, err := kc.GetOIDCConfig(ctx) errors.CheckError(err) authToken, refreshToken = oauth2login(ctx, ssoProt, oauth2conf, ssoLaunchBrowser) authCfg.ClientId = "microcks-app-js" @@ -308,11 +308,11 @@ func ssoAuthFlow(url string, ssoLaunchBrowser bool) { } } -func passwordLogin(keycloakURL, clientId, clientSecret, Username, Password string) (string, string) { +func passwordLogin(ctx context.Context, keycloakURL, clientId, clientSecret, Username, Password string) (string, string) { kc := connectors.NewKeycloakClient(keycloakURL, clientId, clientSecret) username, password := promptCredentials(Username, Password) - authToken, refreshToken, err := kc.ConnectAndGetTokenAndRefreshToken(username, password) + authToken, refreshToken, err := kc.ConnectAndGetTokenAndRefreshToken(ctx, username, password) if err != nil { panic(err) diff --git a/cmd/test.go b/cmd/test.go index ca14a83..0922bda 100644 --- a/cmd/test.go +++ b/cmd/test.go @@ -16,6 +16,7 @@ package cmd import ( + "context" "fmt" "os" "strconv" @@ -105,7 +106,7 @@ func NewTestCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command { serverAddr = globalClientOpts.ServerAddr mc = connectors.NewMicrocksClient(serverAddr) - keycloakURL, err := mc.GetKeycloakURL() + keycloakURL, err := mc.GetKeycloakURL(context.Background()) if err != nil { fmt.Printf("Got error when invoking Microcks client retrieving config: %s", err) os.Exit(1) @@ -116,7 +117,7 @@ func NewTestCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command { // If Keycloak is enabled, retrieve an OAuth token using Keycloak Client. kc := connectors.NewKeycloakClient(keycloakURL, globalClientOpts.ClientId, globalClientOpts.ClientSecret) - oauthToken, err = kc.ConnectAndGetToken() + oauthToken, err = kc.ConnectAndGetToken(context.Background()) if err != nil { fmt.Printf("Got error when invoking Keycloack client: %s", err) os.Exit(1) @@ -156,7 +157,7 @@ func NewTestCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command { } var testResultID string - testResultID, err := mc.CreateTestResult(serviceRef, testEndpoint, runnerType, secretName, waitForMilliseconds, filteredOperations, operationsHeaders, oAuth2Context) + testResultID, err := mc.CreateTestResult(context.Background(), serviceRef, testEndpoint, runnerType, secretName, waitForMilliseconds, filteredOperations, operationsHeaders, oAuth2Context) if err != nil { fmt.Printf("Got error when invoking Microcks client creating Test: %s", err) os.Exit(1) @@ -172,7 +173,7 @@ func NewTestCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command { var success = false for nowInMilliseconds() < future { - testResultSummary, err := mc.GetTestResult(testResultID) + testResultSummary, err := mc.GetTestResult(context.Background(), testResultID) if err != nil { fmt.Printf("Got error when invoking Microcks client check TestResult: %s", err) os.Exit(1) diff --git a/pkg/connectors/keycloak_client.go b/pkg/connectors/keycloak_client.go index 3c2257b..44e0df4 100644 --- a/pkg/connectors/keycloak_client.go +++ b/pkg/connectors/keycloak_client.go @@ -17,6 +17,7 @@ package connectors import ( "bytes" + "context" "encoding/base64" "encoding/json" "fmt" @@ -31,9 +32,9 @@ import ( // KeycloakClient defines methods for cinteracting with Keycloak type KeycloakClient interface { - ConnectAndGetToken() (string, error) - ConnectAndGetTokenAndRefreshToken(string, string) (string, string, error) - GetOIDCConfig() (*oauth2.Config, error) + ConnectAndGetToken(ctx context.Context) (string, error) + ConnectAndGetTokenAndRefreshToken(ctx context.Context, username string, password string) (string, string, error) + GetOIDCConfig(ctx context.Context) (*oauth2.Config, error) } type keycloakClient struct { @@ -69,11 +70,11 @@ func NewKeycloakClient(realmURL string, username string, password string) Keyclo } // ConnectAndGetToken implementation on keycloakClient structure -func (c *keycloakClient) ConnectAndGetToken() (string, error) { +func (c *keycloakClient) ConnectAndGetToken(ctx context.Context) (string, error) { rel := &url.URL{Path: "protocol/openid-connect/token"} u := c.BaseURL.ResolveReference(rel) - req, err := http.NewRequest("POST", u.String(), strings.NewReader(url.Values{"grant_type": {"client_credentials"}}.Encode())) + req, err := http.NewRequestWithContext(ctx, "POST", u.String(), strings.NewReader(url.Values{"grant_type": {"client_credentials"}}.Encode())) if err != nil { return "", err } @@ -109,12 +110,12 @@ func (c *keycloakClient) ConnectAndGetToken() (string, error) { return accessToken, err } -func (c *keycloakClient) GetOIDCConfig() (*oauth2.Config, error) { +func (c *keycloakClient) GetOIDCConfig(ctx context.Context) (*oauth2.Config, error) { rel := &url.URL{Path: ".well-known/openid-configuration"} u := c.BaseURL.ResolveReference(rel) // Create HTTP request - req, err := http.NewRequest("GET", u.String(), nil) + req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) if err != nil { fmt.Println("Error creating request:", err) } @@ -146,7 +147,7 @@ func (c *keycloakClient) GetOIDCConfig() (*oauth2.Config, error) { }, nil } -func (c *keycloakClient) ConnectAndGetTokenAndRefreshToken(username, password string) (string, string, error) { +func (c *keycloakClient) ConnectAndGetTokenAndRefreshToken(ctx context.Context, username, password string) (string, string, error) { rel := &url.URL{Path: "protocol/openid-connect/token"} u := c.BaseURL.ResolveReference(rel) @@ -158,7 +159,7 @@ func (c *keycloakClient) ConnectAndGetTokenAndRefreshToken(username, password st data.Set("password", password) data.Set("grant_type", "password") // Create HTTP request - req, err := http.NewRequest("POST", u.String(), bytes.NewBufferString(data.Encode())) + req, err := http.NewRequestWithContext(ctx, "POST", u.String(), bytes.NewBufferString(data.Encode())) if err != nil { fmt.Println("Error creating request:", err) } diff --git a/pkg/connectors/microcks_client.go b/pkg/connectors/microcks_client.go index cabb85f..1e9a231 100644 --- a/pkg/connectors/microcks_client.go +++ b/pkg/connectors/microcks_client.go @@ -46,12 +46,12 @@ var ( // MicrocksClient allows interacting with Microcks APIs type MicrocksClient interface { HttpClient() *http.Client - GetKeycloakURL() (string, error) + GetKeycloakURL(ctx context.Context) (string, error) SetOAuthToken(oauthToken string) - CreateTestResult(serviceID string, testEndpoint string, runnerType string, secretName string, timeout int64, filteredOperations string, operationsHeaders string, oAuth2Context string) (string, error) - GetTestResult(testResultID string) (*TestResultSummary, error) - UploadArtifact(specificationFilePath string, mainArtifact bool) (string, error) - DownloadArtifact(artifactURL string, mainArtifact bool, secret string) (string, error) + CreateTestResult(ctx context.Context, serviceID string, testEndpoint string, runnerType string, secretName string, timeout int64, filteredOperations string, operationsHeaders string, oAuth2Context string) (string, error) + GetTestResult(ctx context.Context, testResultID string) (*TestResultSummary, error) + UploadArtifact(ctx context.Context, specificationFilePath string, mainArtifact bool) (string, error) + DownloadArtifact(ctx context.Context, artifactURL string, mainArtifact bool, secret string) (string, error) } // TestResultSummary represents a simple view on Microcks TestResult @@ -202,12 +202,12 @@ func (c *microcksClient) HttpClient() *http.Client { return c.httpClient } -func (c *microcksClient) GetKeycloakURL() (string, error) { +func (c *microcksClient) GetKeycloakURL(ctx context.Context) (string, error) { // Ensure we have a correct URL for retrieving Keycloal configuration. rel := &url.URL{Path: "keycloak/config"} u := c.APIURL.ResolveReference(rel) - req, err := http.NewRequest("GET", u.String(), nil) + req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) if err != nil { return "", err } @@ -292,10 +292,10 @@ func (c *microcksClient) refreshAuthToken(localCfg *config.LocalConfig, ctxName, } func (c *microcksClient) redeemRefreshToken(auth config.Auth) (string, string, error) { - keyCloakUrl, err := c.GetKeycloakURL() + keyCloakUrl, err := c.GetKeycloakURL(context.Background()) errors.CheckError(err) kc := NewKeycloakClient(keyCloakUrl, "", "") - oauth2Conf, err := kc.GetOIDCConfig() + oauth2Conf, err := kc.GetOIDCConfig(context.Background()) errors.CheckError(err) oauth2Conf.ClientID = auth.ClientId oauth2Conf.ClientSecret = auth.ClientSecret @@ -318,7 +318,7 @@ func (c *microcksClient) SetOAuthToken(oauthToken string) { c.AuthToken = oauthToken } -func (c *microcksClient) CreateTestResult(serviceID string, testEndpoint string, runnerType string, secretName string, timeout int64, filteredOperations string, operationsHeaders string, oAuth2Context string) (string, error) { +func (c *microcksClient) CreateTestResult(ctx context.Context, serviceID string, testEndpoint string, runnerType string, secretName string, timeout int64, filteredOperations string, operationsHeaders string, oAuth2Context string) (string, error) { // Ensure we have a correct URL. rel := &url.URL{Path: "tests"} u := c.APIURL.ResolveReference(rel) @@ -344,7 +344,7 @@ func (c *microcksClient) CreateTestResult(serviceID string, testEndpoint string, input += "}" - req, err := http.NewRequest("POST", u.String(), strings.NewReader(input)) + req, err := http.NewRequestWithContext(ctx, "POST", u.String(), strings.NewReader(input)) if err != nil { return "", err } @@ -379,12 +379,12 @@ func (c *microcksClient) CreateTestResult(serviceID string, testEndpoint string, return testID, err } -func (c *microcksClient) GetTestResult(testResultID string) (*TestResultSummary, error) { +func (c *microcksClient) GetTestResult(ctx context.Context, testResultID string) (*TestResultSummary, error) { // Ensure we have a correct URL. rel := &url.URL{Path: "tests/" + testResultID} u := c.APIURL.ResolveReference(rel) - req, err := http.NewRequest("GET", u.String(), nil) + req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) if err != nil { return nil, err } @@ -415,7 +415,7 @@ func (c *microcksClient) GetTestResult(testResultID string) (*TestResultSummary, return &result, err } -func (c *microcksClient) UploadArtifact(specificationFilePath string, mainArtifact bool) (string, error) { +func (c *microcksClient) UploadArtifact(ctx context.Context, specificationFilePath string, mainArtifact bool) (string, error) { // Ensure file exists on fs. file, err := os.Open(specificationFilePath) if err != nil { @@ -447,7 +447,7 @@ func (c *microcksClient) UploadArtifact(specificationFilePath string, mainArtifa rel := &url.URL{Path: "artifact/upload"} u := c.APIURL.ResolveReference(rel) - req, err := http.NewRequest("POST", u.String(), body) + req, err := http.NewRequestWithContext(ctx, "POST", u.String(), body) if err != nil { return "", err } @@ -479,7 +479,7 @@ func (c *microcksClient) UploadArtifact(specificationFilePath string, mainArtifa return string(respBody), err } -func (c *microcksClient) DownloadArtifact(artifactURL string, mainArtifact bool, secret string) (string, error) { +func (c *microcksClient) DownloadArtifact(ctx context.Context, artifactURL string, mainArtifact bool, secret string) (string, error) { // create Multipart Form to add fields body := &bytes.Buffer{} @@ -501,7 +501,7 @@ func (c *microcksClient) DownloadArtifact(artifactURL string, mainArtifact bool, rel := &url.URL{Path: "artifact/download"} u := c.APIURL.ResolveReference(rel) - req, err := http.NewRequest("POST", u.String(), body) + req, err := http.NewRequestWithContext(ctx, "POST", u.String(), body) if err != nil { return "", err } diff --git a/pkg/watcher/executor.go b/pkg/watcher/executor.go index 3347fc6..e87001c 100644 --- a/pkg/watcher/executor.go +++ b/pkg/watcher/executor.go @@ -1,6 +1,7 @@ package watcher import ( + "context" "fmt" "os" @@ -17,7 +18,7 @@ func TriggerImport(entry config.WatchEntry) { fmt.Println("[INFO] Re-importing changed file: " + entry.FilePath) - for _, context := range entry.Context { + for _, ctx := range entry.Context { // Prepare Microcks client. var mc connectors.MicrocksClient @@ -26,23 +27,23 @@ func TriggerImport(entry config.WatchEntry) { if _, err := os.Stat(cfgPath); err == nil { globalClientOpts := &connectors.ClientOptions{ ConfigPath: cfgPath, - Context: context, + Context: ctx, } mc, err = connectors.NewClient(*globalClientOpts) if err != nil { - fmt.Printf("[ERROR] Cannot connect to Microcks client: %v in context '%s'\n", err, context) + fmt.Printf("[ERROR] Cannot connect to Microcks client: %v in context '%s'\n", err, ctx) } } else { // We have no config file, so just create a client with context as server URL. - mc = connectors.NewMicrocksClient(context) + mc = connectors.NewMicrocksClient(ctx) } - _, err = mc.UploadArtifact(entry.FilePath, entry.MainArtifact) + _, err = mc.UploadArtifact(context.Background(), entry.FilePath, entry.MainArtifact) if err != nil { fmt.Printf("[WARN] Error re-importing %s: %v\n", entry.FilePath, err) } else { - fmt.Printf("[INFO] Successfully re-imported %s in context '%s'\n", entry.FilePath, context) + fmt.Printf("[INFO] Successfully re-imported %s in context '%s'\n", entry.FilePath, ctx) } } }