@@ -8,6 +8,7 @@ import com.intellij.openapi.components.service
8
8
import com.intellij.openapi.project.Project
9
9
import com.intellij.util.io.HttpRequests
10
10
import org.apache.commons.codec.digest.DigestUtils
11
+ import software.amazon.awssdk.awscore.exception.AwsServiceException
11
12
import software.amazon.awssdk.services.codewhispererruntime.model.CodeAnalysisUploadContext
12
13
import software.amazon.awssdk.services.codewhispererruntime.model.CodeFixUploadContext
13
14
import software.amazon.awssdk.services.codewhispererruntime.model.CreateUploadUrlRequest
@@ -21,6 +22,7 @@ import software.aws.toolkits.core.utils.debug
21
22
import software.aws.toolkits.core.utils.getLogger
22
23
import software.aws.toolkits.jetbrains.core.AwsClientManager
23
24
import software.aws.toolkits.jetbrains.services.amazonq.RetryableOperation
25
+ import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhispererCodeScanServerException
24
26
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhispererCodeScanSession.Companion.APPLICATION_ZIP
25
27
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhispererCodeScanSession.Companion.AWS_KMS
26
28
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhispererCodeScanSession.Companion.CONTENT_MD5
@@ -32,7 +34,11 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.codeScanS
32
34
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.invalidSourceZipError
33
35
import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.CodeTestException
34
36
import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor
37
+ import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.getStartUrl
35
38
import software.aws.toolkits.resources.message
39
+ import software.aws.toolkits.telemetry.AmazonqTelemetry
40
+ import software.aws.toolkits.telemetry.AmazonqUploadIntent
41
+ import software.aws.toolkits.telemetry.MetricResult
36
42
import java.io.File
37
43
import java.io.FileInputStream
38
44
import java.io.IOException
@@ -50,29 +56,67 @@ class CodeWhispererZipUploadManager(private val project: Project) {
50
56
taskName : String ,
51
57
featureUseCase : CodeWhispererConstants .FeatureName ,
52
58
): CreateUploadUrlResponse {
53
- // Throw error if zipFile is invalid.
54
- if (! zipFile.exists()) {
55
- when (featureUseCase) {
56
- CodeWhispererConstants .FeatureName .CODE_REVIEW -> invalidSourceZipError()
57
- CodeWhispererConstants .FeatureName .TEST_GENERATION -> testGenerationInvalidSourceZipError()
58
- else -> throw IllegalArgumentException (" Unsupported feature case: $featureUseCase " ) // Adding else for safety check
59
+ val startTime = System .currentTimeMillis()
60
+ var result: MetricResult = MetricResult .Succeeded
61
+ var failureReason: String? = null
62
+ var failureReasonDesc: String? = null
63
+ var requestId: String? = null
64
+ var requestServiceType: String? = null
65
+ var httpStatusCode: String? = null
66
+ try {
67
+ // Throw error if zipFile is invalid.
68
+ if (! zipFile.exists()) {
69
+ when (featureUseCase) {
70
+ CodeWhispererConstants .FeatureName .CODE_REVIEW -> invalidSourceZipError()
71
+ CodeWhispererConstants .FeatureName .TEST_GENERATION -> testGenerationInvalidSourceZipError()
72
+ else -> throw IllegalArgumentException (" Unsupported feature case: $featureUseCase " ) // Adding else for safety check
73
+ }
59
74
}
60
- }
61
- val fileMd5: String = Base64 .getEncoder().encodeToString(DigestUtils .md5(FileInputStream (zipFile)))
62
- val createUploadUrlResponse = createUploadUrl(fileMd5, artifactType, taskType, taskName, featureUseCase)
63
- val url = createUploadUrlResponse.uploadUrl()
64
- LOG .debug { " $featureUseCase : Uploading $artifactType using the presigned URL." }
75
+ val fileMd5: String = Base64 .getEncoder().encodeToString(DigestUtils .md5(FileInputStream (zipFile)))
76
+ val createUploadUrlResponse = createUploadUrl(fileMd5, artifactType, taskType, taskName, featureUseCase)
77
+ val url = createUploadUrlResponse.uploadUrl()
78
+ LOG .debug { " $featureUseCase : Uploading $artifactType using the presigned URL." }
65
79
66
- uploadArtifactToS3(
67
- url,
68
- createUploadUrlResponse.uploadId(),
69
- zipFile,
70
- fileMd5,
71
- createUploadUrlResponse.kmsKeyArn(),
72
- createUploadUrlResponse.requestHeaders(),
73
- featureUseCase
74
- )
75
- return createUploadUrlResponse
80
+ uploadArtifactToS3(
81
+ url,
82
+ createUploadUrlResponse.uploadId(),
83
+ zipFile,
84
+ fileMd5,
85
+ createUploadUrlResponse.kmsKeyArn(),
86
+ createUploadUrlResponse.requestHeaders(),
87
+ featureUseCase
88
+ )
89
+ return createUploadUrlResponse
90
+ } catch (e: Exception ) {
91
+ result = MetricResult .Failed
92
+ failureReason = e.javaClass.simpleName
93
+ failureReasonDesc = e.message
94
+ if (e is CodeWhispererCodeScanServerException ) {
95
+ requestId = e.requestId
96
+ requestServiceType = e.requestServiceType
97
+ httpStatusCode = e.httpStatusCode
98
+ }
99
+ throw e
100
+ } finally {
101
+ if (featureUseCase == CodeWhispererConstants .FeatureName .CODE_REVIEW ) {
102
+ AmazonqTelemetry .createUpload(
103
+ amazonqConversationId = " " ,
104
+ amazonqUploadIntent = if (taskType == CodeWhispererConstants .UploadTaskType .SCAN_PROJECT ) {
105
+ AmazonqUploadIntent .FULLPROJECTSECURITYSCAN
106
+ } else {
107
+ AmazonqUploadIntent .AUTOMATICFILESECURITYSCAN
108
+ },
109
+ result = result,
110
+ reason = failureReason,
111
+ reasonDesc = failureReasonDesc,
112
+ duration = (System .currentTimeMillis() - startTime).toDouble(),
113
+ credentialStartUrl = getStartUrl(project),
114
+ requestId = requestId,
115
+ requestServiceType = requestServiceType,
116
+ httpStatusCode = httpStatusCode
117
+ )
118
+ }
119
+ }
76
120
}
77
121
78
122
@Throws(IOException ::class )
@@ -85,6 +129,7 @@ class CodeWhispererZipUploadManager(private val project: Project) {
85
129
requestHeaders : Map <String , String >? ,
86
130
featureUseCase : CodeWhispererConstants .FeatureName ,
87
131
) {
132
+ var connection: HttpURLConnection ? = null
88
133
RetryableOperation <Unit >().execute(
89
134
operation = {
90
135
val uploadIdJson = """ {"uploadId":"$uploadId "}"""
@@ -103,9 +148,9 @@ class CodeWhispererZipUploadManager(private val project: Project) {
103
148
}
104
149
}
105
150
}.connect {
106
- val connection = it.connection as HttpURLConnection
107
- connection.setFixedLengthStreamingMode(fileToUpload.length())
108
- IoUtils .copy(fileToUpload.inputStream(), connection.outputStream)
151
+ connection = it.connection as HttpURLConnection
152
+ connection? .setFixedLengthStreamingMode(fileToUpload.length())
153
+ IoUtils .copy(fileToUpload.inputStream(), connection? .outputStream)
109
154
}
110
155
},
111
156
isRetryable = { e ->
@@ -118,7 +163,12 @@ class CodeWhispererZipUploadManager(private val project: Project) {
118
163
val errorMessage = getTelemetryErrorMessage(e, featureUseCase)
119
164
when (featureUseCase) {
120
165
CodeWhispererConstants .FeatureName .CODE_REVIEW ->
121
- codeScanServerException(" CreateUploadUrlException: $errorMessage " )
166
+ codeScanServerException(
167
+ " CreateUploadUrlException: $errorMessage " ,
168
+ connection?.getHeaderField(" x-amz-request-id" ),
169
+ " s3" ,
170
+ (e as ? HttpRequests .HttpStatusException )?.statusCode.toString()
171
+ )
122
172
CodeWhispererConstants .FeatureName .TEST_GENERATION ->
123
173
throw CodeTestException (
124
174
" UploadTestArtifactToS3Error: $errorMessage " ,
@@ -162,7 +212,11 @@ class CodeWhispererZipUploadManager(private val project: Project) {
162
212
val errorMessage = getTelemetryErrorMessage(e, featureUseCase)
163
213
when (featureUseCase) {
164
214
CodeWhispererConstants .FeatureName .CODE_REVIEW ->
165
- codeScanServerException(" CreateUploadUrlException after $attempts attempts: $errorMessage " )
215
+ codeScanServerException(
216
+ " CreateUploadUrlException after $attempts attempts: $errorMessage " ,
217
+ requestId = (e as ? AwsServiceException )?.requestId(),
218
+ httpStatusCode = (e as ? AwsServiceException )?.statusCode().toString()
219
+ )
166
220
167
221
CodeWhispererConstants .FeatureName .TEST_GENERATION ->
168
222
throw CodeTestException (
0 commit comments