diff --git a/api/src/main/java/marquez/service/models/Dataset.java b/api/src/main/java/marquez/service/models/Dataset.java index d5985f4c2c..60a7203a38 100644 --- a/api/src/main/java/marquez/service/models/Dataset.java +++ b/api/src/main/java/marquez/service/models/Dataset.java @@ -93,6 +93,11 @@ public Dataset( this.isDeleted = isDeleted; } + /** Returns the {@link NodeId} for this dataset, allowing direct queries to the Lineage API. */ + public NodeId getNodeId() { + return NodeId.of(id); + } + public Optional getLastModifiedAt() { return Optional.ofNullable(lastModifiedAt); } diff --git a/api/src/main/java/marquez/service/models/DatasetVersion.java b/api/src/main/java/marquez/service/models/DatasetVersion.java index 3575d3d6c8..1095b64171 100644 --- a/api/src/main/java/marquez/service/models/DatasetVersion.java +++ b/api/src/main/java/marquez/service/models/DatasetVersion.java @@ -23,6 +23,7 @@ import marquez.common.models.DatasetId; import marquez.common.models.DatasetName; import marquez.common.models.DatasetType; +import marquez.common.models.DatasetVersionId; import marquez.common.models.Field; import marquez.common.models.NamespaceName; import marquez.common.models.SourceName; @@ -89,6 +90,16 @@ public DatasetVersion( this.facets = (facets == null) ? ImmutableMap.of() : facets; } + /** + * Returns the {@link NodeId} for this dataset version, allowing direct queries to the Lineage + * API. The returned nodeId includes the version UUID (e.g., {@code + * dataset:namespace:name#version}). + */ + public NodeId getNodeId() { + return NodeId.of( + new DatasetVersionId(id.getNamespace(), id.getName(), version.getValue())); + } + public Optional getDescription() { return Optional.ofNullable(description); } diff --git a/api/src/main/java/marquez/service/models/Job.java b/api/src/main/java/marquez/service/models/Job.java index ccebe337db..ec5a2d92b0 100644 --- a/api/src/main/java/marquez/service/models/Job.java +++ b/api/src/main/java/marquez/service/models/Job.java @@ -90,6 +90,11 @@ public Job( this.tags = (tags == null) ? ImmutableSet.of() : tags; } + /** Returns the {@link NodeId} for this job, allowing direct queries to the Lineage API. */ + public NodeId getNodeId() { + return NodeId.of(id); + } + public Optional getLocation() { return Optional.ofNullable(location); } diff --git a/api/src/test/java/marquez/service/models/NodeIdOnModelsTest.java b/api/src/test/java/marquez/service/models/NodeIdOnModelsTest.java new file mode 100644 index 0000000000..763e55d59c --- /dev/null +++ b/api/src/test/java/marquez/service/models/NodeIdOnModelsTest.java @@ -0,0 +1,122 @@ +/* + * Copyright 2018-2023 contributors to the Marquez project + * SPDX-License-Identifier: Apache-2.0 + */ + +package marquez.service.models; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import java.net.URL; +import java.time.Instant; +import java.util.UUID; +import marquez.common.models.DatasetId; +import marquez.common.models.DatasetName; +import marquez.common.models.DatasetType; +import marquez.common.models.JobId; +import marquez.common.models.JobName; +import marquez.common.models.JobType; +import marquez.common.models.NamespaceName; +import marquez.common.models.SourceName; +import marquez.common.models.Version; +import org.junit.jupiter.api.Test; + +/** Tests that the {@code getNodeId()} method returns the correct {@link NodeId} for API models. */ +class NodeIdOnModelsTest { + + private static final NamespaceName NAMESPACE = NamespaceName.of("test-namespace"); + private static final Instant NOW = Instant.now(); + + @Test + void datasetNodeIdHasCorrectFormat() { + DatasetName datasetName = DatasetName.of("test-dataset"); + DatasetId datasetId = new DatasetId(NAMESPACE, datasetName); + + DbTable dataset = + new DbTable( + datasetId, + datasetName, + DatasetName.of("public.test_dataset"), + NOW, + NOW, + SourceName.of("test-source"), + ImmutableList.of(), + ImmutableSet.of(), + null, + null, + null, + null, + null, + ImmutableMap.of(), + false); + + NodeId nodeId = dataset.getNodeId(); + assertThat(nodeId).isNotNull(); + assertThat(nodeId.isDatasetType()).isTrue(); + assertThat(nodeId.getValue()).isEqualTo("dataset:test-namespace:test-dataset"); + } + + @Test + void datasetVersionNodeIdIncludesVersion() { + DatasetName datasetName = DatasetName.of("test-dataset"); + DatasetId datasetId = new DatasetId(NAMESPACE, datasetName); + UUID versionUuid = UUID.randomUUID(); + + DbTableVersion datasetVersion = + new DbTableVersion( + datasetId, + datasetName, + DatasetName.of("public.test_dataset"), + NOW, + new Version(versionUuid), + SourceName.of("test-source"), + ImmutableList.of(), + ImmutableSet.of(), + null, + null, + null, + null, + ImmutableMap.of()); + + NodeId nodeId = datasetVersion.getNodeId(); + assertThat(nodeId).isNotNull(); + assertThat(nodeId.hasVersion()).isTrue(); + assertThat(nodeId.getValue()) + .isEqualTo("dataset:test-namespace:test-dataset#" + versionUuid); + } + + @Test + void jobNodeIdHasCorrectFormat() { + JobName jobName = JobName.of("test-job"); + JobId jobId = new JobId(NAMESPACE, jobName); + + Job job = + new Job( + jobId, + JobType.BATCH, + jobName, + "test-job", + null, + null, + NOW, + NOW, + ImmutableSet.of(), + ImmutableSet.of(), + null, + null, + null, + null, + ImmutableMap.of(), + null, + null, + null); + + NodeId nodeId = job.getNodeId(); + assertThat(nodeId).isNotNull(); + assertThat(nodeId.isJobType()).isTrue(); + assertThat(nodeId.getValue()).isEqualTo("job:test-namespace:test-job"); + } +}