You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by GitBox <gi...@apache.org> on 2022/06/15 13:54:48 UTC

[GitHub] [incubator-devlake] mappjzc opened a new pull request, #2208: feat: multi-data connections support for ae

mappjzc opened a new pull request, #2208:
URL: https://github.com/apache/incubator-devlake/pull/2208

   # Summary
   Add multi-data support for AE
   Mv randomstr to core
   Add TestConnection for AE
   
   <!--
   Thanks for submitting a pull request!
   
   We appreciate you spending the time to work on these changes.
   Please fill out as many sections below as possible.
   -->
   
   ### Does this close any open issues?
   close #1981 
   
   ### Screenshots
   ![image](https://user-images.githubusercontent.com/2921251/173841503-32f249d4-2d37-4814-ac2b-4673821b0d6b.png)
   ![image](https://user-images.githubusercontent.com/2921251/173841932-7d4f8678-9157-4b03-8de7-6e14b4cec5e2.png)
   ![image](https://user-images.githubusercontent.com/2921251/173842400-68564583-89dc-43b1-b9b4-57fca1e96d96.png)
   ![image](https://user-images.githubusercontent.com/2921251/173842788-2ea3f8b2-fd6d-4ab8-af23-dbda9938ccea.png)
   ![image](https://user-images.githubusercontent.com/2921251/173844003-e30dc950-7dd2-400f-aa2a-cf9b6e3e182a.png)
   ![image](https://user-images.githubusercontent.com/2921251/173844741-414838e8-3e0a-4c2c-9af4-4673ca9678cc.png)
   ![image](https://user-images.githubusercontent.com/2921251/173844764-836bcddf-6caf-46af-a624-c8659568e43b.png)
   
   
   ### Other Information
   Any other information that is important to this PR.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@devlake.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-devlake] klesh commented on a diff in pull request #2208: feat: multi-data connections support for ae

Posted by GitBox <gi...@apache.org>.
klesh commented on code in PR #2208:
URL: https://github.com/apache/incubator-devlake/pull/2208#discussion_r900303406


##########
plugins/ae/api/connection.go:
##########
@@ -18,88 +18,141 @@ limitations under the License.
 package api
 
 import (
-	"github.com/apache/incubator-devlake/config"
+	"fmt"
+	"net/http"
+	"time"
+
 	"github.com/apache/incubator-devlake/plugins/ae/models"
 	"github.com/apache/incubator-devlake/plugins/core"
 	"github.com/apache/incubator-devlake/plugins/helper"
-	"net/http"
+	"github.com/go-playground/validator/v10"
+	"github.com/mitchellh/mapstructure"
+	"github.com/spf13/viper"
+	"gorm.io/gorm"
 )
 
 type ApiMeResponse struct {
 	Name string `json:"name"`
 }
 
-/*
-GET /plugins/ae/test
-*/
-func TestConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
-	// TODO: implement test connection
-	return &core.ApiResourceOutput{Body: true}, nil
+var vld *validator.Validate
+var connectionHelper *helper.ConnectionApiHelper
+
+func Init(config *viper.Viper, logger core.Logger, database *gorm.DB) {
+	basicRes := helper.NewDefaultBasicRes(config, logger, database)
+	vld = validator.New()
+	connectionHelper = helper.NewConnectionHelper(
+		basicRes,
+		vld,
+	)
 }
 
 /*
-PATCH /plugins/ae/connections/:connectionId
+GET /plugins/ae/test/:connectionId

Review Comment:
   The comment doesn't seem correct.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@devlake.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-devlake] mappjzc commented on a diff in pull request #2208: feat: multi-data connections support for ae

Posted by GitBox <gi...@apache.org>.
mappjzc commented on code in PR #2208:
URL: https://github.com/apache/incubator-devlake/pull/2208#discussion_r899124049


##########
plugins/ae/api/connection.go:
##########
@@ -18,88 +18,165 @@ limitations under the License.
 package api
 
 import (
-	"github.com/apache/incubator-devlake/config"
+	"crypto/md5"
+	"encoding/hex"
+	"fmt"
+	"net/http"
+	"net/url"
+	"sort"
+	"strings"
+	"time"
+
 	"github.com/apache/incubator-devlake/plugins/ae/models"
 	"github.com/apache/incubator-devlake/plugins/core"
 	"github.com/apache/incubator-devlake/plugins/helper"
-	"net/http"
+	"github.com/go-playground/validator/v10"
+	"github.com/spf13/viper"
+	"gorm.io/gorm"
 )
 
 type ApiMeResponse struct {
 	Name string `json:"name"`
 }
 
-/*
-GET /plugins/ae/test
-*/
-func TestConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
-	// TODO: implement test connection
-	return &core.ApiResourceOutput{Body: true}, nil
+var connectionHelper *helper.ConnectionApiHelper
+
+func Init(config *viper.Viper, logger core.Logger, database *gorm.DB) {
+	basicRes := helper.NewDefaultBasicRes(config, logger, database)
+	vld := validator.New()
+	connectionHelper = helper.NewConnectionHelper(
+		basicRes,
+		vld,
+	)
+}
+
+func GetSign(query url.Values, appId, secretKey, nonceStr, timestamp string) string {
+	// clone query because we need to add items
+	kvs := make([]string, 0, len(query)+3)
+	kvs = append(kvs, fmt.Sprintf("app_id=%s", appId))
+	kvs = append(kvs, fmt.Sprintf("timestamp=%s", timestamp))
+	kvs = append(kvs, fmt.Sprintf("nonce_str=%s", nonceStr))
+	for key, values := range query {
+		for _, value := range values {
+			kvs = append(kvs, fmt.Sprintf("%s=%s", url.QueryEscape(key), url.QueryEscape(value)))
+		}
+	}
+
+	// sort by alphabetical order
+	sort.Strings(kvs)
+
+	// generate text for signature
+	querystring := fmt.Sprintf("%s&key=%s", strings.Join(kvs, "&"), url.QueryEscape(secretKey))
+
+	// sign it
+	hasher := md5.New()
+	_, err := hasher.Write([]byte(querystring))
+	if err != nil {
+		return ""
+	}
+	return strings.ToUpper(hex.EncodeToString(hasher.Sum(nil)))
 }
 
 /*
-PATCH /plugins/ae/connections/:connectionId
+GET /plugins/ae/test/:connectionId
 */
-func PatchConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
-	v := config.GetConfig()
+func TestConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
 	connection := &models.AeConnection{}
-	err := helper.EncodeStruct(v, connection, "env")
+	err := connectionHelper.First(connection, input.Params)
 	if err != nil {
 		return nil, err
 	}
-	// update from request and save to .env
-	err = helper.DecodeStruct(v, connection, input.Body, "env")
+
+	// load and process cconfiguration
+	endpoint := connection.Endpoint
+	appId := connection.AppId
+	secretKey := connection.SecretKey
+	proxy := connection.Proxy
+
+	apiClient, err := helper.NewApiClient(endpoint, nil, 3*time.Second, proxy, nil)
 	if err != nil {
 		return nil, err
 	}
-	err = config.WriteConfig(v)
+	apiClient.SetBeforeFunction(func(req *http.Request) error {
+		nonceStr := core.RandLetterBytes(8)
+		timestamp := fmt.Sprintf("%v", time.Now().Unix())
+		sign := GetSign(req.URL.Query(), appId, secretKey, nonceStr, timestamp)
+		req.Header.Set("x-ae-app-id", appId)
+		req.Header.Set("x-ae-timestamp", timestamp)
+		req.Header.Set("x-ae-nonce-str", nonceStr)
+		req.Header.Set("x-ae-sign", sign)
+		return nil
+	})
+	res, err := apiClient.Get("projects/", nil, nil)
 	if err != nil {
 		return nil, err
 	}
-	response := models.AeResponse{
-		AeConnection: *connection,
-		Name:         "Ae",
-		ID:           1,
+
+	switch res.StatusCode {
+	case 401: // error secretKey or nonceStr
+		return &core.ApiResourceOutput{Body: false, Status: res.StatusCode}, nil
+	case 404: // right StatusCode

Review Comment:
   it already used projects



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@devlake.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-devlake] klesh commented on a diff in pull request #2208: feat: multi-data connections support for ae

Posted by GitBox <gi...@apache.org>.
klesh commented on code in PR #2208:
URL: https://github.com/apache/incubator-devlake/pull/2208#discussion_r900303403


##########
plugins/ae/api/connection.go:
##########
@@ -18,88 +18,141 @@ limitations under the License.
 package api
 
 import (
-	"github.com/apache/incubator-devlake/config"
+	"fmt"
+	"net/http"
+	"time"
+
 	"github.com/apache/incubator-devlake/plugins/ae/models"
 	"github.com/apache/incubator-devlake/plugins/core"
 	"github.com/apache/incubator-devlake/plugins/helper"
-	"net/http"
+	"github.com/go-playground/validator/v10"
+	"github.com/mitchellh/mapstructure"
+	"github.com/spf13/viper"
+	"gorm.io/gorm"
 )
 
 type ApiMeResponse struct {
 	Name string `json:"name"`
 }
 
-/*
-GET /plugins/ae/test
-*/
-func TestConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
-	// TODO: implement test connection
-	return &core.ApiResourceOutput{Body: true}, nil
+var vld *validator.Validate
+var connectionHelper *helper.ConnectionApiHelper
+
+func Init(config *viper.Viper, logger core.Logger, database *gorm.DB) {
+	basicRes := helper.NewDefaultBasicRes(config, logger, database)
+	vld = validator.New()
+	connectionHelper = helper.NewConnectionHelper(
+		basicRes,
+		vld,
+	)
 }
 
 /*
-PATCH /plugins/ae/connections/:connectionId
+GET /plugins/ae/test/:connectionId

Review Comment:
   The comment doesn't seem correct.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@devlake.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-devlake] klesh commented on a diff in pull request #2208: feat: multi-data connections support for ae

Posted by GitBox <gi...@apache.org>.
klesh commented on code in PR #2208:
URL: https://github.com/apache/incubator-devlake/pull/2208#discussion_r898842469


##########
plugins/ae/api/connection.go:
##########
@@ -18,88 +18,165 @@ limitations under the License.
 package api
 
 import (
-	"github.com/apache/incubator-devlake/config"
+	"crypto/md5"
+	"encoding/hex"
+	"fmt"
+	"net/http"
+	"net/url"
+	"sort"
+	"strings"
+	"time"
+
 	"github.com/apache/incubator-devlake/plugins/ae/models"
 	"github.com/apache/incubator-devlake/plugins/core"
 	"github.com/apache/incubator-devlake/plugins/helper"
-	"net/http"
+	"github.com/go-playground/validator/v10"
+	"github.com/spf13/viper"
+	"gorm.io/gorm"
 )
 
 type ApiMeResponse struct {
 	Name string `json:"name"`
 }
 
-/*
-GET /plugins/ae/test
-*/
-func TestConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
-	// TODO: implement test connection
-	return &core.ApiResourceOutput{Body: true}, nil
+var connectionHelper *helper.ConnectionApiHelper
+
+func Init(config *viper.Viper, logger core.Logger, database *gorm.DB) {
+	basicRes := helper.NewDefaultBasicRes(config, logger, database)
+	vld := validator.New()
+	connectionHelper = helper.NewConnectionHelper(
+		basicRes,
+		vld,
+	)
+}
+
+func GetSign(query url.Values, appId, secretKey, nonceStr, timestamp string) string {

Review Comment:
   I think a better place for this function should be `models/connection.go`



##########
plugins/ae/api/connection.go:
##########
@@ -18,88 +18,165 @@ limitations under the License.
 package api
 
 import (
-	"github.com/apache/incubator-devlake/config"
+	"crypto/md5"
+	"encoding/hex"
+	"fmt"
+	"net/http"
+	"net/url"
+	"sort"
+	"strings"
+	"time"
+
 	"github.com/apache/incubator-devlake/plugins/ae/models"
 	"github.com/apache/incubator-devlake/plugins/core"
 	"github.com/apache/incubator-devlake/plugins/helper"
-	"net/http"
+	"github.com/go-playground/validator/v10"
+	"github.com/spf13/viper"
+	"gorm.io/gorm"
 )
 
 type ApiMeResponse struct {
 	Name string `json:"name"`
 }
 
-/*
-GET /plugins/ae/test
-*/
-func TestConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
-	// TODO: implement test connection
-	return &core.ApiResourceOutput{Body: true}, nil
+var connectionHelper *helper.ConnectionApiHelper
+
+func Init(config *viper.Viper, logger core.Logger, database *gorm.DB) {
+	basicRes := helper.NewDefaultBasicRes(config, logger, database)
+	vld := validator.New()
+	connectionHelper = helper.NewConnectionHelper(
+		basicRes,
+		vld,
+	)
+}
+
+func GetSign(query url.Values, appId, secretKey, nonceStr, timestamp string) string {
+	// clone query because we need to add items
+	kvs := make([]string, 0, len(query)+3)
+	kvs = append(kvs, fmt.Sprintf("app_id=%s", appId))
+	kvs = append(kvs, fmt.Sprintf("timestamp=%s", timestamp))
+	kvs = append(kvs, fmt.Sprintf("nonce_str=%s", nonceStr))
+	for key, values := range query {
+		for _, value := range values {
+			kvs = append(kvs, fmt.Sprintf("%s=%s", url.QueryEscape(key), url.QueryEscape(value)))
+		}
+	}
+
+	// sort by alphabetical order
+	sort.Strings(kvs)
+
+	// generate text for signature
+	querystring := fmt.Sprintf("%s&key=%s", strings.Join(kvs, "&"), url.QueryEscape(secretKey))
+
+	// sign it
+	hasher := md5.New()
+	_, err := hasher.Write([]byte(querystring))
+	if err != nil {
+		return ""
+	}
+	return strings.ToUpper(hex.EncodeToString(hasher.Sum(nil)))
 }
 
 /*
-PATCH /plugins/ae/connections/:connectionId
+GET /plugins/ae/test/:connectionId
 */
-func PatchConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
-	v := config.GetConfig()
+func TestConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
 	connection := &models.AeConnection{}
-	err := helper.EncodeStruct(v, connection, "env")
+	err := connectionHelper.First(connection, input.Params)
 	if err != nil {
 		return nil, err
 	}
-	// update from request and save to .env
-	err = helper.DecodeStruct(v, connection, input.Body, "env")
+
+	// load and process cconfiguration
+	endpoint := connection.Endpoint
+	appId := connection.AppId
+	secretKey := connection.SecretKey
+	proxy := connection.Proxy
+
+	apiClient, err := helper.NewApiClient(endpoint, nil, 3*time.Second, proxy, nil)
 	if err != nil {
 		return nil, err
 	}
-	err = config.WriteConfig(v)
+	apiClient.SetBeforeFunction(func(req *http.Request) error {
+		nonceStr := core.RandLetterBytes(8)
+		timestamp := fmt.Sprintf("%v", time.Now().Unix())
+		sign := GetSign(req.URL.Query(), appId, secretKey, nonceStr, timestamp)
+		req.Header.Set("x-ae-app-id", appId)
+		req.Header.Set("x-ae-timestamp", timestamp)
+		req.Header.Set("x-ae-nonce-str", nonceStr)
+		req.Header.Set("x-ae-sign", sign)
+		return nil
+	})
+	res, err := apiClient.Get("projects/", nil, nil)
 	if err != nil {
 		return nil, err
 	}
-	response := models.AeResponse{
-		AeConnection: *connection,
-		Name:         "Ae",
-		ID:           1,
+
+	switch res.StatusCode {
+	case 401: // error secretKey or nonceStr
+		return &core.ApiResourceOutput{Body: false, Status: res.StatusCode}, nil
+	case 404: // right StatusCode

Review Comment:
   This is kind of confusing, can we find another path which exists on API? try `projects` 



##########
plugins/ae/api/connection.go:
##########
@@ -18,88 +18,165 @@ limitations under the License.
 package api
 
 import (
-	"github.com/apache/incubator-devlake/config"
+	"crypto/md5"
+	"encoding/hex"
+	"fmt"
+	"net/http"
+	"net/url"
+	"sort"
+	"strings"
+	"time"
+
 	"github.com/apache/incubator-devlake/plugins/ae/models"
 	"github.com/apache/incubator-devlake/plugins/core"
 	"github.com/apache/incubator-devlake/plugins/helper"
-	"net/http"
+	"github.com/go-playground/validator/v10"
+	"github.com/spf13/viper"
+	"gorm.io/gorm"
 )
 
 type ApiMeResponse struct {
 	Name string `json:"name"`
 }
 
-/*
-GET /plugins/ae/test
-*/
-func TestConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
-	// TODO: implement test connection
-	return &core.ApiResourceOutput{Body: true}, nil
+var connectionHelper *helper.ConnectionApiHelper
+
+func Init(config *viper.Viper, logger core.Logger, database *gorm.DB) {
+	basicRes := helper.NewDefaultBasicRes(config, logger, database)
+	vld := validator.New()
+	connectionHelper = helper.NewConnectionHelper(
+		basicRes,
+		vld,
+	)
+}
+
+func GetSign(query url.Values, appId, secretKey, nonceStr, timestamp string) string {
+	// clone query because we need to add items
+	kvs := make([]string, 0, len(query)+3)
+	kvs = append(kvs, fmt.Sprintf("app_id=%s", appId))
+	kvs = append(kvs, fmt.Sprintf("timestamp=%s", timestamp))
+	kvs = append(kvs, fmt.Sprintf("nonce_str=%s", nonceStr))
+	for key, values := range query {
+		for _, value := range values {
+			kvs = append(kvs, fmt.Sprintf("%s=%s", url.QueryEscape(key), url.QueryEscape(value)))
+		}
+	}
+
+	// sort by alphabetical order
+	sort.Strings(kvs)
+
+	// generate text for signature
+	querystring := fmt.Sprintf("%s&key=%s", strings.Join(kvs, "&"), url.QueryEscape(secretKey))
+
+	// sign it
+	hasher := md5.New()
+	_, err := hasher.Write([]byte(querystring))
+	if err != nil {
+		return ""
+	}
+	return strings.ToUpper(hex.EncodeToString(hasher.Sum(nil)))
 }
 
 /*
-PATCH /plugins/ae/connections/:connectionId
+GET /plugins/ae/test/:connectionId
 */
-func PatchConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
-	v := config.GetConfig()
+func TestConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
 	connection := &models.AeConnection{}
-	err := helper.EncodeStruct(v, connection, "env")
+	err := connectionHelper.First(connection, input.Params)
 	if err != nil {
 		return nil, err
 	}
-	// update from request and save to .env
-	err = helper.DecodeStruct(v, connection, input.Body, "env")
+
+	// load and process cconfiguration
+	endpoint := connection.Endpoint
+	appId := connection.AppId
+	secretKey := connection.SecretKey
+	proxy := connection.Proxy
+
+	apiClient, err := helper.NewApiClient(endpoint, nil, 3*time.Second, proxy, nil)
 	if err != nil {
 		return nil, err
 	}
-	err = config.WriteConfig(v)
+	apiClient.SetBeforeFunction(func(req *http.Request) error {
+		nonceStr := core.RandLetterBytes(8)
+		timestamp := fmt.Sprintf("%v", time.Now().Unix())
+		sign := GetSign(req.URL.Query(), appId, secretKey, nonceStr, timestamp)
+		req.Header.Set("x-ae-app-id", appId)
+		req.Header.Set("x-ae-timestamp", timestamp)
+		req.Header.Set("x-ae-nonce-str", nonceStr)
+		req.Header.Set("x-ae-sign", sign)
+		return nil
+	})
+	res, err := apiClient.Get("projects/", nil, nil)

Review Comment:
   Try remove trailing /, should not be expecting 404



##########
plugins/ae/models/migrationscripts/archived/connection.go:
##########
@@ -0,0 +1,29 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package archived
+
+import "github.com/apache/incubator-devlake/plugins/helper"
+
+type AeConnection struct {
+	helper.RestConnection `mapstructure:",squash"`

Review Comment:
   Do not refer struct outside of migrationscripts, they might be modified in future



##########
plugins/ae/tasks/task_data.go:
##########
@@ -20,8 +20,9 @@ package tasks
 import "github.com/apache/incubator-devlake/plugins/helper"
 
 type AeOptions struct {
-	ProjectId int
-	Tasks     []string `json:"tasks,omitempty"`
+	ConnectionId uint64 `json:"connectionId"`
+	ProjectId    int
+	Tasks        []string `json:"tasks,omitempty"`

Review Comment:
   not needed anymore, please remove this field



##########
plugins/ae/tasks/api_client.go:
##########
@@ -18,85 +18,31 @@ limitations under the License.
 package tasks
 
 import (
-	"crypto/md5"
-	"encoding/hex"
 	"fmt"
-	"math/rand"
 	"net/http"
-	"net/url"
-	"sort"
-	"strings"
 	"time"
 
+	"github.com/apache/incubator-devlake/plugins/ae/api"
+	"github.com/apache/incubator-devlake/plugins/ae/models"
 	"github.com/apache/incubator-devlake/plugins/core"
 	"github.com/apache/incubator-devlake/plugins/helper"
 )
 
-const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
-
-func init() {
-	rand.Seed(time.Now().UnixNano())
-}
-
-func RandString(n int) string {
-	b := make([]byte, n)
-	for i := range b {
-		b[i] = letterBytes[rand.Intn(len(letterBytes))]
-	}
-	return string(b)
-}
-
-func getSign(query url.Values, appId, secretKey, nonceStr, timestamp string) string {
-	// clone query because we need to add items
-	kvs := make([]string, 0, len(query)+3)
-	kvs = append(kvs, fmt.Sprintf("app_id=%s", appId))
-	kvs = append(kvs, fmt.Sprintf("timestamp=%s", timestamp))
-	kvs = append(kvs, fmt.Sprintf("nonce_str=%s", nonceStr))
-	for key, values := range query {
-		for _, value := range values {
-			kvs = append(kvs, fmt.Sprintf("%s=%s", url.QueryEscape(key), url.QueryEscape(value)))
-		}
-	}
-
-	// sort by alphabetical order
-	sort.Strings(kvs)
-
-	// generate text for signature
-	querystring := fmt.Sprintf("%s&key=%s", strings.Join(kvs, "&"), url.QueryEscape(secretKey))
-
-	// sign it
-	hasher := md5.New()
-	_, err := hasher.Write([]byte(querystring))
-	if err != nil {
-		return ""
-	}
-	return strings.ToUpper(hex.EncodeToString(hasher.Sum(nil)))
-}
-
-func CreateApiClient(taskCtx core.TaskContext) (*helper.ApiAsyncClient, error) {
+func CreateApiClient(taskCtx core.TaskContext, connection *models.AeConnection) (*helper.ApiAsyncClient, error) {
 	// load and process cconfiguration
-	endpoint := taskCtx.GetConfig("AE_ENDPOINT")
-	if endpoint == "" {
-		return nil, fmt.Errorf("invalid AE_ENDPOINT")
-	}
-	appId := taskCtx.GetConfig("AE_APP_ID")
-	if appId == "" {
-		return nil, fmt.Errorf("invalid AE_APP_ID")
-	}
-	secretKey := taskCtx.GetConfig("AE_SECRET_KEY")
-	if secretKey == "" {
-		return nil, fmt.Errorf("invalid AE_SECRET_KEY")
-	}
-	proxy := taskCtx.GetConfig("AE_PROXY")
+	endpoint := connection.Endpoint
+	appId := connection.AppId
+	secretKey := connection.SecretKey
+	proxy := connection.Proxy
 
 	apiClient, err := helper.NewApiClient(endpoint, nil, 0, proxy, taskCtx.GetContext())
 	if err != nil {
 		return nil, err
 	}
 	apiClient.SetBeforeFunction(func(req *http.Request) error {
-		nonceStr := RandString(8)
+		nonceStr := core.RandLetterBytes(8)
 		timestamp := fmt.Sprintf("%v", time.Now().Unix())
-		sign := getSign(req.URL.Query(), appId, secretKey, nonceStr, timestamp)
+		sign := api.GetSign(req.URL.Query(), appId, secretKey, nonceStr, timestamp)

Review Comment:
   It makes no sense, for a `tasks` package to use sth from `api` package.
   `api` package should be always sitting on top of everything except `test cases`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@devlake.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-devlake] klesh commented on a diff in pull request #2208: feat: multi-data connections support for ae

Posted by GitBox <gi...@apache.org>.
klesh commented on code in PR #2208:
URL: https://github.com/apache/incubator-devlake/pull/2208#discussion_r899814327


##########
plugins/ae/ae.go:
##########
@@ -82,20 +101,25 @@ func (plugin AE) RootPkgPath() string {
 }
 
 func (plugin AE) MigrationScripts() []migration.Script {
-	return []migration.Script{new(migrationscripts.InitSchemas)}
+	return []migration.Script{
+		new(migrationscripts.InitSchemas),
+		new(migrationscripts.UpdateSchemas20220615),
+	}
 }
 
 func (plugin AE) ApiResources() map[string]map[string]core.ApiResourceHandler {
 	return map[string]map[string]core.ApiResourceHandler{
-		"test": {
+		"test/:connectionId": {

Review Comment:
   No, connections/test is used by config-ui to test if the connection works or not BEFORE saving it. 
   At that point, no :connectionId yet



##########
plugins/ae/api/connection.go:
##########
@@ -18,88 +18,133 @@ limitations under the License.
 package api
 
 import (
-	"github.com/apache/incubator-devlake/config"
+	"fmt"
+	"net/http"
+	"time"
+
 	"github.com/apache/incubator-devlake/plugins/ae/models"
 	"github.com/apache/incubator-devlake/plugins/core"
 	"github.com/apache/incubator-devlake/plugins/helper"
-	"net/http"
+	"github.com/go-playground/validator/v10"
+	"github.com/spf13/viper"
+	"gorm.io/gorm"
 )
 
 type ApiMeResponse struct {
 	Name string `json:"name"`
 }
 
-/*
-GET /plugins/ae/test
-*/
-func TestConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
-	// TODO: implement test connection
-	return &core.ApiResourceOutput{Body: true}, nil
+var connectionHelper *helper.ConnectionApiHelper
+
+func Init(config *viper.Viper, logger core.Logger, database *gorm.DB) {
+	basicRes := helper.NewDefaultBasicRes(config, logger, database)
+	vld := validator.New()
+	connectionHelper = helper.NewConnectionHelper(
+		basicRes,
+		vld,
+	)
 }
 
 /*
-PATCH /plugins/ae/connections/:connectionId
+GET /plugins/ae/test/:connectionId
 */
-func PatchConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
-	v := config.GetConfig()
+func TestConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
 	connection := &models.AeConnection{}
-	err := helper.EncodeStruct(v, connection, "env")
+	err := connectionHelper.First(connection, input.Params)
 	if err != nil {
 		return nil, err
 	}
-	// update from request and save to .env
-	err = helper.DecodeStruct(v, connection, input.Body, "env")
+
+	// load and process cconfiguration
+	endpoint := connection.Endpoint
+	appId := connection.AppId
+	secretKey := connection.SecretKey
+	proxy := connection.Proxy
+
+	apiClient, err := helper.NewApiClient(endpoint, nil, 3*time.Second, proxy, nil)
 	if err != nil {
 		return nil, err
 	}
-	err = config.WriteConfig(v)
+	apiClient.SetBeforeFunction(func(req *http.Request) error {
+		nonceStr := core.RandLetterBytes(8)
+		timestamp := fmt.Sprintf("%v", time.Now().Unix())
+		sign := models.GetSign(req.URL.Query(), appId, secretKey, nonceStr, timestamp)
+		req.Header.Set("x-ae-app-id", appId)
+		req.Header.Set("x-ae-timestamp", timestamp)
+		req.Header.Set("x-ae-nonce-str", nonceStr)
+		req.Header.Set("x-ae-sign", sign)
+		return nil
+	})
+	res, err := apiClient.Get("projects", nil, nil)
 	if err != nil {
 		return nil, err
 	}
-	response := models.AeResponse{
-		AeConnection: *connection,
-		Name:         "Ae",
-		ID:           1,
+
+	switch res.StatusCode {
+	case 200: // right StatusCode
+		return &core.ApiResourceOutput{Body: true, Status: 200}, nil
+	case 401: // error secretKey or nonceStr
+		return &core.ApiResourceOutput{Body: false, Status: res.StatusCode}, nil
+	default: // unknow what happen , back to user
+		return &core.ApiResourceOutput{Body: res.Body, Status: res.StatusCode}, nil
 	}
-	return &core.ApiResourceOutput{Body: response, Status: http.StatusOK}, nil
 }
 
 /*
-GET /plugins/ae/connections
+POST /plugins/ae/connections
 */
-func ListConnections(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
-	// RETURN ONLY 1 SOURCE (FROM ENV) until multi-connection is developed.
-	v := config.GetConfig()
+func PostConnections(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
 	connection := &models.AeConnection{}
-
-	err := helper.EncodeStruct(v, connection, "env")
+	fmt.Printf("%+v\r\n", connectionHelper)

Review Comment:
   Either use logger or remove it .



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@devlake.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-devlake] klesh merged pull request #2208: feat: multi-data connections support for ae

Posted by GitBox <gi...@apache.org>.
klesh merged PR #2208:
URL: https://github.com/apache/incubator-devlake/pull/2208


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@devlake.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org