### Example Implementation of DiscoverableForgeListener Interface in Java Source: https://developer.atlassian.com/platform/app-migration/prepare-server-app-forge This Java code provides a concrete example of how to implement the `DiscoverableForgeListener` interface. It demonstrates the implementation of `onStartAppMigration`, `getForgeAppId`, `getForgeEnvironmentName`, `getCloudAppKey`, `getServerAppKey`, and `getDataAccessScopes` methods, showing typical logic and return values for a server app. ```Java @Override public void onStartAppMigration(AppCloudForgeMigrationGateway gateway, MigrationDetailsV1 migrationDetails) { PaginatedMapping paginatedMapping = gateway.getPaginatedMapping("confluence:page", 5); while (paginatedMapping.next()) { try { Map mappings = paginatedMapping.getMapping(); log.info("mappings = {}", new ObjectMapper().writeValueAsString(mappings)); } catch (IOException e) { log.error("Error retrieving migration mappings", e); } } } @Override public UUID getForgeAppId() { // Example Forge app ID - "1234abcd-efgh-4ucb-bc95-e006kd08e0e6" return UUID.fromString("your-forge-app-id"); } @Override public String getForgeEnvironmentName() { return ForgeEnvironmentName.DEVELOPMENT; } @Override public String getCloudAppKey() { return "your-cloud-app-key"; } @Override public String getServerAppKey() { return "your-server-app-key"; } @Override public Set getDataAccessScopes() { return Stream.of( APP_DATA_OTHER, PRODUCT_DATA_OTHER, MIGRATION_TRACING_IDENTITY, MIGRATION_TRACING_PRODUCT ).collect(Collectors.toCollection(HashSet::new)); } ``` -------------------------------- ### Event Context JSON Structure Source: https://developer.atlassian.com/platform/app-migration/tutorials/connect-vs-forge-migrations Presents a simple JSON example of the context object that accompanies app migration events. This object typically contains `installContext`, providing information about the installation environment, such as the site's cloud ID. ```JSON { "installContext": "ari:cloud:jira::site/0c7a3eb6-f72e-428e-bc0b-f7e261d1d85f" } ``` -------------------------------- ### Example JSON for Cloud Migration Assistant Compatibility Ranges Source: https://developer.atlassian.com/platform/app-migration/manage-app-info This JSON array demonstrates how to declare server app compatibility ranges for the Atlassian Migrations API. It includes examples for versions less than or equal to 2.0.0, versions 4.2.0 through 5.0.9, and versions 8.3.0 and greater, using `start` and `end` properties with `null` for wildcards. ```JSON [ { "start": null, "end": "2.0.0" }, { "start": "4.2.0", "end": "5.0.9" }, { "start": "8.3.0", "end": null } ] ``` -------------------------------- ### Example Java Implementation of App Cloud Migration Listener Source: https://developer.atlassian.com/platform/app-migration/prepare-server-app-connect This Java code provides a concrete example of implementing the `AppCloudMigrationListenerV1` interface. It demonstrates how to handle the `onStartAppMigration` event, retrieve paginated mappings, and define the cloud app key, server app key, and required data access scopes for a migration. ```java @Override public void onStartAppMigration(String transferId, MigrationDetailsV1 migrationDetails) { PaginatedMapping paginatedMapping = gateway.getPaginatedMapping(transferId, "confluence:page", 5); while (paginatedMapping.next()) { try { Map mappings = paginatedMapping.getMapping(); log.info("mappings = {}", new ObjectMapper().writeValueAsString(mappings)); } catch (IOException e) { log.error("Error retrieving migration mappings", e); } } } @Override public String getCloudAppKey() { return "my-cloud-app-key"; } @Override public String getServerAppKey() { return "my-server-app-key"; } @Override public Set getDataAccessScopes() { return Stream.of( APP_DATA_OTHER, PRODUCT_DATA_OTHER, MIGRATION_TRACING_IDENTITY, MIGRATION_TRACING_PRODUCT ).collect(Collectors.toCollection(HashSet::new)); } ``` -------------------------------- ### Handling App Migration Start Event (onStartAppMigration) Source: https://developer.atlassian.com/platform/app-migration/app-migration-transfers When an app migration begins, the platform triggers the `onStartAppMigration()` method on the server app. This method signifies the start of a transfer, setting its state to `IN_PROGRESS` and allowing the app to initiate its migration logic. ```APIDOC Method: onStartAppMigration() Context: Triggered on server app by platform. Effect: Sets transfer state to IN_PROGRESS. ``` -------------------------------- ### Retrieve Mappings with Pagination API (Java) Source: https://developer.atlassian.com/platform/app-migration/mappings Example Java code demonstrating how to use the `getPaginatedMapping` method to retrieve product mappings from a server app, iterating through paginated results and logging them. ```Java PaginatedMapping paginatedMapping = gateway.getPaginatedMapping(transferId, "confluence:page", 5); while (paginatedMapping.next()) { try { Map mappings = paginatedMapping.getMapping(); log.info("mappings = {}", new ObjectMapper().writeValueAsString(mappings)); } catch (IOException e) { log.error("Error retrieving migration mappings", e); } } ``` -------------------------------- ### Example of Multiple Server Mappings for a Single Cloud User Source: https://developer.atlassian.com/platform/app-migration/mappings Shows how a single cloud user can have multiple server-side identifiers (e.g., email, Jira user key, Jira username) all mapping to the same cloud user ID. ```JSON { "email/jsmith@example.com": "1234", "jira.userkey/JIRAUSER1410": "1234", "jira.username/jsmith": "1234" } ``` -------------------------------- ### Example Confluence App Migration Event JSON Source: https://developer.atlassian.com/platform/app-migration/prepare-cloud-app-connect Illustrates the JSON structure of a Confluence app migration event object, showing typical values for various event attributes and nested migration details. ```JSON { "eventType": "listener-triggered", "cloudAppKey": "my-cloud-app-key", "transferId": "e4166374-2345-4c31-918c-83b14eb644f6", "serverAppVersion": "1.0", "migrationDetails": { "migrationId": "8e60dc59-78d6-484f-966a-a09ff8be8ed0", "migrationScopeId": "442bdd69-622d-323d-889d-383b41d8e536", "name": "Migration of my Confluence page", "createdAt": 1597211035, "jiraClientKey": "unknown", "confluenceClientKey": "03a7cb4b-23b6-3a79-8916-8824a053e786", "cloudUrl": "https://cloud-site-under-migration.atlassian.net" } } ``` -------------------------------- ### Retrieve Registered Webhooks for Atlassian App Migration Source: https://developer.atlassian.com/platform/app-migration/prepare-cloud-app-connect This example shows how to fetch all webhooks currently registered by your cloud app with the Atlassian app migration platform using a GET request. It provides the `curl` command and the JSON response containing the list of registered endpoints. ```curl curl -X GET "https://your-cloud-site/rest/atlassian-connect/1/migration/webhook" \ --header 'Content-Type: application/json' ``` ```JSON { "endpoints": [ "https:///", "https:///" ] } ``` -------------------------------- ### cURL Example for Mappings API (Default Page Size) Source: https://developer.atlassian.com/platform/app-migration/mappings This cURL command demonstrates how to make a GET request to the Mappings API to retrieve mappings for a specific `transferId` and `namespace` without explicitly defining a page size. By default, this request will return up to 5000 entries. ```cURL curl -X GET "https://your-site.atlassian.net/rest/atlassian-connect/1/migration/mapping/26925583-10bd-49fb-b67c-15fc2447a97b/page?namespace=identity:user" ``` -------------------------------- ### Example JSON Response for Mappings Pagination API Source: https://developer.atlassian.com/platform/app-migration/mappings This JSON object illustrates a typical response from the Mappings Pagination API. It contains a `meta` object with pagination details (`pageSize`, `hasNext`, `lastEntity`) and an `items` object holding the actual key-value mappings. ```JSON { "meta": { "pageSize": 2, "hasNext": true, "lastEntity": "key2" }, "items": { "key1": "value1", "key2": "value2" } } ``` -------------------------------- ### Get Migration Mappings using Forge Migration API Source: https://developer.atlassian.com/platform/app-migration/apis/forge This example demonstrates how to import the `@forge/migrations` package and utilize the `migration.getMappings` method. It shows how to retrieve migration mappings for a specified `transferId` and `namespace`, returning a list of key-value pairs. ```javascript import { migration } from "@forge/migrations"; export function getMigrationMappings() { return migration .getMappings(transferId, "jira/classic:appCustomField") .getMany(); // => {"results":[{"key":"10004","value":"10011"}, ...]} } ``` -------------------------------- ### Sample cURL Request to Retrieve S3 URL Source: https://developer.atlassian.com/platform/app-migration/app-data An example cURL command demonstrating how to make a GET request to the migration data endpoint to retrieve a downloadable S3 URL using a specific s3Key. ```curl curl -X GET "https://your-site.atlassian.net/rest/atlassian-connect/1/migration/data/f9d95eb3-924b-43d4-8115-447beca388c3" ``` -------------------------------- ### DiscoverableForgeListener Interface Methods for Forge Migrations Source: https://developer.atlassian.com/platform/app-migration/prepare-server-app-forge This section details the methods of the `DiscoverableForgeListener` interface that must be implemented to enable Forge migrations. Each method plays a specific role in the migration process, handling aspects like migration start, app IDs, environment, and data access scopes. ```APIDOC interface DiscoverableForgeListener: onStartAppMigration: description: Core product migration is complete. Server app can begin Forge migration at this point. getForgeAppId: description: The Forge app ID to which the migration is being carried out to. getForgeEnvironmentName: description: The Forge environment to which the migration is being carried out to. This is by default set to "development" when not specified. getCloudAppKey: description: The cloud app key of your Forge app to which the migration is being exported to. You will need to specify a cloud key listed on Marketplace to enable App Assessment. During development, you can ignore this field. getServerAppKey: description: The server app key for where the migration is being exported from. When using atlassian-app-cloud-migration-listener this is not required if your app key is the same as your OSGi bundle name. getDataAccessScopes: description: The data access scopes required to access the migration mappings. ``` -------------------------------- ### Implement Workflow Rule Mappings in Java Source: https://developer.atlassian.com/platform/app-migration/tutorials/migration-app-workflow-rules This example demonstrates how to implement the `getSupportedWorkflowRuleMappings` method of the `JiraAppCloudMigrationListenerV1` interface. It shows how to populate a `HashMap` with server workflow rule class names as keys and their corresponding cloud workflow rule keys as values, which JCMA uses for migration. ```Java @Override public Map getSupportedWorkflowRuleMappings() { Map map = new HashMap<>(); map.put("com.vendor.impl.workflows.ParentIssueBlockingCondition", "parentIssueBlockingCondition-cloud"); map.put("com.vendor.impl.workflows.CloseParentIssuePostFunction", "closeParentIssuePostFunction-cloud"); map.put("com.vendor.impl.workflows.CloseIssueWorkflowValidator", "closeIssueWorkflowValidator-cloud"); return map; } ``` -------------------------------- ### Forge Manifest Event Subscription Example Source: https://developer.atlassian.com/platform/app-migration/tutorials/connect-vs-forge-migrations Illustrates how to subscribe to specific app migration events within a Forge app's `manifest.yml` file. This example uses the `trigger` module to associate functions with events like `avi:ecosystem.migration:triggered:listener` and `avi:ecosystem.migration:uploaded:app_data`, enabling serverless event handling. ```YAML modules: trigger: - key: test-trigger function: migration-start-funct events: - avi:ecosystem.migration:triggered:listener - avi:ecosystem.migration:uploaded:app_data ``` -------------------------------- ### Handling App Migration Start and Data Transfer Events Source: https://developer.atlassian.com/platform/app-migration/transfer This section details the key methods and events involved in the app migration lifecycle. It covers the `onStartAppMigration()` method triggered by the platform and the `app-data-uploaded` event for Forge apps, along with functions to acknowledge or fail data processing. ```APIDOC Method: onStartAppMigration() Description: Executed by the platform on your server app when a transfer starts. State: IN_PROGRESS Event: app-data-uploaded (Forge apps) Description: Sent to the Forge app for each uploaded app-data. Payload includes: transferId, messageId Function: messageProcessed(transferId: string, messageId: string) (from @forge/migrations) Description: Acknowledges successful processing of an app-data-uploaded event. Usage: Must be invoked within 15 minutes to prevent TIMED_OUT state. Function: messageFailed() (from @forge/migrations) Description: Sets the transfer status to FAILED instantly due to an unrecoverable error. Recommendation: Pair with addLog for context. Function: addLog() (from @forge/migrations) Description: Provides additional context and potential solutions for errors to customers. ``` -------------------------------- ### Sample JSON Response for S3 URL Retrieval Source: https://developer.atlassian.com/platform/app-migration/app-data An example of the JSON response received after successfully calling the S3 URL retrieval endpoint. It contains a single 'url' field with the downloadable link. ```json { "url" : "http://s3DownloadableLink" } ``` -------------------------------- ### Example JSON Response for Mappings API (Default Page Size) Source: https://developer.atlassian.com/platform/app-migration/mappings This JSON snippet shows a sample response from the Mappings API when no `pageSize` is specified. It indicates a `pageSize` of 5000, `hasNext` as false (meaning all data is returned), and `lastEntity` as null, along with a truncated list of `items`. ```JSON { "meta": { "pageSize": 5000, "hasNext": false, "lastEntity": null }, "items": { "server-id-1": "cloud-id-1", "server-id-10": "cloud-id-10", ... "server-id-100": "cloud-id-100" } } ``` -------------------------------- ### Migrations API: Documentation Link Parameters Source: https://developer.atlassian.com/platform/app-migration/manage-app-info This section describes parameters within the Atlassian Migrations API for providing links to app migration documentation. These links appear in the app assessment screen, helping customers access information about migration progress, feature differences, and migration guides. ```APIDOC Migrations API: Documentation Links Parameters: cloudVersionDevelopmentRoadmap: Link to: Documentation customers can use to follow the progress of your migration path. Link text in assessment screen: Cloud availability column: View Roadmap link. featureDifferenceDocumentation: Link to: Documentation that explains the differences between the server and cloud versions of your app. Link text in assessment screen: Cloud availability column: Yes link. migrationDocumentation: Link to: Your migration guide. Link text in assessment screen: Migration path column: Automated path and View path links. migrationRoadmapTicketLink: Link to: A Jira ticket or other documentation customers can use to follow the progress of your migration path. Link text in assessment screen: Migration path column: Track request link. ``` -------------------------------- ### Trigger Full App Migration for a Specific Plan (GET Request) Source: https://developer.atlassian.com/platform/app-migration/testing/trigger-app-migration This `curl` command initiates a full app migration for a specified `planId` using a GET request to the Confluence REST API. It requires administrator credentials for authentication and will invoke all migration listeners. ```curl curl -u admin:admin -X GET "http://localhost:1990/confluence/rest/migration/latest/app-migration/trigger/e508b1f0-364d-4a0f-8c66-198ac67b2a2b" ``` -------------------------------- ### Example Migrated Workflow Rule ID Mappings Source: https://developer.atlassian.com/platform/app-migration/tutorials/migration-app-workflow-rules This JSON example illustrates actual migrated workflow rule ID mappings. Each key represents a server workflow rule ID (UUID), and its value is a string combining the cloud workflow ID and the cloud workflow rule ID (both UUIDs) after migration. ```JSON { "b1357138-b7fd-4a7a-910f-a61d5adea551": "9674634a-c02f-4383-a4b6-fbb3ca228b23/d3a7c66e-c76b-4ac0-aa7c-a44e15a54c43", "c96282be-1f2f-4a28-94ce-5d6fe36ac4d8": "9674634a-c02f-4383-a4b6-fbb3ca228b23/e863d81d-fc90-41f6-afe4-271cef08a032", "dba809dd-433d-4ffa-9046-c1a41a17c8e4": "9674634a-c02f-4383-a4b6-fbb3ca228b23/9b2b1b87-4bfc-4197-9ee9-d5097765d4f0" } ``` -------------------------------- ### Example Atlassian App Migration Event Payload Source: https://developer.atlassian.com/platform/app-migration/apis/forge/events This JSON object represents an example payload for an `app_data` uploaded event within the Atlassian ecosystem migration process. It includes details about the event type, transfer ID, migration specifics (ID, scope, creation time, cloud URL, name), and identifiers for the associated data like key, label, server app version, and message ID. ```json { "eventType": "avi:ecosystem.migration:uploaded:app_data", "transferId": "3f3a47f2-a6a2-4204-84bb-d0fc504c9dc6", "migrationDetails": { "migrationId": "403c4f71-a0d1-4a63-97a8-487d18691c46", "migrationScopeId": "0ba07dd9-3804-4600-9102-fa6e1efeab08", "createdAt": 1723111376499, "cloudUrl": "https://your-customer-cloud-site.atlassian.net", "name": "Migration Plan Name" }, "key": "e094ca53-3747-4541-b263-0bf7b56a5bca", "label": "file-label-you-used", "serverAppVersion": "1.0", "messageId": "53f88ea7-a2d2-4dd2-9f36-2d8c43401b11" } ``` -------------------------------- ### Publish App Migration Path Availability via Marketplace Migrations API Source: https://developer.atlassian.com/platform/app-migration/readiness-checklist Explains how to use the Marketplace Migrations API to inform customers about the availability of an app's migration path in the CMA's 'Assess your apps' screen. It details required fields like `migrationPath` and `cloudMigrationAssistantCompatibilityRanges`, and optional fields for linking to documentation explaining feature differences or migration guides. ```APIDOC Marketplace Migrations API: Endpoint: PUT /platform/marketplace/rest/v2/api-group-migrations/addons/{addonKey}/migration Purpose: Publish the availability of an app's migration path to the Atlassian Marketplace. Parameters: - migrationPath (string, required): Set to 'AUTOMATED' to indicate an automated migration path. - cloudMigrationAssistantCompatibilityRanges (array of objects, required): Specifies server app version ranges compatible with the automated migration path. Customers with server app versions outside these ranges will be prompted to upgrade. - featureDifferenceDocumentation (string, optional): URL to documentation explaining differences between server and cloud app versions. - migrationDocumentation (string, optional): URL to the app's migration guide. Impact: Informs customers about migration path availability in the CMA 'Assess your apps' screen. ``` -------------------------------- ### Jira Workflow Rule Configuration Migration Example Source: https://developer.atlassian.com/platform/app-migration/tutorials/migration-app-workflow-rules This snippet demonstrates the transformation of a Jira workflow rule configuration from its server-side XML representation to its corresponding cloud-side JSON format. It highlights how server parameters are encapsulated within a JSON string for compatibility with cloud applications. ```xml workflowMode,5,atl_token,descriptorTab com.example.plugins.tutorial.jira.workflow.ParentIssueBlockingCondition ``` ```json { "value": "{ \"statuses\": \"workflowMode,5,atl_token,descriptorTab\", \"class.name\":\"com.example.plugins.tutorial.jira.workflow.ParentIssueBlockingCondition\" }" } ``` -------------------------------- ### DiscoverableForgeListener Interface Methods Source: https://developer.atlassian.com/platform/app-migration/tutorials/connect-vs-forge-migrations Details the methods introduced or changed in the `DiscoverableForgeListener` interface, which is part of the `atlassian-app-cloud-migration-listener` library. These methods are crucial for defining how a Forge app participates in the migration process, including specifying app IDs, environments, and handling migration start events. ```APIDOC DiscoverableForgeListener: getForgeAppId(): string description: This method must return the Forge app ID selected as the destination of this migration. status: new getForgeEnvironmentName(): string description: Allows you to specify the Forge environment name to be used in this migration. Custom environments are supported. If no value is provided, it defaults to 'development'. status: new getCloudAppKey(): string description: You will need to specify a cloud key listed on Marketplace to enable App Assessment. During development, you can ignore this field. status: changed onStartAppMigration(): void description: Just like Connect migrations, this is the method that will be invoked when it's time to perform App Migrations. Please check details on AppCloudForgeMigrationGateway. status: changed getServerAppKey(): string description: (No description provided) status: unmodified getDataAccessScopes(): Array description: (No description provided) status: unmodified ``` -------------------------------- ### Export App Data to Cloud Storage using Java Source: https://developer.atlassian.com/platform/app-migration/app-data This Java code snippet demonstrates how to upload binary data to the secure cloud storage using `migrationGateway.createAppData`. It shows examples of uploading data without a label and with an optional label for better organization during import. The `OutputStream` is used to write the byte data. ```Java OutputStream firstDataStream = migrationGateway.createAppData(transferId); firstDataStream.write("Your binary data goes here".getBytes()); firstDataStream.close(); // You can also apply labels to distinguish data or to add meta data to support your import process OutputStream secondDataStream = migrationGateway.createAppData(transferId, "some-optional-label"); secondDataStream.write("more bytes".getBytes()); secondDataStream.close(); ``` -------------------------------- ### Example Atlassian App Migration Re-run Event JSON Source: https://developer.atlassian.com/platform/app-migration/tutorials/re-run This JSON object illustrates the structure of an event generated during an app migration re-run. It includes standard event properties like `eventType`, `cloudAppKey`, `transferId`, and importantly, `originalTransferId` to link back to the initial migration attempt. The `migrationDetails` object provides further context about the migration. ```JSON { "eventType": "listener-triggered", "cloudAppKey": "my-cloud-app-key", "transferId": "e4166374-2345-4c31-918c-83b14eb644f6", "originalTransferId": "d241e03d-b205-3c5d-a5eb-805a49df0f38", "migrationDetails": { "migrationId": "8e60dc59-78d6-484f-966a-a09ff8be8ed0", "migrationScopeId": "442bdd69-622d-323d-889d-383b41d8e536", "name": "Migration of my Confluence page", "createdAt": 1597211035, "jiraClientKey": "unknown", "confluenceClientKey": "03a7cb4b-23b6-3a79-8916-8824a053e786", "cloudUrl": "https://cloud-site-under-migration.atlassian.net" } } ``` -------------------------------- ### Using MriIdMapping Transformer with Key-Value Store in Java Source: https://developer.atlassian.com/platform/app-migration/data-transformers This Java code example demonstrates how to configure and use the `MriIdMapping` transformer when exporting data via the Key-Value Store. It shows how to specify the transformer in `KeyValueParameters`, prepare a map of data containing MRI references using the `gateway.convertIdToMappingId` helper, and then send this data for transformation and ingestion into Forge Storage. ```Java // Configure parameters with MriIdMapping transformer List transformers = Arrays.asList("MriIdMapping"); KeyValueParameters parameters = new KeyValueParameters("my-forge-custom-entity", true, transformers); // Prepare data with MRI references Map kvs = new HashMap<>(); kvs.put("config", "{\"defaultIssue\": " + gateway.convertIdToMappingId("jira:issue", "001") + "}"); kvs.put("settings", "{\"linkedPage\": " + gateway.convertIdToMappingId("confluence:page", "002") + "}"); // Send data for transformation and posterior ingestion gateway.sendKeyValuePair(kvs, parameters); gateway.completeExport(); ``` -------------------------------- ### Implement getServerAppKey for Custom App Key (Java) Source: https://developer.atlassian.com/platform/app-migration/tutorials/migrating-osgi-to-discoverable-listener If your application's key differs from its OSGi bundle name, you must implement the `getServerAppKey()` method from the `DiscoverableListener` interface. This snippet provides an example of how to return your specific server app key. ```Java @Override public String getServerAppKey() { return "my-server-app-key"; } ``` -------------------------------- ### Atlassian App Migration Event Attribute Definitions Source: https://developer.atlassian.com/platform/app-migration/prepare-cloud-app-connect Defines the various attributes found in Atlassian app migration event objects, explaining their meaning, purpose, and examples of their application within the migration process. ```APIDOC eventType: description: Specifies the event type. examples: Your cloud app can respond with a request, based on the event type it receives. For example, it can make a query for mappings. cloudAppKey: description: The app key installed app key in the cloud site. examples: NA transferId: description: An ID (UUID) that the app migration platform uniquely generates per migration for each listener. examples: Your cloud app must include this UUID when making a request for migration-related mappings. messageId: description: An ID (UUID) that the app migration platform generates to uniquely recognise an event. examples: The app migration platform may send duplicate notifications for the same event. Use this ID to detect duplication, if your app is sensitive to duplicate notifications. serverAppVersion: description: Version of the P2 plugin exporting app migration data (your app). examples: NA migrationId: description: An ID (UUID) that the app migration platform uses to uniquely identify a migration. examples: NA migrationScopeId: description: An ID that the app migration platform generates to uniquely determine a source (server) and destination (cloud-site) of migration. examples: NA name: description: The name of the migration plan provided by the user who initiated the migration. examples: Use this as a quick way to identify a migration while troubleshooting. createdAt: description: Timestamp of when the app migration was created. examples: NA jiraClientKey: description: This is the `clientKey` of the Jira cloud instance, present in the `installed` [lifecycle callback](https://developer.atlassian.com/cloud/jira/platform/app-descriptor/#lifecycle) sent to your cloud application during installation. examples: This value is 'unknown' when the Jira product is not involved in the migration. confluenceClientKey: description: This is the `clientKey` of the Confluence cloud instance, present in the `installed` [lifecycle callback](https://developer.atlassian.com/cloud/confluence/app-descriptor/#lifecycle) sent to your cloud application during installation. examples: This value is 'unknown' when the Confluence product is not involved in the migration. cloudUrl: description: URL of the destination cloud site for the migration. examples: Use this URL to upload/modify data related to your app migration. s3Key: description: An ID (UUID) to uniquely identify the data your server app uploads to cloud storage. This will only be present on `app-data-uploaded` events. examples: Your cloud app must use this ID to request access to ID-specific data in cloud storage. label: description: Metadata that provides additional information about the data your server app uploads to cloud storage. This will only be present on `app-data-uploaded` events. examples: NA originalTransferId: description: When re-running a migration, this attribute represents the transfer ID of the original, unsuccessful migration. Events generated during an original migration don't include this attribute. examples: Utilize this to distinguish between an original transfer and a rerun transfer. Additionally, it can be used to associate a rerun transfer with its corresponding original transfer. ``` -------------------------------- ### cURL Example: Report App Migration Progress Source: https://developer.atlassian.com/platform/app-migration/report-progress-for-connect This cURL command demonstrates how to send an IN_PROGRESS status update to the Atlassian App Migration Status API. It includes the current percentage of completion and an optional informative message. ```curl curl -X POST 'https://your-site.atlassian.net/rest/atlassian-connect/1/migration/progress/{transferId}' \ --header 'Content-Type: application/json' \ --data-raw '{ "status" : "IN_PROGRESS", "percent": 90, "message" : "App data migration is in the last stage. For more info, refer to http://documentation.example.com." }' ``` -------------------------------- ### Define ServerAppCustomField Structure (APIDOC) Source: https://developer.atlassian.com/platform/app-migration/tutorials/migrating-app-custom-fields This API documentation defines the structure of the ServerAppCustomField class, used in the JiraAppCloudMigrationListenerV1 interface. It specifies two properties: fieldName for the server app custom field name and fieldTypeKey for its type key. ```APIDOC ServerAppCustomField: class ServerAppCustomField { fieldName: String // Server app custom field name fieldTypeKey: String // Server app custom field type key } ``` -------------------------------- ### Information Progress Logs for Atlassian App Migration Source: https://developer.atlassian.com/platform/app-migration/progress-logs Expected progress logs that occur during an Atlassian app migration, detailing events like migration start, data upload, cloud app notifications, status updates, and cancellation requests. ```APIDOC Log Message: App migration started. Details: {cloudAppKey}, for transfer: {transferId} Explanation: Logged at the start of the app migration. Use the transfer ID to correlate progress logs with your internal logs. Log Message: App data uploaded. Details: ID: {s3Key} Explanation: App data has been uploaded to cloud storage. Learn more about retrieving app data Log Message: Notified cloud app... Explanation: Your cloud app has successfully responded to a webhook call. Log Message: App migration updated by the Cloud app with status {status}, progress {percent} and message: {message} Explanation: Represents a status update provided by your cloud app. The entry includes up to 1000 characters of your message. Log Message: Initiated your request to cancel app migration. Explanation: A customer has requested to cancel a transfer. Log Message: Older logs have been omitted for transfer: {transferId} Explanation: There are too many log entries to return, so older entries are omitted. ``` -------------------------------- ### Example JSON Response for Migration Progress Source: https://developer.atlassian.com/platform/app-migration/testing/retrieve-migration-progress This JSON object illustrates the typical structure of the response received from the app migration progress endpoint. It contains a list of migrations, each detailing associated applications, their unique identifiers, cloud/server keys, completion percentage, current status, status message, and the last update timestamp. ```json { "migrations": [ { "migrationId": "68eb047d-b03a-45aa-a5d7-1f4525b53f5e", "apps": [ { "serverAppKey": "com.myapp.server", "containerId": "6b0ace9c-a859-5286-9f63-6464190b2125", "cloudAppKey": "com.myapp.cloud", "completionPercent": 0, "status": "IN_PROGRESS", "statusMessage": "unknown", "lastUpdatedAt": 1712710726935 } ] } ] } ``` -------------------------------- ### Sample Jira Server App Custom Field Configuration Source: https://developer.atlassian.com/platform/app-migration/tutorials/migrating-app-custom-fields This XML snippet shows a typical configuration for a custom field within a Jira Server application. It defines the custom field's name, key, class, description, and resource locations for view and edit templates, which are essential for its functionality on the server. ```XML The Money Custom Field Plugin ``` -------------------------------- ### Sample Jira Cloud App Issue Field Configuration Source: https://developer.atlassian.com/platform/app-migration/tutorials/migrating-app-custom-fields This JSON snippet illustrates how a server app custom field is represented as a Jira issue field configuration in the cloud environment. It includes the field's key, name, description, and type, demonstrating the structured mapping from the server configuration to its cloud equivalent. ```JSON "jiraIssueFields": [ { "key" : "money-custom-field", "name" : { "value" : "Money Custom Field" }, "description" : { "value" : "The Money Custom Field App" }, "type": "number" } ] ``` -------------------------------- ### Implement JiraAppCloudMigrationListenerV1 for Server Custom Field Mappings (Java) Source: https://developer.atlassian.com/platform/app-migration/tutorials/migrating-app-custom-fields This Java interface, JiraAppCloudMigrationListenerV1, must be implemented by server apps (Connect or Forge) to provide a map of custom fields that need to be migrated to Jira Cloud. The getSupportedCustomFieldMappings method returns a Map where keys are ServerAppCustomField objects and values are cloud app Jira issue field module keys. ```Java public interface JiraAppCloudMigrationListenerV1 { Map getSupportedCustomFieldMappings(); } ``` -------------------------------- ### Sample JSON Response for App Data Retrieval Source: https://developer.atlassian.com/platform/app-migration/app-data This JSON object represents a sample response from the App Data Retrieval API's `GET /migration/data/{transferId}/all` endpoint. It returns an array of objects, each containing an `s3Key` (unique identifier for the uploaded data) and an optional `label` if provided during the data export. ```JSON { [ { "s3Key": "dbc96598-fc84-4c91-9e60-2fc01f705de7", "label": "my-data-export" }, { "s3Key": "abc86558-jg32-5c82-9e60-2fc01f705de7" }, { "s3Key": "f9d95eb3-924b-43d4-8115-447beca388c3", "label": "some-optional-label" } ] } ``` -------------------------------- ### Confluence App Migration Required HTTP Header Source: https://developer.atlassian.com/platform/app-migration/rate-limiting Example of the `Migration-App` HTTP header that must be included in all requests to Confluence REST APIs during app migration. This header helps ensure that migration activities do not negatively impact other Confluence customers and prevents potential app key bans. ```HTTP Migration-App: true ``` -------------------------------- ### Request Mappings with Page Size using cURL Source: https://developer.atlassian.com/platform/app-migration/mappings This snippet demonstrates how to retrieve a paginated list of migration mappings using a GET request. It shows how to specify the maximum number of mappings per page using the `pageSize` query parameter. The response includes metadata like `pageSize`, `hasNext`, and `lastEntity`, along with the actual mapping items. ```curl curl -X GET "https://your-site.atlassian.net/rest/atlassian-connect/1/migration/mapping/26925583-10bd-49fb-b67c-15fc2447a97b/page?namespace=jira:priority&pageSize=10" ``` ```json { "meta": { "pageSize": 10, "hasNext": true, "lastEntity": "server-id-10" }, "items": { "server-id-1": "cloud-id-1", "server-id-2": "cloud-id-2", "server-id-3": "cloud-id-3", "server-id-4": "cloud-id-4", "server-id-5": "cloud-id-5", "server-id-6": "cloud-id-6", "server-id-7": "cloud-id-7", "server-id-8": "cloud-id-8", "server-id-9": "cloud-id-9", "server-id-10": "cloud-id-10" } } ``` -------------------------------- ### App Cloud Migration Listener Interface Methods Reference Source: https://developer.atlassian.com/platform/app-migration/prepare-server-app-connect This section details the methods that must be implemented when working with the `DiscoverableListener`, `AppCloudMigrationListenerV1`, or `CloudMigrationListenerV1` interfaces. It provides a description for each method, outlining its purpose and expected behavior during the migration process. ```APIDOC Interface: DiscoverableListener / AppCloudMigrationListenerV1 / CloudMigrationListenerV1 Method: onStartAppMigration Description: Core product migration is complete. Server app can begin migration at this point. Parameters: transferId: String - Identifier for the migration transfer. migrationDetails: MigrationDetailsV1 - Details about the migration. Returns: void Method: getCloudAppKey Description: The cloud app key for where the migration is being exported to. Parameters: None Returns: String - The cloud application key. Method: getServerAppKey Description: The server app key for where the migration is being exported from. When using `atlassian-app-cloud-migration-listener` this is not required if your app key is the same as your OSGi bundle name. Parameters: None Returns: String - The server application key. Method: getDataAccessScopes Description: The data access scopes required to access the migration mappings. Parameters: None Returns: Set - A set of required data access scopes. ``` -------------------------------- ### Execute App Migration Check and Process Results Source: https://developer.atlassian.com/platform/app-migration/build-app-vendor-checks This section details the `executeCheck()` method, which is invoked during migration for each supported check. It specifies the time limits for execution and describes the `CheckResult` object returned by the method, including its `status` (SUCCESS, WARNING, BLOCKING, CHECK_EXECUTION_ERROR), `stepsToResolveKey`, and the option to provide a CSV file for additional context. ```APIDOC Method: executeCheck(checkId: string) -> CheckResult Description: Invoked when a user performs a migration. Each checkId triggers a separate execution. Time Limits: - Per check execution: 5 minutes - Global for all checks: 10 minutes Class: CheckResult Attributes: status: Enum Description: The outcome of the check. Possible Values: - SUCCESS: No issues found, migration can proceed. - WARNING: Issues found, but migration can still proceed. - BLOCKING: Issue prevents migration (currently behaves like WARNING, future blocking planned). - CHECK_EXECUTION_ERROR: Check could not be completed due to an error. stepsToResolveKey: string Description: Corresponds to a key in CheckSpec.stepsToResolve to display instructions. Note: Must match a key in CheckSpec.stepsToResolve for instructions to render. CSV file: File (optional) Description: Provides context for issues (e.g., list of problematic Jira tickets). Constraints: - Max size: 250kb - Max characters per row: 250 - Max rows: 1000 per check - Exceeding limits results in truncation. ``` -------------------------------- ### Implement PreMigrationCheckRepository Interface Source: https://developer.atlassian.com/platform/app-migration/set-up-app-vendor-checks Expose an OSGi component that implements the `PreMigrationCheckRepository` interface. This interface defines the contract for retrieving available checks and executing a specific check, which is crucial for defining your custom pre-migration logic. ```Java public interface PreMigrationCheckRepository { Set getAvailableChecks(); CheckResult executeCheck(String checkId, MigrationPlanContext context); } ``` -------------------------------- ### cURL Example: Settle App Migration Transfer Source: https://developer.atlassian.com/platform/app-migration/report-progress-for-connect This cURL command illustrates how to send a final status update to the Atlassian App Migration Status API to settle a transfer. It shows an example of a SUCCESS status with 100% completion and a final message. Other statuses like INCOMPLETE or FAILED can also be used. ```curl curl -X POST 'https://your-site.atlassian.net/rest/atlassian-connect/1/migration/progress/{transferId}' \ --header 'Content-Type: application/json' \ --data-raw '{ "status" : "SUCCESS", "percent": 100, "message" : "App data migration is complete. For next steps, refer to http://documentation.example.com/." }' ``` -------------------------------- ### Implement executeCheck() for App Migration Checks Source: https://developer.atlassian.com/platform/app-migration/set-up-app-vendor-checks Describes the `executeCheck()` method, which is invoked per check during migration. It details the `CheckResult` object returned by this method, including its `status` field (SUCCESS, WARNING, BLOCKING, CHECK_EXECUTION_ERROR), `stepsToResolveKey`, and optional CSV file support for detailed issue context. Time limits for execution are also specified. ```APIDOC Method: executeCheck() Invoked: When the user is performing a migration (a different execution for each checkId). Time Limit: 5 minutes per check, 10 minutes global for all checks. Returns: CheckResult CheckResult Attributes: status: enum Possible values: SUCCESS: The check found no issues; migration can proceed. WARNING: Issues found, but customer can still proceed. BLOCKING: An issue that will prevent migration (currently same customer experience as WARNING, blocking behavior planned). CHECK_EXECUTION_ERROR: The check could not be completed due to a problem. stepsToResolveKey: string Description: The template key from CheckSpec.stepsToResolve to display to the customer. If no match, no instructions rendered. CSV file: file (optional) Description: Provides context for specific issues (e.g., Jira tickets with permission problems). Limits: 250kb max, 250 chars per row max, 1000 rows per check max. Truncated if limits exceeded. ``` -------------------------------- ### Add Maven Dependency for App Migration Listener Source: https://developer.atlassian.com/platform/app-migration/set-up-app-vendor-checks To create pre-migration app vendor checks, ensure you are using the latest version of the `atlassian-app-cloud-migration-listener` library by adding this Maven dependency to your project's `pom.xml` file. ```XML com.atlassian atlassian-app-cloud-migration-listener 1.2.1 ``` -------------------------------- ### Remove OSGi Util Tracker Maven Dependency Source: https://developer.atlassian.com/platform/app-migration/tutorials/migrating-tracker-to-discoverable-listener This example shows the dependency block for 'org.osgi.util.tracker' that should be removed from your pom.xml. This library is likely no longer needed after the migration updates. ```XML org.osgi org.osgi.util.tracker 1.5.1 provided ```