DAM Migrator

Easily migrate from one DAM to another, either one-time or continuously (if the DAM generates events).

The underlying technology is Apache Camel, a fantastic integration framework with all sorts of EIP.

Every supported DAM is implemented as a Camel-Endpoint, providing a consumer (fetch asset from a DAM) and/or a producer (upsert assets to a DAM).

This is developer-ware, as every migration will require some custom mapping code.

A basic camel route will look like this:

public class MyRoutes extends RouteBuilder {
  @Override
  public void configure() {
    from("source-dam://old.place.com?token=xxxxx&query=some-condition")
      .transform().body(CommonAsset.class, asset -> {/* custom mapping code*/})
      .to("target-dam://new.place.com?token=xxxxx&previous-ID=some-field");
    }
}

In practice however we would advise to use a queue for buffering and rate-limiting:

from("source-dam://old.place.com?token=xxxxx&query=some-condition")
  .transform().body(CommonAsset.class, asset -> {/* custom mapping code*/})
  .to("vm:my-queue?blockWhenFull=true&size=50");

from("vm:my-queue?concurrentConsumers=5")
  .throttle(250).timePeriodMillis(60000) // in case you are rate-limited
  .to("target-dam://new.place.com?token=xxxxx&previous-ID=some-field");

This is where all the pre-built camel stuff comes in handy!

dam-common

As we're trying to map from one DAM to another, and every DAM has different ideas when it comes to metadata, folders, relations, etc., we map everything to and from dam-common. Overview:

  • Identifiable (unique ID)
    • Nameable (name of the thing)
    • CommonEntity (metadata and relations)
      • CommonAsset (file or url)
      • CommonNode (structure object)

... note that metadata and relations themselves use Identifiable/CommonEntity themselves, allowing relations between arbitrary DAM objects (e.g. the folder structure an asset is assigned to is simply a relation to a CommonNode).

Bynder

Usage: bynder://your-instance.bynder.com?token=xxxxx, based on their API. Currently only the producer side is implemented.

Parameters

token

type: String, required: yes, default: -

The API token used to authenticate against Bynder's API. To create one, head over to "Advanced Settings > Portal Settings > Permanent Tokens"

previousIdField

type: String, required: no (but recommended), default: -

The metaproperty text-field (name or UUID) where the asset ID of the previous DAM is stored. This enables deduplication and later updates to the asset.

locale

type: locale, required: no, default: English

When encountering a Nameable that needs to be resolved to a string, which locale to prefer. This should probably be set to the default locale of the source.

dryRun

type: boolean, required: no, default: false

Handy for development, does the mapping, but without the final call to the API.

CELUM

Usage: celum-remote://some.place.com/remoteapi?clientId=xxxx&clientSecret=xxxx&serverSecret=xxxxx. Requires their Remote-SDK. Currently only the consumer-side is implemented.

clientId

type: String, required: yes, default: -

The client ID for the Remote-SDK (see appserver/conf/remote.yml)

clientSecret

type: String, required: yes, default: -

The client secret for the Remote-SDK (see appserver/conf/remote.yml)

serverSecret

type: String, required: yes, default: -

The server secret for the Remote-SDK (see appserver/conf/remote.yml)

assetQuery

type: String, required: yes (until listeners are implemented), default: -

A SearchUtil2 query that define the scope of the assets to be transferred, e.g. assetType=123 and info_456=true. Note that due to the poor quality of the Remote-SDK, not every query parameter can be used (most notably everything involving a NOT, except emptiness-checks).

downloadFormat

type: Long, required: no, default: 1

The download format ID that should be used, defaults to OriginalFormat (1 on most servers, 6 on older ones - see CMA).

preferredDownloadFormat

type: Long, required: no, default: -

Under certain circumstances you may prefer an alternative download format for certain assets. When enabled, the endpoint will check if the preferred format is available for a given asset - otherwise downloadFormat will be used.