Contact usRequest a demo

utransfer

This article describes how to use the utransfer utility.

Introduction

Setting up a test or staging environment can require a great deal of effort. Unblu has many configuration properties and text properties that allow you to customize it to meet your needs. You probably also created entities such as conversation templates, named areas, and teams that are similar or even identical to the ones you want to use in production.

It would therefore be helpful if, when the time comes to put Unblu into production, you were able to transfer as many settings as possible to the new environment. However, this isn’t as straightforward as you might think:

  • The Account and Global Server Configuration interfaces offer ways to export the configuration and text properties that you customized. But Unblu accounts also have other attributes, such as a name or an avatar, as well as metadata associated with them, that you can’t export via the configuration interfaces.

  • The Unblu web API’s read endpoints with the appropriate expand query parameter provides a means to export a JSON representation of an entity or set of entities, but there are no corresponding endpoints to reimport the JSON into an account.

  • Entities are interrelated. For example, a user may be a member of a particular team, or a conversation template may be linked to a particular named area. These relationships are expressed using references based on entity IDs, which are specific to a setup and can’t be transferred.

utransfer solves these issues.

What is utransfer?

utransfer is a utility to transfer entities and configurations from one Unblu account to another. It relies in part on the Unblu web API, but includes additional features such as ID modification and filtering.

You can:

  • Export data from an account to a single JSON file, multiple JSON files, or zipped JSON files

  • Import data from exports into one or more accounts on one or more servers

  • Export and import global configuration properties and text properties if you provide superadministrator credentials

utransfer uses version 3 of the Unblu web API.

You can’t transfer entities between two different major versions of Unblu.

We strongly recommend that you use the most recent version of utransfer for the major version that corresponds with your server installation, although it’s not a strict requirement. For example, you can transfer entities from an installation of Unblu 7.30.3 to an installation of Unblu 7.36.1 using version 7.34.3 of utransfer.

The utransfer CLI

The utransfer command line interface (CLI) comes bundled as a JAR file. Running the JAR file with the --help option provides an overview of the options available:

Listing 1. The output of running utransfer with the --help option
$ java -jar <name-of-utransfer-jar-file>.jar --help (1)
Usage: utransfer [-fhjkvVz] [--fromNoAuth] [--keepApiKeys] [--noAuth]
                 [--toNoAuth] [--fromAccount=<fromAccountId>]
                 [--fromAdmin=<fromAdmin>] [--fromPassword=<fromPassword>]
                 [--fromSuperadmin=<fromSuperadmin>]
                 [--idConversion=<idConversionStrategy>] [--toAdmin=<toAdmin>]
                 [--toPassword=<toPassword>] [--toSuperadmin=<toSuperadmin>]
                 [-a=<admin>] [-p=<password>] [-s=<superadmin>]
                 [--fromHeader=<String=String>]... [--just=<justEntities>]...
                 [--skip=<skipEntities>]... [--toHeader=<String=String>]...
                 [-d=<String=String>]... FROM TO

Transfer Unblu entity configuration and localization from FROM to TO where
FROM, TO are either an Unblu server URL or a path

      FROM                  path or URL. If a path is provided, it's assumed to be a
                              directory where previously exported utransfer files
                              are located. If a URL is provided, it is assumed to be
                              an Unblu server web API endpoint from which data is
                              exported. URL must be fully qualified including unblu
                              prefix (trusted entry-path). Example: https:
                              //unbluserver:1234/unblu
      TO                    path or URL. If a path is provided, it should be a file
                              path ending with ('.zip' or '.json') or directory
                              where the export should be stored. If a URL is
                              provided, it is assumed to be an Unblu server web API
                              endpoint where data is imported into. URL must be
                              fully qualified including unblu prefix (trusted
                              entry-path). Example: https://unbluserver:1234/unblu
  -a, --admin=<admin>       Unblu username with admin (or superadmin) role to use
                              when only one of FROM or TO is an Unblu url
  -s, --superadmin=<superadmin>
                            Unblu username with superadmin role to use when only one
                              of FROM or TO is an Unblu url
  -p, --password=<password> Password to use for the --admin or --superadmin
  -d, --header=<String=String>
                            Headers sent when only one of FROM or TO is an Unblu url
  -v, --verbose             Print the HTTP requests
      --noAuth              Work without basic auth when one of FROM or TO is an
                              Unblu url
      --fromAdmin=<fromAdmin>
                            Unblu username with admin (or superadmin) role to use
                              when FROM is an Unblu url
      --fromSuperadmin=<fromSuperadmin>
                            Unblu username with superadmin role to use when FROM is
                              an Unblu url
      --fromPassword=<fromPassword>
                            Password to use for the --fromAdmin or --fromSuperadmin
      --fromAccount=<fromAccountId>
                            Unblu account to use in case superadmin is provided and
                              account should not be the superadmin's when FROM is an
                              Unblu url
      --fromHeader=<String=String>
                            Headers sent when FROM is an Unblu url
      --fromNoAuth          Work without basic auth when FROM is an Unblu url
      --toAdmin=<toAdmin>   Unblu username with admin (or superadmin) role to use
                              when TO is an Unblu url
      --toSuperadmin=<toSuperadmin>
                            Unblu username with superadmin role to use when TO is an
                              Unblu url
      --toPassword=<toPassword>
                            Password to use for the --toAdmin or --toSuperadmin
      --toHeader=<String=String>
                            Headers sent when TO is an Unblu url
      --toNoAuth            Work without basic auth when TO is an Unblu url
  -k, --keepMarkers         By default database markers like creation date of
                              entities are removed on export to have clean data.
                              With this option set, markers are kept in the export
      --keepApiKeys         By default api keys values are removed on export to have
                              clean data. With this option set, api keys are kept in
                              the export
  -f                        Create a folder with multiple json files in TO instead
                              of creating a single json file
  -z                        Create a zip file in TO instead of creating a single
                              json file
  -j                        Create a json file in TO (default behavior)
      --idConversion=<idConversionStrategy>
                            How IDs should be converted on export. NAME: use unique
                              entity name, ID: use original id, HASH: create hash
                              based on unique entity name, COUNTER: replace the id
                              based on a counter. Default is NAME
      --add-suffix=<addSuffix>
                            Add a suffix to the attributes of the entities that are
                              globally unique on a server
      --remove-suffix=<removeSuffix>
                            Remove a suffix to the attributes of the entities that
                              are globally unique on a server
      --new-user-password=<newUserPassword>
                            Password value for created users
      --no-utransfer-user   When superadmin is used, prevent the creation of a
                              temporary user in the target account. Instead the
                              superadmin perform a switch to account
      --skip=<skipEntities> A comma separated list of entities that should not be
                              transferred. By default TEAMS, USERS and DEPUTIES are
                              skipped. Can not be used together with --just
      --just=<justEntities> A comma separated list of entities that should be
                              transferred (all the other will be skipped). Can not
                              be used together with --skip
  -h, --help                Show this help message and exit.
  -V, --version             Print version information and exit.
1 Replace <name-of-utransfer-jar-file>.jar with the name of your utransfer JAR file.

The sections below go into how to use utransfer in more detail.

Exporting data

The command for an administrator to export the account from https://foo.com to the folder /tmp/unblu-export would be:

Listing 2. Exporting an account to a single JSON file
$ java -jar <name-of-utransfer-jar-file>.jar \ (1)
    https://foo.com/app \ (2)
    /tmp/unblu-export \ (3)
    --fromAdmin=<admin-username> \ (4)
    --fromPassword=<admin-password> (5)
1 Replace <name-of-utransfer-jar-file>.jar with the name of your utransfer JAR file.
2 FROM
3 TO
4 Replace <admin-username> with your admin username. Since only FROM is an Unblu URL, you could use -a instead of --fromAdmin.
5 Replace <admin-password> with your admin password. Since only FROM is an Unblu URL, you could use -p instead of --fromPassword.

When you execute this command, utransfer exports the entity configuration to a single JSON file in the folder /tmp/unblu-export.

Export formats

utransfer offers different export formats:

  • A single JSON file containing all the exported entities as the default export format. This is the default. The JSON file is saved in the TO folder (/tmp/unblu-export in the example above) . The name of the JSON file is <account_ID>-<export_date>-<export_time>.json.

    Having all entities in a single JSON file makes it particularly easy to compare two or more installations.

  • A single folder containing a set of individual JSON files for each entity. The ZIP file is generated in the TO folder with missing parent directories being created as needed. The name of the ZIP file is <account_ID>-<export_date>-<export_time>.zip.

    Use the -f option in the command above to choose this export format.

  • A single ZIP file containing the same set of individual JSON files for each entity as the single folder export format. The ZIP file is generated in the TO folder with missing parent directories being created as needed. The name of the ZIP file is <account_ID>-<export_date>-<export_time>.zip.

    Use the -z option in the command above to choose this export format.

If you run the export command with the option --fromSuperadmin, the data includes global configuration and text properties.

Transferring persons

The only person entities that can be transferred are those of dialog bots or the concierge. Other persons belong to conversations. Since it isn’t possible to transfer conversations, there is no point in transferring other persons, either.

Skipping entities

You may not want or need to transfer all types of entity. In that case, you can exclude entities using the --skip option with a comma-separated list of the types of entity you don’t want to transfer.

The list of possible values to exclude is:

  • API_KEYS

  • BOTS

  • CANNED_RESPONSES

  • CONVERSATION_TEMPLATES

  • DEPUTIES (excluded by default)

  • DOMAINS

  • EXTERNAL_MESSENGERS

  • GLOBAL (only relevant when utransfer is called with superadmin credentials)

  • NAMED_AREAS

  • NONE

  • TEAMS (excluded by default)

  • USERS (excluded by default)

  • WEBHOOKS

  • RECORD_RETENTION

This can be useful if, for example, you exported all an account’s entities but only want to import, say, its conversation templates and named areas into a new account. In that case, you would run utransfer with the option --skip=API_KEYS,BOTS,CANNED_RESPONSES,DEPUTIES,DOMAINS,EXTERNAL_MESSENGERS,TEAMS,USERS,WEBHOOKS,RECORD_RETENTION.

By default, utransfer doesn’t transfer users, teams, and deputies. The reason for this is that it isn’t possible to export users with their credentials, teams without users often make little sense, and deputy relationships depend on users. If you would like to transfer users, teams, and deputies anyway, include the option --skip=NONE when you run utransfer. Including NONE in a list with actual entities results in an error.

The license key is never included in a utransfer export.

Impact of skipping interrelated entities

Some entities have configuration properties that refer to other entities through their ID. In this example, the exported account references three conversation templates.

Listing 3. Export of an account
"account" : {
    "$_type" : "Account",
    "id" : "account001",
    "name" : "Main Account",
    "configuration" : {
      "com.unblu.conversation.template.agentTemplateIds" : "[\"conversationTemplate002\"]",
      "com.unblu.conversation.template.chatTemplateId" : "conversationTemplate003",
      "com.unblu.conversation.template.offlineChatTemplateId" : "conversationTemplate004"
    },
    "metadata" : { },
    "text" : { }
  },

If you skip an entity when exporting, the configuration properties referencing the skipped entity appear in the exported JSON file, but their value is *UNKNOWN_BECAUSE_SKIPPED*.

Therefore, an export of the same account when skipping conversation templates appears as follows.

Listing 4. Export of the same account with --skip=CONVERSATION_TEMPLATES
"account" : {
    "$_type" : "Account",
    "id" : "Main Account",
    "name" : "Main Account",
    "translations" : { },
    "configuration" : {
      "com.unblu.conversation.template.agentTemplateIds" : "**UNKNOWN_BECAUSE_SKIPPED**",
      "com.unblu.conversation.template.chatTemplateId" : "**UNKNOWN_BECAUSE_SKIPPED**",
      "com.unblu.conversation.template.offlineChatTemplateId" : "**UNKNOWN_BECAUSE_SKIPPED**"
    },
    "metadata" : { },
    "text" : { }
  },

If you skip a referenced entity when importing:

  • Any existing entity configuration properties referencing the skipped entity in the target are preserved. For example, if an account references conversation templates that already exist in the target, those values aren’t deleted or updated when importing the account with the --skip=CONVERSATION_TEMPLATES option.

  • If no entity configuration properties referencing the skipped entity exist in the target, nothing is created. For example, if an account doesn’t reference any conversation templates, no reference configuration properties are added.

We recommend you use the same --skip value when exporting and reimporting the JSON export file.

Exporting and importing just specific entities

Rather than excluding what you don’t want using --skip, you can use the --just command to specify what you do want to export and import.

Taking the same example as above: you exported all an account’s entities but only want to import its conversation templates and named areas into a new account. Using --just, you would run utransfer with the option --just=CONVERSATION_TEMPLATES,NAMED_AREAS.

The --skip and --just options can’t be used together.

Importing data

To import data into an account, use a command such as the following one:

Listing 5. Importing data from a ZIP file into an account
$ java -jar <name-of-utransfer-jar-file>.jar \ (1)
    /tmp/unblu-export \ (2)
    https://foo.com/app \ (3)
    --toAdmin=<admin-username> \ (4)
    --toPassword=<admin-password> (5)
1 Replace <name-of-utransfer-jar-file>.jar with the name of your utransfer JAR file.
2 FROM
3 TO
4 Replace <admin-username> with you admin username. Since only TO is an Unblu URL, you could use -a instead of --toAdmin.
5 Replace <admin-password> with your admin password. Since only TO is an Unblu URL, you could use -p instead of --toPassword.

This command merges the transferred data into the account of the administrator whose credentials were provided.

When you run the command with the option --toSuperadmin (and the corresponding credentials), the behavior depends on the name of the account whose entities you are importing.

  • If no account with that name exists at the TO location, utransfer creates a new account.

  • If an account of the same name exists, utransfer merges the transferred entities into the existing account of the same name.

  • If the exported data contains global configuration and text properties, these, too, are imported.

    Importing global configuration and text properties may affect all the accounts on the target installation. You should therefore give careful thought to the effect of including global entities when using utransfer.

If the TO parameter is an Unblu URL and your import will create new users in Unblu, you can specify a default password for the new users with the option --new-user-password. The option only affects new users; users that are onlly modified in the import retain their original password.

Import hints

If the target of your transfer isn’t a brand-new account, it may contain a significant number of entities. Even if it’s new, it already contains a number of default entities. Thus the question arises of how to deal with existing entities at the import target.

utransfer uses hints to determine how to proceed. When you export, the JSON file contains an object named "hints" like the one below:

Listing 6. An example hints object generated with --skip=CONVERSATION_TEMPLATES,NAMED_AREAS
{
    "apiKeysStrategy" : "DELETE",
    "cannedResponsesStrategy" : "DELETE",
    "conversationTemplatesStrategy" : "KEEP",
    "domainsStrategy" : "DELETE",
    "namedAreasStrategy" : "KEEP",
    "teamsStrategy" : "DELETE",
    "usersStrategy" : "DELETE",
    "deputyRelationshipsStrategy" : "DELETE",
    "webhookRegistrationsStrategy" : "DELETE",
    "dialogBotsStrategy" : "DELETE",
    "externalMessengersStrategy" : "DELETE",
}

If you use the -f or -z options to export to a folder or ZIP file, your export includes a file named hints.json whose values mirror those of the hints object above.

As you can see, there are two import strategies, DELETE and KEEP.

  • DELETE: Entities at the target that have no corresponding entity with the same name in the imported data are deleted.

  • KEEP: Entities at the target that have no corresponding entity with the same name in the imported data remain unchanged.

Suppose you exported the named areas NA01, NA02, and NA03 from account A and want to import them into account B, which already has the named areas NA02, NA03, and NA04.

  • With the import hint "namedAreaStrategy" set to KEEP, you end up with four named areas in account B: NA01, NA02, NA03, and NA04,

  • With the import hint set to DELETE, account B ends up with only three named areas: NA01, NA02, and NA03.

  • In both cases, the named areas NA02 and NA03 in account B are updated to reflect the named area exported from account A.

Some entities, such as the default team and default conversation templates, are never deleted, regardless of the strategy specified in the import hints.

Which strategy utransfer defaults to for each type of entity depends on whether that type of entity is skipped or not during the export.

  • Entity types that are skipped are assigned the KEEP strategy.

  • Entity types that are included in the export are assigned the DELETE strategy.

Importing the same data multiple times

There can be situations where you want to import set of data into an Unblu Collaboration Server multiple times. For example, you might want different groups of testers to be able to use the same data set, but work in different Unblu accounts.

To make this easier, utransfer has an option to add a suffix to entities that are globally unique, such as account names and API keys.

Listing 7. Adding a suffix to globally unique entities
$ java -jar <name-of-utransfer-jar-file>.jar \ (1)
    <input-json-filename> \ (2)
    /tmp/out \ (3)
    -j \ (4)
    --add-suffix=_DEV \ (5)
    --keepApiKeys \ (6)
    --skip=NONE (7)
1 Replace <name-of-utransfer-jar-file>.jar with the name of your utransfer JAR file.
2 FROM
3 TO
4 Create a JSON file in TO
5 Add the suffix _DEV to all globally unique entities
6 Keep the API keys
7 Export all entities

Running the command above with different suffixes creates different JSON files that you can then import into the same Collaboration Server without any conflicts.

You should aim to keep the suffix short so you don’t come up against any length constraints when you later import the file with suffixes into the Collaboration Server.

If you make changes to an entity with a suffix that you later want to import without the suffix, you can remove the suffix again:

Listing 8. Removing a suffix from globally unique entities
$ java -jar <name-of-utransfer-jar-file>.jar \ (1)
    <input-json-filename-with-suffixes> \ (2)
    /tmp/out \ (3)
    -j \ (4)
    --remove-suffix=_DEV \ (5)
    --keepApiKeys \ (6)
1 Replace <name-of-utransfer-jar-file>.jar with the name of your utransfer JAR file.
2 FROM
3 TO
4 Create a JSON file in TO
5 Remove the suffix _DEV from all globally unique entities
6 Keep the API keys

The --remove-suffix option only removes the suffix specified. If you have, say, two teams called "Advisors_DEV" and "Advisors_DEVS" (note the S at the end), respectively, the result of running the command is that "Advisors_DEV" is renamed to "Advisors" whereas "Advisors_DEVS" is untouched.

Data modification

utransfer can carry out three types of modification on the data you are transferring: API key value removal, database marker removal, and ID conversion.

By default, the values of the API keys are removed when they’re exported. (The other values of API key entities are exported.) To disable this behavior and export API keys with their key values, run utransfer with the option --keepApiKey.

Database markers, too, are removed by default during utransfer data exports. You can retain them by including the option --keepMarkers

To give you a better idea of the options' effect, compare the two excerpts below, taken from an export to a single JSON file. The first example is exported with the options --keepApiKeys and --keepMarkers. The second export is run without these options.

As you can see, the first example includes various values that are missing from the second example: "apiKey", "creationTimestamp", "modificationTimestamp", and a number of "$_version" entries. Apart from "apiKey", the missing values are all database markers.

Listing 9. Extract of an export with the options -j --keepApiKeys --keepMarkers
"mobile-agent" : {
  "$_type" : "ApiKey",
  "id" : "mobile-agent",
  "creationTimestamp" : 1605607944974,
  "modificationTimestamp" : 1605607944974,
  "version" : 1,
  "accountId" : "The Bank",
  "apiKey" : "HGXXQQI1TA6OFiE_OzNg8g",
  "name" : "mobile-agent",
  "description" : "Demo api key for usage in area: mobile-agent",
  "configuration" : {
    "$_version" : "50d60323f704eb76a5cc181039d113f8",
    "com.unblu.conversation.ui.individualUiActionBarTheme" : "DARK"
  },
  "text" : {
    "$_version" : {
      "$_version" : "d41d8cd98f00b204e9800998ecf8427e"
    }
  },
  "metadata" : {
    "$_version" : "2fe774b6fd245e8c80d136f67a4c344b",
    "demo.data" : "true"
  }
}
Listing 10. Extract of an export with the option -j
"mobile-agent" : {
  "$_type" : "ApiKey",
  "id" : "mobile-agent",
  "accountId" : "The Bank",
  "name" : "mobile-agent",
  "description" : "Demo api key for usage in area: mobile-agent",
  "configuration" : {
    "com.unblu.conversation.ui.individualUiActionBarTheme" : "DARK"
  },
  "text" : { },
  "metadata" : {
    "demo.data" : "true"
  }
}
When you import data that includes API keys or database markers, run utransfer with the same option to include the data that’s normally removed. For example, to include API keys in your import, run utransfer with the option --keepApiKeys.

ID conversion

The default entity IDs in Unblu are random character sequences that are automatically generated when the entity’s created. This makes them hard to remember and to find when one wants to compare entities from two or more different environments. It also makes it hard to compare two or more different installations.

Transforming IDs into something more legible to humans makes it easier to find one’s way around an export. Transforming IDs in a stable fashion also makes comparisons between different installations simply a matter of performing a diff.

To transform entity IDs during an export, run utransfer with the option --idConversion=<strategy>, where <strategy> is one of the following:

COUNTER

An entity’s ID is replaced with an ID based on a counter and its entity type (account001, namedArea002, cannedResponse003, and so on). The result depends on the order in which the entities are processed.

HASH

ID is a hash based on the business logic attribute (such as title or name).

ID

The entity keeps its original ID, that is, no transformation occurs.

NAME

This is the default strategy for the utransfer CLI. The entity’s name or title is used as its ID.

The strategies NAME and HASH are stable across installations, that is, the same entity exported from two or more environments have the same ID.

An ID clash occurs when an ID transformation results in the same output ID for two different input entities. If an ID clash occurs, utransfer uses ID instead of NAME and HASH. Transformation strategies such as ID or COUNTER can’t create clashes.

Consider the API key used in the examples of the previous section. This is the exported data with the original IDs, that is, using the conversion strategy ID:

Listing 11. API key exported via utransfer with the options -j --idConversion=ID --keepApiKeys --keepMarkers
"QA9tsi5QRZ2dFMo7JOUwHQ" : {
  "$_type" : "ApiKey",
  "id" : "QA9tsi5QRZ2dFMo7JOUwHQ",
  "creationTimestamp" : 1610359268499,
  "modificationTimestamp" : 1610359268499,
  "version" : 1,
  "accountId" : "T-fc_kUHQ_WNvY1ZX9ZA0w",
  "apiKey" : "JmvURvDWQdywtaN0sTFZYQ",
  "name" : "mobile-agent",
  "description" : "Demo api key for usage in area: mobile-agent",
  "configuration" : {
    "$_version" : "50d60323f704eb76a5cc181039d113f8",
    "com.unblu.conversation.ui.individualUiActionBarTheme" : "DARK"
  },
  "text" : {
    "$_version" : {
      "$_version" : "d41d8cd98f00b204e9800998ecf8427e"
    }
  },
  "metadata" : {
    "$_version" : "2fe774b6fd245e8c80d136f67a4c344b",
    "demo.data" : "true"
  }
}

This is what the entity looks like when exported with the ID conversion strategy COUNTER:

Listing 12. API key exported with the options -j --idConversion=COUNTER --keepApiKeys --keepMarkers
"apiKey030" : {
  "$_type" : "ApiKey",
  "id" : "apiKey030",
  "creationTimestamp" : 1610359268499,
  "modificationTimestamp" : 1610359268499,
  "version" : 1,
  "accountId" : "account001",
  "apiKey" : "JmvURvDWQdywtaN0sTFZYQ",
  "name" : "mobile-agent",
  "description" : "Demo api key for usage in area: mobile-agent",
  "configuration" : {
    "$_version" : "50d60323f704eb76a5cc181039d113f8",
    "com.unblu.conversation.ui.individualUiActionBarTheme" : "DARK"
  },
  "text" : {
    "$_version" : {
      "$_version" : "d41d8cd98f00b204e9800998ecf8427e"
    }
  },
  "metadata" : {
    "$_version" : "2fe774b6fd245e8c80d136f67a4c344b",
    "demo.data" : "true"
  }
}

Note that the reference to the account this entity belongs to, the value of "accountId", has been changed to reflect the new value of the account’s ID. This shows how utransfer keeps track of all cross-references between the entities it processes.

Here is the same entity exported with the HASH strategy:

Listing 13. API key exported via utransfer with the options -j --idConversion=HASH --keepApiKeys --keepMarkers
"4085760720999967238" : {
  "$_type" : "ApiKey",
  "id" : "4085760720999967238",
  "creationTimestamp" : 1610359268499,
  "modificationTimestamp" : 1610359268499,
  "version" : 1,
  "accountId" : "7303578532599678026",
  "apiKey" : "JmvURvDWQdywtaN0sTFZYQ",
  "name" : "mobile-agent",
  "description" : "Demo api key for usage in area: mobile-agent",
  "configuration" : {
    "$_version" : "50d60323f704eb76a5cc181039d113f8",
    "com.unblu.conversation.ui.individualUiActionBarTheme" : "DARK"
  },
  "text" : {
    "$_version" : {
      "$_version" : "d41d8cd98f00b204e9800998ecf8427e"
    }
  },
  "metadata" : {
    "$_version" : "2fe774b6fd245e8c80d136f67a4c344b",
    "demo.data" : "true"
  }
}

Finally, here is the entity exported with the NAME strategy:

Listing 14. API key exported via utransfer with the options -j --idConversion=NAME --keepApiKeys --keepMarkers
"mobile-agent" : {
  "$_type" : "ApiKey",
  "id" : "mobile-agent",
  "creationTimestamp" : 1610359268499,
  "modificationTimestamp" : 1610359268499,
  "version" : 1,
  "accountId" : "The Bank",
  "apiKey" : "JmvURvDWQdywtaN0sTFZYQ",
  "name" : "mobile-agent",
  "description" : "Demo api key for usage in area: mobile-agent",
  "configuration" : {
    "$_version" : "50d60323f704eb76a5cc181039d113f8",
    "com.unblu.conversation.ui.individualUiActionBarTheme" : "DARK"
  },
  "text" : {
    "$_version" : {
      "$_version" : "d41d8cd98f00b204e9800998ecf8427e"
    }
  },
  "metadata" : {
    "$_version" : "2fe774b6fd245e8c80d136f67a4c344b",
    "demo.data" : "true"
  }
},

When you reimport the data of entities whose IDs were transformed, the entities are assigned random character sequences as IDs again.

Exporting and importing SECRET and MULTILINE_SECRET configuration properties

Configuration properties that contain passwords, secrets, or keys are of the type SECRET or MULTILINE_SECRET. The configuration property com.unblu.conversation.call.tokbox.apiSecret, for example, is used to store the Vonage Video API secret used for video and audio chat.

utransfer behaves differently depending on the values of the SECRET or MULTILINE_SECRET configuration properties:

  • When exporting an entity with a SECRET or MULTILINE_SECRET configuration property, the configuration property is exported with a masked value (**PROTECTED_SECRET**).

  • When importing:

    • The value in the target server isn’t modified if the entity has a masked **PROTECTED_SECRET** configuration property value in the JSON file.

    • The value in the target server is modified if the entity has an actual, unmasked configuration property value in the JSON file.

If you haven’t yet defined a value for the configuration property at the destination, you can replace the masked value with the actual value before importing the entity.

Using utransfer with different user roles

utransfer has options to specify the username and password of either an admin or a superadmin. Which of the two roles you use utransfer with affects how imports and exports of entities work.

Administrator

If you run utransfer with the option --fromAdmin, then that administrator’s account is exported.

When you run utransfer with the --toAdmin option, the data is imported into that administrator’s account. Any GLOBAL entities in the data are ignored.

Technical administrator

If the credentials you provide belong to a technical administrator, utransfer runs as if it’s called with the credentials of a normal account administrator. However, not all entities are transferred. The following types of entity are always skipped, regardless of any --skip option you may include:

  • BOTS

  • EXTERNAL_MESSENGERS

  • PERSONS

  • WEBHOOKS

Superadministrator

When you run utransfer with the option --fromSuperadmin, then the superadministrator’s account is exported. You can, however, include the --fromAccount option to specify a different account. If the superadministrator doesn’t belong to the account specified, utransfer creates a temporary administrator. The temporary administrator carries out the export and is deleted once the export has finished.

To avoid this, you can provide the superadministrator’s username in the --fromAdmin option instead.

Exports carried out by superadministrators include global configuration and text properties. To prevent this, include the value GLOBAL in the --skip option.

Running utransfer with ID propagation

You can use ID propagation when you run utransfer. To do so, use the appropriate --header, --FromHeader or --ToHeader option:

Listing 15. Example of exporting data using authentication with ID propagation
$ java -jar <name-of-utransfer-jar-file>.jar \ (1)
    http://localhost:7777/app \ (2)
    /tmp/unblu-export \ (3)
    -j (4)
    -d x-propagated-trusted-user-id=utransferUser -d x-propagated-trusted-user-roles=ADMIN (5)
1 Replace <name-of-utransfer-jar-file>.jar with the name of your utransfer JAR file.
2 FROM
3 TO
4 Generate a single JSON file.
5 -d is the shorthand notation for the --header. Since only FROM is an Unblu URL, there is no need to use the more specific --fromHeader.

Replace the header with the header(s) you need.

The headers you have to include depend on your particular setup. Suppose you need to include a header such as x-awesome-proxy-header: YesDefinitely for the reverse proxy, which then carries out authentication. In that case, you would call utransfer with the option -d x-awesome-proxy-header=YesDefinitely.

If necessary, you can remove the basic authentication headers from the request with the options --noAuth, --noFromAuth or --noToAuth.

Logging

By default, utransfer has regular log levels. If you require more detailed logging to identify issues, use the --verbose option to see the HTTP requests. For example, this may be useful if you manipulate the JSON structure between exporting and importing.

Listing 16. Logging with the option --verbose
$ java -jar utransfer6.jar https://unbluserver.com/co-unblu/ out -j --fromAdmin=<admin-username> --fromPassword=<admin-password>
Exporting from 'https://unbluserver.com/co-unblu/' as admin '<admin-username>'
Exporting to json file in 'out'
Starting to read data
Feb 23, 2022 11:41:14 AM org.glassfish.jersey.logging.LoggingInterceptor log
INFO: 1 * Sending client request on thread main
1 > GET https://unbluserver.com/co-unblu/rest/v3/accounts/getCurrentAccount (1)
1 > Accept: application/json
1 > Authorization: Basic <credentials>
1 > User-Agent: OpenAPI-Generator/1.0.0/java

Feb 23, 2022 11:41:15 AM org.glassfish.jersey.logging.LoggingInterceptor log
INFO: 1 * Client response received on thread main
1 < 200 (2)
1 < Cache-Control: no-cache, no-store, no-transform, must-revalidate, proxy-revalidate, max-age=0, s-maxage=0
1 < Content-Length: 263
1 < Content-Type: application/json
1 < Date: Wed, 23 Feb 2022 10:41:15 GMT
1 < Expires: 0
1 < Pragma: no-cache
1 < Server: nginx
1 < Strict-Transport-Security: max-age=31536000
1 < X-Unblu-Start-Time: 1644917826694
{"$_type":"Account","id":"wZvcAnbBSpOps9oteH-Oxw","creationTimestamp":1644917764609,"modificationTimestamp":1644918149916,"version":3,"name":"Main Account","billingAddress":null,"contactAddress":null,"avatar":null,"configuration":null,"metadata":null,"text":null}

Feb 23, 2022 11:41:15 AM org.glassfish.jersey.logging.LoggingInterceptor log
INFO: 2 * Sending client request on thread main
2 > GET https://unbluserver.com/co-unblu/rest/v3/authenticator/getCompactUser
2 > Accept: application/json
2 > Authorization: Basic <credentials>
2 > User-Agent: OpenAPI-Generator/1.0.0/java

Feb 23, 2022 11:41:15 AM org.glassfish.jersey.logging.LoggingInterceptor log
INFO: 2 * Client response received on thread main
2 < 200
2 < Cache-Control: no-cache, no-store, no-transform, must-revalidate, proxy-revalidate, max-age=0, s-maxage=0
2 < Content-Length: 692
2 < Content-Type: application/json
2 < Date: Wed, 23 Feb 2022 10:41:15 GMT
2 < Expires: 0
2 < Pragma: no-cache
2 < Server: nginx
2 < Strict-Transport-Security: max-age=31536000
2 < X-Unblu-Start-Time: 1644917850404
{"$_type":"CompactUser","id":"le3I8rXwS9q3Wb4kPDd4rg","accountId":"wZvcAnbBSpOps9oteH-Oxw","username":"<admin-username>","displayName":"<admin-displayname> Admin","firstName":"<admin-firstname>","lastName":"<admin-lastname>","avatar":null,"teamId":"JZh4ADRnEeasYZ5xEoyudw","parentTeamIds":["JZh4ADRnEeasYZ5xEoyudw"],"permissions":{"$_type":"Permissions","allPermissions":false,"permissions":["USER-ROLE-ADMIN","USER-ROLE-ANONYMOUS_USER","USER-ROLE-REGISTERED_USER","USER-ROLE-SUPERVISOR","USER-ROLE-TECHNICAL_ADMIN","USER-ROLE-WEBUSER","USER-VALID_USER"]},"authorizationRole":"ADMIN","passwordDefined":true,"virtual":false,"propagated":false,"impersonatedFromUserId":null,"impersonatedFromAccountId":null}

You see the counter N before each request:

1 Each HTTP request sent is preceded by N >
2 The response received is preceded by N <

You may then be able to recreate a curl command from the logs to replay the request.

The log files contain sensitive information. The Authorization header contains user credentials and can be decoded.