Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds contract spec initialization #852

Merged
merged 5 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ log4j = "2.24.0"
wiremock = "3.9.1"
jnanoid = "2.0.0"
numaflow = "0.8.0"
awssdk = "2.28.8"
awssdk = "2.28.9"
gcs = "26.47.0"
system-stubs = "2.1.6"
fastcsv = "3.3.1"
Expand All @@ -19,7 +19,7 @@ simplejavamail = "8.11.3"
swagger = "2.1.22"
jsonpath = "2.9.0"
commons-compress = "1.27.1"
sqlite = "3.46.1.1"
sqlite = "3.46.1.2"
jakarta-mail = "2.1.3"
angus-mail = "2.0.3"
pkl = "0.26.3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,19 @@ void createColumn8() throws AtlanException {
assertEquals(column8.getConnectionQualifiedName(), connection.getQualifiedName());
}

@Test(
groups = {"asset.create.contract"},
dependsOnGroups = {"asset.create.column.*"})
void generateContract() throws AtlanException {
String tableContract = Atlan.getDefaultClient().contracts.generateInitialSpec(table);
assertNotNull(tableContract);
assertTrue(tableContract.startsWith("---"));
assertTrue(tableContract.contains("columns:"));
assertTrue(tableContract.contains(" - name: " + COLUMN_NAME1));
assertTrue(tableContract.contains(" - name: " + COLUMN_NAME2));
assertTrue(tableContract.endsWith("...\n"));
}

@Test(
groups = {"asset.read.column.5"},
dependsOnGroups = {"asset.create.column.5"})
Expand Down
4 changes: 4 additions & 0 deletions sdk/src/main/java/com/atlan/AtlanClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ public class AtlanClient {
/** Endpoint with operations to interact with OpenLineage. */
public final OpenLineageEndpoint openLineage;

/** Endpoint with operations to interact with data contracts. */
public final ContractsEndpoint contracts;

/** Client-aware asset deserializer. */
@Getter
private final AssetDeserializer assetDeserializer;
Expand Down Expand Up @@ -225,6 +228,7 @@ public class AtlanClient {
tasks = new TaskEndpoint(this);
sso = new SSOEndpoint(this);
openLineage = new OpenLineageEndpoint(this);
contracts = new ContractsEndpoint(this);
atlanTagCache = new AtlanTagCache(typeDefs);
customMetadataCache = new CustomMetadataCache(typeDefs);
enumCache = new EnumCache(typeDefs);
Expand Down
79 changes: 79 additions & 0 deletions sdk/src/main/java/com/atlan/api/ContractsEndpoint.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* SPDX-License-Identifier: Apache-2.0
Copyright 2022 Atlan Pte. Ltd. */
package com.atlan.api;

import com.atlan.AtlanClient;
import com.atlan.exception.AtlanException;
import com.atlan.model.assets.Asset;
import com.atlan.model.core.AtlanObject;
import com.atlan.net.ApiResource;
import com.atlan.net.RequestOptions;
import lombok.EqualsAndHashCode;
import lombok.Getter;

/**
* API endpoints for data contract-specific operations.
*/
public class ContractsEndpoint extends HeraclesEndpoint {

private static final String endpoint = "/contracts";

private static final String endpoint_init = endpoint + "/init";

public ContractsEndpoint(AtlanClient client) {
super(client);
}

/**
* Generate an initial contract spec for the provided asset.
* The asset must have at least its qualifiedName (and type) populated.
*
* @param asset for which to generate the initial contract spec
* @return the YAML for the initial contract spec for the provided asset
* @throws AtlanException on any issue interacting with the API
*/
public String generateInitialSpec(Asset asset) throws AtlanException {
return generateInitialSpec(asset, null);
}

/**
* Generate an initial contract spec for the provided asset.
* The asset must have at least its qualifiedName (and type) populated.
*
* @param asset for which to generate the initial contract spec
* @param options to override default client settings
* @return the YAML for the initial contract spec for the provided asset
* @throws AtlanException on any issue interacting with the API
*/
public String generateInitialSpec(Asset asset, RequestOptions options) throws AtlanException {
InitRequest request = new InitRequest(asset);
String url = String.format("%s%s", getBaseUrl(), endpoint_init);
InitResponse response =
ApiResource.request(client, ApiResource.RequestMethod.POST, url, request, InitResponse.class, options);
return response.getContract();
}

@Getter
@EqualsAndHashCode(callSuper = false)
private static final class InitRequest extends AtlanObject {
private static final long serialVersionUID = 2L;
String assetType;
String assetQualifiedName;

public InitRequest(String assetType, String assetQualifiedName) {
this.assetType = assetType;
this.assetQualifiedName = assetQualifiedName;
}

public InitRequest(Asset asset) {
this(asset.getTypeName(), asset.getQualifiedName());
}
}

@Getter
@EqualsAndHashCode(callSuper = false)
private static final class InitResponse extends ApiResource {
private static final long serialVersionUID = 2L;
String contract;
}
}
Loading