From 8936e5900dff1559ac24fc2e66f7f6c4d431843a Mon Sep 17 00:00:00 2001 From: arpit-at Date: Wed, 3 Jul 2024 20:01:39 +0530 Subject: [PATCH] DG-1697: Adding endpoint for linking/unlink policy --- .../instance/LinkBusinessPolicyRequest.java | 73 +++++++++++++++++++ .../store/graph/AtlasEntityStore.java | 6 ++ .../store/graph/v2/AtlasEntityStoreV2.java | 21 +++++- .../store/graph/v2/EntityGraphMapper.java | 22 ++++++ .../org/apache/atlas/web/rest/EntityREST.java | 42 +++++++++++ 5 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 intg/src/main/java/org/apache/atlas/model/instance/LinkBusinessPolicyRequest.java diff --git a/intg/src/main/java/org/apache/atlas/model/instance/LinkBusinessPolicyRequest.java b/intg/src/main/java/org/apache/atlas/model/instance/LinkBusinessPolicyRequest.java new file mode 100644 index 0000000000..413e9ec22f --- /dev/null +++ b/intg/src/main/java/org/apache/atlas/model/instance/LinkBusinessPolicyRequest.java @@ -0,0 +1,73 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.atlas.model.instance; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import java.io.Serializable; +import java.util.List; + +import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE; +import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY; + +/** + * Request to link/unlink policies from asset. + */ +@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = PUBLIC_ONLY, fieldVisibility = NONE) +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@XmlRootElement +@XmlAccessorType(XmlAccessType.PROPERTY) +public class LinkBusinessPolicyRequest implements Serializable { + private static final long serialVersionUID = 1L; + + private List linkGuids; + private List unlinkGuids; + + public List getLinkGuids() { + return linkGuids; + } + + public void setLinkGuids(List linkGuids) { + this.linkGuids = linkGuids; + } + + public List getUnlinkGuids() { + return unlinkGuids; + } + + public void setUnlinkGuids(List unlinkGuids) { + this.unlinkGuids = unlinkGuids; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("LinkBusinessPolicyRequest{"); + sb.append("linkGuids=").append(linkGuids); + sb.append(", unlinkGuids=").append(unlinkGuids); + sb.append('}'); + return sb.toString(); + } +} diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java index 912799cdd6..3eb3a42728 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java @@ -365,4 +365,10 @@ EntityMutationResponse deleteByUniqueAttributes(List objectIds) void repairAccesscontrolAlias(String guid) throws AtlasBaseException; + + void linkBusinessPolicy(String policyId, List linkGuids) throws AtlasBaseException; + + + void unlinkBusinessPolicy(String policyId, List unlinkGuids) throws AtlasBaseException; + } diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java index 83df0fe2ef..a227e5d36c 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java @@ -1550,8 +1550,8 @@ private EntityMutationResponse createOrUpdate(EntityStream entityStream, boolean // Notify the change listeners - entityChangeNotifier.onEntitiesMutated(ret, RequestContext.get().isImportInProgress()); - atlasRelationshipStore.onRelationshipsMutated(RequestContext.get().getRelationshipMutationMap()); + // entityChangeNotifier.onEntitiesMutated(ret, RequestContext.get().isImportInProgress()); + // atlasRelationshipStore.onRelationshipsMutated(RequestContext.get().getRelationshipMutationMap()); if (LOG.isDebugEnabled()) { LOG.debug("<== createOrUpdate()"); } @@ -2737,6 +2737,23 @@ public void repairAccesscontrolAlias(String guid) throws AtlasBaseException { RequestContext.get().endMetricRecord(metric); } + + @Override + @GraphTransaction + public void linkBusinessPolicy(String guid, List linkGuids) { + AtlasPerfMetrics.MetricRecorder metric = RequestContext.get().startMetricRecord("linkBusinessPolicy"); + this.entityGraphMapper.linkBusinessPolicy(guid, linkGuids); + RequestContext.get().endMetricRecord(metric); + } + + + @Override + @GraphTransaction + public void unlinkBusinessPolicy(String guid, List unlinkGuids) { + AtlasPerfMetrics.MetricRecorder metric = RequestContext.get().startMetricRecord("linkBusinessPolicy"); + this.entityGraphMapper.unlinkBusinessPolicy(guid, unlinkGuids); + RequestContext.get().endMetricRecord(metric); + } } diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java index 97ff277872..70835b74cb 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java @@ -4514,5 +4514,27 @@ public void addHasLineage(Set inputOutputEdges, boolean isRestoreEnti } RequestContext.get().endMetricRecord(metricRecorder); } + public void linkBusinessPolicy(String policyId, List linkGuids) { + for (String guid : linkGuids) { + AtlasVertex ev = AtlasGraphUtilsV2.findByGuid(graph, guid); + if (ev != null) { + Set existingValues = ev.getMultiValuedSetProperty("assetPolicyGUIDs", String.class); + ev.setProperty("assetPolicyGUIDs", policyId); + ev.setProperty("assetPoliciesCount", existingValues.size() + 1); + updateModificationMetadata(ev); + } + } + } + public void unlinkBusinessPolicy(String policyId, List unlinkGuids) { + for (String guid : unlinkGuids) { + AtlasVertex ev = AtlasGraphUtilsV2.findByGuid(graph, guid); + if (ev != null) { + Set existingValues = ev.getMultiValuedSetProperty("assetPolicyGUIDs", String.class); + ev.removePropertyValue("assetPolicyGUIDs", policyId); + ev.setProperty("assetPoliciesCount", existingValues.size() - 1); + updateModificationMetadata(ev); + } + } + } } \ No newline at end of file diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java index 3aadc06ad2..62c77b142d 100644 --- a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java +++ b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java @@ -75,7 +75,9 @@ import static org.apache.atlas.AtlasErrorCode.BAD_REQUEST; import static org.apache.atlas.AtlasErrorCode.DEPRECATED_API; +import static org.apache.atlas.authorize.AtlasAuthorizationUtils.getCurrentUserName; import static org.apache.atlas.authorize.AtlasPrivilege.*; +import static org.apache.atlas.repository.util.AccessControlUtils.ARGO_SERVICE_USER_NAME; /** @@ -1952,7 +1954,47 @@ public void repairAccessControlAlias(@PathParam("guid") String guid) throws Atla } finally { AtlasPerfTracer.log(perf); } + } + + + @POST + @Path("/{policyId}/link-business-policy") + @Produces(Servlets.JSON_MEDIA_TYPE) + @Consumes(Servlets.JSON_MEDIA_TYPE) + @Timed + public void linkBusinessPolicy(@PathParam("policyId") final String policyId, final LinkBusinessPolicyRequest request) throws AtlasBaseException { + if (ARGO_SERVICE_USER_NAME.equals(RequestContext.getCurrentUser())) { + throw new AtlasBaseException(AtlasErrorCode.UNAUTHORIZED_ACCESS, RequestContext.getCurrentUser(), "Policy linking"); + } + AtlasPerfTracer perf = null; + try { + if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) { + perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityREST.linkBusinessPolicy(" + policyId + ")"); + } + entitiesStore.linkBusinessPolicy(policyId, request.getLinkGuids()); + } finally { + AtlasPerfTracer.log(perf); + } + } + @POST + @Path("/{policyId}/unlink-business-policy") + @Produces(Servlets.JSON_MEDIA_TYPE) + @Consumes(Servlets.JSON_MEDIA_TYPE) + @Timed + public void unlinkBusinessPolicy(@PathParam("policyId") final String policyId, final LinkBusinessPolicyRequest request) throws AtlasBaseException { + if (ARGO_SERVICE_USER_NAME.equals(RequestContext.getCurrentUser())) { + throw new AtlasBaseException(AtlasErrorCode.UNAUTHORIZED_ACCESS, RequestContext.getCurrentUser(), "Policy unlinking"); + } + AtlasPerfTracer perf = null; + try { + if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) { + perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityREST.unlinkBusinessPolicy(" + policyId + ")"); + } + entitiesStore.unlinkBusinessPolicy(policyId, request.getUnlinkGuids()); + } finally { + AtlasPerfTracer.log(perf); + } } }