Suppliers moved to bookshop namespace

This commit is contained in:
Uwe Klinger
2021-05-04 08:56:20 +02:00
parent 98113c46fd
commit 8601bd8a46
7 changed files with 67 additions and 32 deletions

View File

@@ -85,8 +85,17 @@ In case you've a question, find a bug, or otherwise need support, use our [commu
Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, version 2.0 except as noted otherwise in the [LICENSE](LICENSE.txt) file.
# Suppliers - in progress for Service Consumption -
## TODOs
1. Move `Suppliers` out of `API_BUSINESS_PARTNER` - remove additional lines in monkey patch --> Uwe
2. Fix problem with `await S4bupa.read (Suppliers).where('ID in',IDs)` --> Johannes
3.
1. Fix problem with `await S4bupa.read (Suppliers).where('ID in',IDs)` --> Johannes
2. Fix issues when running in same process
3. Automated tests
## Usage
1. Run: `PORT=5001 cds mock API_BUSINESS_PARTNER`
2. Wait until startup is completed
3. Run in a 2nd terminal: `cds serve all --with-mocks --in-memory`
4. Now, you can issues the requests listed in `suppliers/requests.http`

View File

@@ -18,6 +18,11 @@
"API_BUSINESS_PARTNER": {
"kind": "odata",
"model": "srv/external/API_BUSINESS_PARTNER"
},
"[development]": {
"messaging": {
"kind": "file-based-messaging"
}
}
}
}

View File

@@ -1,9 +1,9 @@
@server = http://localhost:4004
@bpServer = http://localhost:59847
@bpServer = http://localhost:5001
@authAlice = Authorization: Basic alice:
PATCH {{server}}/api-business-partner/A_BusinessPartner('ACME')
PATCH {{bpServer}}/api-business-partner/A_BusinessPartner('ACME')
Content-Type: application/json
{

View File

@@ -1,10 +1,11 @@
const cds = require('@sap/cds');
module.exports = cds.service.impl(function (srv) {
module.exports = cds.service.impl(async function (srv) {
const messaging = await cds.connect.to('messaging')
const { A_BusinessPartner } = this.entities;
srv.after('UPDATE', A_BusinessPartner, data => {
console.log(`>>> BusinessPartner updated ${data.BusinessPartner}`);
srv.emit("BusinessPartners/Changed", { businessPartners: [ data.BusinessPartner ] });
messaging.emit("BusinessPartners/Changed", { businessPartners: [ data.BusinessPartner ] });
});
});

View File

@@ -1,5 +1,5 @@
ID;name
ACME;A Company Making Everything
ACME;A Company Making Everything (X)
B4U;Books for You
S&C;Shakespeare & Co.
WSL;Waterstones
1 ID name
2 ACME A Company Making Everything A Company Making Everything (X)
3 B4U Books for You
4 S&C Shakespeare & Co.
5 WSL Waterstones

View File

@@ -3,9 +3,12 @@
you actually want to use from there.
*/
using { sap.capire.bookshop as bookshop } from '@capire/bookshop';
using { API_BUSINESS_PARTNER as S4 } from './external/API_BUSINESS_PARTNER.csn';
extend service S4 with {
entity Suppliers as projection on S4.A_BusinessPartner {
@cds.autoexpose // or expose explicitly in Catalog and AdminService
@cds.persistence: {table,skip:false} // add persistency
entity sap.capire.bookshop.Suppliers as projection on S4.A_BusinessPartner {
// TODO: Aliases not supported in Java, yet?
key BusinessPartner as ID,
BusinessPartnerFullName as name,
@@ -21,27 +24,28 @@ extend service S4 with {
// REVISIT: following is not supported so far in cqn2odata...
// to_BusinessPartnerAddress.CityCode as city,
// to_BusinessPartnerAddress.CityName as city_name,
}
// REVISIT: Alternative idea to use a specific replication view, but request data from
// a different view and manual map values.
// entity ReplicatedSuppliers as projection on Suppliers {
// ID,
// name,
// to_BusinessPartnerAddress.CityCode as city,
// to_BusinessPartnerAddress.CityName as city_name
// }
}
// REVISIT: Alternative idea to use a specific replication view, but request data from
// a different view and manual map values.
// entity ReplicatedSuppliers as projection on Suppliers {
// ID,
// name,
// to_BusinessPartnerAddress.CityCode as city,
// to_BusinessPartnerAddress.CityName as city_name
// }
/*
You can mashup entities from external services, or projections
thereof, with your project's own entities
*/
using { sap.capire.bookshop.Books, CatalogService } from '@capire/bookshop';
extend Books with {
supplier : Association to S4.Suppliers;
supplier : Association to bookshop.Suppliers;
}
@@ -51,15 +55,9 @@ extend Books with {
addressed to your services into calls to the external service.
*/
extend service AdminService with {
entity Suppliers as projection on S4.Suppliers;
entity Suppliers as projection on bookshop.Suppliers;
}
/*
Optionally add a local persistence to keep replicas of external
entities to have data in fast access locally; much like a cache.
*/
annotate S4.Suppliers with @cds.persistence:{table,skip:false};
/**
Having locally cached replicas also allows us to display supplier
data in lists of books, which otherwise would generate unwanted

View File

@@ -10,9 +10,10 @@ module.exports = async()=>{ // called by server.js
const S4bupa = await cds.connect.to('API_BUSINESS_PARTNER') //> external S4 service
const admin = await cds.connect.to('AdminService') //> local domain service
const db = await cds.connect.to('db') //> our primary database
const messaging = await cds.connect.to('messaging');
// Reflect CDS definition of the Suppliers entity
const { Suppliers } = S4bupa.entities
const Suppliers = db.entities["sap.capire.bookshop.Suppliers"];
admin.prepend (()=>{ //> to ensure our .on handlers below go before the default ones
@@ -38,9 +39,9 @@ module.exports = async()=>{ // called by server.js
})
// Subscribe to changes in the S4 origin of Suppliers data
// REVISIT: cds context is still from the UPDAT method when running in same programm, but should
// REVISIT: cds context is still from the UPDATE method when running in same programm, but should
// be a separate
S4bupa.on ('BusinessPartners/Changed', async msg => { //> would be great if we had batch events from S/4
messaging.on ('BusinessPartners/Changed', async msg => { //> would be great if we had batch events from S/4
await new Promise( resolve => setTimeout( resolve, 1000 ));
const tx = cds.db.tx(msg);
let replicas = await tx.run(SELECT('ID').from (Suppliers) .where ('ID in', msg.data.businessPartners));
@@ -79,4 +80,25 @@ module.exports = async()=>{ // called by server.js
))
}
{
// one server: returns AdminSuppliers
// two servers: returns A_BusinessPartner
const tx = S4bupa.tx({});
let result = await tx.run(SELECT('*').from ('AdminService.Suppliers') .where ('ID =', 'ACME'));
tx.commit();
console.log(result);
}
{
// one server: returns AdminSuppliers
// two servers: returns AdminSuppliers
const tx = db.tx({});
let result = await db.run(SELECT('*').from ('AdminService.Suppliers') .where ('ID =', 'ACME'));
tx.commit();
console.log(result);
}
//process.exit(0);
}