Skip to content

Commit 615ca65

Browse files
Merge pull request #408 from cap-java/bugfixtm
Saving entity before attachment state is "Virus Scan In Progress(refresh page)" in trend micro enabled repository
2 parents 3703995 + e3dcdfc commit 615ca65

5 files changed

Lines changed: 623 additions & 92 deletions

File tree

README.md

Lines changed: 13 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ This plugin can be consumed by the CAP application deployed on BTP to store thei
2424
- Attachment changelog: Provides the capability to view complete audit trail of attachments.
2525
- Localization of error messages and UI fields: Provides the capability to have the UI fields and error messages translated to the local language of the leading application.
2626
- Attachment Upload Status: Upload Status is the new field which displays the upload status of attachment when being uploaded.
27-
- Attachment Virus Scanning: Provides the capability to scan uploaded attachments for viruses using either Malware Scan (synchronous) or Trend Micro Scan (asynchronous) during the upload process.
2827

2928
## Table of Contents
3029

@@ -43,7 +42,6 @@ This plugin can be consumed by the CAP application deployed on BTP to store thei
4342
- [Support for Link type attachments](#support-for-link-type-attachments)
4443
- [Support for Edit of Link type attachments](#support-for-edit-of-link-type-attachments)
4544
- [Support for Localization](#support-for-localization)
46-
- [Support for Attachment Virus Scanning](#support-for-attachment-virus-scanning)
4745
- [Support for Attachment Upload Status](#support-for-attachment-upload-status)
4846
- [Known Restrictions](#known-restrictions)
4947
- [Support, Feedback, Contributing](#support-feedback-contributing)
@@ -70,7 +68,7 @@ This plugin can be consumed by the CAP application deployed on BTP to store thei
7068
7169
## Setup
7270

73-
In this guide, we use the Bookshop sample app in the [deploy branch](https://github.com/cap-java/sdm/tree/deploy) of this repository, to integrate SDM CAP plugin. Follow the steps in this section for a quick way to deploy and test the plugin without needing to create your own custom CAP application.
71+
In this guide, we use the Bookshop sample app in the [local_deploy branch](https://github.com/cap-java/sdm/tree/local_deploy) of this repository, to integrate SDM CAP plugin. Follow the steps in this section for a quick way to deploy and test the plugin without needing to create your own custom CAP application.
7472

7573
### Using the released version
7674
If you want to use the version of SDM CAP plugin released on the central maven repository follow the below steps:
@@ -83,10 +81,10 @@ If you want to use the version of SDM CAP plugin released on the central maven r
8381
git clone https://github.com/cap-java/sdm
8482
```
8583

86-
3. Checkout to the branch **deploy**:
84+
3. Checkout to the branch **local_deploy**:
8785

8886
```sh
89-
git checkout deploy
87+
git checkout local_deploy
9088
```
9189

9290
4. Navigate to the demoapp folder:
@@ -130,10 +128,10 @@ To use a development version of the SDM CAP plugin, follow these steps. This is
130128
```
131129
The plugin is now added to your local .m2 repository, giving it priority over the version available in the central Maven repository during the application build.
132130

133-
3. Checkout to the branch **deploy**:
131+
3. Checkout to the branch **local_deploy**:
134132

135133
```sh
136-
git checkout deploy
134+
git checkout local_deploy
137135
```
138136

139137
4. Navigate to the demoapp folder:
@@ -1187,11 +1185,17 @@ annotate my.Books.attachments with @UI: {
11871185
},
11881186
LineItem : [
11891187
{Value: type, @HTML5.CssDefaults: {width: '10%'}},
1190-
{Value: fileName, @HTML5.CssDefaults: {width: '25%'}},
1188+
{Value: fileName, @HTML5.CssDefaults: {width: '20%'}},
11911189
{Value: content, @HTML5.CssDefaults: {width: '0%'}},
11921190
{Value: createdAt, @HTML5.CssDefaults: {width: '20%'}},
11931191
{Value: createdBy, @HTML5.CssDefaults: {width: '20%'}},
1194-
{Value: note, @HTML5.CssDefaults: {width: '25%'}},
1192+
{Value: note, @HTML5.CssDefaults: {width: '20%'}},
1193+
{
1194+
Value : uploadStatus,
1195+
Criticality: uploadStatusNav.criticality,
1196+
@Common.FieldControl: #ReadOnly,
1197+
@HTML5.CssDefaults: {width: '10%'}
1198+
},
11951199
{
11961200
$Type : 'UI.DataFieldForActionGroup',
11971201
ID : 'TableActionGroup',
@@ -1276,48 +1280,6 @@ SDM.mimetypeInvalidError=Der Dateityp ist nicht zulässig
12761280
SDM.maxCountErrorMessage=Maximale Anzahl von Anhängen erreicht
12771281
```
12781282

1279-
## Support for Attachment Virus Scanning
1280-
1281-
The SDM CAP plugin supports two types of virus scanning for uploaded attachments:
1282-
1283-
### 1. Malware Scan
1284-
1285-
Malware scanning can be enabled by setting the `VirusScanEnabled` property to `true` during repository onboarding.
1286-
1287-
**Enable Malware Scan:**
1288-
```java
1289-
repository.setIsVirusScanEnabled(true);
1290-
```
1291-
1292-
**Workflow:**
1293-
- When a file is uploaded to a malware scan-enabled repository, the initial status displays as **"Uploading"**.
1294-
- If the attachment is clean, the status changes to **"Success"**.
1295-
- If a virus is detected, an error message is displayed and the file is automatically removed from the UI.
1296-
1297-
**Limitations:**
1298-
- Malware scanning supports a maximum file size of **400 MB**.
1299-
- Files exceeding this limit cannot be scanned and will show an error.
1300-
1301-
### 2. Trend Micro Scan
1302-
1303-
Trend Micro scanning provides advanced virus detection capabilities with asynchronous processing.
1304-
1305-
**Enable Trend Micro Scan:**
1306-
```java
1307-
repository.setIsAsyncVirusScanEnabled(true);
1308-
```
1309-
1310-
**Workflow:**
1311-
- When a file is uploaded to a Trend Micro scan-enabled repository, the initial status displays as **"Uploading"**.
1312-
- The status then transitions to **"Virus Scanning in Progress"**.
1313-
- After the scan completes:
1314-
- If the attachment is virus-free, the status changes to **"Success"** (requires page refresh).
1315-
- If a virus is detected, the status changes to **"Virus Detected"** and the user must manually delete the file before saving the entity.
1316-
1317-
**Key Considerations:**
1318-
- There is no restriction on file size for Trend Micro scanning.
1319-
- Files with **"Virus Scanning in Progress"** or **"Virus Detected"** status cannot be downloaded or viewed.
1320-
- Users need to refresh the page to see updated scan results.
13211283

13221284
## Support for Attachment Upload Status
13231285

@@ -1329,19 +1291,12 @@ The upload status transitions from "Uploading" to "Success".
13291291
**For repositories with malware scanning:**
13301292
The upload status transitions from "Uploading" to "Success" if no virus is detected. If a virus is detected, the attachment is automatically deleted.
13311293

1332-
**For repositories with Trend Micro virus scanning:**
1333-
The upload status transitions from "Uploading" to "Virus Scanning in Progress". After refreshing the page, if the scan completes successfully and the attachment is virus-free, the status changes to "Success". If a virus is detected, the status changes to "Virus Detected" and the user must manually delete the file before saving the entity.
1334-
1335-
**Note:** Files with "Virus Scanning in Progress" or "Virus Detected" status cannot be downloaded or viewed.
1336-
13371294
To display color-coded status indicators in the UI, create a `sap.attachments-UploadScanStates.csv` file in the `db/data` folder with the following content:
13381295
```
13391296
code;name;criticality
13401297
uploading;Uploading;5
13411298
Success;Success;3
13421299
Failed;Scan Failed;2
1343-
VirusDetected;Virus detected;1
1344-
VirusScanInprogress;Virus scanning inprogress(refresh page);5
13451300
```
13461301

13471302
## Known Restrictions

sdm/src/main/java/com/sap/cds/sdm/handler/applicationservice/SDMReadAttachmentsHandler.java

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,14 @@ public void processBefore(CdsReadEventContext context) throws IOException {
122122
sdmService.checkRepositoryType(repositoryId, context.getUserInfo().getTenant());
123123
Optional<CdsEntity> attachmentDraftEntity =
124124
context.getModel().findEntity(context.getTarget().getQualifiedName() + "_drafts");
125-
125+
String upIdKey = "", upID = "";
126126
if (attachmentDraftEntity.isPresent()) {
127-
String upIdKey = SDMUtils.getUpIdKey(attachmentDraftEntity.get());
127+
upIdKey = SDMUtils.getUpIdKey(attachmentDraftEntity.get());
128128
CqnSelect select = (CqnSelect) context.get("cqn");
129-
String upID = SDMUtils.fetchUPIDFromCQN(select, attachmentDraftEntity.get());
129+
upID = SDMUtils.fetchUPIDFromCQN(select, attachmentDraftEntity.get());
130130

131131
if (!repoValue.getIsAsyncVirusScanEnabled()) {
132+
132133
dbQuery.updateInProgressUploadStatusToSuccess(
133134
attachmentDraftEntity.get(), persistenceService, upID, upIdKey);
134135
}
@@ -167,7 +168,6 @@ public Predicate where(Predicate where) {
167168
return CQL.and(where, repositoryFilter);
168169
}
169170
});
170-
171171
setErrorMessagesInCache(context);
172172
context.setCqn(modifiedCqn);
173173
} catch (Exception e) {
@@ -231,18 +231,28 @@ private void processVirusScanInProgressAttachments(
231231
// Get all attachments with virus scan in progress
232232
Optional<CdsEntity> attachmentDraftEntity =
233233
context.getModel().findEntity(context.getTarget().getQualifiedName() + "_drafts");
234+
Optional<CdsEntity> attachmentActiveEntity =
235+
context.getModel().findEntity(context.getTarget().getQualifiedName());
234236

235237
List<CmisDocument> attachmentsInProgress =
236238
dbQuery.getAttachmentsWithVirusScanInProgress(
237-
attachmentDraftEntity.get(), persistenceService, upID, upIDkey);
239+
attachmentDraftEntity.orElse(null),
240+
attachmentActiveEntity.orElse(null),
241+
persistenceService,
242+
upID,
243+
upIDkey);
238244

239245
// Get SDM credentials
240246
var sdmCredentials = tokenHandler.getSDMCredentials();
241247

242248
// Iterate through each attachment and call getObject
243249
for (CmisDocument attachment : attachmentsInProgress) {
244250
processAttachmentVirusScanStatus(
245-
attachment, sdmCredentials, attachmentDraftEntity.get(), persistenceService);
251+
attachment,
252+
sdmCredentials,
253+
attachmentDraftEntity.orElse(null),
254+
attachmentActiveEntity.orElse(null),
255+
persistenceService);
246256
}
247257

248258
if (!attachmentsInProgress.isEmpty()) {
@@ -261,12 +271,14 @@ private void processVirusScanInProgressAttachments(
261271
* @param attachment the attachment document to process
262272
* @param sdmCredentials the SDM credentials for API calls
263273
* @param attachmentDraftEntity the draft entity for the attachment
274+
* @param attachmentActiveEntity the active entity for the attachment
264275
* @param persistenceService the persistence service for database operations
265276
*/
266277
private void processAttachmentVirusScanStatus(
267278
CmisDocument attachment,
268279
SDMCredentials sdmCredentials,
269280
CdsEntity attachmentDraftEntity,
281+
CdsEntity attachmentActiveEntity,
270282
PersistenceService persistenceService) {
271283
try {
272284
String objectId = attachment.getObjectId();
@@ -299,7 +311,11 @@ private void processAttachmentVirusScanStatus(
299311
if (scanStatus != null) {
300312
SDMConstants.ScanStatus scanStatusEnum = SDMConstants.ScanStatus.fromValue(scanStatus);
301313
dbQuery.updateUploadStatusByScanStatus(
302-
attachmentDraftEntity, persistenceService, objectId, scanStatusEnum);
314+
attachmentDraftEntity,
315+
attachmentActiveEntity,
316+
persistenceService,
317+
objectId,
318+
scanStatusEnum);
303319
logger.info(
304320
"Updated uploadStatus for objectId: {} based on scanStatus: {}",
305321
objectId,

0 commit comments

Comments
 (0)