You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by kl...@apache.org on 2023/01/30 09:43:57 UTC

[incubator-devlake] branch main updated: fix(sonarqube): modify connection to conform pr4260 (#4276)

This is an automated email from the ASF dual-hosted git repository.

klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new ceb3a8080 fix(sonarqube): modify connection to conform pr4260 (#4276)
ceb3a8080 is described below

commit ceb3a80806f80781e9df16a7b5b2f8fb54fc5195
Author: Warren Chen <yi...@merico.dev>
AuthorDate: Mon Jan 30 17:43:52 2023 +0800

    fix(sonarqube): modify connection to conform pr4260 (#4276)
---
 backend/plugins/ae/api/connection.go           |  2 +-
 backend/plugins/sonarqube/api/connection.go    | 41 +++++++++-------------
 backend/plugins/sonarqube/impl/impl.go         |  2 +-
 backend/plugins/sonarqube/models/connection.go |  3 +-
 backend/plugins/sonarqube/tasks/api_client.go  | 47 ++++----------------------
 5 files changed, 26 insertions(+), 69 deletions(-)

diff --git a/backend/plugins/ae/api/connection.go b/backend/plugins/ae/api/connection.go
index 91d3a0325..31e1e5af1 100644
--- a/backend/plugins/ae/api/connection.go
+++ b/backend/plugins/ae/api/connection.go
@@ -44,7 +44,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 	// decode
 	var err errors.Error
 	var connection models.AeConn
-	if err := api.Decode(input.Body, &connection, vld); err != nil {
+	if err = api.Decode(input.Body, &connection, vld); err != nil {
 		return nil, errors.BadInput.Wrap(err, "could not decode request parameters")
 	}
 
diff --git a/backend/plugins/sonarqube/api/connection.go b/backend/plugins/sonarqube/api/connection.go
index bf518c0ad..dc861ece0 100644
--- a/backend/plugins/sonarqube/api/connection.go
+++ b/backend/plugins/sonarqube/api/connection.go
@@ -19,13 +19,11 @@ package api
 
 import (
 	"context"
-	"fmt"
 	"github.com/apache/incubator-devlake/core/errors"
 	"github.com/apache/incubator-devlake/core/plugin"
 	"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 	"github.com/apache/incubator-devlake/plugins/sonarqube/models"
 	"net/http"
-	"time"
 )
 
 type validation struct {
@@ -39,17 +37,7 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 	if err = api.Decode(input.Body, &connection, vld); err != nil {
 		return nil, err
 	}
-	// test connection
-	apiClient, err := api.NewApiClient(
-		context.TODO(),
-		connection.Endpoint,
-		map[string]string{
-			"Authorization": fmt.Sprintf("Basic %s", connection.GetEncodedToken()),
-		},
-		3*time.Second,
-		connection.Proxy,
-		basicRes,
-	)
+	apiClient, err := api.NewApiClientFromConnection(context.TODO(), basicRes, connection)
 	if err != nil {
 		return nil, err
 	}
@@ -58,19 +46,22 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 	if err != nil {
 		return nil, err
 	}
-	if res.StatusCode != http.StatusOK {
-		return nil, errors.HttpStatus(res.StatusCode).New(fmt.Sprintf("unexpected status code: %d", res.StatusCode))
+	switch res.StatusCode {
+	case 200: // right StatusCode
+		body := &validation{}
+		err = api.UnmarshalResponse(res, body)
+		if err != nil {
+			return nil, err
+		}
+		if !body.Valid {
+			return nil, errors.Default.New("Authentication failed, please check your access token.")
+		}
+		return &plugin.ApiResourceOutput{Body: true, Status: 200}, nil
+	case 401: // error secretKey or nonceStr
+		return &plugin.ApiResourceOutput{Body: false, Status: res.StatusCode}, nil
+	default: // unknow what happen , back to user
+		return &plugin.ApiResourceOutput{Body: res.Body, Status: res.StatusCode}, nil
 	}
-
-	body := &validation{}
-	err = api.UnmarshalResponse(res, body)
-	if err != nil {
-		return nil, err
-	}
-	if !body.Valid {
-		return nil, errors.Default.New("Authentication failed, please check your access token.")
-	}
-	return nil, nil
 }
 
 /*
diff --git a/backend/plugins/sonarqube/impl/impl.go b/backend/plugins/sonarqube/impl/impl.go
index 82b7c55ad..50d5d8751 100644
--- a/backend/plugins/sonarqube/impl/impl.go
+++ b/backend/plugins/sonarqube/impl/impl.go
@@ -73,7 +73,7 @@ func (p Sonarqube) PrepareTaskData(taskCtx plugin.TaskContext, options map[strin
 		return nil, errors.Default.Wrap(err, "unable to get Sonarqube connection by the given connection ID")
 	}
 
-	apiClient, err := tasks.NewSonarqubeApiClient(taskCtx, connection)
+	apiClient, err := tasks.CreateApiClient(taskCtx, connection)
 	if err != nil {
 		return nil, errors.Default.Wrap(err, "unable to get Sonarqube API client instance")
 	}
diff --git a/backend/plugins/sonarqube/models/connection.go b/backend/plugins/sonarqube/models/connection.go
index 422d88d51..6d29013de 100644
--- a/backend/plugins/sonarqube/models/connection.go
+++ b/backend/plugins/sonarqube/models/connection.go
@@ -47,8 +47,7 @@ func (sat SonarqubeAccessToken) GetEncodedToken() string {
 type SonarqubeConnection struct {
 	helper.BaseConnection `mapstructure:",squash"`
 	helper.RestConnection `mapstructure:",squash"`
-	// For sonarqube, we can `use user_token:`
-	SonarqubeAccessToken `mapstructure:",squash"`
+	SonarqubeAccessToken  `mapstructure:",squash"`
 }
 
 // SonarqubeConn holds the essential information to connect to the sonarqube API
diff --git a/backend/plugins/sonarqube/tasks/api_client.go b/backend/plugins/sonarqube/tasks/api_client.go
index e7864f4a7..958535ff8 100644
--- a/backend/plugins/sonarqube/tasks/api_client.go
+++ b/backend/plugins/sonarqube/tasks/api_client.go
@@ -18,57 +18,24 @@ limitations under the License.
 package tasks
 
 import (
-	"fmt"
 	"github.com/apache/incubator-devlake/core/errors"
 	"github.com/apache/incubator-devlake/core/plugin"
 	"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
-	"net/http"
-	"strconv"
-	"time"
-
 	"github.com/apache/incubator-devlake/plugins/sonarqube/models"
 )
 
-func NewSonarqubeApiClient(taskCtx plugin.TaskContext, connection *models.SonarqubeConnection) (*api.ApiAsyncClient, errors.Error) {
-	// create synchronize api client so we can calculate api rate limit dynamically
-	headers := map[string]string{
-		"Authorization": fmt.Sprintf("Basic %s", connection.GetEncodedToken()),
-	}
-	apiClient, err := api.NewApiClient(taskCtx.GetContext(), connection.Endpoint, headers, 30*time.Second, connection.Proxy, taskCtx)
+// CreateApiClient creates a new asynchronize API Client for AE
+func CreateApiClient(taskCtx plugin.TaskContext, connection *models.SonarqubeConnection) (*api.ApiAsyncClient, errors.Error) {
+	apiClient, err := api.NewApiClientFromConnection(taskCtx.GetContext(), taskCtx, connection)
 	if err != nil {
 		return nil, err
 	}
-	apiClient.SetAfterFunction(func(res *http.Response) errors.Error {
-		if res.StatusCode == http.StatusUnauthorized {
-			return errors.HttpStatus(res.StatusCode).New("authentication failed, please check your AccessToken")
-		}
-		return nil
-	})
 
-	// create rate limit calculator
-	rateLimiter := &api.ApiRateLimitCalculator{
-		UserRateLimitPerHour: connection.RateLimitPerHour,
-		DynamicRateLimit: func(res *http.Response) (int, time.Duration, errors.Error) {
-			rateLimitHeader := res.Header.Get("RateLimit-Limit")
-			if rateLimitHeader == "" {
-				// use default
-				return 0, 0, nil
-			}
-			rateLimit, err := strconv.Atoi(rateLimitHeader)
-			if err != nil {
-				return 0, 0, errors.Default.Wrap(err, "failed to parse RateLimit-Limit header")
-			}
-			// seems like {{ .plugin-ame }} rate limit is on minute basis
-			return rateLimit, 1 * time.Minute, nil
-		},
-	}
-	asyncApiClient, err := api.CreateAsyncApiClient(
-		taskCtx,
-		apiClient,
-		rateLimiter,
-	)
+	// create ae api client
+	asyncApiCLient, err := api.CreateAsyncApiClient(taskCtx, apiClient, nil)
 	if err != nil {
 		return nil, err
 	}
-	return asyncApiClient, nil
+
+	return asyncApiCLient, nil
 }