Skip to content

Commit

Permalink
feat(amazonq): add job ID to Transformation Hub #6154
Browse files Browse the repository at this point in the history
## Problem
Users find it difficult to locate the job ID in the "job history" tab of
the Transformation Hub.

## Solution
Put the job ID in the main tab of the Transformation Hub as soon as it's
available. Also, delete some unused / unneeded functionality.
  • Loading branch information
dhasani23 authored Dec 5, 2024
1 parent ffd94b4 commit 3a39b10
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 90 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Feature",
"description": "Amazon Q Code Transformation: show job ID in Transformation Hub"
}
5 changes: 2 additions & 3 deletions packages/core/src/amazonqGumby/activation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { transformByQState } from '../codewhisperer/models/model'
import { ProposedTransformationExplorer } from '../codewhisperer/service/transformByQ/transformationResultsViewProvider'
import { CodeTransformTelemetryState } from './telemetry/codeTransformTelemetryState'
import { telemetry } from '../shared/telemetry/telemetry'
import { CancelActionPositions } from './telemetry/codeTransformTelemetry'
import { setContext } from '../shared'

export async function activate(context: ExtContext) {
Expand Down Expand Up @@ -50,9 +49,9 @@ export async function activate(context: ExtContext) {
context.extensionContext.subscriptions.push(
vscode.window.registerWebviewViewProvider('aws.amazonq.transformationHub', transformationHubViewProvider),

Commands.register('aws.amazonq.stopTransformationInHub', async (cancelSrc: CancelActionPositions) => {
Commands.register('aws.amazonq.stopTransformationInHub', async () => {
if (transformByQState.isRunning()) {
await stopTransformByQ(transformByQState.getJobId(), cancelSrc)
await stopTransformByQ(transformByQState.getJobId())
await postTransformationJob()
await cleanupTransformationJob()
}
Expand Down
6 changes: 1 addition & 5 deletions packages/core/src/amazonqGumby/chat/controller/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ export class GumbyController {
this.messenger.sendJobSubmittedMessage(message.tabID)
break
case ButtonActions.STOP_TRANSFORMATION_JOB:
await stopTransformByQ(transformByQState.getJobId(), CancelActionPositions.Chat)
await stopTransformByQ(transformByQState.getJobId())
await postTransformationJob()
await cleanupTransformationJob()
break
Expand Down Expand Up @@ -466,10 +466,6 @@ export class GumbyController {
message.tabID
)

if (fromJDKVersion === JDKVersion.UNSUPPORTED) {
this.messenger.sendUnrecoverableErrorResponse('unsupported-source-jdk-version', message.tabID)
return
}
await processLanguageUpgradeTransformFormInput(pathToProject, fromJDKVersion, toJDKVersion)
await this.messenger.sendSkipTestsPrompt(message.tabID)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export type UnrecoverableErrorType =
| 'no-maven-java-project-found'
| 'could-not-compile-project'
| 'invalid-java-home'
| 'unsupported-source-jdk-version'
| 'upload-to-s3-failed'
| 'job-start-failed'
| 'unsupported-source-db'
Expand Down Expand Up @@ -234,10 +233,6 @@ export class Messenger {
value: JDKVersion.JDK17,
label: JDKVersion.JDK17,
},
{
value: JDKVersion.UNSUPPORTED,
label: 'Other',
},
],
})

Expand Down Expand Up @@ -473,9 +468,6 @@ export class Messenger {
case 'invalid-java-home':
message = CodeWhispererConstants.noJavaHomeFoundChatMessage
break
case 'unsupported-source-jdk-version':
message = CodeWhispererConstants.unsupportedJavaVersionChatMessage
break
case 'unsupported-source-db':
message = CodeWhispererConstants.invalidMetadataFileUnsupportedSourceDB
break
Expand Down
96 changes: 46 additions & 50 deletions packages/core/src/codewhisperer/commands/startTransformByQ.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ import {
prepareProjectDependencies,
runMavenDependencyUpdateCommands,
} from '../service/transformByQ/transformMavenHandler'
import { CodeTransformCancelSrcComponents, telemetry } from '../../shared/telemetry/telemetry'
import { telemetry } from '../../shared/telemetry/telemetry'
import { CodeTransformTelemetryState } from '../../amazonqGumby/telemetry/codeTransformTelemetryState'
import { CancelActionPositions, calculateTotalLatency } from '../../amazonqGumby/telemetry/codeTransformTelemetry'
import { calculateTotalLatency } from '../../amazonqGumby/telemetry/codeTransformTelemetry'
import { MetadataResult } from '../../shared/telemetry/telemetryClient'
import { submitFeedback } from '../../feedback/vue/submitFeedback'
import { placeholder } from '../../shared/vscode/commands2'
Expand Down Expand Up @@ -919,55 +919,51 @@ export async function cleanupTransformationJob() {
CodeTransformTelemetryState.instance.resetCodeTransformMetaDataField()
}

export async function stopTransformByQ(
jobId: string,
cancelSrc: CancelActionPositions = CancelActionPositions.BottomHubPanel
) {
if (transformByQState.isRunning()) {
getLogger().info('CodeTransformation: User requested to stop transformation. Stopping transformation.')
transformByQState.setToCancelled()
transformByQState.setPolledJobStatus('CANCELLED')
await setContext('gumby.isStopButtonAvailable', false)
try {
await stopJob(jobId)
void vscode.window
.showErrorMessage(
CodeWhispererConstants.jobCancelledNotification,
CodeWhispererConstants.amazonQFeedbackText
)
.then((choice) => {
if (choice === CodeWhispererConstants.amazonQFeedbackText) {
void submitFeedback(
placeholder,
CodeWhispererConstants.amazonQFeedbackKey,
getFeedbackCommentData()
)
}
})
} catch (err) {
void vscode.window
.showErrorMessage(
CodeWhispererConstants.errorStoppingJobNotification,
CodeWhispererConstants.amazonQFeedbackText
)
.then((choice) => {
if (choice === CodeWhispererConstants.amazonQFeedbackText) {
void submitFeedback(
placeholder,
CodeWhispererConstants.amazonQFeedbackKey,
getFeedbackCommentData()
)
}
})
getLogger().error(`CodeTransformation: Error stopping transformation ${err}`)
} finally {
telemetry.codeTransform_jobIsCancelledByUser.emit({
codeTransformCancelSrcComponents: cancelSrc as CodeTransformCancelSrcComponents,
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(),
result: MetadataResult.Pass,
})
export async function stopTransformByQ(jobId: string) {
await telemetry.codeTransform_jobIsCancelledByUser.run(async () => {
telemetry.record({
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(),
})
if (transformByQState.isRunning()) {
getLogger().info('CodeTransformation: User requested to stop transformation. Stopping transformation.')
transformByQState.setToCancelled()
transformByQState.setPolledJobStatus('CANCELLED')
await setContext('gumby.isStopButtonAvailable', false)
try {
await stopJob(jobId)
void vscode.window
.showErrorMessage(
CodeWhispererConstants.jobCancelledNotification,
CodeWhispererConstants.amazonQFeedbackText
)
.then((choice) => {
if (choice === CodeWhispererConstants.amazonQFeedbackText) {
void submitFeedback(
placeholder,
CodeWhispererConstants.amazonQFeedbackKey,
getFeedbackCommentData()
)
}
})
} catch (err) {
void vscode.window
.showErrorMessage(
CodeWhispererConstants.errorStoppingJobNotification,
CodeWhispererConstants.amazonQFeedbackText
)
.then((choice) => {
if (choice === CodeWhispererConstants.amazonQFeedbackText) {
void submitFeedback(
placeholder,
CodeWhispererConstants.amazonQFeedbackKey,
getFeedbackCommentData()
)
}
})
getLogger().error(`CodeTransformation: Error stopping transformation ${err}`)
}
}
}
})
}

async function setContextVariables() {
Expand Down
20 changes: 1 addition & 19 deletions packages/core/src/codewhisperer/models/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,8 +417,6 @@ export const maxBufferSize = 1024 * 1024 * 8 // this is 8MB; the default max buf

export const transformationJobPollingIntervalSeconds = 5

export const transformationJobTimeoutSeconds = 3 * 60 * 60 // 3 hours, to match backend

export const defaultLanguage = 'Java'

export const contentChecksumType = 'SHA_256'
Expand Down Expand Up @@ -578,8 +576,6 @@ export const buildSucceededNotification =
export const absolutePathDetectedMessage = (numPaths: number, buildFile: string, listOfPaths: string) =>
`I detected ${numPaths} potential absolute file path(s) in your ${buildFile} file: **${listOfPaths}**. Absolute file paths might cause issues when I build your code. Any errors will show up in the build log.`

export const unsupportedJavaVersionChatMessage = `I can only upgrade Java 8, Java 11, or Java 17 projects. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`

export const selectSQLMetadataFileHelpMessage =
'Okay, I can convert the embedded SQL code for your Oracle to PostgreSQL transformation. To get started, upload the zipped metadata file from your schema conversion in AWS Data Migration Service (DMS). To retrieve the metadata file:\n1. Open your database migration project in the AWS DMS console.\n2. Open the schema conversion and choose **Convert the embedded SQL in your application**.\n3. Choose the link to Amazon S3 console.\n\nYou can download the metadata file from the {schema-conversion-project}/ directory. For more info, refer to the [documentation](https://docs.aws.amazon.com/dms/latest/userguide/schema-conversion-save-apply.html#schema-conversion-save).'

Expand Down Expand Up @@ -610,18 +606,6 @@ export const failedToStartJobTooManyJobsChatMessage =
export const failedToStartJobTooManyJobsNotification =
'Amazon Q could not begin the transformation. You have too many active transformations running. Please try again after your other transformations have completed.'

export const failedToStartJobMonthlyLimitNotification =
'Amazon Q cannot transform your project because it will exceed the free tier limit of 2000 lines of code per month. Try transforming a smaller project.'

export const failedToStartJobMonthlyLimitChatMessage =
'I am sorry, I cannot transform your project because it will exceed the free tier limit of 2000 lines of code per month. You can try again with a smaller project.'

export const failedToStartJobLinesLimitNotification =
'Your project exceeds the free tier limit of 1000 lines of code per transformation. Try transforming a smaller project.'

export const failedToStartJobLinesLimitChatMessage =
'I am sorry, your project exceeds the free tier limit of 1000 lines of code per transformation. You can try again with a smaller project.'

export const failedToUploadProjectChatMessage =
"Sorry, I couldn't upload your project. Please try starting the transformation again."

Expand Down Expand Up @@ -674,9 +658,7 @@ export const jobPartiallyCompletedNotification = (multipleDiffsString: string) =
return `Amazon Q transformed part of your code. ${multipleDiffsString} The transformation summary has details about the files I updated and the errors that prevented a complete transformation.`
}

export const noPomXmlFoundChatMessage = `I couldn\'t find a project that I can upgrade. I couldn\'t find a pom.xml file in any of your open projects, nor could I find any embedded SQL statements. Currently, I can upgrade Java 8 or Java 11 projects built on Maven, or Oracle SQL to PostgreSQL statements in Java projects. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`

export const noPomXmlFoundNotification = `None of your open modules are supported for code transformation with Amazon Q. A pom.xml is required for transformation.`
export const noPomXmlFoundChatMessage = `I couldn\'t find a project that I can upgrade. I couldn\'t find a pom.xml file in any of your open projects, nor could I find any embedded SQL statements. Currently, I can upgrade Java 8, 11, or 17 projects built on Maven, or Oracle SQL to PostgreSQL statements in Java projects. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`

export const noJavaHomeFoundChatMessage = `Sorry, I couldn\'t locate your Java installation. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,6 @@ export async function getTransformationSteps(jobId: string, handleThrottleFlag:

export async function pollTransformationJob(jobId: string, validStates: string[]) {
let status: string = ''
let timer: number = 0
while (true) {
throwIfCancelled()
try {
Expand Down Expand Up @@ -680,10 +679,6 @@ export async function pollTransformationJob(jobId: string, validStates: string[]
throw new JobStoppedError(response.$response.requestId)
}
await sleep(CodeWhispererConstants.transformationJobPollingIntervalSeconds * 1000)
timer += CodeWhispererConstants.transformationJobPollingIntervalSeconds
if (timer > CodeWhispererConstants.transformationJobTimeoutSeconds) {
throw new Error('Job timed out')
}
} catch (e: any) {
let errorMessage = (e as Error).message
errorMessage += ` -- ${transformByQState.getJobFailureMetadata()}`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,11 @@ export class TransformationHubViewProvider implements vscode.WebviewViewProvider
const isTransformFailed = jobPlanProgress['transformCode'] === StepProgress.Failed
const progress = this.getTransformationStepProgressMarkup(planSteps, isTransformFailed)
const latestGenericStepDetails = this.getLatestGenericStepDetails(transformByQState.getPolledJobStatus())
const jobId = transformByQState.getJobId()
progressHtml = `
<div id="progress" class="column">
<p><b>Transformation Progress</b> <span id="runningTime"></span></p>
<p>${jobId ? `Job ID: ${jobId}` : ''}</p>
${waitingMarkup}
${buildMarkup}
${planMarkup}
Expand Down

0 comments on commit 3a39b10

Please sign in to comment.