Skip to content

Commit a478a24

Browse files
fix: restore dataContractLatest relationship on single-version delete (DQ-665)
When deleting only the latest contract version, the dataContractLatest relationship edge was left in DELETED state because JanusGraph doesn't restore previously-replaced edges. This caused the UI to show "something went wrong" on the asset's contract tab. Fix: restoreAssetContractPointers() uses entityStore.createOrUpdate() to re-establish the dataContractLatest (and dataContractLatestCertified if VERIFIED) relationship edges pointing to the previous version. Also adds __state=ACTIVE filter to getSecondLatestVersion ES query to avoid matching soft-deleted contracts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1f35d8b commit a478a24

1 file changed

Lines changed: 34 additions & 5 deletions

File tree

repository/src/main/java/org/apache/atlas/repository/store/graph/v2/preprocessor/contract/ContractPreProcessor.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,7 @@ private void processSingleVersionDelete(String contractGuid, String assetGuid) t
157157
AtlasEntity previousVersion = getSecondLatestVersion(assetGuid);
158158

159159
if (previousVersion != null) {
160-
// Previous version becomes the new latest — asset relationship edges to the
161-
// deleted contract are auto-removed by JanusGraph on hard delete.
162-
// The dataContractLatest/dataContractLatestCertified edges will be set by
163-
// the next create/update operation on this contract. For now, just ensure
164-
// hasContract stays true since versions remain.
160+
restoreAssetContractPointers(assetGuid, previousVersion);
165161
LOG.info("processSingleVersionDelete: contract={}, asset={}, previousVersion={}",
166162
contractGuid, assetGuid, previousVersion.getGuid());
167163
} else {
@@ -170,6 +166,38 @@ private void processSingleVersionDelete(String contractGuid, String assetGuid) t
170166
}
171167
}
172168

169+
private void restoreAssetContractPointers(String assetGuid, AtlasEntity previousVersion) throws AtlasBaseException {
170+
AtlasVertex assetVertex = AtlasGraphUtilsV2.findByGuid(assetGuid);
171+
if (assetVertex == null) {
172+
LOG.warn("Asset vertex not found for guid {}, cannot restore contract pointers", assetGuid);
173+
return;
174+
}
175+
176+
String assetTypeName = GraphHelper.getTypeName(assetVertex);
177+
String assetQualifiedName = assetVertex.getProperty(QUALIFIED_NAME, String.class);
178+
179+
AtlasEntity assetUpdate = new AtlasEntity(assetTypeName);
180+
assetUpdate.setGuid(assetGuid);
181+
assetUpdate.setAttribute(QUALIFIED_NAME, assetQualifiedName);
182+
183+
assetUpdate.setRelationshipAttribute(REL_ATTR_LATEST_CONTRACT, getAtlasObjectId(previousVersion));
184+
185+
String prevStatus = (String) previousVersion.getAttribute(ATTR_CERTIFICATE_STATUS);
186+
if (DataContract.Status.VERIFIED.name().equals(prevStatus)) {
187+
assetUpdate.setRelationshipAttribute(REL_ATTR_GOVERNED_ASSET_CERTIFIED, getAtlasObjectId(previousVersion));
188+
}
189+
190+
EntityStream entityStream = new AtlasEntityStream(new AtlasEntity.AtlasEntitiesWithExtInfo(assetUpdate));
191+
192+
try {
193+
RequestContext.get().setSkipAuthorizationCheck(true);
194+
entityStore.createOrUpdate(entityStream, true);
195+
LOG.info("Restored contract pointers on asset {} to previous version {}", assetGuid, previousVersion.getGuid());
196+
} finally {
197+
RequestContext.get().setSkipAuthorizationCheck(false);
198+
}
199+
}
200+
173201
private List<AtlasEntityHeader> getAllVersions(String assetGuid) throws AtlasBaseException {
174202
Map<String, Object> dsl = new HashMap<>();
175203

@@ -190,6 +218,7 @@ private AtlasEntity getSecondLatestVersion(String assetGuid) throws AtlasBaseExc
190218
List<Map<String, Object>> mustClauseList = new ArrayList<>();
191219
mustClauseList.add(mapOf("term", mapOf("__typeName.keyword", CONTRACT_ENTITY_TYPE)));
192220
mustClauseList.add(mapOf("term", mapOf(ATTR_ASSET_GUID, assetGuid)));
221+
mustClauseList.add(mapOf("term", mapOf("__state", "ACTIVE")));
193222

194223
dsl.put("query", mapOf("bool", mapOf("must", mustClauseList)));
195224
dsl.put("sort", Collections.singletonList(mapOf(ATTR_CONTRACT_VERSION, mapOf("order", "desc"))));

0 commit comments

Comments
 (0)