Skip to content

Commit

Permalink
Merge pull request #2937 from atlanhq/data-contract
Browse files Browse the repository at this point in the history
DQ-22: Data contract PreProcessor
  • Loading branch information
bichitra95 authored Apr 30, 2024
2 parents ff7cdd5 + fb0ee62 commit 7a3a1c5
Show file tree
Hide file tree
Showing 7 changed files with 742 additions and 1 deletion.
70 changes: 70 additions & 0 deletions addons/policies/bootstrap_entity_policies.json
Original file line number Diff line number Diff line change
Expand Up @@ -3005,6 +3005,76 @@
"entity-delete"
]
}
},
{
"typeName": "AuthPolicy",
"attributes":
{
"name": "READ_DATA_CONTRACT",
"qualifiedName": "READ_DATA_CONTRACT",
"policyCategory": "bootstrap",
"policySubCategory": "default",
"policyServiceName": "atlas",
"policyType": "allow",
"policyPriority": 1,
"policyUsers":
[],
"policyGroups":
[],
"policyRoles":
[
"$admin",
"$member",
"$api-token-default-access"
],
"policyResourceCategory": "ENTITY",
"policyResources":
[
"entity-type:DataContract",
"entity-classification:*",
"entity:*"
],
"policyActions":
[
"entity-read"
]
}
},
{
"typeName": "AuthPolicy",
"attributes":
{
"name": "CU_DATA_CONTRACT",
"qualifiedName": "CU_DATA_CONTRACT",
"description": "cu allow for data contract",
"policyCategory": "bootstrap",
"policySubCategory": "default",
"policyServiceName": "atlas",
"policyType": "allow",
"policyPriority": 1,
"policyUsers":
[],
"policyGroups":
[],
"policyRoles":
[
"$admin",
"$member",
"$api-token-default-access"
],
"policyResourceCategory": "ENTITY",
"policyResources":
[
"entity-type:DataContract",
"entity-classification:*",
"entity:*"
],
"policyActions":
[
"entity-create",
"entity-update"
]
}
}
]
}
10 changes: 9 additions & 1 deletion common/src/main/java/org/apache/atlas/repository/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,13 @@ public final class Constants {
public static final String ASSET_README_EDGE_LABEL = "__Asset.readme";
public static final String ASSET_LINK_EDGE_LABEL = "__Asset.links";

/**
* Contract
*/
public static final String CONTRACT_ENTITY_TYPE = "DataContract";
public static final String ATTR_CONTRACT_VERSION = "dataContractVersion";


/**
* Lineage relations.
*/
Expand Down Expand Up @@ -403,7 +410,8 @@ public enum SupportedFileExtensions { XLSX, XLS, CSV }
public static final String ATTR_STARRED_DETAILS_LIST = "starredDetailsList";
public static final String ATTR_ASSET_STARRED_BY = "assetStarredBy";
public static final String ATTR_ASSET_STARRED_AT = "assetStarredAt";

public static final String ATTR_CERTIFICATE_STATUS = "certificateStatus";
public static final String ATTR_CONTRACT = "dataContractJson";
public static final String STRUCT_STARRED_DETAILS = "StarredDetails";

public static final String KEYCLOAK_ROLE_ADMIN = "$admin";
Expand Down
6 changes: 6 additions & 0 deletions repository/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,12 @@
<version>3.0.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.3.2.Final</version>
</dependency>

</dependencies>

<profiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import org.apache.atlas.repository.store.graph.v1.RestoreHandlerV1;
import org.apache.atlas.repository.store.graph.v2.preprocessor.AuthPolicyPreProcessor;
import org.apache.atlas.repository.store.graph.v2.preprocessor.ConnectionPreProcessor;
import org.apache.atlas.repository.store.graph.v2.preprocessor.contract.ContractPreProcessor;
import org.apache.atlas.repository.store.graph.v2.preprocessor.resource.LinkPreProcessor;
import org.apache.atlas.repository.store.graph.v2.preprocessor.PreProcessor;
import org.apache.atlas.repository.store.graph.v2.preprocessor.accesscontrol.PersonaPreProcessor;
Expand Down Expand Up @@ -1835,6 +1836,10 @@ public PreProcessor getPreProcessor(String typeName) {
case README_ENTITY_TYPE:
preProcessor = new ReadmePreProcessor(typeRegistry, entityRetriever);
break;

case CONTRACT_ENTITY_TYPE:
preProcessor = new ContractPreProcessor(graph, typeRegistry, entityRetriever, storeDifferentialAudits, discovery);
break;
}

return preProcessor;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package org.apache.atlas.repository.store.graph.v2.preprocessor.contract;

import org.apache.atlas.RequestContext;
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
import org.apache.atlas.authorize.AtlasEntityAccessRequest;
import org.apache.atlas.authorize.AtlasPrivilege;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever;
import org.apache.atlas.repository.store.graph.v2.preprocessor.PreProcessor;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.utils.AtlasPerfMetrics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

import static org.apache.atlas.AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND;
import static org.apache.atlas.AtlasErrorCode.TYPE_NAME_INVALID;
import static org.apache.atlas.repository.Constants.*;

public abstract class AbstractContractPreProcessor implements PreProcessor {
private static final Logger LOG = LoggerFactory.getLogger(AbstractContractPreProcessor.class);

public final AtlasTypeRegistry typeRegistry;
public final EntityGraphRetriever entityRetriever;
public final AtlasGraph graph;


AbstractContractPreProcessor(AtlasGraph graph, AtlasTypeRegistry typeRegistry,
EntityGraphRetriever entityRetriever) {
this.graph = graph;
this.typeRegistry = typeRegistry;
this.entityRetriever = entityRetriever;
}

void authorizeContractCreateOrUpdate(AtlasEntity contractEntity, AtlasEntity.AtlasEntityWithExtInfo associatedAsset) throws AtlasBaseException {
AtlasPerfMetrics.MetricRecorder metricRecorder = RequestContext.get().startMetricRecord("authorizeContractUpdate");
try {
AtlasEntityHeader entityHeader = new AtlasEntityHeader(associatedAsset.getEntity());

//First authorize entity update access
verifyAssetAccess(entityHeader, AtlasPrivilege.ENTITY_UPDATE, contractEntity, AtlasPrivilege.ENTITY_UPDATE);

} finally {
RequestContext.get().endMetricRecord(metricRecorder);
}
}


private void verifyAssetAccess(AtlasEntityHeader asset, AtlasPrivilege assetPrivilege,
AtlasEntity contract, AtlasPrivilege contractPrivilege) throws AtlasBaseException {
verifyAccess(asset, assetPrivilege);
verifyAccess(contract, contractPrivilege);
}

private void verifyAccess(AtlasEntity entity, AtlasPrivilege privilege) throws AtlasBaseException {
verifyAccess(new AtlasEntityHeader(entity), privilege);
}

private void verifyAccess(AtlasEntityHeader entityHeader, AtlasPrivilege privilege) throws AtlasBaseException {
String errorMessage = privilege.name() + " entity: " + entityHeader.getTypeName();
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, privilege, entityHeader), errorMessage);
}

AtlasEntity.AtlasEntityWithExtInfo getAssociatedAsset(String datasetQName, String typeName) throws AtlasBaseException {

Map<String, Object> uniqAttributes = new HashMap<>();
uniqAttributes.put(QUALIFIED_NAME, datasetQName);

AtlasEntityType entityType = ensureEntityType(typeName);

AtlasVertex entityVertex = AtlasGraphUtilsV2.getVertexByUniqueAttributes(graph, entityType, uniqAttributes);

return entityRetriever.toAtlasEntityWithExtInfo(entityVertex);
}

AtlasEntityType ensureEntityType(String typeName) throws AtlasBaseException {
AtlasEntityType ret = typeRegistry.getEntityTypeByName(typeName);

if (ret == null) {
throw new AtlasBaseException(TYPE_NAME_INVALID, TypeCategory.ENTITY.name(), typeName);
}

return ret;
}


}
Loading

0 comments on commit 7a3a1c5

Please sign in to comment.