As a Connect app developer, you might be curious about the new server to Forge migration path that Atlassian is introducing. This new path retains many elements from the existing Connect migration process, which has been extensively tested and widely used by our customers. However, it also incorporates some aspects of Forge's design and functionality.
The areas that required some changes to support Forge migrations are the migration listeners and the way you interact with the migration platform. We will cover them in detail in the subsequent sections.
Starting from version 1.5.2
the library atlassian-app-cloud-migration-listener
will bring a new type of listener
with DiscoverableForgeListener
.
method | status | description |
---|---|---|
getForgeAppId | new | This method must return the Forge app ID selected as the destination of this migration. |
getForgeEnvironmentName | new | 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 . |
getCloudAppKey | changed | You will need to specify a cloud key listed on Marketplace to enable App Assessment. During development, you can ignore this field. |
onStartAppMigration | changed | 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 |
getServerAppKey | unmodified | |
getDataAccessScopes | unmodified |
Compared to the existing gateway we use for Connect (AppCloudMigrationGateway
), this one have some simplified method
parameters due to the lack of transferId
in them. This is thanks to the fact that now the gateway is transfer-aware,
so you don't need to inform it.
If your app requires transferId for an operation, you can retrieve it using the getTransferId()
method.
Because Forge is a serverless platform, webhooks aren't as convenient as they are in Connect. Instead, Forge uses events and method invocations.
The same events as before will be produced, but you will need to subscribe to them through the manifest file.
Here's an example:
1 2modules: trigger: - key: test-trigger function: migration-start-funct events: - avi:ecosystem.migration:triggered:listener - avi:ecosystem.migration:uploaded:app_data
And here's a complete list of events:
avi:ecosystem.migration:triggered:listener
avi:ecosystem.migration:uploaded:app_data
avi:ecosystem.migration:requested:transfer_cancellation
avi:ecosystem.migration:errored:listener
avi:ecosystem.migration:completed:export_phase
avi:ecosystem.migration:settled:transfer
Whenever there's an event, the subscribed functions will be invoked with two arguments: the event and the context.
Here's an example of an event:
1 2{ "eventType": "avi:ecosystem.migration:uploaded:app_data", "transferId": "86f5ea78-8608-5479-9ee7-15b0bb777f6e", "migrationDetails": { "migrationId": "731ad5f9-f258-4a18-94da-7a579ca1c8ad", "migrationScopeId": "7ed3ea6c-02dc-459c-ba49-9befb4e23104", "createdAt": 1716273864561, "cloudUrl": "https://your-site.atlassian.net", "name": "Migrating all the accounting projects" }, "key": "29e3b203-1c7c-4ec1-a323-f94efd009baa", "label": "file-9", "messageId": "11c5a6f2-e844-4c81-aaf1-b7aa33e082ff", "selfGenerated": false, "context": { "cloudId": "0c7a3eb6-f72e-428e-bc0b-f7e261d1d85f", "moduleKey": "test-trigger" }, "contextToken": "..." }
And here's an example of a context:
1 2{ "installContext": "ari:cloud:jira::site/0c7a3eb6-f72e-428e-bc0b-f7e261d1d85f" }
With Forge, you use modules to interact with the app migration platform instead of REST APIs.
All you need to do is to import @forge/migrations
module (starting
from version 1.0.0
) and have access to the following features:
1 2interface MigrationAdapter { getAppDataList(transferId: string): Promise<AppDataListResponse>; getAppDataPayload(key: string): Promise<APIResponse>; getContainers(transferId: string, containerType: string): DefaultQueryBuilder; getMappingById(transferId: string, namespace: string, keys: Array<string>): Promise<MappingResponse>; getMappings(transferId: string, namespace: string): DefaultQueryBuilder; messageProcessed(transferId: string, messageId: string); }
In terms of triggering app migrations, nothing changes. Your app migration listeners will still get a call
on onStartAppMigration()
once the product migrations has completed.
However, once the data export is done, we require an explicit call to completeExport()
on the gateway so the progress
reporting can start. If the method doesn't get called, the platform will assume all the data has been exported after 15
minutes of inactivity.
Also, there's no longer cloud feedback for the server to listen to. This is so that we have predictable exports that can later be replayed (feature not available yet).
That's all there is for server-side changes, but there's one more difference on the cloud (Forge) side. For every
uploaded data (event avi:ecosystem.migration:uploaded:app_data
), your forge function will need to inform us that the
data got processed. That's done by invoking messageProcessed(transferId: string, messageId: string)
from
the @forge/migrations
module. The transferId
and messageId
are provided in the event payload. If the message isn't
flagged as processed within 15 minutes we'll assume it timed-out and that will impact the transfer progress.
Please note that there's no limit on the number of operations to export data. In case Forge compute limitations are reached, one possible way to overcome this is by spreading the workload across multiple exports. That will also help customers to observe migration progress with a greater granularity.
Migrating Forge custom fields is mostly the same as Connect custom fields refer to our guide here.
The difference is that we have added support to migrate custom field types for Forge. To specify a custom field type you want to migrate use null
for the name e.g.
1 2@Override public Map<ServerAppCustomField, String> getSupportedCustomFieldMappings() { HashMap<ServerAppCustomField, String> serverToForgeCFMap = new HashMap<>(); serverToForgeCFMap.put(new ServerAppCustomField(null, "cf-server-type"), "forge-cf-type"); return serverToForgeCFMap; }
In this example we will migrate all custom fields of type cf-server-type
and recreate it as forge-cf-type
in the cloud site.
Custom field values are not yet migrated by Atlassian.
In your migration listener, you can still export as many entities as you want, but each App Data can't be bigger than 16 mega bytes.
Your migration code running on Forge functions will also be subjected the same limits as any other Forge function.
Rate this page: