Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(amazonq): java21 support #6414

Merged
merged 6 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Feature",
"description": "/transform: support Java 21 transformations"
}
36 changes: 36 additions & 0 deletions packages/amazonq/test/e2e/amazonq/transformByQ.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,42 @@ describe('Amazon Q Code Transformation', function () {
assert.strictEqual(viewSummaryChatItem?.body?.includes('view a summary'), true)
})

it('CANNOT do a Java 21 to Java 17 transformation', async () => {
sinon.stub(startTransformByQ, 'getValidSQLConversionCandidateProjects').resolves([])
sinon.stub(GumbyController.prototype, 'validateLanguageUpgradeProjects' as keyof GumbyController).resolves([
{
name: 'qct-sample-java-8-app-main',
path: '/Users/alias/Desktop/qct-sample-java-8-app-main',
JDKVersion: JDKVersion.JDK21,
},
])
tab.addChatMessage({ command: '/transform' })
await tab.waitForEvent(() => tab.getChatItems().length > 3, {
waitTimeoutInMs: 5000,
waitIntervalInMs: 1000,
})
const projectForm = tab.getChatItems().pop()
assert.strictEqual(projectForm?.formItems?.[0]?.id ?? undefined, 'GumbyTransformLanguageUpgradeProjectForm')

const projectFormItemValues = {
GumbyTransformLanguageUpgradeProjectForm: '/Users/alias/Desktop/qct-sample-java-8-app-main',
GumbyTransformJdkFromForm: '21',
GumbyTransformJdkToForm: '17',
}
const projectFormValues: Record<string, string> = { ...projectFormItemValues }
tab.clickCustomFormButton({
id: 'gumbyLanguageUpgradeTransformFormConfirm',
text: 'Confirm',
formItemValues: projectFormValues,
})
await tab.waitForEvent(() => tab.getChatItems().length > 4, {
waitTimeoutInMs: 5000,
waitIntervalInMs: 1000,
})
const errorMessage = tab.getChatItems().pop()
assert.strictEqual(errorMessage?.body, CodeWhispererConstants.invalidFromToJdkChatMessage)
})

it('Can provide metadata file for a SQL conversion', async () => {
sinon.stub(startTransformByQ, 'getValidSQLConversionCandidateProjects').resolves([
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,12 @@ export class GumbyController {
message.tabID
)

// do not allow downgrades (only this combination can be selected in the UI)
if (fromJDKVersion === JDKVersion.JDK21 && toJDKVersion === JDKVersion.JDK17) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why block this but allow other downgrades? e.g. 21 -> 11

Copy link
Contributor Author

@dhasani23 dhasani23 Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only this one is possible

The source Java versions we show in dropdown form are: 8, 11, 17, 21
The target Java versions we show in dropdown form are: 17, 21

So the only downgrade possible for user to select is 21 -> 17

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in other words you don't allow downgrades. This is a confusing if statement if that is the original intent, can we maybe check that source version is not >= target version? Or a comment at the very least.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comment

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added another comment to make it more specific but after that LGTM

this.messenger.sendUnrecoverableErrorResponse('invalid-from-to-jdk', 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 @@ -51,6 +51,7 @@ export type UnrecoverableErrorType =
| 'unsupported-target-db'
| 'error-parsing-sct-file'
| 'invalid-zip-no-sct-file'
| 'invalid-from-to-jdk'

export enum GumbyNamedMessages {
COMPILATION_PROGRESS_MESSAGE = 'gumbyProjectCompilationMessage',
Expand Down Expand Up @@ -176,7 +177,9 @@ export class Messenger {
this.dispatcher.sendAsyncEventProgress(
new AsyncEventProgressMessage(tabID, {
inProgress: true,
message: CodeWhispererConstants.userPatchDescriptionChatMessage,
message: CodeWhispererConstants.userPatchDescriptionChatMessage(
transformByQState.getTargetJDKVersion() ?? ''
),
})
)

Expand Down Expand Up @@ -233,6 +236,10 @@ export class Messenger {
value: JDKVersion.JDK17,
label: JDKVersion.JDK17,
},
{
value: JDKVersion.JDK21,
label: JDKVersion.JDK21,
},
],
})

Expand All @@ -246,6 +253,10 @@ export class Messenger {
value: JDKVersion.JDK17,
label: JDKVersion.JDK17,
},
{
value: JDKVersion.JDK21,
label: JDKVersion.JDK21,
},
],
})

Expand Down Expand Up @@ -481,6 +492,9 @@ export class Messenger {
case 'invalid-zip-no-sct-file':
message = CodeWhispererConstants.invalidMetadataFileNoSctFile
break
case 'invalid-from-to-jdk':
message = CodeWhispererConstants.invalidFromToJdkChatMessage
break
}

this.sendJobFinishedMessage(tabID, message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export default class MessengerUtils {
javaHomePrompt += ` ${CodeWhispererConstants.macJavaVersionHomeHelpChatMessage(11)}`
} else if (jdkVersion === JDKVersion.JDK17) {
javaHomePrompt += ` ${CodeWhispererConstants.macJavaVersionHomeHelpChatMessage(17)}`
} else if (jdkVersion === JDKVersion.JDK21) {
javaHomePrompt += ` ${CodeWhispererConstants.macJavaVersionHomeHelpChatMessage(21)}`
}
} else {
javaHomePrompt += ` ${CodeWhispererConstants.linuxJavaHomeHelpChatMessage}`
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/codewhisperer/client/user-service-2.json
Original file line number Diff line number Diff line change
Expand Up @@ -2606,7 +2606,7 @@
},
"TransformationJavaRuntimeEnv": {
"type": "string",
"enum": ["JVM_8", "JVM_11", "JVM_17"]
"enum": ["JVM_8", "JVM_11", "JVM_17", "JVM_21"]
},
"TransformationJob": {
"type": "structure",
Expand All @@ -2629,7 +2629,7 @@
},
"TransformationLanguage": {
"type": "string",
"enum": ["JAVA_8", "JAVA_11", "JAVA_17", "C_SHARP", "COBOL", "PL_I", "JCL"]
"enum": ["JAVA_8", "JAVA_11", "JAVA_17", "JAVA_21", "C_SHARP", "COBOL", "PL_I", "JCL"]
},
"TransformationLanguages": {
"type": "list",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ async function validateJavaHome(): Promise<boolean> {
javaVersionUsedByMaven = JDKVersion.JDK11
} else if (javaVersionUsedByMaven === '17.') {
javaVersionUsedByMaven = JDKVersion.JDK17
} else if (javaVersionUsedByMaven === '21.') {
javaVersionUsedByMaven = JDKVersion.JDK21
}
}
if (javaVersionUsedByMaven !== transformByQState.getSourceJDKVersion()) {
Expand Down
19 changes: 12 additions & 7 deletions packages/core/src/codewhisperer/models/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export const AWSTemplateCaseInsensitiveKeyWords = ['cloudformation', 'cfn', 'tem

const patchDescriptions: { [key: string]: string } = {
'Prepare minimal upgrade to Java 17':
'This diff patch covers the set of upgrades for Springboot, JUnit, and PowerMockito frameworks.',
'This diff patch covers the set of upgrades for Springboot, JUnit, and PowerMockito frameworks in Java 17.',
'Prepare minimal upgrade to Java 21':
'This diff patch covers the set of upgrades for Springboot, JUnit, and PowerMockito frameworks in Java 21.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked at the closures for java 21 (I can look), but assuming they make the same corresponding upgrades as the first patch for java 17

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes will confirm, but that should be true

'Popular Enterprise Specifications and Application Frameworks upgrade':
'This diff patch covers the set of upgrades for Jakarta EE 10, Hibernate 6.2, and Micronaut 3.',
'HTTP Client Utilities, Apache Commons Utilities, and Web Frameworks':
Expand Down Expand Up @@ -505,14 +507,14 @@ export const codeTransformLocThreshold = 100000
export const jobStartedChatMessage =
'I am starting to transform your code. It can take 10 to 30 minutes to upgrade your code, depending on the size of your project. To monitor progress, go to the Transformation Hub. If I run into any issues, I might pause the transformation to get input from you on how to proceed.'

export const chooseTransformationObjective = `I can help you with the following tasks:\n- Upgrade your Java 8 and Java 11 codebases to Java 17, or upgrade Java 17 code with up to date libraries and other dependencies.\n- Convert embedded SQL code for Oracle to PostgreSQL database migrations in AWS DMS. [Learn more](https://docs.aws.amazon.com/dms/latest/userguide/schema-conversion-embedded-sql.html).\n\nWhat would you like to do? You can enter "language upgrade" or "sql conversion".`
export const chooseTransformationObjective = `I can help you with the following tasks:\n- Upgrade your Java 8, Java 11, and Java 17 codebases to Java 17 or Java 21.\n- Upgrade Java 17 or Java 21 code with up-to-date libraries and other dependencies.\n- Convert embedded SQL code for Oracle to PostgreSQL database migrations in AWS DMS. [Learn more](https://docs.aws.amazon.com/dms/latest/userguide/schema-conversion-embedded-sql.html).\n\nWhat would you like to do? You can enter "language upgrade" or "sql conversion".`

export const chooseTransformationObjectivePlaceholder = 'Enter "language upgrade" or "sql conversion"'

export const userPatchDescriptionChatMessage = `
export const userPatchDescriptionChatMessage = (version: string) => `
If you'd like to update and test your code with fewer changes at a time, I can divide the transformation results into separate diff patches. If applicable to your application, I can split up the diffs up into the following groups of upgrades. Here are the upgrades included in each diff:

• Minimal Compatible Library Upgrade to Java 17: Dependencies to the minimum compatible versions in Java 17, including Springboot, JUnit, and PowerMockito.
• Minimal Compatible Library Upgrade to Java ${version}: Dependencies to the minimum compatible versions in Java ${version}, including Springboot, JUnit, and PowerMockito.

• Popular Enterprise Specifications Application Frameworks: Popular enterprise and application frameworks like Jakarta EE, Hibernate, and Micronaut 3.

Expand Down Expand Up @@ -597,6 +599,9 @@ export const invalidMetadataFileErrorParsing =
export const invalidMetadataFileNoSctFile =
"An .sct file is required for transformation. Make sure that you've uploaded the .zip file you retrieved from your schema conversion in AWS DMS."

export const invalidFromToJdkChatMessage =
"I can't transform a project from Java 21 to Java 17, but I can upgrade Java 21 code with up to date libraries and other dependencies. Try again with a supported language upgrade."

export const sqlMetadataFileReceived =
'I found the following source database, target database, and host based on the schema conversion metadata you provided:'

Expand Down Expand Up @@ -669,7 +674,7 @@ export const noPomXmlFoundChatMessage = `I couldn\'t find a project that I can u
export const noJavaHomeFoundChatMessage = `Sorry, I couldn\'t locate your Java installation. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`

export const dependencyVersionsErrorMessage =
'I could not find any other versions of this dependency in your local Maven repository. Try transforming the dependency to make it compatible with Java 17, and then try transforming this module again.'
'I could not find any other versions of this dependency in your local Maven repository. Try transforming the dependency to make it compatible with your target Java version, and then try transforming this module again.'

export const errorUploadingWithExpiredUrl = `The upload error may have been caused by the expiration of the S3 pre-signed URL that was used to upload code artifacts to Q Code Transformation. The S3 pre-signed URL expires in 30 minutes. This could be caused by any delays introduced by intermediate services in your network infrastructure. Please investigate your network configuration and consider allowlisting 'amazonq-code-transformation-us-east-1-c6160f047e0.s3.amazonaws.com' to skip any reviewing that might delay the upload. For more information, see the [Amazon Q documentation](${codeTransformTroubleshootAllowS3Access}).`

Expand Down Expand Up @@ -719,7 +724,7 @@ export const changesAppliedNotificationMultipleDiffs = (currentPatchIndex: numbe
}
}

export const noOpenProjectsFoundChatMessage = `I couldn\'t find a project that I can upgrade. Currently, I support Java 8, Java 11, and Java 17 projects built on Maven. Make sure your project is open in the IDE. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`
export const noOpenProjectsFoundChatMessage = `I couldn\'t find a project that I can upgrade. Currently, I support Java 8, Java 11, Java 17, and Java 21 projects built on Maven. Make sure your project is open in the IDE. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`

export const noOpenFileFoundChatMessage = `Sorry, there isn't a source file open right now that I can generate a test for. Make sure you open a source file so I can generate tests.`

Expand All @@ -731,7 +736,7 @@ export const unitTestGenerationCancelMessage = 'Unit test generation cancelled.'

export const tooManyRequestErrorMessage = 'Too many requests. Please wait before retrying.'

export const noJavaProjectsFoundChatMessage = `I couldn\'t find a project that I can upgrade. Currently, I support Java 8, Java 11, and Java 17 projects built on Maven. Make sure your project is open in the IDE. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`
export const noJavaProjectsFoundChatMessage = `I couldn\'t find a project that I can upgrade. Currently, I support Java 8, Java 11, Java 17, and Java 21 projects built on Maven. Make sure your project is open in the IDE. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`

export const linkToDocsHome = 'https://docs.aws.amazon.com/amazonq/latest/aws-builder-use-ug/code-transformation.html'

Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/codewhisperer/models/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ export enum JDKVersion {
JDK8 = '8',
JDK11 = '11',
JDK17 = '17',
JDK21 = '21',
UNSUPPORTED = 'UNSUPPORTED',
}

Expand Down Expand Up @@ -739,7 +740,7 @@ export class TransformByQState {

private sourceJDKVersion: JDKVersion | undefined = undefined

private targetJDKVersion: JDKVersion = JDKVersion.JDK17
private targetJDKVersion: JDKVersion | undefined = undefined

private produceMultipleDiffs: boolean = false

Expand Down Expand Up @@ -1131,7 +1132,7 @@ export class TransformByQState {
this.payloadFilePath = ''
this.metadataPathSQL = ''
this.sourceJDKVersion = undefined
this.targetJDKVersion = JDKVersion.JDK17
this.targetJDKVersion = undefined
this.sourceDB = undefined
this.targetDB = undefined
this.sourceServerName = ''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ export async function startJob(uploadId: string) {
transformationSpec: {
transformationType: CodeWhispererConstants.transformationType, // shared b/w language upgrades & sql conversions for now
source: { language: sourceLanguageVersion }, // dummy value of JDK8 used for SQL conversions just so that this API can be called
target: { language: targetLanguageVersion }, // always JDK17
target: { language: targetLanguageVersion }, // JAVA_17 or JAVA_21
},
})
getLogger().info('CodeTransformation: called startJob API successfully')
Expand Down
Loading