Skip to content

Releases: atlanhq/atlan-java

v1.3.1

26 Sep 13:11
Compare
Choose a tag to compare

⛑️ Deprecations

  • Deprecates the LineageRequest-based lineage operations.
    • The methods are still there, only marked deprecated, to avoid any existing code compilation breakages.
    • However, be advised that any code that still relies on these deprecated methods may no longer work in the near future (or indeed already).
    • Instead, use the LineageListRequest-based lineage operations, which offer equivalent functionality with improved performance.

🐞 Bug fixes

  • Adds an API token check as part of cache refreshes. Previously an expired or otherwise no-longer-valid API token would silently create empty caches, causing knock-on effects related to things like Atlan tags and custom metadata not being found. Now such tokens will be immediately identified and raised during the cache refresh process rather than silently failing.
  • Fixes deserialization of string-encoded primitives in JSON response payloads.

πŸ₯— QOL improvements

  • Enumerates the out-of-the-box Atlan packages, for use in searching for workflows to rerun using WorkflowSearchRequest.findByType()

v1.3.0

18 Sep 20:52
Compare
Choose a tag to compare

πŸŽ‰ New features

  • Adds models for new asset types:
    • Matillion
    • (Experimental) MongoDB
  • Adds query shortcuts for searchable relationships
  • (Experimental) Enhancements to provide the foundation for using the Java SDK for workflows (custom packages):
    • Adds user impersonation capability
    • Adds ability to include custom headers (at AtlanClient-level and as RequestOptions)

πŸ₯— QOL improvements

  • Improves error message passthrough
  • Adds handling for www-form-urlencoded requests
  • Adds further options for defining custom metadata attributes

v1.2.2

12 Sep 13:16
Compare
Choose a tag to compare

⛑️ Deprecations

  • Deprecates the ability to activate or deactivate users programmatically. This can no longer be achieved using an API token, so will be removed from the SDKs.
    • The methods are still there, only marked deprecated, to avoid any existing code compilation breakages.
    • However, be advised that any code that still relies on these deprecated methods will always receive an error at runtime now due to back-end changes.

🐞 Bug fixes

  • Uses explicit column projections for user listing API to reduce latency
  • Fixes deserialization of empty values (now treats null and "" as equivalent)

πŸ₯— QOL improvements

  • Adds option to further configure bucket aggregation, specifically to return the actual value of the field used for bucketing and control how many buckets to create
  • Extends the options that can be used for filtering entities in lineage beyond only CONTAINS

v1.2.1

05 Sep 09:57
Compare
Choose a tag to compare

🐞 Bug fixes

  • Fixes to allow associating API tokens with personas
  • Fixes incorrect field name being returned for custom metadata inclusion in search results

πŸ₯— QOL improvements

  • Adds option to capture any failed assets during AssetBatch processing

v1.2.0

31 Aug 16:30
Compare
Choose a tag to compare

πŸŽ‰ New features

  • Allows API tokens to be assigned as connection admins, query collection editors and viewers

🐞 Bug fixes

  • Parameterizes and defaults page size to 20 for users, groups and API tokens
  • Fixes bug where a number of the updater() helper methods did not include placeholder GUIDs

πŸ₯— QOL improvements

  • Adds more reusable approach to serde

v1.1.0

24 Aug 16:42
Compare
Choose a tag to compare

πŸŽ‰ New features

Fluent search

FluentSearch further simplifies searches. You can access the simplified searching using a new select() method in the same way you can use the all() method in v1.0.0. However, fluent search further simplifies and validates searches:

  • All attributes and search index fields are now defined as constants, so you no longer need to remember or deal with string values directly.
  • The predicates you can use to search a particular field are now accessible directly on these constants β€” and are restricted to those that apply to that kind of field. No more mistakenly using a gt to search on a boolean field, for example, or a startsWith on a numeric field. (These validations are also applied to custom metadata attributes, but only at runtime due to the runtime nature of custom metadata.)
  • You can now also directly get a count of results to a query using count() at the end of a fluent search chain, or directly translate the criteria defined in the chain into a search request using toRequest(). (All existing AssetFilter mechanisms also still apply to fluent searches: streaming, parallel streaming, etc.)
  • You no longer need to use or statically import the QueryFactory class β€” this has been replaced by a new CompoundQuery class that has static query helpers defined within it.
  • Aggregations are available within fluent searches.
  • The field constants also contain methods for sorting results by those fields, and for creating aggregations based on those fields.

For example, with an AssetFilter you would previously have written:

Column.all()
    .filter(QueryFactory.where(KeywordFields.QUALIFIED_NAME).startsWith("default/snowflake"))
    .batch(100)
    .attribute("description")
    .sort(QueryFactory.Sort.by(KeywordFields.NAME, SortOrder.Asc))
    .stream()
    .forEach(c -> {
        log.info("Column: {}", c);
    });

With the new FluentSearch you can now write the same as:

Column.select()
    .where(Column.QUALIFIED_NAME.startsWith("default/snowflake"))
    .pageSize(100)
    .includeOnResults(Column.DESCRIPTION)
    .sort(Column.NAME.order(SortOrder.Asc))
    .stream()
    .forEach(c -> {
        log.info("Column: {}", c);
    });

🐞 Bug fixes

  • Changes internal AssetBatch structures to be thread-safe
  • Fixes criteria for listing users to avoid an infinite loop

πŸͺ« Deprecations

  • The existing AssetFilter search simplification, its all() method, and the QueryFactory class all still exist, but they have all been marked as deprecated (and will be removed in the next major release).

v1.0.0

14 Aug 10:47
Compare
Choose a tag to compare

πŸŽ‰ Our official initial release of the Java SDK!

From here on out, we'll be using https://semver.org for releases, so you can expect more stability in your own dependency management going forward.

πŸŽ‰ New features

  • Adds models:
    • Airflow
    • Soda
  • Adds helpers to AssetMutationResponse to more easily retrieve information: subsets of assets by type, the mutation operation that occurred given a specific asset, and directly retrieving the result of a specific asset.
  • Adds placeholder GUIDs to all creator() methods, so it is now actually possible to use a single bulk asset save() that contains related assets (including parents and children).
  • Adds a parallel streaming option for iterating through indexsearch results that can greatly speed up algorithms that need to iterate through a large number of (large) results.
  • Adds new ability to attach and detach terms to assets as part of purpose policies.

⛑️ Breaking changes

  • GlossaryCategory.findByName() now returns multiple categories, since a category name is not unique.
  • This release removes the ability to delete users. This functionality was problematic in that it did not fully remove a user and could result in knock-on impacts such as failing future workflow runs and leaving dangling references. We will reinstate a similar method once available.

🐞 Bug fixes

  • Fixes an issue where a CategoryHierarchy class that contained only top-level categories may not have been fully initialized.
  • Fixes default sorting of index search results, when no other sorting has been applied.
  • Fixes issues where the default client would always be used, even if an alternative client is provided.

πŸ₯— QOL improvements

  • Lowers the default retry limit to 3 and only adds extra retries for blocking async mutation operations. Note that this means if you are not using the block() call on these async operations already, it will be your responsibility to add any extra retries or confirmation logic that the operations (and their async policies) are completed.
  • Adds operations that will explicitly update, and not create, assets.
  • Adds helper to the CategoryHierarchy class to retrieve any arbitrary category from the structure.

v0.9.0

03 Aug 13:02
Compare
Choose a tag to compare

πŸŽ‰ New features

  • Asset filters to pipeline bulk query and update operations directly and efficiently
  • Search for terms by their categories and categories by their parent category
  • Search and retrieve logged administrative events, such as user logins
  • Models for:
    • Azure Event Hub
    • Functions
    • StarredBy details
    • DbtTag
  • Adds a unique X-Atlan-Request-Id header to every call that can be used for tracing requests all the way through Atlan's back-end operations

⛑️ Breaking changes

  • Replaces the retrieveFull(), retrieveMinimal(), retrieveByGuid() and retrieveByQualifiedName() methods with a single overloaded get() method:
    • From any asset you can now retrieve an instance using get(), for example: Table.get(). The SDK will automatically detect whether you are retrieving the asset by GUID or qualifiedName and act accordingly. To retrieve the minimal version (without relationships) simply pass an optional argument of false to not include the relationships.
    • For dynamic typing, you can use Asset.get() in place of Asset.retrieveFull() and Asset.retrieveMinimal().
  • The builder() method of assets was only ever intended for internal use. As such, it has now been renamed _internal() to make this more apparent. Unless explicitly mentioned in developer.atlan.com, you should always use creator(), updater(), or trimToRequired() rather than directly accessing _internal() to construct an asset.
  • The SDK now supports running against multiple tenants in a single JVM. To enable this, we've:
    • Added a mandatory AtlanClient parameter when creating an AssetBatch. (You can pass Atlan.getDefaultClient() to retain the existing behavior.)
    • Removed the ability to directly access the Serde.mapper ObjectMapper β€” instead now use the .readValue() and .writeValueAsString() operations on an AtlanClient. (For example: Atlan.getDefaultClient().readValue().)
    • Related to above, toJson() on any asset now requires a client β€” if you were using this directly, you can now call .toJson(Atlan.getDefaultClient()) to retain the existing behavior.
    • Removed the ability to directly access the various ...Endpoint classes. These are now only available through an AtlanClient, for example: Atlan.getDefaultClient().assets.save(List.of(asset1, asset2), false) rather than BulkEntityEndpoint.upsert(List.of(asset1, asset2), false).
    • Removed static caches β€” caches are now client-specific:
      • Anywhere you previously did something like RoleCache.getIdForName() you will now need to use Atlan.getDefaultClient().getRoleCache().getIdForName().
      • Note that this pattern applies to all caches (RoleCache, CustomMetadataCache, AtlanTagCache, EnumCache, UserCache and GroupCache).
  • The static getBaseUrlSafe() method has been removed, as the getBaseUrl() method no longer throws a checked exception and can therefore be used directly instead.
  • The upsert() operation has been deprecated, replaced by a save() operation that takes the same arguments and behaves in the same way.

(Note: we're reserving the right to make breaking changes to the SDK prior to a 1.0.0 release, without incrementing the major version. Once we hit 1.0.0, we'll adhere to https://semver.org)

🐞 Bug fixes

  • Fixes an IndexOutOfBoundsException that could occur when trying to retrieve a non-existent API token by its name.
  • Fixes an issue with the default page size used for asset filters, so they should now work even if no page size is explicitly set.
  • Marks all API-operable objects as serializable.
  • Replaces the toString() method that produced JSON output with an object-native toString(). While this may feel less readable, it removes any dependency on tenant-specific information for the serialization process, and should avoid hiding any transformation or translations that would occur through such a serialization.
  • Adds a missing PURGED status that can exist in some circumstances on deleted instances of metadata.
  • No longer fails if custom metadata that no longer exists is encountered, but instead uses a value of (DELETED) and logs.
  • Fixes blocking check on asset deletion.

πŸ₯— QOL improvements

  • Asset instance retrieval has been simplified to a single get() method that works for both GUIDs and qualifiedNames.
  • The findByName() method that exists for various assets (connections, glossary objects, etc) no longer requires an attributes argument (if none is provided it will default to the minimal set of attributes now).
  • With asset filters you can now quickly query assets of a given type, without needing to build or run a separate IndexSearchRequest. For example: Table.all().filter(...).stream().forEach(a -> log.info("Found asset: {}", a));
  • All operations that you can invoke against an endpoint now have variants that can take an (optional) RequestOptions object. When provided, these allow you to override default client settings for that individual request β€” timeouts, max retries, etc.
  • Bumps all library dependencies to their latest stable versions.

v0.8.0

30 Jun 18:20
Compare
Choose a tag to compare

πŸŽ‰ New features

  • Adds the ability to manage arbitrary files as assets
  • Adds an abstraction layer for easing implementation of real-time event-processing through webhooks, in particular when implemented using AWS Lambda functions
  • Index searches have been simplified through their builder() method, defaults for paging, and providing other shortcut factory methods (like of() for the DSL)
  • Lineage listings have been simplified through their builder() method and defaults for parameters
  • Index search and lineage listing responses now provide Iterable<Asset> and .stream() interfaces to simplify iterating through results. These make looping much simpler while simultaneously more efficient β€” In both cases the next pages of results are automatically fetched as-needed, lazily, so you can always break-out early without retrieving unnecessary results.

⛑️ Breaking changes

  • Search builders now have a required argument (the DSL or query to search), rather than starting blank.
  • Lineage list builders now have a required argument (the GUID of the asset to start from), rather than starting blank.
  • AssetBatch operations now throw any checked exceptions rather than swallowing and logging them.
  • Implements multi-inheritance polymorphism for assets.
    • This means a given asset type can now inherit its full set of attributes and relationships (across multiple supertypes).
    • However, it means we have removed the abstract classes that represented supertypes of assets and replaced these with interfaces. For example, there is no longer a SQL or a Catalog class, but an ISQL and an ICatalog interface.
    • Anywhere you previously were checking an asset using if (a instanceof Catalog) with such an abstract class, you'll now need to do the same check against the interface instead (e.g. if (a instanceof ICatalog)).
    • The benefit of this change is that the asset types in the SDK now accurately reflect multi-inheritance of Atlan itself. So a SnowflakeTag for example will be both instanceof ITag and instanceof ISQL. (With class-based inheritance, we had to choose just one of these to extend.)
    • Relationships are all now specified using their interface rather than their class, so for example getAssignedTerms() will now return IGlossaryTerms rather than GlossaryTerms. As long as you are accessing instance methods for your operations, this should be a transparent change for you in almost all cases, as the interface has all the same (non-static) methods defined on it that exist on the class.

(Note: we're reserving the right to make breaking changes to the SDK prior to a 1.0.0 release, without incrementing the major version. Once we hit 1.0.0, we'll adhere to https://semver.org)

🐞 Bug fixes

  • Fixes an issue introduced in the last release where the assignedTerms relationship was missing from generated test classes.
  • Fixes an issue that required an attributes.csv file to be present for injecting descriptions into generated POJOs β€” this is now optional as part of the code generation.
  • Fixes an issue for TableauDatasource objects, which can now return both calculated fields and datasource fields through the single fields relationship.
  • Fixes the level of caching attempted for roles β€” previously every role was cached, whereas now only the workspace-roles will be cached.

πŸ₯— QOL improvements

  • The Iterable<Asset> interface provided by index search and lineage listing responses allow you to:
    • Use a simple for-each loop: for (Asset a : response) { ... }
    • Use a forEach() lambda: response.forEach(a -> { ... });
  • The .stream() interface provides the results as a stream, allowing you to:
    • Use chain-able stream operations, such as: response.stream().filter(...).limit(n).forEach(a -> {...}).collect()
  • When the retry limit is reached for automated retries, any underlying exceptions or response body should now be logged in addition to the fact that the retry limit was reached.
  • Every snapshot build and release now uploads a lambda-layer.zip file that can be uploaded directly as an AWS Lambda layer, providing the full Java SDK (and its dependencies). You can then implement any of your own logic through the abstraction layer and simply upload that minimal code directly, without needing to re-package the entire SDK and its dependencies. (This allows you to upload and manage the SDK layer independently of possibly many event handlers implemented on top of it.)

v0.7.0

19 Jun 11:29
Compare
Choose a tag to compare

πŸŽ‰ New features

  • Adds higher-performance lineage list API
  • Adds ability to manage an icon or image for tags (classifications)
  • Adds new type definitions for:
    • MicroStrategy objects
  • Renames "classification" to "tag" to align with UI changes
  • Adds new persona/purpose/policy management

⛑️ Breaking changes

  • Renames "classifications" to "tags". Back-end payloads remain unchanged, but any properties or methods that referred to classification will now refer to atlanTag. For example:
    • mappedClassificationName -> mappedAtlanTagName
    • purposeClassifications -> purposeAtlanTags
    • ClassificationCache -> AtlanTagCache
    • Classification -> AtlanTag
    • ClassificationDef -> AtlanTagDef
    • classifications -> atlanTags
    • classificationNames -> atlanTagNames
    • appendClassifications -> appendAtlanTags
    • addClassifications -> addAtlanTags
  • Updates persona, purpose and policy management to use new optimized internal changes. As a result, the specific objects and methods needed to manage personas, purposes and policies have changed:
    • Persona and Purpose have moved into com.atlan.model.assets
    • These now directly provide createMetadataPolicy and createDataPolicy (and createGlossaryPolicy in Persona) helpers to manage the policies
    • AuthPolicy is the new base object for all policies (the helpers above now create AuthPolicy objects)
    • Policy management is now more consistent across the two mechanisms, and policies can now be created in bulk for both as well

(Note: we're reserving the right to make breaking changes to the SDK prior to a 1.0.0 release, without incrementing the major version. Once we hit 1.0.0, we'll adhere to https://semver.org)

πŸ₯— QOL improvements

  • Refactors the code generators used to build the SDK, so that they can be reused to create "extended" SDKs. All generated code is now also annotated (javax.annotation.Generated) for easier identification and simplifying common tasks like excluding generated code from coverage tests.

(Note: this is really just a re-issue of the v0.7.0 release that fixes a JavaDoc error that caused publishing to Maven Central to fail.)