-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: event resources generation #55
Conversation
I extended service definitions of bookshop in the test: using { sap.capire.bookshop as my } from '../db/schema';
service AdminService @(requires:'authenticated-user') {
entity Books as projection on my.Books;
entity Authors as projection on my.Authors;
event BookCreated : {
ID : Integer;
title : String @title: 'Title';
};
event BookDeleted : {
ID : Integer;
};
event BookUpdated : {
ID : Integer;
title : String @title: 'Title';
}
} using { sap.capire.bookshop as my } from '../db/schema';
service CatalogService @(path:'/browse') {
@readonly entity Books as select from my.Books {*,
author.name as author
} excluding { createdBy, modifiedBy };
@requires: 'authenticated-user'
action submitOrder (book: Books:ID, quantity: Integer);
event BookCreated : {
ID : Integer;
title : String @title: 'Title';
};
event BookDeleted : {
ID : Integer;
};
event BookUpdated : {
ID : Integer;
title : String @title: 'Title';
}
} Resulting ORD Document: {
"$schema": "https://sap.github.io/open-resource-discovery/spec-v1/interfaces/Document.schema.json",
"apiResources": [
//...
],
"description": "this is an application description",
"eventResources": [
{
"description": "This is an example event catalog that contains only a partial ODM cap-js-ord V1 event",
"extensible": {
"supported": "no",
},
"ordId": "capjs.ord:eventResource:undefined.AdminService:v1",
"partOfGroups": [
"sap.cds:service:capjs.ord:undefined.AdminService",
],
"partOfPackage": "capjsord:package:undefined:v1",
"releaseStatus": "beta",
"resourceDefinitions": [
{
"accessStrategies": [
{
"type": "open",
},
],
"mediaType": "application/json",
"type": "asyncapi-v2",
"url": "/.well-known/open-resource-discovery/v1/api-metadata/AdminService.asyncapi2.json",
},
],
"shortDescription": "Example ODM Event",
"title": "ODM capjsord Events",
"version": "1.0.0",
"visibility": "public",
},
{
"description": "This is an example event catalog that contains only a partial ODM cap-js-ord V1 event",
"extensible": {
"supported": "no",
},
"ordId": "capjs.ord:eventResource:undefined.CatalogService:v1",
"partOfGroups": [
"sap.cds:service:capjs.ord:undefined.CatalogService",
],
"partOfPackage": "capjsord:package:undefined:v1",
"releaseStatus": "beta",
"resourceDefinitions": [
{
"accessStrategies": [
{
"type": "open",
},
],
"mediaType": "application/json",
"type": "asyncapi-v2",
"url": "/.well-known/open-resource-discovery/v1/api-metadata/CatalogService.asyncapi2.json",
},
],
"shortDescription": "Example ODM Event",
"title": "ODM capjsord Events",
"version": "1.0.0",
"visibility": "public",
},
],
"groups": [
{
"groupId": "sap.cds:service:capjs.ord:undefined.AdminService",
"groupTypeId": "sap.cds:service",
"title": "Admin Service Title",
},
{
"groupId": "sap.cds:service:capjs.ord:undefined.CatalogService",
"groupTypeId": "sap.cds:service",
"title": "Catalog Service Title",
},
],
"openResourceDiscovery": "1.9",
"packages": [
{
"description": "Description for capjs ord",
"ordId": "capjsord:package:undefined:v1",
"partOfProducts": [
"customer:product:capjs.ord:",
],
"shortDescription": "Short description for capjs ord",
"title": "capjs ord",
"vendor": "customer:vendor:Customer:",
"version": "1.0.0",
},
],
"policyLevel": "none",
"products": [
{
"ordId": "customer:product:cap.js.ord:",
"shortDescription": "Description for cap js ord",
"title": "cap js ord",
"vendor": "customer:vendor:customer:",
},
],
} |
Result with our example: |
Co-authored-by: Zongqi Chen <137198879+zongqichen@users.noreply.github.com>
@@ -113,14 +112,9 @@ const fGetGroups = (csn, global) => { | |||
// storing the group ids in a set to avoid duplicates | |||
let groupIds = new Set(); | |||
|
|||
let serviceGroups = global.aServices | |||
return global.aServices |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's not your problem, but this function implementation is really wired:
- We should avoid using global to store data.
- If we have to use global, we should not pass it as argument, which against the usage of global.
- The name 'global.aServices' is really confused. I would suggest that, later we use oop to refactor it.
- The function name and return are also confused. The name is fGetGroups, and I would expect to get the list of group. But the return value is indirectly indication. I would suggest, either we define a variable: 'const groupList' and return this variable, or remove line "let groupIds = new Set();", e.g
const fGetGroups = (csn, global) => return global.aServices
.map((serviceName) => fCreateGroupsTemplateForService(serviceName, csn.definitions[serviceName], new Set()))
.filter((resource) => resource !== null && resource !== undefined);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few cents from my side:
- We should avoid using global to store data.
- If we have to use global, we should not pass it as argument, which against the usage of global.
This probably just my preference. I don't really want to mock a global variable in tests and rather pass a mocked object into the function. Not sure what the others think about it.
- The name 'global.aServices' is really confused. I would suggest that, later we use oop to refactor it.
Could you please elaborate what exactly is confusing you?
The whole project uses a functional programming approach. Not sure how much sense it makes to switch to a totally different concept.
- The function name and return are also confused. The name is fGetGroups, and I would expect to get the list of group. But the return value is indirectly indication. I would suggest, either we define a variable: 'const groupList' and return this variable, or remove line "let groupIds = new Set();", e.g ...
Good point. It would even make sense to remove the groupIds from the function signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thx @ductaily, I see https://github.com/cap-js/ord/blob/main/lib/ord.js#L163, the global is the name of object. This is what I want, but the name is conflict with javascript keyword. We should avoid it. And good point, the naming pattern for example aServices and fGetGroups, we should have agreement in discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to document something that @zongqichen and I discussed via call:
I don't think that global
is a global variable. It's very likely a variable that the CAP Framework passes into the plugins, to pass a global context, where the CAP framework keeps the overall information on what is part of the current application. This is where you find a list of all services, entities etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was also my understanding what the global variable here is. I misinterpreted the statements above.
let service = match.groups?.service | ||
if (service.startsWith("undefined")) service = service.replace("undefined.", "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain these two lines? And service seems to imply to serviceName?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, service imply serviceName, you can see it in the group id regex as a named capturing group.
The implementation here is not finished but my goal was to find the corresponding service in the CSN definition using the information I have in the ORD Document. In this case, I want to find that the eventResource partOfGroups
is assigned to a groupId
that is actually a service in the CSN.
Since they are attaching the namespace
in the groupId, I want to remove the namespace part here to find the corresponding CSN definition. In this case, undefined
.
I will improve this to check for the namespace and remove the namespace instead of undefined
.
I hope this answered the question.
Co-authored-by: Zongqi Chen <137198879+zongqichen@users.noreply.github.com>
…nto fix/event-resources
The tests are failing and I can't reproduce the error on @zongqichen and my machine. @RoshniNaveenaS Do you have an idea what could be the cause and how we could resolve it? |
I see now that the failure is caused by the new CDS Version: https://github.tools.sap/cap/cds/releases/tag/rel%2F8.2.0 |
Cool, your commit has fixed it. I have one more question, it seems github action will always install the latest version of cds, and brings the issue like it. We should control peerDepdencies upper limits as well? |
lib/templates.js
Outdated
@@ -289,7 +289,7 @@ const fCreateEventResourceTemplate = (srv, srvDefinition, global,packageIds) => | |||
*/ | |||
function checkEntityFunctionAction(srvDefinition, global) { | |||
if (srvDefinition.entities) { | |||
return srvDefinition.entities.map((entity) => { | |||
return [...srvDefinition.entities].map((entity) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there are 5 more places need to be adjust, for example srvDefinition.actions.map. But we don't have corresponding test, lets ignore it in this pr.
|
||
|
||
describe("eventResources", () => { | ||
const GROUP_ID_REGEX = /^([a-z0-9-]+(?:[.][a-z0-9-]+)*):([a-zA-Z0-9._\-/]+):([a-z0-9-]+(?:[.][a-z0-9-]+)*):(?<service>[a-zA-Z0-9._\-/]+)$/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this idea to have named groups in a regexp!
@zongqichen Yes, we should specify the exact version. |
"extensible": { | ||
"supported": "no", | ||
}, | ||
"ordId": "capjs.ord:eventResource:undefined.AdminService:v1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still feel bad about all those undefined
here. But this is planned to be fixed with a follow up PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I will fix it in next PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The undefined
issues are all related and coming from the global.capNamespace
. That will also fix this.
@ductaily: There are a few merge conflicts to be resolved... |
Done. |
@RoshniNaveenaS @RamIndia : Can we merge this PR? |
@ductaily : I guess the following one is solved as well, correct? |
Correct. This PR would also solve that issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checked the generated documents for incidents app, looks fine as well
Address issues from #38
eventResources