Files
awesome-copilot/extensions/java-modernization-studio/catalog.mjs
T
Ayan Gupta 65ba0b3922 Add Java Modernization Studio canvas extension (#2156)
* Add Java Modernization Studio canvas extension

A canvas extension that drives the GitHub Copilot App Modernization for Java workflow from an interactive dashboard: environment readiness checks, repo assessment, prioritized plan/progress, validation gates (CVE scan, test generation), and one-click predefined-task runs — all grounded in the repo's real artifacts (.appmod/assessment.json, plan.md, progress.md). Includes a node:test suite (109 tests) for the grounding logic.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Ayan Gupta <74832088+ayangupt@users.noreply.github.com>

* Secure cockpit loopback server with a per-instance token

Address Copilot review feedback on the Java Modernization Studio canvas:

- Mint a per-instance secret in createInstanceServer, embed it in the
  iframe URL, and validate it on every loopback request (/, /state,
  /events, /action). Other local processes can no longer read repo
  state or dispatch agent actions just by guessing the random port.
  Mirrors the existing diagram-viewer token pattern; the client echoes
  the token from its boot payload. The guard is a no-op when no token is
  set, so direct makeHandler unit tests are unaffected.
- Handle async request-handler rejections in createServer with a .catch
  that returns 500 and logs, instead of leaking an unhandled rejection
  that could destabilize the extension process.
- Tests: token guard 403s unauthenticated /, /state, /events and
  /action and allows valid-token requests; the end-to-end test asserts
  the tokenized URL and a tokenless 403.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix CI: add preview screenshot and clear codespell hits

Add the required assets/preview.png screenshot for the canvas-extension
validator, and resolve two codespell findings in the cockpit:
rename the planSim helper's `nd` variable to `notDone` and reword a
catalog comment to avoid the `invokable`/`invocable` flag.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Harden cockpit loopback server per Copilot review

Address the second-round Copilot review comments on the loopback server:

- broadcast(): drop an SSE client whose write() throws instead of keeping
  it in the Set, so a uncleanly-disconnected client can't cause repeated
  exceptions or leak dead entries on every subsequent broadcast.
- POST /action: treat a malformed JSON body or a missing/invalid "kind"
  as a 400 client error (with an application/json body) instead of a 200
  carrying { ok:false, error:"Unknown action: undefined" }.
- Handler catch: set Content-Type: application/json on the 500 error
  response so it is consistent with the other JSON routes.

Adds four tests covering dead-client eviction, the two 400 paths, and the
JSON-typed 500. Full suite: 115 passing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Ayan Gupta <74832088+ayangupt@users.noreply.github.com>

* Add canvas.json gallery metadata for Java Modernization Studio

Aaron requested a canvas.json so the awesome-copilot website/gallery can
list this extension. Generated via `npm run website:data`
(writePerExtensionCanvasManifests), which derives id/name/description/
version/keywords/screenshots from package.json + the createCanvas source +
assets, and carries the author through. Output committed verbatim so a CI
regeneration produces no diff.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Ayan Gupta <74832088+ayangupt@users.noreply.github.com>

* Add author tag to package.json

Declare the author in the package manifest (object form, matching the
author already carried in canvas.json so it includes the profile URL).
The published gallery sources author from canvas.json; this adds the
conventional npm author tag to package.json for completeness. Verified
`npm run website:data` still emits the author on the extensions record
and leaves canvas.json byte-identical.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Ayan Gupta <74832088+ayangupt@users.noreply.github.com>

---------

Signed-off-by: Ayan Gupta <74832088+ayangupt@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-01 11:10:53 +10:00

176 lines
7.0 KiB
JavaScript

// catalog.mjs — Static catalog of GitHub Copilot App Modernization for Java
// predefined tasks and supported Java upgrade paths. Sourced from Microsoft Learn:
// /azure/developer/java/migration/migrate-github-copilot-app-modernization-for-java-predefined-tasks
// /azure/developer/github-copilot-app-modernization/tools
//
// `detect` lists dependency-signature keys (see scan.mjs DEP_SIGNATURES). When a
// repo's build files match one of those keys, the task is flagged "relevant".
export const PREDEFINED_TASKS = [
{
id: "rabbitmq-to-servicebus",
name: "RabbitMQ to Azure Service Bus",
category: "Messaging",
summary:
"Convert RabbitMQ usage (Spring AMQP, Spring JMS, or Jakarta EE over AMQP) to Azure Service Bus, preserving messaging semantics with secure auth by default.",
detect: ["rabbitmq"],
},
{
id: "activemq-to-servicebus",
name: "ActiveMQ to Azure Service Bus",
category: "Messaging",
summary:
"Convert ActiveMQ producers, consumers, connection factories, and queue/topic interactions to Azure Service Bus equivalents.",
detect: ["activemq"],
},
{
id: "aws-sqs-to-servicebus",
name: "AWS SQS to Azure Service Bus",
category: "Messaging",
summary:
"Translate AWS SQS queue operations and message handling to Azure Service Bus, preserving at-least-once delivery, batching, and visibility-timeout behaviors.",
detect: ["awsSqs"],
},
{
id: "managed-identity-db",
name: "Managed Identities for Database migration",
category: "Identity & Secrets",
summary:
"Prepare your codebase for Managed Identity authentication when moving from a local database to Azure SQL, MySQL, PostgreSQL, or Cosmos DB.",
detect: ["jdbc"],
},
{
id: "managed-identity-credentials",
name: "Managed Identities for Credential Migration",
category: "Identity & Secrets",
summary:
"Replace connection strings / shared access signatures for messaging services (Event Hubs, Service Bus) with Azure Managed Identity authentication.",
detect: ["rabbitmq", "activemq", "jms"],
},
{
id: "secrets-to-keyvault",
name: "Secrets & Certificate Management to Azure Key Vault",
category: "Identity & Secrets",
summary:
"Move hardcoded secrets and local TLS/mTLS certificates (Java KeyStores) to Azure Key Vault, retrieving them at runtime via the JCA provider.",
detect: ["keystore"],
},
{
id: "crypto-to-keyvault",
name: "Cryptography operations to Azure Key Vault",
category: "Identity & Secrets",
summary:
"Migrate local signing, verification, encryption, and decryption to Azure Key Vault so keys never leave the vault.",
detect: ["crypto"],
},
{
id: "aws-secrets-to-keyvault",
name: "AWS Secret Manager to Azure Key Vault",
category: "Identity & Secrets",
summary:
"Reconfigure secret creation, retrieval, update, and deletion from AWS Secret Manager to Azure Key Vault.",
detect: ["awsSecrets"],
},
{
id: "entra-id-auth",
name: "User authentication to Microsoft Entra ID",
category: "Identity & Secrets",
summary:
"Transition LDAP-based user authentication to Microsoft Entra ID authentication.",
detect: ["ldap"],
},
{
id: "aws-s3-to-blob",
name: "AWS S3 to Azure Storage Blob",
category: "Storage",
summary:
"Convert code that interacts with AWS S3 into Azure Storage Blob logic while maintaining the same semantics.",
detect: ["awsS3"],
},
{
id: "file-io-to-fileshare",
name: "Local file I/O to Azure Storage File share mounts",
category: "Storage",
summary:
"Convert local file reads/writes to unified mount-path access so an Azure Storage File share can persist data across replicas.",
detect: [],
},
{
id: "logging-to-console",
name: "Logging to local file → console (Azure Monitor)",
category: "Observability",
summary:
"Convert file-based logging to console-based logging so Azure hosting integrates it with Azure Monitor automatically.",
detect: ["filelog"],
},
{
id: "javamail-to-acs",
name: "Java Mail to Azure Communication Services",
category: "Email",
summary:
"Convert SMTP-based mail sending to Azure Communication Services, which works in Azure hosting environments that block port 25.",
detect: ["javamail"],
},
{
id: "databases-to-azure",
name: "On-prem databases to Azure database offerings",
category: "Database",
summary:
"Migrate Oracle, IBM Db2, Informix, or Sybase ASE to Azure Database for PostgreSQL or Azure SQL with passwordless Entra ID auth, reconciling SQL dialect differences.",
detect: ["oracle", "db2", "sybase", "informix"],
},
{
id: "cache-to-redis",
name: "Cache solutions to Azure Managed Redis",
category: "Cache",
summary:
"Migrate in-memory or distributed caches (Infinispan, SwarmCache, Memcached, etc.) to Azure Managed Redis with passwordless Entra ID auth.",
detect: ["cache"],
},
{
id: "ant-eclipse-to-maven",
name: "Ant / Eclipse project to Maven",
category: "Build",
summary:
"Convert Ant or Eclipse IDE projects to Maven so the project builds consistently from any environment.",
detect: ["ant"],
},
];
// Java runtime upgrade ladder targeted by App Modernization (8 → 11 → 17 → 21 → 25),
// with particular focus on Spring Boot apps.
export const JAVA_UPGRADE_TARGETS = [11, 17, 21, 25];
// Day-to-day Java utilities you can invoke in Copilot Chat with the `#` prefix.
export const APPMOD_TOOLS = {
cve: {
id: "appmod-validate-cves-for-java",
label: "Validate CVEs",
summary:
"Scan the project for known Java CVEs and validate that critical vulnerabilities are addressed.",
},
tests: {
id: "appmod-generate-tests-for-java",
label: "Generate unit tests",
summary: "Use AI code understanding to generate unit tests for the Java code.",
},
};
// The five validation gates App Modernization runs after code transformation.
export const VALIDATION_GATES = [
{ key: "build", label: "Build" },
{ key: "tests", label: "Unit Tests" },
{ key: "cve", label: "CVE Check" },
{ key: "consistency", label: "Consistency" },
{ key: "completeness", label: "Completeness" },
];
/** Return the catalog with a `relevant` flag set per task based on detected deps. */
export function catalogWithRelevance(detectedKeys) {
const set = new Set(detectedKeys || []);
return PREDEFINED_TASKS.map((t) => ({
...t,
relevant: t.detect.some((d) => set.has(d)),
}));
}