You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by ab...@apache.org on 2023/02/03 13:52:27 UTC

[incubator-devlake] branch main updated: feat(sonarqube): add hotspots collector&extractor (#4322)

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

abeizn 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 e844f61b7 feat(sonarqube): add hotspots collector&extractor (#4322)
e844f61b7 is described below

commit e844f61b742d756d28283c1249e7cd95dec9250c
Author: Warren Chen <yi...@merico.dev>
AuthorDate: Fri Feb 3 21:52:22 2023 +0800

    feat(sonarqube): add hotspots collector&extractor (#4322)
    
    * feat(sonarqube): add hotspots
    
    * feat(sonarqube): add hotspot
---
 .../template/plugin/api/blueprint.go-template      |  2 +-
 .../template/plugin/api/connection.go-template     |  2 +-
 .../generator/template/plugin/api/init.go-template |  2 +-
 .../template/plugin/plugin_main.go-template        |  2 +-
 .../template/plugin/tasks/api_client.go-template   |  2 +-
 .../plugin/tasks/api_collector.go-template         |  6 +--
 backend/plugins/sonarqube/impl/impl.go             |  2 +
 .../migrationscripts/20230111_add_init_tables.go   |  3 +-
 .../migrationscripts/archived/sonarqube_hotspot.go | 46 ++++++++++++++++++++
 .../migrationscripts/archived/sonarqube_project.go |  1 +
 .../plugins/sonarqube/models/sonarqube_hotspot.go  | 46 ++++++++++++++++++++
 .../plugins/sonarqube/models/sonarqube_project.go  |  1 +
 backend/plugins/sonarqube/sonarqube.go             |  6 +--
 .../sonarqube/tasks/hotspots_collector.go}         | 49 +++++++++++-----------
 ...projects_extractor.go => hotspots_extractor.go} | 18 ++++----
 .../plugins/sonarqube/tasks/projects_extractor.go  |  3 +-
 backend/plugins/sonarqube/tasks/shared.go          |  1 -
 backend/plugins/sonarqube/tasks/task_data.go       |  2 -
 18 files changed, 145 insertions(+), 49 deletions(-)

diff --git a/backend/generator/template/plugin/api/blueprint.go-template b/backend/generator/template/plugin/api/blueprint.go-template
index 054caac4e..11f9ca702 100644
--- a/backend/generator/template/plugin/api/blueprint.go-template
+++ b/backend/generator/template/plugin/api/blueprint.go-template
@@ -20,7 +20,7 @@ package api
 import (
 	"encoding/json"
 	"github.com/apache/incubator-devlake/core/errors"
-	core "github.com/apache/incubator-devlake/core/plugin"
+	"github.com/apache/incubator-devlake/core/plugin"
 	helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 	"github.com/apache/incubator-devlake/plugins/{{ .plugin_name }}/tasks"
 )
diff --git a/backend/generator/template/plugin/api/connection.go-template b/backend/generator/template/plugin/api/connection.go-template
index 8d3b1d3af..3067f57b5 100644
--- a/backend/generator/template/plugin/api/connection.go-template
+++ b/backend/generator/template/plugin/api/connection.go-template
@@ -24,7 +24,7 @@ import (
 	"net/http"
 	"time"
 
-	core "github.com/apache/incubator-devlake/core/plugin"
+	"github.com/apache/incubator-devlake/core/plugin"
 	helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 	"github.com/apache/incubator-devlake/plugins/{{ .plugin_name }}/models"
 )
diff --git a/backend/generator/template/plugin/api/init.go-template b/backend/generator/template/plugin/api/init.go-template
index 982c1d388..a981cea5e 100644
--- a/backend/generator/template/plugin/api/init.go-template
+++ b/backend/generator/template/plugin/api/init.go-template
@@ -18,7 +18,7 @@ limitations under the License.
 package api
 
 import (
-	core "github.com/apache/incubator-devlake/core/plugin"
+	"github.com/apache/incubator-devlake/core/plugin"
 	helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 	"github.com/go-playground/validator/v10"
 )
diff --git a/backend/generator/template/plugin/plugin_main.go-template b/backend/generator/template/plugin/plugin_main.go-template
index 3aeffef7d..f54349eaa 100644
--- a/backend/generator/template/plugin/plugin_main.go-template
+++ b/backend/generator/template/plugin/plugin_main.go-template
@@ -19,7 +19,7 @@ package main
 
 import (
     "github.com/apache/incubator-devlake/core/errors"
-	core "github.com/apache/incubator-devlake/core/plugin"
+	"github.com/apache/incubator-devlake/core/plugin"
 	"github.com/apache/incubator-devlake/core/errors"
 	"github.com/apache/incubator-devlake/plugins/{{ .plugin_name }}/tasks"
 	"github.com/apache/incubator-devlake/runner"
diff --git a/backend/generator/template/plugin/tasks/api_client.go-template b/backend/generator/template/plugin/tasks/api_client.go-template
index 6a0d77ffb..f3344590f 100644
--- a/backend/generator/template/plugin/tasks/api_client.go-template
+++ b/backend/generator/template/plugin/tasks/api_client.go-template
@@ -24,7 +24,7 @@ import (
 	"time"
 
 	"github.com/apache/incubator-devlake/plugins/{{ .plugin_name }}/models"
-	core "github.com/apache/incubator-devlake/core/plugin"
+	"github.com/apache/incubator-devlake/core/plugin"
 	"github.com/apache/incubator-devlake/core/errors"
 	helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 )
diff --git a/backend/generator/template/plugin/tasks/api_collector.go-template b/backend/generator/template/plugin/tasks/api_collector.go-template
index 5526314ea..4199cd8b9 100644
--- a/backend/generator/template/plugin/tasks/api_collector.go-template
+++ b/backend/generator/template/plugin/tasks/api_collector.go-template
@@ -23,16 +23,16 @@ import (
 	"net/url"
 	"strconv"
 
-	core "github.com/apache/incubator-devlake/core/plugin"
+	"github.com/apache/incubator-devlake/core/plugin"
 	"github.com/apache/incubator-devlake/core/errors"
 	helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 )
 
 const RAW_{{ .COLLECTOR_DATA_NAME }}_TABLE = "{{ .plugin_name }}_{{ .collector_data_name }}"
 
-var _ core.SubTaskEntryPoint = Collect{{ .CollectorDataName }}
+var _ plugin.SubTaskEntryPoint = Collect{{ .CollectorDataName }}
 
-func Collect{{ .CollectorDataName }}(taskCtx core.SubTaskContext) errors.Error {
+func Collect{{ .CollectorDataName }}(taskCtx plugin.SubTaskContext) errors.Error {
 	data := taskCtx.GetData().(*{{ .PluginName }}TaskData)
 	rawDataSubTaskArgs, data := CreateRawDataSubTaskArgs(taskCtx, RAW_{{ .COLLECTOR_DATA_NAME }}_TABLE)
 	logger := taskCtx.GetLogger()
diff --git a/backend/plugins/sonarqube/impl/impl.go b/backend/plugins/sonarqube/impl/impl.go
index 50d5d8751..833a8c41f 100644
--- a/backend/plugins/sonarqube/impl/impl.go
+++ b/backend/plugins/sonarqube/impl/impl.go
@@ -54,6 +54,8 @@ func (p Sonarqube) SubTaskMetas() []plugin.SubTaskMeta {
 	return []plugin.SubTaskMeta{
 		tasks.CollectProjectsMeta,
 		tasks.ExtractProjectsMeta,
+		tasks.CollectHotspotsMeta,
+		tasks.ExtractHotspotsMeta,
 	}
 }
 
diff --git a/backend/plugins/sonarqube/models/migrationscripts/20230111_add_init_tables.go b/backend/plugins/sonarqube/models/migrationscripts/20230111_add_init_tables.go
index 3511113e6..13078555c 100644
--- a/backend/plugins/sonarqube/models/migrationscripts/20230111_add_init_tables.go
+++ b/backend/plugins/sonarqube/models/migrationscripts/20230111_add_init_tables.go
@@ -31,11 +31,12 @@ func (*addInitTables) Up(basicRes context.BasicRes) errors.Error {
 		basicRes,
 		&archived.SonarqubeConnection{},
 		&archived.SonarqubeProject{},
+		&archived.SonarqubeHotspot{},
 	)
 }
 
 func (*addInitTables) Version() uint64 {
-	return 20230130000011
+	return 20230203000011
 }
 
 func (*addInitTables) Name() string {
diff --git a/backend/plugins/sonarqube/models/migrationscripts/archived/sonarqube_hotspot.go b/backend/plugins/sonarqube/models/migrationscripts/archived/sonarqube_hotspot.go
new file mode 100644
index 000000000..6217826ee
--- /dev/null
+++ b/backend/plugins/sonarqube/models/migrationscripts/archived/sonarqube_hotspot.go
@@ -0,0 +1,46 @@
+/*
+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/core/models/migrationscripts/archived"
+	"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+)
+
+type SonarqubeHotspot struct {
+	archived.NoPKModel
+	ConnectionId             uint64           `gorm:"primaryKey"`
+	Key                      string           `json:"key" gorm:"primaryKey"`
+	BatchId                  string           `json:"batchId" gorm:"primaryKey"` // from collection time
+	Component                string           `json:"component"`
+	Project                  string           `json:"project" gorm:"index"`
+	SecurityCategory         string           `json:"securityCategory"`
+	VulnerabilityProbability string           `json:"vulnerabilityProbability"`
+	Status                   string           `json:"status"`
+	Line                     int              `json:"line"`
+	Message                  string           `json:"message"`
+	Assignee                 string           `json:"assignee"`
+	Author                   string           `json:"author"`
+	CreationDate             *api.Iso8601Time `json:"creationDate"`
+	UpdateDate               *api.Iso8601Time `json:"updateDate"`
+	RuleKey                  string           `json:"ruleKey"`
+}
+
+func (SonarqubeHotspot) TableName() string {
+	return "_tool_sonarqube_hotspots"
+}
diff --git a/backend/plugins/sonarqube/models/migrationscripts/archived/sonarqube_project.go b/backend/plugins/sonarqube/models/migrationscripts/archived/sonarqube_project.go
index fa2473dd8..ef1754dcb 100644
--- a/backend/plugins/sonarqube/models/migrationscripts/archived/sonarqube_project.go
+++ b/backend/plugins/sonarqube/models/migrationscripts/archived/sonarqube_project.go
@@ -24,6 +24,7 @@ import (
 
 type SonarqubeProject struct {
 	archived.NoPKModel
+	ConnectionId     uint64     `gorm:"primaryKey"`
 	Key              string     `json:"key" gorm:"type:varchar(64);primaryKey"`
 	Name             string     `json:"name" gorm:"type:varchar(255)"`
 	Qualifier        string     `json:"qualifier" gorm:"type:varchar(255)"`
diff --git a/backend/plugins/sonarqube/models/sonarqube_hotspot.go b/backend/plugins/sonarqube/models/sonarqube_hotspot.go
new file mode 100644
index 000000000..03bea2877
--- /dev/null
+++ b/backend/plugins/sonarqube/models/sonarqube_hotspot.go
@@ -0,0 +1,46 @@
+/*
+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 models
+
+import (
+	"github.com/apache/incubator-devlake/core/models/common"
+	"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+)
+
+type SonarqubeHotspot struct {
+	common.NoPKModel
+	ConnectionId             uint64           `gorm:"primaryKey"`
+	Key                      string           `json:"key" gorm:"primaryKey"`
+	BatchId                  string           `json:"batchId" gorm:"primaryKey"` // from collection time
+	Component                string           `json:"component"`
+	Project                  string           `json:"project" gorm:"index"` // projects.key
+	SecurityCategory         string           `json:"securityCategory"`
+	VulnerabilityProbability string           `json:"vulnerabilityProbability"`
+	Status                   string           `json:"status"`
+	Line                     int              `json:"line"`
+	Message                  string           `json:"message"`
+	Assignee                 string           `json:"assignee"`
+	Author                   string           `json:"author"`
+	CreationDate             *api.Iso8601Time `json:"creationDate"`
+	UpdateDate               *api.Iso8601Time `json:"updateDate"`
+	RuleKey                  string           `json:"ruleKey"`
+}
+
+func (SonarqubeHotspot) TableName() string {
+	return "_tool_sonarqube_hotspots"
+}
diff --git a/backend/plugins/sonarqube/models/sonarqube_project.go b/backend/plugins/sonarqube/models/sonarqube_project.go
index d549aca6b..0fdc7f978 100644
--- a/backend/plugins/sonarqube/models/sonarqube_project.go
+++ b/backend/plugins/sonarqube/models/sonarqube_project.go
@@ -24,6 +24,7 @@ import (
 
 type SonarqubeProject struct {
 	common.NoPKModel
+	ConnectionId     uint64           `gorm:"primaryKey"`
 	Key              string           `json:"key" gorm:"type:varchar(64);primaryKey"`
 	Name             string           `json:"name" gorm:"type:varchar(255)"`
 	Qualifier        string           `json:"qualifier" gorm:"type:varchar(255)"`
diff --git a/backend/plugins/sonarqube/sonarqube.go b/backend/plugins/sonarqube/sonarqube.go
index 927398a3c..9fd2222ed 100644
--- a/backend/plugins/sonarqube/sonarqube.go
+++ b/backend/plugins/sonarqube/sonarqube.go
@@ -30,15 +30,15 @@ func main() {
 	cmd := &cobra.Command{Use: "sonarqube"}
 
 	connectionId := cmd.Flags().Uint64P("connectionId", "c", 0, "sonarqube connection id")
-	projectName := cmd.Flags().StringP("projectName", "o", "", "sonarqube projectName")
+	projectKey := cmd.Flags().StringP("projectKey", "p", "", "sonarqube projectKey")
 	createdDateAfter := cmd.Flags().StringP("createdDateAfter", "a", "", "collect data that are created after specified time, ie 2006-05-06T07:08:09Z")
 	_ = cmd.MarkFlagRequired("connectionId")
-	//_ = cmd.MarkFlagRequired("projectName")
+	//_ = cmd.MarkFlagRequired("projectKey")
 
 	cmd.Run = func(cmd *cobra.Command, args []string) {
 		runner.DirectRun(cmd, args, PluginEntry, map[string]interface{}{
 			"connectionId":     *connectionId,
-			"projectName":      *projectName,
+			"projectKey":       *projectKey,
 			"createdDateAfter": *createdDateAfter,
 		})
 	}
diff --git a/backend/generator/template/plugin/tasks/api_collector.go-template b/backend/plugins/sonarqube/tasks/hotspots_collector.go
similarity index 56%
copy from backend/generator/template/plugin/tasks/api_collector.go-template
copy to backend/plugins/sonarqube/tasks/hotspots_collector.go
index 5526314ea..6d733f135 100644
--- a/backend/generator/template/plugin/tasks/api_collector.go-template
+++ b/backend/plugins/sonarqube/tasks/hotspots_collector.go
@@ -19,25 +19,21 @@ package tasks
 
 import (
 	"encoding/json"
-	"net/http"
-	"net/url"
-	"strconv"
-
-	core "github.com/apache/incubator-devlake/core/plugin"
+	"fmt"
 	"github.com/apache/incubator-devlake/core/errors"
+	"github.com/apache/incubator-devlake/core/plugin"
 	helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
+	"net/http"
+	"net/url"
 )
 
-const RAW_{{ .COLLECTOR_DATA_NAME }}_TABLE = "{{ .plugin_name }}_{{ .collector_data_name }}"
-
-var _ core.SubTaskEntryPoint = Collect{{ .CollectorDataName }}
+const RAW_HOTSPOTS_TABLE = "sonarqube_hotspots"
 
-func Collect{{ .CollectorDataName }}(taskCtx core.SubTaskContext) errors.Error {
-	data := taskCtx.GetData().(*{{ .PluginName }}TaskData)
-	rawDataSubTaskArgs, data := CreateRawDataSubTaskArgs(taskCtx, RAW_{{ .COLLECTOR_DATA_NAME }}_TABLE)
-	logger := taskCtx.GetLogger()
+var _ plugin.SubTaskEntryPoint = CollectHotspots
 
-    collectorWithState, err := helper.NewApiCollectorWithState(*rawDataSubTaskArgs, data.CreatedDateAfter)
+func CollectHotspots(taskCtx plugin.SubTaskContext) errors.Error {
+	rawDataSubTaskArgs, data := CreateRawDataSubTaskArgs(taskCtx, RAW_HOTSPOTS_TABLE)
+	collectorWithState, err := helper.NewApiCollectorWithState(*rawDataSubTaskArgs, data.CreatedDateAfter)
 	if err != nil {
 		return err
 	}
@@ -46,19 +42,22 @@ func Collect{{ .CollectorDataName }}(taskCtx core.SubTaskContext) errors.Error {
 	err = collectorWithState.InitCollector(helper.ApiCollectorArgs{
 		Incremental: incremental,
 		ApiClient:   data.ApiClient,
-		// PageSize:    100,
-		// TODO write which api would you want request
-		UrlTemplate: "{{ .HttpPath }}",
+		PageSize:    100,
+		UrlTemplate: "hotspots/search",
 		Query: func(reqData *helper.RequestData) (url.Values, errors.Error) {
 			query := url.Values{}
-			input := reqData.Input.(*helper.DatePair)
-			query.Set("start_time", strconv.FormatInt(input.PairStartTime.Unix(), 10))
-			query.Set("end_time", strconv.FormatInt(input.PairEndTime.Unix(), 10))
+			// no time range
+			query.Set("projectKey", data.Options.ProjectKey)
+			query.Set("p", fmt.Sprintf("%v", reqData.Pager.Page))
+			query.Set("ps", fmt.Sprintf("%v", reqData.Pager.Size))
 			return query, nil
 		},
 		ResponseParser: func(res *http.Response) ([]json.RawMessage, errors.Error) {
-			// TODO decode result from api request
-			return []json.RawMessage{}, nil
+			var resData struct {
+				Data []json.RawMessage `json:"hotspots"`
+			}
+			err = helper.UnmarshalResponse(res, &resData)
+			return resData.Data, err
 		},
 	})
 	if err != nil {
@@ -67,9 +66,9 @@ func Collect{{ .CollectorDataName }}(taskCtx core.SubTaskContext) errors.Error {
 	return collectorWithState.Execute()
 }
 
-var Collect{{ .CollectorDataName }}Meta = plugin.SubTaskMeta{
-	Name:             "Collect{{ .CollectorDataName }}",
-	EntryPoint:       Collect{{ .CollectorDataName }},
+var CollectHotspotsMeta = plugin.SubTaskMeta{
+	Name:             "CollectHotspots",
+	EntryPoint:       CollectHotspots,
 	EnabledByDefault: true,
-	Description:      "Collect {{ .CollectorDataName }} data from {{ .PluginName }} api",
+	Description:      "Collect Hotspots data from Sonarqube api",
 }
diff --git a/backend/plugins/sonarqube/tasks/projects_extractor.go b/backend/plugins/sonarqube/tasks/hotspots_extractor.go
similarity index 78%
copy from backend/plugins/sonarqube/tasks/projects_extractor.go
copy to backend/plugins/sonarqube/tasks/hotspots_extractor.go
index bd94f5007..21dd96353 100644
--- a/backend/plugins/sonarqube/tasks/projects_extractor.go
+++ b/backend/plugins/sonarqube/tasks/hotspots_extractor.go
@@ -25,15 +25,17 @@ import (
 	"github.com/apache/incubator-devlake/plugins/sonarqube/models"
 )
 
-var _ plugin.SubTaskEntryPoint = ExtractProjects
+var _ plugin.SubTaskEntryPoint = ExtractHotspots
+
+func ExtractHotspots(taskCtx plugin.SubTaskContext) errors.Error {
+	rawDataSubTaskArgs, data := CreateRawDataSubTaskArgs(taskCtx, RAW_HOTSPOTS_TABLE)
 
-func ExtractProjects(taskCtx plugin.SubTaskContext) errors.Error {
-	rawDataSubTaskArgs, _ := CreateRawDataSubTaskArgs(taskCtx, RAW_PROJECTS_TABLE)
 	extractor, err := helper.NewApiExtractor(helper.ApiExtractorArgs{
 		RawDataSubTaskArgs: *rawDataSubTaskArgs,
 		Extract: func(resData *helper.RawData) ([]interface{}, errors.Error) {
-			body := &models.SonarqubeProject{}
+			body := &models.SonarqubeHotspot{}
 			err := errors.Convert(json.Unmarshal(resData.Data, body))
+			body.ConnectionId = data.Options.ConnectionId
 			if err != nil {
 				return nil, err
 			}
@@ -47,9 +49,9 @@ func ExtractProjects(taskCtx plugin.SubTaskContext) errors.Error {
 	return extractor.Execute()
 }
 
-var ExtractProjectsMeta = plugin.SubTaskMeta{
-	Name:             "ExtractProjects",
-	EntryPoint:       ExtractProjects,
+var ExtractHotspotsMeta = plugin.SubTaskMeta{
+	Name:             "ExtractHotspots",
+	EntryPoint:       ExtractHotspots,
 	EnabledByDefault: true,
-	Description:      "Extract raw data into tool layer table sonarqube_projects",
+	Description:      "Extract raw data into tool layer table sonarqube_hotspots",
 }
diff --git a/backend/plugins/sonarqube/tasks/projects_extractor.go b/backend/plugins/sonarqube/tasks/projects_extractor.go
index bd94f5007..a07c7d7bf 100644
--- a/backend/plugins/sonarqube/tasks/projects_extractor.go
+++ b/backend/plugins/sonarqube/tasks/projects_extractor.go
@@ -28,12 +28,13 @@ import (
 var _ plugin.SubTaskEntryPoint = ExtractProjects
 
 func ExtractProjects(taskCtx plugin.SubTaskContext) errors.Error {
-	rawDataSubTaskArgs, _ := CreateRawDataSubTaskArgs(taskCtx, RAW_PROJECTS_TABLE)
+	rawDataSubTaskArgs, data := CreateRawDataSubTaskArgs(taskCtx, RAW_PROJECTS_TABLE)
 	extractor, err := helper.NewApiExtractor(helper.ApiExtractorArgs{
 		RawDataSubTaskArgs: *rawDataSubTaskArgs,
 		Extract: func(resData *helper.RawData) ([]interface{}, errors.Error) {
 			body := &models.SonarqubeProject{}
 			err := errors.Convert(json.Unmarshal(resData.Data, body))
+			body.ConnectionId = data.Options.ConnectionId
 			if err != nil {
 				return nil, err
 			}
diff --git a/backend/plugins/sonarqube/tasks/shared.go b/backend/plugins/sonarqube/tasks/shared.go
index 316ef36c7..f0c4746cf 100644
--- a/backend/plugins/sonarqube/tasks/shared.go
+++ b/backend/plugins/sonarqube/tasks/shared.go
@@ -32,7 +32,6 @@ func CreateRawDataSubTaskArgs(taskCtx plugin.SubTaskContext, rawTable string) (*
 	var params = SonarqubeApiParams{
 		ConnectionId: data.Options.ConnectionId,
 		ProjectKey:   data.Options.ProjectKey,
-		HotspotKey:   data.Options.HotspotKey,
 	}
 	rawDataSubTaskArgs := &api.RawDataSubTaskArgs{
 		Ctx:    taskCtx,
diff --git a/backend/plugins/sonarqube/tasks/task_data.go b/backend/plugins/sonarqube/tasks/task_data.go
index c409340e7..9b1b70f5e 100644
--- a/backend/plugins/sonarqube/tasks/task_data.go
+++ b/backend/plugins/sonarqube/tasks/task_data.go
@@ -26,7 +26,6 @@ import (
 type SonarqubeApiParams struct {
 	ConnectionId uint64 `json:"connectionId"`
 	ProjectKey   string
-	HotspotKey   string
 }
 
 type SonarqubeOptions struct {
@@ -35,7 +34,6 @@ type SonarqubeOptions struct {
 	// You can use it in subtasks, and you need to pass it to main.go and pipelines.
 	ConnectionId     uint64   `json:"connectionId"`
 	ProjectKey       string   `json:"projectKey"`
-	HotspotKey       string   `json:"hotspotKey"`
 	CreatedDateAfter string   `json:"createdDateAfter" mapstructure:"createdDateAfter,omitempty"`
 	Tasks            []string `json:"tasks,omitempty"`
 }