Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions xmpls/messaging/app/incidents/field.cds
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using ProcessorService as service from '../../srv/services.cds';
using from './annotations.cds';
using ProcessorService as service from '../../../../srv/processor-service.cds';
using from '../../../../app/incidents/annotations';
annotate service.Incidents with @(
/*adding email to the object page enables users to view the
changes recieved via Messaging/Eventing*/
Expand Down
40 changes: 2 additions & 38 deletions xmpls/messaging/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@
"@sap-cloud-sdk/http-client": "^3.6.0",
"@sap-cloud-sdk/resilience": "^3.6.0",
"@sap-cloud-sdk/util": "^3.6.0",
"@sap/cds": ">=7",
"@cap-js/hana": ">=1",
"@sap/xssec": "^3",
"@sap/cds": ">=8",
"express": "^4",
"passport": "^0",
"@sap/xb-msg-amqp-v100": "^0"
},
"devDependencies": {
Expand All @@ -22,27 +19,12 @@
"scripts": {
"watch": "cds watch",
"start": "cds-serve",
"test": "npx jest --silent",
"add-change-tracking": "npm add @cap-js/change-tracking && cp xmpls/change-tracking.cds ./srv && cp xmpls/change-tracking.test.js ./test",
"add-telemetry": "npm add @cap-js/telemetry",
"add-attachments": "npm add @cap-js/attachments && cp xmpls/attachments.cds ./srv && cp -r xmpls/content ./db/data/content",
"clone-add-attachments": "git clone https://github.com/cap-js/attachments.git && cp -r attachments/xmpl/db . && cp -r attachments/xmpl/app . && npm add https://github.com/cap-js/attachments.git",
"add-notifications": "npm add @cap-js/notifications && cp xmpls/alert-notifications.js ./srv && cp xmpls/notification-types.json ./srv",
"add-audit-log": "npm add @cap-js/audit-logging && cp xmpls/data-privacy.cds ./srv && cp xmpls/audit-log.test.js ./test",
"add-remote-service": "cp -r xmpls/remote-service/* .",
"add-messaging": "cp -r xmpls/messaging/* .",
"add-all-xmpls": "npm run add-remote-service && npm run add-messaging && npm run add-change-tracking && npm run add-audit-log",
"reset": "read -p 'This will irreversibly reset your working directory including ALL files in this git repo. Continue?' -n 1 -r && echo && if [[ $REPLY =~ ^[Yy]$ ]]; then git clean -fd && git reset --hard && npm i; fi"
"test": "npx jest --silent"
},
"private": true,
"sapux": [
"app/incidents"
],
"jest": {
"modulePathIgnorePatterns": [
"<rootDir>/xmpls/"
]
},
"cds": {
"requires": {
"incidents-app": {
Expand All @@ -59,24 +41,6 @@
"kind": "cloudfoundry"
}
},
"[development]": {
"auth": {
"kind": "mocked",
"users": {
"alice": {
"roles": [
"support",
"admin"
]
},
"bob": {
"roles": [
"support"
]
}
}
}
},
"db": {
"kind": "sql"
},
Expand Down
9 changes: 9 additions & 0 deletions xmpls/messaging/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const cds = require ('@sap/cds')

// Add routes to UI
cds.once('bootstrap',(app)=>{
if (cds.watched) app.serve ('/incidents') .from ('../..', '../../app/incidents/webapp')
})

// Returning cds.server
module.exports = cds.server
7 changes: 5 additions & 2 deletions xmpls/messaging/services.cds
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Using local service implementation
// Using local service implementation with remote service
using { ProcessorService } from '../../app/services';
annotate ProcessorService with @impl: 'srv/services.js';
annotate ProcessorService with @impl: 'srv/processor-service.js';

// add the additional field to display changes to email on UI
using from './app/incidents/field';
119 changes: 119 additions & 0 deletions xmpls/messaging/srv/processor-service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
const cds = require('@sap/cds')

class ProcessorService extends cds.ApplicationService {
async init() {
const { Incidents } = this.entities

this.before('UPDATE', Incidents, async req => {
let closed = await SELECT.one(1).from(req.subject).where`status.code = 'C'`
if (closed) req.reject`Can't modify a closed incident!`
})

this.before(['CREATE', 'UPDATE'], Incidents, req => {
let urgent = req.data.title?.match(/urgent/i)
if (urgent) req.data.urgency_code = 'H'
})

this.on('READ', 'Customers', req => this.onCustomerRead(req))
this.on(['CREATE', 'UPDATE'], 'Incidents', (req, next) => this.onCustomerCache(req, next))
this.S4bupa = await cds.connect.to('API_BUSINESS_PARTNER')
this.remoteService = await cds.connect.to('RemoteService') // REVISIT: What is this for?

// Added Handlers for Eventing on top of remote service sample
this.messaging = await cds.connect.to('messaging')
this.messaging.on(
'sap.s4.beh.businesspartner.v1.BusinessPartner.Changed.v1',
async ({ event, data }) => await this.onBusinessPartnerChanged(event, data)
)

return super.init()
}
async onBusinessPartnerChanged(event, data) {
const { Customers } = this.entities
const { BusinessPartnerAddress } = this.remoteService.entities
console.log('<< received', event, data)
const Id = data.BusinessPartner
const customer = await this.S4bupa.run(
SELECT.one(BusinessPartnerAddress, address => {
address('*'),
address.email(emails => {
emails('*')
})
}).where({ BusinessPartner: Id })
)
if (customer) {
customer.email = customer.email[0]?.email
const result = await cds.run(UPDATE(Customers).where({ ID: customer.ID }).set({ email: customer.email }))
console.log('result', result)
}
}

async onCustomerCache(req, next) {
const { Customers } = this.entities
const newCustomerId = req.data.customer_ID
const result = await next()
const { BusinessPartner } = this.remoteService.entities
if (newCustomerId && newCustomerId !== '' && (req.event == 'CREATE' || req.event == 'UPDATE')) {
console.log('>> CREATE or UPDATE customer!')

// Expands are required as the runtime does not support path expressions for remote services
const customer = await this.S4bupa.run(
SELECT.one(BusinessPartner, bp => {
bp('*'),
bp.addresses(address => {
address('email', 'phoneNumber'),
address.email(emails => {
emails('email')
}),
address.phoneNumber(phoneNumber => {
phoneNumber('phone')
})
})
}).where({ ID: newCustomerId })
)

if (customer) {
customer.email = customer.addresses[0]?.email[0]?.email
customer.phone = customer.addresses[0]?.phoneNumber[0]?.phone
delete customer.addresses
delete customer.name
await UPSERT.into(Customers).entries(customer)
}
}
return result
}

async onCustomerRead(req) {
console.log('>> delegating to S4 service...', req.query)
const top = parseInt(req._queryOptions?.$top) || 100
const skip = parseInt(req._queryOptions?.$skip) || 0

const { BusinessPartner } = this.remoteService.entities

// Expands are required as the runtime does not support path expressions for remote services
let result = await this.S4bupa.run(
SELECT.from(BusinessPartner, bp => {
bp('*'),
bp.addresses(address => {
address('email'),
address.email(emails => {
emails('email')
})
})
}).limit(top, skip)
)

result = result.map(bp => ({
ID: bp.ID,
name: bp.name,
email: bp.addresses[0]?.email[0]?.email
}))

// Explicitly set $count so the values show up in the value help in the UI
result.$count = 1000
console.log('after result', result)
return result
}
}

module.exports = { ProcessorService }
123 changes: 0 additions & 123 deletions xmpls/messaging/srv/services.js

This file was deleted.

3 changes: 1 addition & 2 deletions xmpls/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,4 @@ Overwrite existing files.

## Messaging

Copy all files from the `messaging` folder into the main project.
Overwrite existing files.
Start messaging with `cds w xmpls/messaging`