cap-js-community / event-queue

An event queue that enables secure multi-tenant enabled transactional processing of asynchronous events, featuring instant event processing with Redis Pub/Sub and load distribution across all application instances.
https://cap-js-community.github.io/event-queue/
Apache License 2.0
11 stars 1 forks source link

Broken service reference in dev mode #158

Closed corporateuser closed 3 months ago

corporateuser commented 3 months ago

On the line https://github.com/cap-js-community/event-queue/blob/6f967cd58b851906893c74e56cd3ddc285f548bc/src/initialize.js#L232 you're trying do cds.connect.to to cds.xt.SaasProvisioningService if we're connecting to db service. But actually connection to db service occurs much earlier than cds.xt.SaasProvisioningService becomes available. So connection would fail if there is no "cds.xt.SaasProvisioningService": true is specified in cds.requires.

Could this cleanup job be registered to be executed after SaaS provisioning service becomes available?

Not sure how it was working previously, this error was found after updating to the latest cds-shim and cds 7.7.1

soccermax commented 3 months ago

I only do the connect if multi-tenancy is enabled. cds.requires.multitenancy is this specified in your case? As you use cds-shim I assume you have a multi-tenancy application right? Can you attach which exact error that occurs if you start the application locally?

corporateuser commented 3 months ago

Yes, exactly, we're having multitenancy enabled in development mode with connection to a real Hana Cloud (service-manager) specified in default-env.json The full error output is:

[/eventQueue/runner] - first event-queue run scheduled { firstRunScheduledFor: '2024-03-15T07:46:13.015Z' }
[/eventQueue/runner] - executing event queue run for single instance and multi tenant
[/eventQueue/runner] - Couldn't fetch tenant ids for event queue processing! Next try after defined interval. Error: No configuration found for 'cds.requires.saas-registry'
    at _required (/Users/dmitry/nexontis/ace/node_modules/@sap/cds/lib/srv/factory.js:34:80)
    at new ServiceFactory (/Users/dmitry/nexontis/ace/node_modules/@sap/cds/lib/srv/factory.js:20:16)
    at AsyncFunction.connect.to (/Users/dmitry/nexontis/ace/node_modules/@sap/cds/lib/srv/cds-connect.js:48:17)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Object.getAllTenantIds (/Users/dmitry/nexontis/ace/node_modules/@cap-js-community/event-queue/src/shared/cdsHelper.js:132:15)
    at async _multiTenancyDb (/Users/dmitry/nexontis/ace/node_modules/@cap-js-community/event-queue/src/runner.js:296:23)
2024-03-15T07:46:13.912Z | ERROR | Layer:/Bootstrap | CorrId:d3e1f486-5cb2-42ff-905d-ed1685dd2b96 | 
Unhandled exception: Promise rejected/uncaught exception but not handled. This is considered a bug - please catch all promises/exceptions!: No configuration found for 'cds.requires.saas-registry'
    at process.unhandledExceptionHandler (/Users/dmitry/nexontis/ace/node_modules/@sap/cds-shim/src/srv/server.js:192:7)
    at process.emit (node:events:514:28)
    at process.emit (node:domain:488:12)
    at process.emit.sharedData.processEmitHook.installedValue [as emit] (/Users/dmitry/nexontis/ace/node_modules/@cspotcode/source-map-support/source-map-support.js:745:40)
    at emit (node:internal/process/promises:150:20)
    at processPromiseRejections (node:internal/process/promises:284:27)
    at processTicksAndRejections (node:internal/process/task_queues:96:32)
caused by: Error: No configuration found for 'cds.requires.saas-registry'
    at _required (/Users/dmitry/nexontis/ace/node_modules/@sap/cds/lib/srv/factory.js:34:80)
    at new ServiceFactory (/Users/dmitry/nexontis/ace/node_modules/@sap/cds/lib/srv/factory.js:20:16)
    at AsyncFunction.connect.to (/Users/dmitry/nexontis/ace/node_modules/@sap/cds/lib/srv/cds-connect.js:48:17)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Object.getAllTenantIds (/Users/dmitry/nexontis/ace/node_modules/@cap-js-community/event-queue/src/shared/cdsHelper.js:132:15)
    at async _multiTenancyDb (/Users/dmitry/nexontis/ace/node_modules/@cap-js-community/event-queue/src/runner.js:296:23): 
vErrorInfos: {
  reason: Error: No configuration found for 'cds.requires.saas-registry'
      at _required (/Users/dmitry/nexontis/ace/node_modules/@sap/cds/lib/srv/factory.js:34:80)
      at new ServiceFactory (/Users/dmitry/nexontis/ace/node_modules/@sap/cds/lib/srv/factory.js:20:16)
      at AsyncFunction.connect.to (/Users/dmitry/nexontis/ace/node_modules/@sap/cds/lib/srv/cds-connect.js:48:17)
      at processTicksAndRejections (node:internal/process/task_queues:95:5)
      at async Object.getAllTenantIds (/Users/dmitry/nexontis/ace/node_modules/@cap-js-community/event-queue/src/shared/cdsHelper.js:132:15)
      at async _multiTenancyDb (/Users/dmitry/nexontis/ace/node_modules/@cap-js-community/event-queue/src/runner.js:296:23)
}
soccermax commented 3 months ago
No configuration found for 'cds.requires.saas-registry'

means that this service is not configured at all. Could you please attach your cds.env configuration? For me, it seems that the local configuration for HANA is not correct. You also are running with the development profile. Why not using "production" if you connect against a HANA-Cloud?

cds env --profile <PROFILE>
corporateuser commented 3 months ago

On the other hand, everything works fine in production, including SaaSProvisioningService. Are you sure it could not be caused by the fact, that you're trying to access service when it is not yet ready? I've put a breakpoing to connect.to line and what I see inside of cds.services is that the only service available there is db, all other are either in pending, or even not yet pending.

In config we're following cds docs and enable multitenancy the following way:

    'cds.xt.ExtensibilityService': {
      model: '@sap/cds-mtxs/srv/extensibility-service',
      'element-prefix': [ 'Z', 'z' ],
      'extension-allowlist': [ { for: [ 'Ext' ], kind: 'service' } ]
    },
    multitenancy: {
      model: [ '@sap/cds-mtxs/srv/bootstrap' ],
      kind: 'saas-registry',
      t0: 't0',
      jobs: { workerSize: 1, clusterSize: 1 }
    },
    extensibility: {
      model: [ '@sap/cds-mtxs/srv/bootstrap', '@sap/cds-mtxs/db/extensions' ],
      tenantCheckInterval: 10000,
      evictionInterval: 900000
    },
soccermax commented 3 months ago

This has nothing to do with timing. If there is no configuration for cds.requires.saas-registry your setup is not right. Please check if cds.requires.saas-registry is defined. If not you might want to add this to your cds.require section in the package.json --> "cds.xt.SaasProvisioningService": true. Without this service, the onboarded tenants can't be queried.

corporateuser commented 3 months ago

Sorry, but I do not agree with you. saas-registry is just a default kind for cds.xt.SaasProvisioningService initialized by mtxs. It has nothing to do with end-user configuration.

I've created a simple project to demonstrate this: https://github.com/corporateuser/queue-error

Clone it, install deps and run npm run start. It will be running without errors, connection to the cds.xt.SaasProvisioningService works perfectly well.

Now, uncomment https://github.com/corporateuser/queue-error/blob/main/srv/server.js#L5-L11 - so we'll be trying to connect to cds.xt.SaasProvisioningService before it was initialized. It will crash with:

node:internal/process/promises:289
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error: No configuration found for 'cds.requires.saas-registry'
    at _required (/Users/dmitry/sap/queue-error/node_modules/@sap/cds/lib/srv/factory.js:34:80)
    at new ServiceFactory (/Users/dmitry/sap/queue-error/node_modules/@sap/cds/lib/srv/factory.js:20:16)
    at connect.to (/Users/dmitry/sap/queue-error/node_modules/@sap/cds/lib/srv/cds-connect.js:48:17)
    at async cds.<anonymous> (/Users/dmitry/sap/queue-error/srv/server.js:6:18)

Settings for the service remain the same in the both cases, in one case it fails, in other it works perfectly fine.

soccermax commented 3 months ago

@corporateuser very interesting - thanks for providing the example. I'll look into it

soccermax commented 3 months ago

That might be related to the fact that mtxs is adding services dynamically. If that's the case I'll report that to CAP. In the meantime I would check for temporary workarounds. The service configuration should be available at any time.

soccermax commented 3 months ago

fix will be included in 1.4.0 which I can hopefully release today

corporateuser commented 3 months ago

@soccermax I believe it is more related to the fact mtxs is using kind "saas-registry", which is not defined anywhere. This is how mtxs defines kinds: node_modules/@sap/cds-mtxs/env.js This is how cds defines kinds: node_modules/@sap/cds/lib/env/cds-requires.js So "saas-registry" is used as a kind, but not implemented anywhere.

soccermax commented 3 months ago

@corporateuser Yes, I saw that. IMO this is not right. I addressed this to the CAP colleagues. For now, we have the workaround in place. Let's see how they respond. Thanks again for reporting and providing the minimal example - this helped a lot 👍