
In my previous blog: Extend Upload Set to Fiori Elements and utilize Document Management Service, I introduced a sample program for SAP BTP that manages both text and file information. Previous blog is explaining about completed artifacts, and I think someone (including myself) would like to know how to build this artifacts. It is more difficult to describe dynamic workflow in document, but I would like to focus on important findings that are not yet documented from my perspective.
This document is useful for you when you are new to implement / test / deploy Fiori Elements (including SAPUI5 extension) and CAP OData services integrated with another services like SAP Document Management service (SDM).
You already tried to implement and deploy application with "Full-Stack Application Using Productivity Tools" dev space in Business Application Studio (BAS). For example, follow Develop Full-Stack App Using the High Productivity Tools of SAP Business Application Studio and Create a CAP Service with BAS Productivity Tools tutorials.
From now I use "Full-Stack Cloud Application" dev space in BAS to align with your environment. Usually, I am using local VSCode environment, that is just my preference to prevent annoying disconnection in BAS. So, you can choose your preferred one.
First step is CAP OData service from scratch. I think it is convenient to use command to generate template code by running `cds init` in prompt.
I can start writing db/schema.cds file for database entity `TemplateRequests` and file entity `Attachments`. I need to add SDM specific annotation to `Attachments` entity and properties (refer to sap-cap-sdm-plugin). Then I write srv/user-service.cds to expose above entities as service.
I feel it is not difficult to manually write these CDS files, compared with Fiori Elements application. If you feel difficulty, instead you can open Storyboard from command pallet then generate CDS files via GUI data modeler.
After two files are written, I need to create .cdsrc.json file to connect to SDM service (refer to sap-cap-sdm-plugin too). This file is similar meaning with `cds` part of package.json as reference mentioned.
Let's test what I created.
First, I need `npm i sap-cap-sdm-plugin` command to add this plugin and install all required packages.
Run `cds watch` command and go to http://localhost:4004 (or equivalent URL in case of BAS). You can see Service Endpoint `/odata/v4/user` and two entities I created. After mocked authentication (alice/123 is enough), `TemplateRequests` is working well (just see zero record), but `Attachments` failed with error `[cds] - Error: Could not find service binding of type 'destination'.`.
This error mentioned that we need destination to access to SDM. It is happened when we need to access to another cloud services. Next step is to setup to connect to SDM.
As mentioned in previous section, we need destination to test my CAP OData service. Destination service, with help of XSUAA (Authorization and Trust Management) service, will be deployed to Cloud Foundry environment. These services are required for both local (hybrid) testing and production, so I will create deployment file `mta.yaml` for production purpose, and utilize associated destination service for testing.
Run `cds add hana,xsuaa,destination,mta` to generate `mta.yaml` file for XSUAA / destination services (and HANA database for production).
Follow `Setup sample application` section of my previous blog, except for cloning sample code to deploy your current application with services. In my environment, I need to delete `-${org}-${space}` from `xsappname` in `mta.yaml` to process deployment.
After deployment has done, I do not use application (OData service) in Cloud Foundry, but use XSUAA / destination for next step.
Now I am ready to test in local environment. Local test using Cloud Foundry service is called hybrid testing. I use `cds bind` command to bind to XSUAA and destination service instances (if you want to persist testing data to HANA Cloud, you will bind to HDI container service too).
After binding to service instances, you can find `.cdsrc-private.json` file, that is generated by above command. That file is only used for hybrid testing, and when we keep binding part of this file, it is fine to change the rest for my convenience. I changed authentication from XSUAA auth to mocked auth and in-memory (SQLite) db .
From:
"requires": {
"[hybrid]": {
"auth": {
"kind": "xsuaa-auth",
To:
"requires": {
"[hybrid]": {
"db":{
"kind": "sql"
},
"auth": {
"kind": "mocked",
"users": {"alice": {"roles":[]}},
Now I start `cds watch --profile hybrid` command to use binding services above. Open http://localhost:4004 again and this time I can process `Attachments` entity successfully as below.
GET result of Attachments entity
It is fine to test GET request of OData in this way, but I would like to test POST/PATCH/DELETE requests too. To do this, I will use test/test.http file that is utilizing REST Client as below screen. REST Client is more convenient way to test OData service, for example I can collect multiple requests to file and pass one response value (generated ID e.g.) to variable and extract it at next request.
When OData service is fully tested, I will move to Fiori Elements. Please keep in mind that hybrid testing is effective for testing Fiori Elements (and other SAPUI5 app) too.
Test OData service using REST Client
Next step is to implement Fiori Elements application. You may be surprised at many files inside app directory in my repository. No worry 😌, most of files are generated by Application Generator in SAP Fiori tools and no need to change manually.
I can open Command Pallete to type `Fiori: Open Application Generator` in it. Then you can choose configurations below.
After app files are generated, you can start Page Map to modify default Fiori Elements (if you cannot open Page Map, you will reload browser and try again). Changing configuration in this GUI tool is affected to generated files, like annotations.cds and manifest.json.
In most of cases it is enough to use Page Map for configuring Fiori Elements, but there are some cases to manually append annotations (for example `UI.UpdateHidden` annotation is disappearing Edit button). Below references are helpful.
When some configuration changed, I can check what is happened using local (hybrid) testing. Run `cds watch --profile hybrid` command and go to http://localhost:4004, now I can see UI5 applications at Web Applications part (first one is for production purpose, and the rest of three are for automation testing that I do not mention today).
Thanks to mocked authentication I setup before, I can access to UI5 application with binding to destination service. (If you are interested, please revert back to `xsuaa-auth` in `.cdsrc-private.json` and check if what is happened, you are not possible to authenticate from here.)
In this app, I setup Flexible Column Layout in Page Map to resolve UploadSet issue.
Flexible Column Layout in Page Map
Next step is extending custom section for handling SDM files. From Page Map, I will go to Object Page and click `+` button in Sections, then select Custom Section. In the popup, I will select to create New Fragment and Generate Event Handler (Controller). Those are ones I will modify later for my requirement.
Extend custom section in Object Page
After click Add button, you can find `Attachments.fragment.xml` and `Attachments.ts` files in ext/fragment directory. Run `cds watch --profile hybrid` command and go to http://localhost:4004 and UI5 app, now I can see Attachments section and one button at the last section. It is derived from default XML fragment and controller.
I will start my implementation from Sample code of UploadSet. First, I will copy `Page.view.xml` to paste to my `Attachments.fragment.xml`. Sample code is for View and not fit to my Fragment, so you should copy `<upload:UploadSet> part only. Also to recognize `upload` namespace, you will copy `xmlns:upload="sap.m.upload"` in the FragmentDefinition tag.
Run `cds watch --profile hybrid` command and go to http://localhost:4004 and UI5 app, and I can see UploadSet component (not working yet, will modify).
Copy sample UploadSet to XML fragment
Next, let's remove buttons to simplify implementation. I will remove `<upload:toolbar>` part and check again. Hmm 🤔, no change happened to browser 😓. At that time, you will go to development tools in the browser (Microsoft Edge in my case), go to Application, then clear site data. Then reload BAS to authenticate again and try again, now updated XML view is applied and removed buttons 😀.
Clear site data in developer tools
From now, I will read UploadSet and UploadSetItem API reference to understand each property and events. Then finally completed Attachments.fragment.xml coding.
Even XML fragment is possible to some part of requirements (e.g. list up files in directory), I know I need to modify standard logic to align with CAP OData service, so I will start modifying `Attachments.ts` TypeScript file.
First, TypeScript is easier for me compared with JavaScript in two perspective, first TypeScript syntax is similar to my previously learned language, second TypeScript is checking syntax error at coding (before testing). I recommend to select TypeScript when selecting which language is used when generating Fiori Elements.
Going back to Sample code of UploadSet to find `Page.controller.js` file. This is JavaScript code, and I am not familiar with this syntax (first few lines especially). Now we have convenient tool, Generative AI to convert to TypeScript. I used Bing Copilot to do this task (convert below Javascript code to TypeScript <<sample code>>).
Converting sample JavaScript to TypeScript
Converted code is better for me to understand code structure. We need to import some UI5 classes at first, and implement action against each event. Actually I do not use sample code for my case, but it is useful for reference.
Event name described in XML fragment is linked with function name in TypeScript. To find controller logic correctly, I need to write `core:require="{ handler: 'kaztakata/templaterequests/ext/fragment/Attachments'}"` in XML fragment. That handler path is written in the generated dummy button at the beginning, so move this part to UploadSet tag.
After that, I will read UploadSet and UploadSetItem API reference again and iterate writing code and testing it. Below list is my workflow.
Finally completed Attachments.ts coding.
Deploying Fiori Elements (and SAPUI5) needs some preparation.
I will add Approuter configuration from now. Approuter is mandatory parts for publishing SAPUI5 apps to Cloud Foundry. There are two types, one is stand alone type that is deployed by myself, the other is managed type that is used from Work Zone, standard edition etc (see SAP Tech Bytes: FAQ Managed Approuter vs. Standalone Approuter for detail). I will simply use managed Approuter in Work Zone, standard edition.
Read Set Up Your Development Environment then update below points (Check following documents in detail of each topic). I will provide my files (link) for your reference.
Add Fiori Launchpad (Work Zone) Config
After setup has done, run `mbt build` and `cf deploy your_mta_file` to deploy your app and surrounding services.
Everything is deployed to Cloud Foundry environment. I can go to HTML5 applications menu in SAP BTP Cockpit to find my Fiori Elements. Click app and I will authenticate by Approuter, then go to Fiori Elements successfully. I can test creating entry and uploading/downloading document, same as local (hybrid) testing.
Conglaturation ㊗️. That is all of my instruction.
I will skip setting of Work Zone, but you can check Integrating Business Content for detail.
HTML5 Application in Cloud Foundry environment
I am creating this blog for my follower to catch up development skill quickly, and to summarize my acquired knowledge for myself. So if you have any question and feedback, please response to this blog or raise issue to GitHub repository, that is helpful for me.
I am happy if you will implement your application with this workflow 😊.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
11 | |
10 | |
9 | |
7 | |
6 | |
5 | |
5 | |
5 | |
4 | |
4 |