Skip to content

loopback-datasource-juggler datasource definition for setup method is missing #7115

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

Open
andreyunugro opened this issue Feb 26, 2021 · 4 comments
Assignees
Labels

Comments

@andreyunugro
Copy link

andreyunugro commented Feb 26, 2021

Steps to reproduce

At https://github.com/strongloop/loopback-datasource-juggler/blob/master/types/datasource.d.ts,
there is no definition for method setup, which is defined at:
https://github.com/strongloop/loopback-datasource-juggler/blob/06428247ad1cc48bce82d135f795fb3eaae28b33/lib/datasource.js#L382

  1. I create custom datasource class MyDataSource which extends juggler.Datasource.
  2. I create method setup inside class MyDataSource .
  3. I can not use: super.setup() inside method setup.

Current Behavior

When I want to use super.setup(), there will be ts error: Property 'setup' does not exists on type 'Datasource'.
Selection_161

Expected Behavior

No ts error when I want to use super.setup() inside setup method on my custom datasource class.

Additional information

Setup method definition:

  /**
   * Setup datasource
   * @param dsName The name of the datasource.
   * @param settings The datasource settings
   */
  setup(dsName: string, settings: Options): void;
  setup(settings: Options): void;
@marioestradarosa
Copy link
Contributor

I think the setup() method your are trying to call is called inside the constructor. I think you are trying to dynamically specify parameters ? Can't see your code above but you have to options if that's what you want to achieve.

    new DataSource(yourDsname, Yoursettings)

or even more if you see the code lb4 datasource generates, the dataSourceName is a static member of the extended class from juggler.DataSource and inside the constructor there is call to super(dsConfig).

What I usually is to provide to my micro services environment variables with the connection property values such as:

const config = {
  name: 'session2',
  connector: 'mysql',
  url: '',
  host: process.env.SESSION_DB_HOST,
  port: process.env.SESSION_DB_PORT,
  user: process.env.SESSION_DB_USER,
  password: process.env.SESSION_DB_PASSWORD,
  database: process.env.SESSION_DB
};

@marioestradarosa
Copy link
Contributor

@andreyunugro , here is a complete example.

import {inject, lifeCycleObserver, LifeCycleObserver, ValueOrPromise} from '@loopback/core';
import {AnyObject, juggler} from '@loopback/repository';

const config = {
  name: 'demo',
  connector: 'mysql',
  url: '',
  host: '',
  port: 3306,
  user: '',
  password: '',
  database: '',
};

function updateConfig(dsConfig: AnyObject) {
  if (process.env.DEMO_DB_HOST) {
    dsConfig.host = process.env.DEMO_DB_HOST;
    dsConfig.port = +process.env.DEMO_DB_PORT!;
    dsConfig.user = process.env.DEMO_DB_USER;
    dsConfig.password = process.env.DEMO_DB_PASS;
    dsConfig.database = process.env.DEMO_DB_NAME;
  }
  return dsConfig;
}

// Observe application's life cycle to disconnect the datasource when
// application is stopped. This allows the application to be shut down
// gracefully. The `stop()` method is inherited from `juggler.DataSource`.
// Learn more at https://loopback.io/doc/en/lb4/Life-cycle.html
@lifeCycleObserver('datasource')
export class DemoDataSource extends juggler.DataSource
  implements LifeCycleObserver {
  static dataSourceName = 'demo';
  static readonly defaultConfig = config;

  constructor(
    @inject('datasources.config.demo', {optional: true})
    dsConfig: object = config,
  ) {
    super(updateConfig(dsConfig));
  }

  /**
   * Disconnect the datasource when application is stopped. This allows the
   * application to be shut down gracefully.
   */
  stop(): ValueOrPromise<void> {
    return super.disconnect();
  }
}

@andreyunugro
Copy link
Author

Hi @marioestradarosa,

Yes, you are correct. Method setup() is called inside the constructor. Thank you for your example.

My use case is: MongoDB Automatic Client-Side Field Level Encryption.
Routine: I need to connect to current MongoDB key vault (which need MongoDB connection), add key management service, define JSON schema, and connect again to MongoDB with autoEncryption parameter; right after the setup.
If I can use setup() method, I can add the routine just after super.setup(), and I can use promise (not promise inside constructor).

The way I can do right now is using connect() method, and I have to call connect() manually.
Something like this:
image

It will be great if I can use setup() method.

Thank you.

@stale stale bot added the stale label Oct 4, 2021
@achrinza achrinza removed the stale label Oct 5, 2021
@achrinza achrinza self-assigned this Oct 5, 2021
@loopbackio loopbackio deleted a comment from stale bot Oct 21, 2021
@inceserhatabdullah
Copy link

If the Redis connection suddenly breaks while the backend server is running, I naturally get an error as follows.

[ioredis] Unhandled error event: Error: connect ECONNREFUSED 127.0.0.1:6379 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)

Is it possible to do something like just turn off/deactivate the Redis DataSource without getting this error?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants