Skip to content

cap-java/cds-feature-attachments

Java Build with Maven Deploy new Version with Maven REUSE status

Attachments Plugin for SAP Cloud Application Programming Model (CAP)

The com.sap.cds:cds-feature-attachments dependency is a CAP Java plugin that provides out-of-the box attachments storage and handling by using an aspect Attachments.

It supports the AWS, Azure, and Google object stores and can connect to a malware scanner.

Table of Contents

Quick Start

For a quick setup with in-memory storage:

  • Add the cds-feature-attachments Maven dependency to the srv/pom.xml and configure the cds-maven-plugin with the resolve goal as described in MVN Setup.
  • Extend the CDS model with the Attachments aspect and annotate the service for UI integration as explained in Changes in the CDS Models and for the UI.

The incidents app provides a demonstration of how to use this plugin.

For object store integration, see Amazon, Azure, and Google Object Stores.

Usage

MVN Setup

As described in the CAP Java Documentation, the attachments plugin needs to be referenced in the srv/pom.xml of the consuming CAP Java application:

<dependency>
    <groupId>com.sap.cds</groupId>
    <artifactId>cds-feature-attachments</artifactId>
    <version>${latest-version}</version>
</dependency>

Additionally, the cds-maven-plugin must be configured with the resolve goal to ensure CDS models from dependencies are available. For this, add the following to the srv/pom.xml before the entry build as well:

<plugin>
    <groupId>com.sap.cds</groupId>
    <artifactId>cds-maven-plugin</artifactId>
    <version>${cds.services.version}</version>
    <executions>
        <execution>
            <id>cds.resolve</id>
            <goals>
                <goal>resolve</goal>
            </goals>
        </execution>
    </executions>
</plugin>

After that, the aspect Attachments can be used in the application's CDS model.

Changes in the CDS Models and for the UI

To use the aspect Attachments on an existing entity, the corresponding entity needs to be extended in a CDS file in the srv module. The following example shows how to extend the entity Incidents in the srv module with an additional attachments.cds file, it also directly adds the respective UI Facet. To use this file with the incidents app, check out the source code, copy the file from the xmpls folder to the srv folder and run the app as explained in the incidents app README.

using { sap.capire.incidents as my } from '../db/schema';
using { sap.attachments.Attachments } from 'com.sap.cds/cds-feature-attachments';

extend my.Incidents with {
  attachments: Composition of many Attachments;
}

using { ProcessorService as service } from '../app/services';
annotate service.Incidents with @(
  UI.Facets: [
    ...,
    {
      $Type  : 'UI.ReferenceFacet',
      ID     : 'AttachmentsFacet',
      Label  : '{i18n>attachments}',
      Target : 'attachments/@UI.LineItem'
    }
  ]
);

The UI Facet can also be added directly after other UI Facets in a cds file in the app folder.

Storage Targets

By default, the plugin operates without a dedicated storage target, storing attachments directly in the underlying database.

Other available storage targets:

When using a dedicated storage target, the attachment is not stored in the underlying database; instead, it is saved on the specified storage target and only a reference to the file is kept in the database, as defined in the CDS model.

Malware Scanner

This plugin checks for a binding to the SAP Malware Scanning Service, which needs to have the label malware-scanner. The entry in the mta-file may look like:

_schema-version: '0.1'
ID: consuming-app
version: 1.0.0
description: "App consuming the attachments plugin with a malware scanner"
parameters:
  ...
modules:
  - name: consuming-app-srv
# ------------------------------------------------------------
    type: java
    path: srv
    parameters:
      ...
    properties:
      ...
    build-parameters:
      ...
    requires:
      - name: consuming-app-hdi-container
      - name: consuming-app-uaa
      - name: cf-logging
      - name: malware-scanner
...
resources:
  ...
  - name: malware-scanner
    type: org.cloudfoundry.managed-service
    parameters:
      service: malware-scanner
      service-plan: clamav

The malware scanner is used in the AttachmentService to scan attachments.

If there is no malware scanner available, the attachments are automatically marked as Clean.

Scan status codes:

  • Clean: Only attachments with the status Clean are accessible.
  • Scanning: Immediately after upload, the attachment is marked as Scanning. Depending on processing speed, it may already appear as Clean when the page is reloaded.
  • Unscanned: Attachment is still unscanned.
  • Failed: Scanning failed.
  • Infected: The attachment is infected.

Outbox

In this plugin the persistent outbox is used to mark attachments as deleted. When using this plugin, the persistent outbox is enabled by default. In the capire documentation of the persistent outbox is it described how to overwrite the default outbox configuration.

If the default shall be used, nothing needs to be done.

Restore Endpoint

The attachment service has an event RESTORE_ATTACHMENTS. This event can be called with a timestamp to restore externally stored attachments.

Motivation

Documents which are marked as deleted can be restored.

The use cases behind this feature are:

  • Restoring attachments after a database backup is restored: When restoring a database backup, any attachments stored in external storage (object stores, etc.) also need to be restored to maintain data consistency.
  • Restoring attachments that were marked as deleted: The restore endpoint provides a way to recover attachments that were previously marked as deleted, making it possible to undo deletions if needed.

In the default implementation of the technical service AttachmentService this is not needed as the attachments are stored directly in the database and are restored with the database.

If the default implementation is replaced by overwriting the respective handler, for example by the SAP Document Management Service, then the overwriting plugin needs to handle the restore of attachments.

In such cases the restore endpoint can be used to restore attachments.

How long attachments are marked as deleted before they are actually deleted depends on the configuration of the used storage.

HTTP Endpoint

There is no predefined endpoint for the restore action. To call the action of the service from outside the application a service could be defined as in the following example:

service RestoreAttachments {
  action restoreAttachments (restoreTimestamp: Timestamp);
}

See Security for how to secure this endpoint. The action restoreAttachments could get in a timestamp from which the attachments need to be restored. The action could be called with a POST request to the endpoint:

  • OData v4: /odata/v4/RestoreAttachments/restoreAttachments
  • OData v2: /odata/v2/RestoreAttachments/restoreAttachments

With the body:

{
  "restoreTimestamp": "2024-04-17T10:36:38.813491100Z"
}

The action needs to be implemented and can call the attachment service as in the following example:

@ServiceName(RestoreAttachments_.CDS_NAME)
public class RestoreAttachmentsHandler implements EventHandler {

	private final AttachmentService attachmentService;

	public RestoreAttachmentsHandler(AttachmentService attachmentService) {
		this.attachmentService = attachmentService;
	}

	@On(event = RestoreAttachmentsContext.CDS_NAME)
	public void restoreAttachments(RestoreAttachmentsContext context) {
		attachmentService.restoreAttachment(context.getRestoreTimestamp());
		context.setCompleted();
	}

}

In the Spring Boot context the AttachmentService can be autowired in the handler.

Security

To secure the endpoint, security annotations can be used. For example:

using {sap.attachments.Attachments} from `com.sap.cds/cds-feature-attachments`;

entity Items : cuid {
    ...
    attachments : Composition of many Attachments;
    ...
}

annotate RestoreAttachments with @(requires: 'internal-user');

Here the RestoreAttachments service is annotated with the requires annotation to secure the service. Various other annotations can be used to secure the service.

More information about the CAP Java security concept can be found in the CAP Java Documentation.

Releases: Maven Central and Artifactory

Minimum UI5 and CAP Java Version

Component Minimum Version
CAP Java 3.10.3
UI5 1.136.0

Architecture Overview

Design

Multitenancy

  • When using SAP HANA as the storage target, multitenancy support depends on the consuming application. In most cases, multitenancy is achieved by using a dedicated schema for each tenant, providing strong data isolation at the database level.
  • When using an object store as the storage target, true multitenancy is not yet implemented (as of version 1.2.1). In this case, all blobs are stored in a single bucket, and tenant data is not separated.

Object Stores

See Object Stores.

Model Texts

In the model, several fields are annotated with the @title annotation. Default texts are provided in 35 languages. If these defaults are not sufficient for an application, they can be overwritten by applications with custom texts or translations.

The following table gives an overview of the fields and the i18n codes:

Field Name i18n Code
content attachment_content
mimeType attachment_mimeType
fileName attachment_fileName
status attachment_status
note attachment_note

In addition to the field names, header information (@UI.HeaderInfo) are also annotated:

Header Info i18n Code
TypeName attachment
TypeNamePlural attachments

Monitoring & Logging

To configure logging for the attachments plugin, add the following line to the /srv/src/main/resources/application.yaml of the consuming application:

logging:
  level:
    ...
    '[com.sap.cds.feature.attachments]': DEBUG
...

Support, Feedback, Contributing

This project is open to feature requests/suggestions, bug reports etc. via GitHub issues.

Contribution and feedback are encouraged and always welcome. For more information about how to contribute, the project structure, as well as additional contribution information, see our Contribution Guidelines.

References & Links

About

Support for attachments

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 13