diff --git a/sdm/pom.xml b/sdm/pom.xml
index 8210bbc7..fad488be 100644
--- a/sdm/pom.xml
+++ b/sdm/pom.xml
@@ -34,7 +34,7 @@
src/test/gen
17
17
- 1.3.1
+ 1.4.0
1.18.36
0.8.7
3.10.8
diff --git a/sdm/src/main/java/com/sap/cds/sdm/handler/TokenHandler.java b/sdm/src/main/java/com/sap/cds/sdm/handler/TokenHandler.java
index f344b672..ced6701f 100644
--- a/sdm/src/main/java/com/sap/cds/sdm/handler/TokenHandler.java
+++ b/sdm/src/main/java/com/sap/cds/sdm/handler/TokenHandler.java
@@ -71,7 +71,7 @@ public Map getUaaCredentials() {
DefaultServiceBindingAccessor.getInstance().getServiceBindings();
ServiceBinding sdmBinding =
allServiceBindings.stream()
- .filter(binding -> "sdm".equalsIgnoreCase(binding.getServiceName().orElse(null)))
+ .filter(binding -> binding.getTags().contains("sdm"))
.findFirst()
.orElseThrow(() -> new IllegalStateException("SDM binding not found"));
return sdmBinding.getCredentials();
diff --git a/sdm/src/main/java/com/sap/cds/sdm/service/SDMAttachmentsService.java b/sdm/src/main/java/com/sap/cds/sdm/service/SDMAttachmentsService.java
index 6fd663b7..ebebb9c5 100644
--- a/sdm/src/main/java/com/sap/cds/sdm/service/SDMAttachmentsService.java
+++ b/sdm/src/main/java/com/sap/cds/sdm/service/SDMAttachmentsService.java
@@ -181,7 +181,8 @@ public AttachmentModificationResult createAttachment(CreateAttachmentInput input
return new AttachmentModificationResult(
Boolean.TRUE.equals(createContext.getIsInternalStored()),
createContext.getContentId(),
- createContext.getData().getStatus());
+ createContext.getData().getStatus(),
+ Instant.now());
}
@Override
diff --git a/sdm/src/main/java/com/sap/cds/sdm/service/SDMService.java b/sdm/src/main/java/com/sap/cds/sdm/service/SDMService.java
index 440fdfb7..e3fd5223 100644
--- a/sdm/src/main/java/com/sap/cds/sdm/service/SDMService.java
+++ b/sdm/src/main/java/com/sap/cds/sdm/service/SDMService.java
@@ -33,7 +33,8 @@ public String getFolderIdByPath(
public JSONObject getRepositoryInfo(SDMCredentials sdmCredentials) throws IOException;
- public int deleteDocument(String cmisaction, String objectId, String user) throws IOException;
+ public int deleteDocument(String cmisaction, String objectId, String user, Boolean isSystemUser)
+ throws IOException;
public void readDocument(
String objectId, SDMCredentials sdmCredentials, AttachmentReadEventContext context)
diff --git a/sdm/src/main/java/com/sap/cds/sdm/service/SDMServiceImpl.java b/sdm/src/main/java/com/sap/cds/sdm/service/SDMServiceImpl.java
index 69f1d7e2..03a80644 100644
--- a/sdm/src/main/java/com/sap/cds/sdm/service/SDMServiceImpl.java
+++ b/sdm/src/main/java/com/sap/cds/sdm/service/SDMServiceImpl.java
@@ -660,13 +660,17 @@ public Map fetchRepositoryData(JSONObject repoInfo, String re
}
@Override
- public int deleteDocument(String cmisaction, String objectId, String user) {
+ public int deleteDocument(String cmisaction, String objectId, String user, Boolean isSytemUser) {
logger.info(
- "Deleting document - action: {}, objectId: {}, user: {}", cmisaction, objectId, user);
+ "Deleting document - action: {}, objectId: {}, user: {},isSystemUser :{}",
+ cmisaction,
+ objectId,
+ user,
+ isSytemUser);
long startTime = System.currentTimeMillis();
SDMCredentials sdmCredentials = tokenHandler.getSDMCredentials();
HttpClient httpClient;
- if (user.equals(SDMConstants.SYSTEM_USER)) {
+ if (isSytemUser) {
logger.debug("Using TECHNICAL_USER_FLOW for deletion");
httpClient = tokenHandler.getHttpClient(binding, connectionPool, null, TECHNICAL_USER_FLOW);
} else {
diff --git a/sdm/src/main/java/com/sap/cds/sdm/service/handler/SDMAttachmentsServiceHandler.java b/sdm/src/main/java/com/sap/cds/sdm/service/handler/SDMAttachmentsServiceHandler.java
index 2d391971..d041c8fe 100644
--- a/sdm/src/main/java/com/sap/cds/sdm/service/handler/SDMAttachmentsServiceHandler.java
+++ b/sdm/src/main/java/com/sap/cds/sdm/service/handler/SDMAttachmentsServiceHandler.java
@@ -25,6 +25,7 @@
import com.sap.cds.services.utils.StringUtils;
import java.io.IOException;
import java.io.InputStream;
+import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
import org.json.JSONObject;
@@ -107,12 +108,20 @@ public void markAttachmentAsDeleted(AttachmentMarkAsDeletedEventContext context)
if (cmisDocuments.isEmpty()) {
// deleteFolder API
logger.info("Deleting folder: {} for entity: {}", folderId, entity);
- sdmService.deleteDocument("deleteTree", folderId, context.getDeletionUserInfo().getName());
+ sdmService.deleteDocument(
+ "deleteTree",
+ folderId,
+ context.getDeletionUserInfo().getName(),
+ context.getDeletionUserInfo().getIsSystemUser());
logger.info("Folder deleted successfully: {}", folderId);
} else {
if (!isObjectIdPresent(cmisDocuments, objectId)) {
logger.info("Deleting document: {} from repository", objectId);
- sdmService.deleteDocument("delete", objectId, context.getDeletionUserInfo().getName());
+ sdmService.deleteDocument(
+ "delete",
+ objectId,
+ context.getDeletionUserInfo().getName(),
+ context.getDeletionUserInfo().getIsSystemUser());
logger.info("Document deleted successfully: {}", objectId);
} else {
logger.debug("ObjectId {} is still referenced, not deleting", objectId);
@@ -516,6 +525,7 @@ private void handleCreateDocumentResult(
eventContext.setContentId(
existing.getObjectId() + ":" + existing.getFolderId() + ":" + activeEntityName);
eventContext.getData().setStatus("Clean");
+ eventContext.getData().setScannedAt(Instant.now());
eventContext.getData().setContent(null);
eventContext.setCompleted();
return;
@@ -620,6 +630,7 @@ private void finalizeContext(
+ ":"
+ eventContext.getAttachmentEntity().getQualifiedName());
eventContext.getData().setStatus("Clean");
+ eventContext.getData().setScannedAt(Instant.now());
eventContext.getData().setContent(null);
eventContext.setCompleted();
logger.debug("Attachment context finalized and marked as completed");
diff --git a/sdm/src/main/java/com/sap/cds/sdm/service/handler/SDMCustomServiceHandler.java b/sdm/src/main/java/com/sap/cds/sdm/service/handler/SDMCustomServiceHandler.java
index 9fe9c8b6..b393a30a 100644
--- a/sdm/src/main/java/com/sap/cds/sdm/service/handler/SDMCustomServiceHandler.java
+++ b/sdm/src/main/java/com/sap/cds/sdm/service/handler/SDMCustomServiceHandler.java
@@ -1525,13 +1525,20 @@ private void handleCopyFailure(
logger.error("Copy failure detected, initiating cleanup. Error: {}", e.getMessage());
if (!folderExists) {
logger.debug("Deleting newly created folder: {}", folderId);
- sdmService.deleteDocument("deleteTree", folderId, context.getUserInfo().getName());
+ sdmService.deleteDocument(
+ "deleteTree",
+ folderId,
+ context.getUserInfo().getName(),
+ context.getUserInfo().isSystemUser());
} else {
logger.debug(
"Deleting {} copied attachments from existing folder", attachmentsMetadata.size());
for (Map attachmentMetadata : attachmentsMetadata) {
sdmService.deleteDocument(
- "delete", attachmentMetadata.get("cmis:objectId"), context.getUserInfo().getName());
+ "delete",
+ attachmentMetadata.get("cmis:objectId"),
+ context.getUserInfo().getName(),
+ context.getUserInfo().isSystemUser());
}
}
throw new ServiceException(e.getMessage());
diff --git a/sdm/src/test/java/unit/com/sap/cds/sdm/handler/TokenHandlerTest.java b/sdm/src/test/java/unit/com/sap/cds/sdm/handler/TokenHandlerTest.java
index 8d311fdb..e999b83d 100644
--- a/sdm/src/test/java/unit/com/sap/cds/sdm/handler/TokenHandlerTest.java
+++ b/sdm/src/test/java/unit/com/sap/cds/sdm/handler/TokenHandlerTest.java
@@ -140,7 +140,7 @@ public void testGetSDMCredentials() {
mockCredentials.put("uaa", mockUaa);
mockCredentials.put("uri", "https://mock.service.url");
- Mockito.when(mockServiceBinding.getServiceName()).thenReturn(Optional.of("sdm"));
+ Mockito.when(mockServiceBinding.getTags()).thenReturn(Collections.singletonList("sdm"));
Mockito.when(mockServiceBinding.getCredentials()).thenReturn(mockCredentials);
List mockServiceBindings = Collections.singletonList(mockServiceBinding);
@@ -202,7 +202,7 @@ public void testGetHttpClientForOnboardFlow() {
mockCredentials.put("uaa", mockUaa);
mockCredentials.put("uri", "https://mock.service.url");
- Mockito.when(mockServiceBinding.getServiceName()).thenReturn(Optional.of("sdm"));
+ Mockito.when(mockServiceBinding.getTags()).thenReturn(Collections.singletonList("sdm"));
Mockito.when(mockServiceBinding.getCredentials()).thenReturn(mockCredentials);
List mockServiceBindings = Collections.singletonList(mockServiceBinding);
diff --git a/sdm/src/test/java/unit/com/sap/cds/sdm/service/SDMServiceImplTest.java b/sdm/src/test/java/unit/com/sap/cds/sdm/service/SDMServiceImplTest.java
index ef0e7085..ddb27e74 100644
--- a/sdm/src/test/java/unit/com/sap/cds/sdm/service/SDMServiceImplTest.java
+++ b/sdm/src/test/java/unit/com/sap/cds/sdm/service/SDMServiceImplTest.java
@@ -809,10 +809,14 @@ public void testDeleteFolder() throws IOException {
when(response.getEntity()).thenReturn(entity);
when(mockContext.getDeletionUserInfo()).thenReturn(deletionUserInfo);
when(deletionUserInfo.getName()).thenReturn("system-internal");
+ when(deletionUserInfo.getIsSystemUser()).thenReturn(true);
SDMServiceImpl sdmServiceImpl = new SDMServiceImpl(binding, connectionPool, tokenHandler);
int actualResponse =
sdmServiceImpl.deleteDocument(
- "deleteTree", "objectId", mockContext.getDeletionUserInfo().getName());
+ "deleteTree",
+ "objectId",
+ mockContext.getDeletionUserInfo().getName(),
+ mockContext.getDeletionUserInfo().getIsSystemUser());
assertEquals(200, actualResponse);
} finally {
mockWebServer.shutdown();
@@ -841,7 +845,10 @@ public void testDeleteFolderAuthorities() throws IOException {
SDMServiceImpl sdmServiceImpl = new SDMServiceImpl(binding, connectionPool, tokenHandler);
int actualResponse =
sdmServiceImpl.deleteDocument(
- "deleteTree", "objectId", mockContext.getDeletionUserInfo().getName());
+ "deleteTree",
+ "objectId",
+ mockContext.getDeletionUserInfo().getName(),
+ mockContext.getDeletionUserInfo().getIsSystemUser());
assertEquals(200, actualResponse);
} finally {
mockWebServer.shutdown();
@@ -903,10 +910,14 @@ public void testDeleteDocument() throws IOException {
when(tokenHandler.getSDMCredentials()).thenReturn(mockSdmCredentials);
when(mockContext.getDeletionUserInfo()).thenReturn(deletionUserInfo);
when(deletionUserInfo.getName()).thenReturn("system-internal");
+ when(deletionUserInfo.getIsSystemUser()).thenReturn(true);
SDMServiceImpl sdmServiceImpl = new SDMServiceImpl(binding, connectionPool, tokenHandler);
int actualResponse =
sdmServiceImpl.deleteDocument(
- "delete", "objectId", mockContext.getDeletionUserInfo().getName());
+ "delete",
+ "objectId",
+ mockContext.getDeletionUserInfo().getName(),
+ mockContext.getDeletionUserInfo().getIsSystemUser());
assertEquals(200, actualResponse);
} finally {
mockWebServer.shutdown();
@@ -934,7 +945,10 @@ public void testDeleteDocumentNamedUserFlow() throws IOException {
SDMServiceImpl sdmServiceImpl = new SDMServiceImpl(binding, connectionPool, tokenHandler);
int actualResponse =
sdmServiceImpl.deleteDocument(
- "delete", "objectId", mockContext.getDeletionUserInfo().getName());
+ "delete",
+ "objectId",
+ mockContext.getDeletionUserInfo().getName(),
+ mockContext.getDeletionUserInfo().getIsSystemUser());
assertEquals(200, actualResponse);
} finally {
mockWebServer.shutdown();
@@ -961,10 +975,14 @@ public void testDeleteDocumentObjectNotFound() throws IOException {
when(tokenHandler.getSDMCredentials()).thenReturn(mockSdmCredentials);
when(mockContext.getDeletionUserInfo()).thenReturn(deletionUserInfo);
when(deletionUserInfo.getName()).thenReturn("system-internal");
+ when(deletionUserInfo.getIsSystemUser()).thenReturn(true);
SDMServiceImpl sdmServiceImpl = new SDMServiceImpl(binding, connectionPool, tokenHandler);
int actualResponse =
sdmServiceImpl.deleteDocument(
- "delete", "ewdwe", mockContext.getDeletionUserInfo().getName());
+ "delete",
+ "ewdwe",
+ mockContext.getDeletionUserInfo().getName(),
+ mockContext.getDeletionUserInfo().getIsSystemUser());
assertEquals(404, actualResponse);
} finally {
mockWebServer.shutdown();
@@ -1296,12 +1314,16 @@ public void testDeleteDocumentThrowsServiceExceptionOnHttpClientError() throws I
SDMServiceImpl sdmServiceImpl = new SDMServiceImpl(binding, connectionPool, tokenHandler);
when(mockContext.getDeletionUserInfo()).thenReturn(deletionUserInfo);
when(deletionUserInfo.getName()).thenReturn("system-internal");
+ when(deletionUserInfo.getIsSystemUser()).thenReturn(true);
// Ensure ServiceException is thrown
assertThrows(
ServiceException.class,
() ->
sdmServiceImpl.deleteDocument(
- "delete", "123", mockContext.getDeletionUserInfo().getName()));
+ "delete",
+ "123",
+ mockContext.getDeletionUserInfo().getName(),
+ mockContext.getDeletionUserInfo().getIsSystemUser()));
}
@Test
diff --git a/sdm/src/test/java/unit/com/sap/cds/sdm/service/handler/SDMAttachmentsServiceHandlerTest.java b/sdm/src/test/java/unit/com/sap/cds/sdm/service/handler/SDMAttachmentsServiceHandlerTest.java
index 2701d074..672ef09a 100644
--- a/sdm/src/test/java/unit/com/sap/cds/sdm/service/handler/SDMAttachmentsServiceHandlerTest.java
+++ b/sdm/src/test/java/unit/com/sap/cds/sdm/service/handler/SDMAttachmentsServiceHandlerTest.java
@@ -1425,7 +1425,8 @@ public void testDocumentDeletion() throws IOException {
.deleteDocument(
"delete",
objectId,
- attachmentMarkAsDeletedEventContext.getDeletionUserInfo().getName());
+ attachmentMarkAsDeletedEventContext.getDeletionUserInfo().getName(),
+ attachmentMarkAsDeletedEventContext.getDeletionUserInfo().getIsSystemUser());
}
@Test
@@ -1461,7 +1462,8 @@ public void testFolderDeletion() throws IOException {
.deleteDocument(
"deleteTree",
folderId,
- attachmentMarkAsDeletedEventContext.getDeletionUserInfo().getName());
+ attachmentMarkAsDeletedEventContext.getDeletionUserInfo().getName(),
+ attachmentMarkAsDeletedEventContext.getDeletionUserInfo().getIsSystemUser());
}
@Test
@@ -2054,7 +2056,7 @@ public void testMarkAttachmentAsDeleted_WithNullObjectId() throws IOException {
handlerSpy.markAttachmentAsDeleted(deleteContext);
verify(deleteContext).setCompleted();
- verify(sdmService, never()).deleteDocument(anyString(), anyString(), anyString());
+ verify(sdmService, never()).deleteDocument(anyString(), anyString(), anyString(), anyBoolean());
}
@Test
@@ -2068,7 +2070,7 @@ public void testMarkAttachmentAsDeleted_WithInsufficientContextValues() throws I
handlerSpy.markAttachmentAsDeleted(deleteContext);
verify(deleteContext).setCompleted();
- verify(sdmService, never()).deleteDocument(anyString(), anyString(), anyString());
+ verify(sdmService, never()).deleteDocument(anyString(), anyString(), anyString(), anyBoolean());
}
@Test
@@ -2083,7 +2085,7 @@ public void testMarkAttachmentAsDeleted_WithEmptyString() throws IOException {
handlerSpy.markAttachmentAsDeleted(deleteContext);
verify(deleteContext).setCompleted();
- verify(sdmService, never()).deleteDocument(anyString(), anyString(), anyString());
+ verify(sdmService, never()).deleteDocument(anyString(), anyString(), anyString(), anyBoolean());
}
@Test
@@ -2103,7 +2105,7 @@ public void testMarkAttachmentAsDeleted_DeleteFolderWhenNoAttachments() throws I
handlerSpy.markAttachmentAsDeleted(deleteContext);
- verify(sdmService).deleteDocument("deleteTree", "folderId", "testUser");
+ verify(sdmService).deleteDocument("deleteTree", "folderId", "testUser", false);
verify(deleteContext).setCompleted();
}
@@ -2127,7 +2129,7 @@ public void testMarkAttachmentAsDeleted_DeleteObjectWhenNotPresent() throws IOEx
handlerSpy.markAttachmentAsDeleted(deleteContext);
- verify(sdmService).deleteDocument("delete", "objectId", "testUser");
+ verify(sdmService).deleteDocument("delete", "objectId", "testUser", false);
verify(deleteContext).setCompleted();
}
@@ -2151,7 +2153,7 @@ public void testMarkAttachmentAsDeleted_ObjectIdPresent() throws IOException {
handlerSpy.markAttachmentAsDeleted(deleteContext);
- verify(sdmService, never()).deleteDocument(anyString(), anyString(), anyString());
+ verify(sdmService, never()).deleteDocument(anyString(), anyString(), anyString(), anyBoolean());
verify(deleteContext).setCompleted();
}
@@ -2416,7 +2418,7 @@ public void testMarkAttachmentAsDeleted_MultipleObjectsInFolder() throws IOExcep
handlerSpy.markAttachmentAsDeleted(deleteContext);
// Should not call delete on either document since target is present
- verify(sdmService, never()).deleteDocument(anyString(), anyString(), anyString());
+ verify(sdmService, never()).deleteDocument(anyString(), anyString(), anyString(), anyBoolean());
verify(deleteContext).setCompleted();
}
diff --git a/sdm/src/test/java/unit/com/sap/cds/sdm/service/handler/SDMCustomServiceHandlerTest.java b/sdm/src/test/java/unit/com/sap/cds/sdm/service/handler/SDMCustomServiceHandlerTest.java
index c128b437..43741075 100644
--- a/sdm/src/test/java/unit/com/sap/cds/sdm/service/handler/SDMCustomServiceHandlerTest.java
+++ b/sdm/src/test/java/unit/com/sap/cds/sdm/service/handler/SDMCustomServiceHandlerTest.java
@@ -242,7 +242,8 @@ void testCopyAttachments_AttachmentCopyFails() throws IOException {
});
// Verify that deleteDocument was called for cleanup of the first successful attachment
- verify(sdmService, times(1)).deleteDocument(eq("delete"), eq(OBJECT_ID), eq("testUser"));
+ verify(sdmService, times(1))
+ .deleteDocument(eq("delete"), eq(OBJECT_ID), eq("testUser"), eq(false));
assertTrue(exception.getMessage().contains("Copy failed"));
}
@@ -279,7 +280,7 @@ void testCopyAttachments_AttachmentCopyFails_FolderDoesNotExist() throws IOExcep
});
// Should attempt to delete the folder
- verify(sdmService, times(1)).deleteDocument(eq("deleteTree"), eq(FOLDER_ID), any());
+ verify(sdmService, times(1)).deleteDocument(eq("deleteTree"), eq(FOLDER_ID), any(), any());
assertTrue(ex.getMessage().contains("Copy failed"));
}
@@ -320,7 +321,7 @@ void testCopyAttachments_AttachmentCopyFails_FolderExists_AttachmentsDeleted()
});
// Should attempt to delete the copied attachment
- verify(sdmService, times(1)).deleteDocument(eq("delete"), eq(OBJECT_ID), any());
+ verify(sdmService, times(1)).deleteDocument(eq("delete"), eq(OBJECT_ID), any(), any());
assertTrue(ex.getMessage().contains("Copy failed"));
}