diff --git a/.github/workflows/chart-release-dispatcher.yaml b/.github/workflows/chart-release-dispatcher.yaml index 10fc6cbdb0..ecc4348768 100644 --- a/.github/workflows/chart-release-dispatcher.yaml +++ b/.github/workflows/chart-release-dispatcher.yaml @@ -29,7 +29,7 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3 with: - token: ${{ secrets.my_pat }} + token: ${{ secrets.ORG_PAT_GITHUB }} ref: ${{ steps.extract_branch.outputs.branch }} fetch-depth: 0 @@ -50,10 +50,10 @@ jobs: - name: Get PR url and PR User id: get_pr_url_user run: | - head_sha=$(curl -s -H "Authorization: Bearer ${{ secrets.my_pat }}" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}/jobs" | jq -r '.jobs[0].head_sha') + head_sha=$(curl -s -H "Authorization: Bearer ${{ secrets.ORG_PAT_GITHUB }}" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}/jobs" | jq -r '.jobs[0].head_sha') echo "Head SHA: $head_sha" - pr_url=$(curl -s -H "Authorization: Bearer ${{ secrets.my_pat }}" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/search/issues?q=sha:$head_sha+type:pr" | jq -r '.items[0].html_url') - pr_user=$(curl -s -H "Authorization: Bearer ${{ secrets.my_pat }}" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/search/issues?q=sha:$head_sha+type:pr" | jq -r '.items[0].user.login') + pr_url=$(curl -s -H "Authorization: Bearer ${{ secrets.ORG_PAT_GITHUB }}" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/search/issues?q=sha:$head_sha+type:pr" | jq -r '.items[0].html_url') + pr_user=$(curl -s -H "Authorization: Bearer ${{ secrets.ORG_PAT_GITHUB }}" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/search/issues?q=sha:$head_sha+type:pr" | jq -r '.items[0].user.login') echo "pr_url=$pr_url" >> $GITHUB_OUTPUT echo "pr_user=$pr_user" >> $GITHUB_OUTPUT @@ -65,7 +65,7 @@ jobs: - name: Repository Dispatch uses: peter-evans/repository-dispatch@v2 with: - token: ${{ secrets.my_pat }} + token: ${{ secrets.ORG_PAT_GITHUB }} repository: ${{ matrix.repo }} event-type: dispatch_chart_release_workflow client-payload: |- diff --git a/.github/workflows/github-actions-pr-jira.yaml b/.github/workflows/github-actions-pr-jira.yaml new file mode 100644 index 0000000000..76cd01ab38 --- /dev/null +++ b/.github/workflows/github-actions-pr-jira.yaml @@ -0,0 +1,14 @@ +name: GitHub-Jira Link Action +run-name: ${{ github.actor }} is ensuring Jira ID is present in PR title +on: + pull_request: + types: [opened, edited, synchronize, reopened] + branches: [main, staging, master, beta, develop, prod, development] + +jobs: + Enforce-GitHub-Jira-Link-Action: + runs-on: ubuntu-latest + if: ${{ !contains(fromJson('["main", "staging", "master", "beta", "develop", "prod", "development"]'), github.event.pull_request.head.ref) }} + steps: + - name: Enforce Pull Request Title includes Jira Issue Key + uses: ryanvade/enforce-pr-title-style-action@v2.1.1 \ No newline at end of file diff --git a/.github/workflows/main-ecr.yml b/.github/workflows/main-ecr.yml index acb8883f8d..2a64a38c27 100644 --- a/.github/workflows/main-ecr.yml +++ b/.github/workflows/main-ecr.yml @@ -196,4 +196,4 @@ jobs: ${{ steps.login-ecr.outputs.registry }}/atlanhq/${{ github.event.repository.name }}:${{ steps.get_branch.outputs.branch }}-${{ steps.semver_tag.outputs.new_tag }} build-args: | ACCESS_TOKEN_USR=$GITHUB_ACTOR - ACCESS_TOKEN_PWD=${{ secrets.my_pat }} \ No newline at end of file + ACCESS_TOKEN_PWD=${{ secrets.ORG_PAT_GITHUB }} \ No newline at end of file diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 0977cb36a2..f8a09b5589 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -58,7 +58,7 @@ jobs: [{ "id": "github", "username": "atlan-ci", - "password": "${{ secrets.my_pat }}" + "password": "${{ secrets.ORG_PAT_GITHUB }}" }] - name: Build with Maven @@ -77,7 +77,7 @@ jobs: shell: bash - name: Get version tag - run: echo "##[set-output name=version;]$(echo `git ls-remote https://${{ secrets.my_pat }}@github.com/atlanhq/${REPOSITORY_NAME}.git ${{ steps.get_branch.outputs.branch }} | awk '{ print $1}' | cut -c1-7`)abcd" + run: echo "##[set-output name=version;]$(echo `git ls-remote https://${{ secrets.ORG_PAT_GITHUB }}@github.com/atlanhq/${REPOSITORY_NAME}.git ${{ steps.get_branch.outputs.branch }} | awk '{ print $1}' | cut -c1-7`)abcd" id: get_version - name: Set up Buildx @@ -89,7 +89,7 @@ jobs: with: registry: ghcr.io username: $GITHUB_ACTOR - password: ${{ secrets.my_pat }} + password: ${{ secrets.ORG_PAT_GITHUB }} - name: Build and push id: docker_build diff --git a/.github/workflows/trivy-docker-scan.yml b/.github/workflows/trivy-docker-scan.yml index 6be78e7552..f910348903 100644 --- a/.github/workflows/trivy-docker-scan.yml +++ b/.github/workflows/trivy-docker-scan.yml @@ -29,7 +29,7 @@ jobs: output: 'trivy-results-docker.sarif' exit-code: '1' #ignore-unfixed: true - severity: 'CRITICAL,HIGH,MEDIUM' + severity: 'CRITICAL,HIGH' - name: Upload Trivy Docker Scan Results To GitHub Security tab uses: github/codeql-action/upload-sarif@v2 diff --git a/common/src/main/java/org/apache/atlas/repository/Constants.java b/common/src/main/java/org/apache/atlas/repository/Constants.java index 9408328b9f..accea8ec88 100644 --- a/common/src/main/java/org/apache/atlas/repository/Constants.java +++ b/common/src/main/java/org/apache/atlas/repository/Constants.java @@ -431,7 +431,8 @@ public enum SupportedFileExtensions { XLSX, XLS, CSV } 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 ATTR_CONTRACT = "dataContractSpec"; + public static final String ATTR_CONTRACT_JSON = "dataContractJson"; public static final String STRUCT_STARRED_DETAILS = "StarredDetails"; public static final String KEYCLOAK_ROLE_ADMIN = "$admin"; diff --git a/repository/pom.xml b/repository/pom.xml index a2a1a4198f..bbe15338f8 100755 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -327,6 +327,11 @@ hibernate-validator 4.3.2.Final + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.12.7 + diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java index 179d915df9..d5926e8a00 100755 --- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java +++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java @@ -540,7 +540,8 @@ public static List getPropagatedVerticesIds (AtlasVertex classificationV } public static boolean hasEntityReferences(AtlasVertex classificationVertex) { - return classificationVertex.hasEdges(AtlasEdgeDirection.IN, CLASSIFICATION_LABEL); + Iterator edgeIterator = classificationVertex.query().direction(AtlasEdgeDirection.IN).label(CLASSIFICATION_LABEL).edges(1).iterator(); + return edgeIterator != null && edgeIterator.hasNext(); } public static List getAllPropagatedEntityVertices(AtlasVertex classificationVertex) { diff --git a/repository/src/main/java/org/apache/atlas/repository/store/aliasstore/ESAliasStore.java b/repository/src/main/java/org/apache/atlas/repository/store/aliasstore/ESAliasStore.java index ddd57e2664..2d272cb8fc 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/aliasstore/ESAliasStore.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/aliasstore/ESAliasStore.java @@ -65,6 +65,7 @@ @Component public class ESAliasStore implements IndexAliasStore { private static final Logger LOG = LoggerFactory.getLogger(ESAliasStore.class); + public static final String NEW_WILDCARD_DOMAIN_SUPER = "default/domain/*/super"; private final AtlasGraph graph; private final EntityGraphRetriever entityRetriever; @@ -214,7 +215,11 @@ private void personaPolicyToESDslClauses(List policies, } else if (getPolicyActions(policy).contains(ACCESS_READ_PERSONA_DOMAIN)) { for (String asset : assets) { - terms.add(asset); + if(!isAllDomain(asset)) { + terms.add(asset); + } else { + asset = NEW_WILDCARD_DOMAIN_SUPER; + } allowClauseList.add(mapOf("wildcard", mapOf(QUALIFIED_NAME, asset + "*"))); } @@ -246,6 +251,9 @@ private void personaPolicyToESDslClauses(List policies, allowClauseList.add(mapOf("terms", mapOf(QUALIFIED_NAME, terms))); } + private boolean isAllDomain(String asset) { + return asset.equals("*/super") || asset.equals("*") || asset.equals(NEW_WILDCARD_DOMAIN_SUPER); + } private Map esClausesToFilter(List> allowClauseList) { if (CollectionUtils.isNotEmpty(allowClauseList)) { return mapOf("bool", mapOf("should", allowClauseList)); diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/AuthPolicyPreProcessor.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/AuthPolicyPreProcessor.java index 62adf8119a..58fb516564 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/AuthPolicyPreProcessor.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/AuthPolicyPreProcessor.java @@ -42,10 +42,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import static org.apache.atlas.AtlasErrorCode.BAD_REQUEST; @@ -67,6 +64,7 @@ public class AuthPolicyPreProcessor implements PreProcessor { private static final Logger LOG = LoggerFactory.getLogger(AuthPolicyPreProcessor.class); + public static final String ENTITY_DEFAULT_DOMAIN_SUPER = "entity:default/domain/*/super"; private final AtlasGraph graph; private final AtlasTypeRegistry typeRegistry; @@ -127,6 +125,8 @@ private void processCreatePolicy(AtlasStruct entity) throws AtlasBaseException { if (!POLICY_SUB_CATEGORY_DOMAIN.equals(policySubCategory)) { validator.validate(policy, null, parentEntity, CREATE); validateConnectionAdmin(policy); + } else { + validateAndReduce(policy); } policy.setAttribute(QUALIFIED_NAME, String.format("%s/%s", getEntityQualifiedName(parentEntity), getUUID())); @@ -165,6 +165,21 @@ private void processCreatePolicy(AtlasStruct entity) throws AtlasBaseException { RequestContext.get().endMetricRecord(metricRecorder); } + + private void validateAndReduce(AtlasEntity policy) { + List resources = (List) policy.getAttribute(ATTR_POLICY_RESOURCES); + boolean hasAllDomainPattern = resources.stream().anyMatch(resource -> + resource.equals("entity:*") || + resource.equals("entity:*/super") || + resource.equals(ENTITY_DEFAULT_DOMAIN_SUPER) + ); + + if (hasAllDomainPattern) { + policy.setAttribute(ATTR_POLICY_RESOURCES, Collections.singletonList(ENTITY_DEFAULT_DOMAIN_SUPER)); + } + } + + private void processUpdatePolicy(AtlasStruct entity, AtlasVertex vertex) throws AtlasBaseException { AtlasPerfMetrics.MetricRecorder metricRecorder = RequestContext.get().startMetricRecord("processUpdatePolicy"); AtlasEntity policy = (AtlasEntity) entity; @@ -182,6 +197,8 @@ private void processUpdatePolicy(AtlasStruct entity, AtlasVertex vertex) throws if (!POLICY_SUB_CATEGORY_DOMAIN.equals(policySubCategory)) { validator.validate(policy, existingPolicy, parentEntity, UPDATE); validateConnectionAdmin(policy); + } else { + validateAndReduce(policy); } String qName = getEntityQualifiedName(existingPolicy); diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/PreProcessorUtils.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/PreProcessorUtils.java index 3dc97fa642..260f228351 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/PreProcessorUtils.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/PreProcessorUtils.java @@ -60,6 +60,8 @@ public class PreProcessorUtils { public static final String DAAP_VISIBILITY_GROUPS_ATTR = "daapVisibilityGroups"; public static final String OUTPUT_PORT_GUIDS_ATTR = "daapOutputPortGuids"; public static final String INPUT_PORT_GUIDS_ATTR = "daapInputPortGuids"; + public static final String DAAP_STATUS_ATTR = "daapStatus"; + public static final String DAAP_ARCHIVED_STATUS = "Archived"; //Migration Constants public static final String MIGRATION_TYPE_PREFIX = "MIGRATION:"; diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/accesscontrol/StakeholderPreProcessor.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/accesscontrol/StakeholderPreProcessor.java index 1adbb8ec47..1cba29f935 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/accesscontrol/StakeholderPreProcessor.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/accesscontrol/StakeholderPreProcessor.java @@ -58,8 +58,7 @@ import static org.apache.atlas.repository.Constants.STAKEHOLDER_ENTITY_TYPE; import static org.apache.atlas.repository.Constants.STAKEHOLDER_TITLE_ENTITY_TYPE; import static org.apache.atlas.repository.store.graph.v2.preprocessor.PreProcessorUtils.indexSearchPaginated; -import static org.apache.atlas.repository.store.graph.v2.preprocessor.datamesh.StakeholderTitlePreProcessor.ATTR_DOMAIN_QUALIFIED_NAMES; -import static org.apache.atlas.repository.store.graph.v2.preprocessor.datamesh.StakeholderTitlePreProcessor.STAR; +import static org.apache.atlas.repository.store.graph.v2.preprocessor.datamesh.StakeholderTitlePreProcessor.*; import static org.apache.atlas.repository.util.AccessControlUtils.ATTR_ACCESS_CONTROL_ENABLED; import static org.apache.atlas.repository.util.AccessControlUtils.ATTR_PERSONA_ROLE_ID; import static org.apache.atlas.repository.util.AccessControlUtils.REL_ATTR_POLICIES; @@ -290,7 +289,7 @@ protected void ensureTitleAvailableForDomain(String domainQualifiedName, String List domainQualifiedNames = (List) stakeholderTitleHeader.getAttribute(ATTR_DOMAIN_QUALIFIED_NAMES); - if (!domainQualifiedNames.contains(STAR)) { + if (!domainQualifiedNames.contains(STAR) && !domainQualifiedNames.contains(NEW_STAR)) { Optional parentDomain = domainQualifiedNames.stream().filter(x -> domainQualifiedName.startsWith(x)).findFirst(); if (!parentDomain.isPresent()) { diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/contract/ContractPreProcessor.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/contract/ContractPreProcessor.java index 98add96a39..1407c3c2ef 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/contract/ContractPreProcessor.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/contract/ContractPreProcessor.java @@ -1,9 +1,5 @@ package org.apache.atlas.repository.store.graph.v2.preprocessor.contract; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - import org.apache.atlas.RequestContext; import org.apache.atlas.discovery.EntityDiscoveryService; import org.apache.atlas.exception.AtlasBaseException; @@ -19,11 +15,10 @@ import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.databind.ObjectMapper; - import java.util.*; import static org.apache.atlas.AtlasErrorCode.*; @@ -43,6 +38,7 @@ public class ContractPreProcessor extends AbstractContractPreProcessor { private static final Set contractAttributes = new HashSet<>(); static { contractAttributes.add(ATTR_CONTRACT); + contractAttributes.add(ATTR_CONTRACT_JSON); contractAttributes.add(ATTR_CERTIFICATE_STATUS); contractAttributes.add(ATTR_CONTRACT_VERSION); } @@ -78,12 +74,17 @@ public void processAttributes(AtlasStruct entityStruct, EntityMutationContext co } private void processUpdateContract(AtlasEntity entity, EntityMutationContext context) throws AtlasBaseException { - String contractString = (String) entity.getAttribute(ATTR_CONTRACT); + String contractString = getContractString(entity); AtlasVertex vertex = context.getVertex(entity.getGuid()); AtlasEntity existingContractEntity = entityRetriever.toAtlasEntity(vertex); // No update to relationships allowed for the existing contract version resetAllRelationshipAttributes(entity); - if (!isEqualContract(contractString, (String) existingContractEntity.getAttribute(ATTR_CONTRACT))) { + DataContract contract = DataContract.deserialize(contractString); + String existingContractString = getContractString(existingContractEntity); + boolean requestFromMigration = RequestContext.get().getRequestContextHeaders().getOrDefault( + "x-atlan-request-id", "").contains("json-to-yaml-migration"); + if (!requestFromMigration && !StringUtils.isEmpty(contractString) && + !contract.equals(DataContract.deserialize(existingContractString))) { // Update the same asset(entity) throw new AtlasBaseException(OPERATION_NOT_SUPPORTED, "Can't update a specific version of contract"); } @@ -105,7 +106,7 @@ private void processCreateContract(AtlasEntity entity, EntityMutationContext con String contractQName = (String) entity.getAttribute(QUALIFIED_NAME); validateAttribute(!contractQName.endsWith(String.format("/%s", CONTRACT_QUALIFIED_NAME_SUFFIX)), "Invalid qualifiedName for the contract."); - String contractString = (String) entity.getAttribute(ATTR_CONTRACT); + String contractString = getContractString(entity); DataContract contract = DataContract.deserialize(contractString); String datasetQName = contractQName.substring(0, contractQName.lastIndexOf('/')); contractQName = String.format("%s/%s/%s", datasetQName, contract.getType().name(), CONTRACT_QUALIFIED_NAME_SUFFIX); @@ -116,7 +117,8 @@ private void processCreateContract(AtlasEntity entity, EntityMutationContext con boolean contractSync = syncContractCertificateStatus(entity, contract); contractString = DataContract.serialize(contract); entity.setAttribute(ATTR_CONTRACT, contractString); - + String contractStringJSON = DataContract.serializeJSON(contract); + entity.setAttribute(ATTR_CONTRACT_JSON, contractStringJSON); AtlasEntity currentVersionEntity = getCurrentVersion(associatedAsset.getEntity().getGuid()); Long newVersionNumber = 1L; @@ -128,7 +130,7 @@ private void processCreateContract(AtlasEntity entity, EntityMutationContext con // No changes in the contract, Not creating new version removeCreatingVertex(context, entity); return; - } else if (isEqualContract(contractString, (String) currentVersionEntity.getAttribute(ATTR_CONTRACT))) { + } else if (contract.equals(DataContract.deserialize(getContractString(currentVersionEntity)))) { resetAllRelationshipAttributes(entity); // No change in contract, metadata changed updateExistingVersion(context, entity, currentVersionEntity); @@ -168,22 +170,6 @@ private List getDiffAttributes(AtlasEntity entity, AtlasEntity latestExi return attributesSet; } - private boolean isEqualContract(String firstNode, String secondNode) throws AtlasBaseException { - ObjectMapper mapper = new ObjectMapper(); - try { - JsonNode actualObj1 = mapper.readTree(firstNode); - JsonNode actualObj2 = mapper.readTree(secondNode); - //Ignore status field change - ((ObjectNode) actualObj1).remove(CONTRACT_ATTR_STATUS); - ((ObjectNode) actualObj2).remove(CONTRACT_ATTR_STATUS); - - return actualObj1.equals(actualObj2); - } catch (JsonProcessingException e) { - throw new AtlasBaseException(JSON_ERROR, e.getMessage()); - } - - } - private void updateExistingVersion(EntityMutationContext context, AtlasEntity entity, AtlasEntity currentVersionEntity) throws AtlasBaseException { removeCreatingVertex(context, entity); entity.setAttribute(QUALIFIED_NAME, currentVersionEntity.getAttribute(QUALIFIED_NAME)); @@ -304,4 +290,12 @@ private static void validateAttribute(boolean isInvalid, String errorMessage) th if (isInvalid) throw new AtlasBaseException(BAD_REQUEST, errorMessage); } + + private static String getContractString(AtlasEntity entity) { + String contractString = (String) entity.getAttribute(ATTR_CONTRACT); + if (StringUtils.isEmpty(contractString)) { + contractString = (String) entity.getAttribute(ATTR_CONTRACT_JSON); + } + return contractString; + } } diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/contract/DataContract.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/contract/DataContract.java index dc3cdb466b..4dce70108a 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/contract/DataContract.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/contract/DataContract.java @@ -9,6 +9,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.exception.AtlasBaseException; import org.apache.commons.lang.StringUtils; @@ -27,17 +28,18 @@ public class DataContract { private static final String KIND_VALUE = "DataContract"; private static final Pattern versionPattern = Pattern.compile("^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"); - private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final ObjectMapper objectMapperYAML = new ObjectMapper(new YAMLFactory()); + private static final ObjectMapper objectMapperJSON = new ObjectMapper(); static { - objectMapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); + objectMapperYAML.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); + objectMapperJSON.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); } @Valid @NotNull public String kind; - public Status status; - @JsonProperty(value = "template_version", defaultValue = "0.0.1") - public String templateVersion; - @Valid @NotNull + public Status status = Status.DRAFT; + @JsonProperty(value = "template_version") + public String templateVersion = "0.0.1"; public String data_source; @Valid @NotNull public String dataset; @@ -184,6 +186,20 @@ public Map getUnknownFields() { return unknownFields; } + @Override + public boolean equals(Object o) { + if (this == o) { return true; } + if (o == null || getClass() != o.getClass()) { return false; } + BusinessTag that = (BusinessTag) o; + return Objects.equals(name, that.name) && + Objects.equals(unknownFields, that.unknownFields); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), name, unknownFields); + } + } @JsonIgnoreProperties(ignoreUnknown = true) @@ -206,6 +222,22 @@ public void setUnknownFields(String key, Object value) { public Map getUnknownFields() { return unknownFields; } + + @Override + public boolean equals(Object o) { + if (this == o) { return true; } + if (o == null || getClass() != o.getClass()) { return false; } + Column that = (Column) o; + return Objects.equals(name, that.name) && + Objects.equals(description, that.description) && + Objects.equals(data_type, that.data_type) && + Objects.equals(unknownFields, that.unknownFields); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), name, description, data_type, unknownFields); + } } public static DataContract deserialize(String contractString) throws AtlasBaseException { @@ -216,9 +248,13 @@ public static DataContract deserialize(String contractString) throws AtlasBaseEx DataContract contract; try { - contract = objectMapper.readValue(contractString, DataContract.class); + contract = objectMapperYAML.readValue(contractString, DataContract.class); } catch (JsonProcessingException ex) { - throw new AtlasBaseException(ex.getOriginalMessage()); + try { + contract = objectMapperJSON.readValue(contractString, DataContract.class); + } catch (JsonProcessingException e) { + throw new AtlasBaseException(ex.getOriginalMessage()); + } } contract.validate(); return contract; @@ -242,11 +278,45 @@ public void validate() throws AtlasBaseException { public static String serialize(DataContract contract) throws AtlasBaseException { try { - return objectMapper.writeValueAsString(contract); + return objectMapperYAML.writeValueAsString(contract); } catch (JsonProcessingException ex) { throw new AtlasBaseException(JSON_ERROR, ex.getMessage()); } } + @Override + public boolean equals(Object o) { + if (this == o) { return true; } + if (o == null || getClass() != o.getClass()) { return false; } + + DataContract that = (DataContract) o; + return Objects.equals(kind, that.kind) && + Objects.equals(status, that.status) && + Objects.equals(templateVersion, that.templateVersion) && + Objects.equals(data_source, that.data_source) && + Objects.equals(dataset, that.dataset) && + Objects.equals(type, that.type) && + Objects.equals(description, that.description) && + Objects.equals(owners, that.owners) && + Objects.equals(tags, that.tags) && + Objects.equals(certificate, that.certificate) && + Objects.equals(columns, that.columns) && + Objects.equals(unknownFields, that.unknownFields); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), kind, status, templateVersion, data_source, dataset, type, description, owners, + tags, certificate, columns, unknownFields); + } + + public static String serializeJSON(DataContract contract) throws AtlasBaseException { + + try { + return objectMapperJSON.writeValueAsString(contract); + } catch (JsonProcessingException ex) { + throw new AtlasBaseException(JSON_ERROR, ex.getMessage()); + } + } } diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/datamesh/DataProductPreProcessor.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/datamesh/DataProductPreProcessor.java index bda6a0cccb..a619aad063 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/datamesh/DataProductPreProcessor.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/datamesh/DataProductPreProcessor.java @@ -442,6 +442,9 @@ public void processDelete(AtlasVertex vertex) throws AtlasBaseException { } } } + if(RequestContext.get().getDeleteType() == DeleteType.SOFT || RequestContext.get().getDeleteType() == DeleteType.DEFAULT){ + vertex.setProperty(DAAP_STATUS_ATTR, DAAP_ARCHIVED_STATUS); + } } finally { RequestContext.get().endMetricRecord(metricRecorder); diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/datamesh/StakeholderTitlePreProcessor.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/datamesh/StakeholderTitlePreProcessor.java index 97685d1ed6..1de5fe685e 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/datamesh/StakeholderTitlePreProcessor.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/datamesh/StakeholderTitlePreProcessor.java @@ -48,6 +48,7 @@ public class StakeholderTitlePreProcessor implements PreProcessor { public static final String STAR = "*/super"; + public static final String NEW_STAR = "default/domain/*/super"; public static final String ATTR_DOMAIN_QUALIFIED_NAMES = "stakeholderTitleDomainQualifiedNames"; public static final String REL_ATTR_STAKEHOLDERS = "stakeholders"; @@ -114,13 +115,13 @@ private void processCreateStakeholderTitle(AtlasEntity entity) throws AtlasBaseE if (CollectionUtils.isEmpty(domainQualifiedNames)) { throw new AtlasBaseException(BAD_REQUEST, "Please provide attribute " + ATTR_DOMAIN_QUALIFIED_NAMES); } - - if (domainQualifiedNames.contains(STAR)) { + if (domainQualifiedNames.contains(NEW_STAR) || domainQualifiedNames.contains(STAR)) { if (domainQualifiedNames.size() > 1) { - domainQualifiedNames.clear(); - domainQualifiedNames.add(STAR); + domainQualifiedNames.add(NEW_STAR); entity.setAttribute(ATTR_DOMAIN_QUALIFIED_NAMES, domainQualifiedNames); + }else { + domainQualifiedNames.replaceAll(s -> s.equals(STAR) ? NEW_STAR : s); } String qualifiedName = format(PATTERN_QUALIFIED_NAME_ALL_DOMAINS, getUUID()); @@ -211,8 +212,8 @@ private void authorizeDomainAccess(List domainQualifiedNames) throws Atl for (String domainQualifiedName: domainQualifiedNames) { String domainQualifiedNameToAuth; - if (domainQualifiedNames.contains(STAR)) { - domainQualifiedNameToAuth = "*/super"; + if (domainQualifiedNames.contains(STAR) || domainQualifiedNames.contains(NEW_STAR)) { + domainQualifiedNameToAuth = NEW_STAR; } else { domainQualifiedNameToAuth = domainQualifiedName; }