6

Media in SAP Cloud Application Programming Model(CAP)

 1 year ago
source link: https://blogs.sap.com/2022/02/18/media-in-sap-cloud-application-programming-modelcap/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
February 18, 2022 4 minute read

Media in SAP Cloud Application Programming Model(CAP)

7 9 1,082

In this post, I’m going to show how to store media data in SAP HANA DB using SAP Cloud Application Programming Model(CAP) and UI5.

Prerequisites:

Need to know how to create a basic CAP project and adding a UI to it using SAP Business Application Studio.

  • Create a CAP project-Media
Picture-1-3.png
  • Create an entity for media named ‘MediaFile’ in data/data-model.cds. Here two annotations are important.
    • @Core.MediaType – It denotes the data element contains media data.
    • @Core.IsMediaType – It denotes the data element contains a MIME type.
    • namespace Media.db;
      
      entity MediaFile {
          key id        : Integer;
              @Core.MediaType   : mediaType
              content   : LargeBinary;
              @Core.IsMediaType : true
              mediaType : String;
              fileName  : String;
              url       : String;
      };
  • Create a service in srv->media-service.cds to expose the MediaFile Entity.
using {Media.db as db} from '../db/data-model';


service MediaService @(path : '/media') {
    entity MediaFile as projection on db.MediaFile;
};
  • In srv->media-service.js add below logic on the hook handlers
    • On before create handler we will generating the url for the uploaded content which is used to view the content in browser.
    • And we also need to add custom logic in read handler to view the uploaded content in the browser.
    • I have used sequence to generate the ID.
const SequenceHelper = require("./library/SequenceHelper");
const { Readable, PassThrough } = require("stream");
const cds = require('@sap/cds');
cds.env.features.fetch_csrf = true

module.exports = cds.service.impl(async function () {

    const {
        MediaFile
    } = this.entities;


    /**
     * Handler method called before creating data entry
     * for entity Mediafile.
     */
    this.before('CREATE', MediaFile, async (req) => {
        const db = await cds.connect.to("db");
        // Create Constructor for SequenceHelper 
        // Pass the sequence name and db
        const SeqReq = new SequenceHelper({
            sequence: "MEDIA_ID",
            db: db,
        });
        //Call method getNextNumber() to fetch the next sequence number 
        let seq_no = await SeqReq.getNextNumber();
        // Assign the sequence number to id element
        req.data.id = seq_no;
        //Assign the url by appending the id
        req.data.url = `/media/MediaFile(${req.data.id})/content`;
    });

    /**
     * Handler method called on reading data entry
     * for entity Mediafile.
     **/
    this.on("READ", MediaFile, async (req, next) => {
        if (!req.data.id) {
            return next();
        }
        //Fetch the url from where the req is triggered
        const url = req._.req.path;
        //If the request url contains keyword "content"
        // then read the media content
        if (url.includes("content")) {
            const id = req.data.id;
            var tx = cds.transaction(req);
            // Fetch the media obj from database
            var mediaObj = await tx.run(
                SELECT.one.from("Media.db.MediaFile", ["content", "mediaType"]).where(
                    "id =",
                    id
                )
            );
            if (mediaObj.length <= 0) {
                req.reject(404, "Media not found for the ID");
                return;
            }
            var decodedMedia = "";
            decodedMedia = new Buffer.from(
                mediaObj.content.toString().split(";base64,").pop(),
                "base64"
            );
            return _formatResult(decodedMedia, mediaObj.mediaType);
        } else return next();
    });

    function _formatResult(decodedMedia, mediaType) {
        const readable = new Readable();
        const result = new Array();
        readable.push(decodedMedia);
        readable.push(null);
        return {
            value: readable,
            '*@odata.mediaContentType': mediaType
        }
    }

UI to upload the file

  • Add a UI application in your CAP project and create OData model for the above cap service.
  • In the View code to add a File uploader ui and a button to trigger file upload action.
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:u="sap.ui.unified" controllerName="com.ta.mediaui.controller.mediaUpload" displayBlock="true">
    <Shell id="shell">
        <App id="app">
            <pages>
                <Page id="page" title="{i18n>title}">
                    <content>
                        <FlexBox direction="Column" class="sapUiLargeMargin">
                            <Label text="Attach File" labelFor="fileUploader" required="true"/>
                            <u:FileUploader id="__fileUploader" tooltip="Upload your file to DB" change="onFileChange"/>
                            <Button text="Upload" press="onUploadFile" type="Emphasized"/>
                            	<Image ariaDetails="detailsActiveImage" src="media_srv/v2/media/MediaFile(1)/content"
					decorative="false"/>
                        </FlexBox>
                    </content>
                </Page>
            </pages>
        </App>
    </Shell>
</mvc:View>
  • In Button Action add the below logic to upload the file in the SAP HANA DB through CAP.
  • As a first step, create an entity without media data using a CREATE request. After creating the entity, you can insert a media property using the UPDATE method.
// @ts-nocheck
sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/m/MessageBox"
],
    /**
     * @param {typeof sap.ui.core.mvc.Controller} Controller
     */
    function (Controller, MessageBox) {
        "use strict";

        return Controller.extend("com.ta.mediaui.controller.mediaUpload", {
            onInit: function () {
            },

            _getBaseURL: function () {
                var oBaseUrl = this.getOwnerComponent().getManifestEntry("/sap.app/id").replaceAll(".", "/");
                return jQuery.sap.getModulePath(oBaseUrl)
            },

            /**
             * on File Change
             */
            onFileChange: function (oEvent) {
                var file = oEvent.getParameters("files").files[0];
                this.file = file;
            },

            /**
             * On File Upload
             */
            onUploadFile: function () {
                var oUploadSet = this.byId("__fileUploader");
                //Upload image
                var reader = new FileReader();
                reader.onload = function (oEvent) {
                    // get an access to the content of the file
                    this.content = oEvent.currentTarget.result;
                    this.createfile();
                }.bind(this);
                reader.readAsDataURL(this.file);

            },

            /**
             *  Create Operation to create an entry in CAP
             */
            createfile: function () {
                var that = this;
                // Data for CAP to create entry
                var oImageData = {
                    "content": this.content,
                    "mediaType": this.file.type,
                    "fileName": this.file.name
                };
                var oCAPModel = this.getOwnerComponent().getModel("oCAPModel");
                var sURL = "/MediaFile";
                //Create call for CAP OData Service
                oCAPModel.create(sURL, oImageData, {
                    success: function (oData, oResponse) {
                        var id = oData.id;
                        var sMsg = "File Uploaded Successfully for ID: " + id;
                        MessageBox.success(sMsg);
                    },
                    error: function (jqXHR, textStatus) {

                    },
                });
            },


        });
    });

Results:

  • UI Screen to upload the document.I have uploaded a pdf called dummy.pdf
Picture-1-4.png
Screenshot-2022-02-15-at-11.00.49-AM.png
  • The data stored in CAP
Screenshot-2022-02-15-at-11.01.58-AM.png
  • Media file in browser
Screenshot-2022-02-15-at-11.02.52-AM.png

 Conclusion:

From this blog we are able to understand how SAP Cloud Application Programming Model(CAP) provides out-of-the-box support for serving media and other binary data.

However, you can use it to make much more elaborate changes to your applications.

I would love to hear from you! Please leave your feedback below.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK