Skip to main content

Updating asset

All objects in the SDK that you can update within Atlan implement the builder pattern. This allows you to progressively build-up the object you want to update. In addition, each object provides a method that takes the minimal set of required fields to update that asset, when it already exists in Atlan.

Include only your intended changes, nothing more

When enriching an asset in Atlan, you only need to specify the information you want to change. Any information you don't include in your update will be left untouched on the asset in Atlan. This way you don't need to:

  • try to reproduce the complete asset in your request to do targeted updates to specific attributes
  • worry about other changes that may be made to the asset in parallel to the changes you will be making to the asset

Build minimal object needed

For example, to update a glossary term we need to provide the qualifiedName and name of the term, and the GUID of the glossary in which it exists:

Build minimal asset necessary for update
GlossaryTermBuilder<?,?> termUpdater = GlossaryTerm
.updater("gsNccqJraDZqM6WyGP3ea@FzCMyPR2LxkPFgr8eNGrq", // (1)
"Example Term", // (2)
"b4113341-251b-4adc-81fb-2420501c30e6"); // (3)
  1. The qualifiedName of the existing term, which must match exactly (case-sensitive). Note that for some assets (like terms), this may be a strange-looking Atlan-internal string.
  2. The name of the existing term. This must match exactly (case-sensitive).
  3. The GUID of the glossary in which the term exists.

Enrich before updating

The term object now has the minimal required information for Atlan to update it. Without any additional enrichment, though, there isn't really anything to update...

So first you should enrich the object:

Enrich the asset before updating it
GlossaryTerm term = termUpdater // (1)
.certificateStatus(CertificateStatus.VERIFIED) // (2)
.announcementType(AtlanAnnouncementType.INFORMATION) // (3)
.announcementTitle("Imported")
.announcementMessage("This term was imported from ...")
.build(); // (4)
  1. We'll create an object we can take actions on from this updater.

  2. In this example, we're adding a certificate to the object.

  3. Note that you can chain any number of enrichments together. Here we're also adding an announcement to the asset.

  4. To persist the enrichment back to the object, we must build() the builder.

    Assign the result back

Remember to assign the result of the build() operation back to your original object. Otherwise the result isn't persisted back into any variable! (In this case we're assigning to the term variable back on line 5.) :::

Update asset from object

You can then actually update the object in Atlan1:

Update (or create) the asset
AssetMutationResponse response = term.save(client); // (1)
Asset updated = response.getUpdatedAssets().get(0); // (2)
GlossaryTerm term;
if (updated instanceof GlossaryTerm)
  1. The save() method will either update an existing asset (if Atlan already has a term with the same name and qualifiedName in the same glossary) or create a new asset (if Atlan doesn't have a term with the same name in the same glossary). Because this operation will persist the asset in Atlan, you must provide it an AtlanClient through which to connect to the tenant.

  2. You can distinguish what was created or updated:

    • getCreatedAssets() lists assets that were created
    • getUpdatedAssets() lists assets that were updated

    Note that the save() method always returns objects of type Asset, though.

  3. The Asset class is a superclass of all assets. So we need to cast to more specific types (like GlossaryTerm) after verifying the object that was actually returned.

Strictly update the asset
try {
AssetMutationResponse response = term.updateMergingCM(client, false); // (1)
Asset updated = response.getUpdatedAssets().get(0); // (2)
GlossaryTerm term;
if (updated instanceof GlossaryTerm)
} catch (NotFoundException e)
  1. The updateMergingCM() method will only update an existing asset (if Atlan already has an asset of the same type with the same name qualifiedName). Because this operation will persist the asset in Atlan, you must provide it an AtlanClient through which to connect to the tenant. Depending on the update behavior you want, you could also use:

    • updateMergingCM(false) to only overwrite any custom metadata provided in your update (leaving anything you don't provide untouched on the existing asset), while leaving any Atlan tags on the existing asset untouched
    • updateMergingCM(true) to only overwrite any custom metadata provided in your update (leaving anything you don't provide untouched on the existing asset), while replacing any Atlan tags on the existing asset
    • updateReplacingCM(false) to overwrite all custom metadata on the existing asset with what you're providing in your update, while leaving any Atlan tags on the existing asset untouched
    • updateReplacingCM(true) to overwrite all custom metadata on the existing asset with what you're providing in your update, while replacing any Atlan tags on the existing asset
  2. You can distinguish what was created or updated:

    • getUpdatedAssets() lists assets that were updated

    Note that the update...() methods always returns objects of type Asset, though.

  3. The Asset class is a superclass of all assets. So we need to cast to more specific types (like GlossaryTerm) after verifying the object that was actually returned.

  4. Since the update...() methods strictly update (and never create) an asset, if the asset you are trying to update doesn't exist the operation will throw a NotFoundException.

Remove information from asset

As mentioned in Enrich before updating section, only the information in your request will be updated on the object. But what if you want to remove some information that already exists on the asset in Atlan?

Enrich and update the asset
GlossaryTerm term = termUpdater // (1)
.removeCertificate() // (2)
.removeAnnouncement() // (3)
.build(); // (4)
AssetMutationResponse response = term.save(client); // (5)
Asset updated = response.getUpdatedAssets().get(0); // (6)
GlossaryTerm term;
if (updated instanceof GlossaryTerm)
  1. We'll create an object we can take actions on from this updater.

  2. In this example, we'll remove any existing certificate from the object in Atlan.

  3. Note that you can chain any number of enrichments together. Here we're also removing any announcement from the asset.

  4. To persist the enrichment back to the object, we must build() the builder.

    Assign the result back

Remember to assign the result of the build() operation back to your original object. Otherwise the result isn't persisted back into any variable! (In this case we're assigning to the term variable back on line 5.) ::: 5. The save() method will either:

  • Update an existing asset, if Atlan already has a term with the same name and qualifiedName in the same glossary.
  • Create a new asset, if Atlan doesn't have a term with the same name in the same glossary.

Because this operation will persist the asset in Atlan, you must provide it an AtlanClient through which to connect to the tenant.

  1. You can distinguish what was created or updated:

    • getCreatedAssets() lists assets that were created
    • getUpdatedAssets() lists assets that were updated

    Note that the save() method always returns objects of type Asset, though.

  2. The Asset class is a superclass of all assets. So we need to cast to more specific types (like GlossaryTerm) after verifying the object that was actually returned.

Footnotes

  1. Atlan automatically detects changes to determine whether to create or update an asset—see the Importance of identifiers for a more detailed explanation. To strictly update (and avoid creating) an asset, you must first look for the existing asset and only if found proceed with your update. When the SDKs provide such strict update functionality, this is what they're doing behind-the-scenes. Be aware that this will impact performance, so you should only do this where strictly necessary for your logic.

  2. This is because Atlan uses the exact qualifiedName to determine whether it should do an update. For a more detailed explanation, see the Importance of identifiers.

Was this page helpful?