Skip to content

Need for a more flexible mechanism to provide the pulsar connection string

The main problem first:

In the PulsarConnection.ts in line 6 (https://git.geomar.de/digital-earth/dasf/dasf-web/-/blob/master/lib/messaging/PulsarConnection.ts#L6) is currently the digtial-earth namespace hard coded. Currently we tr to introduce the usage of a backend module with a different server and a different namespace, so we need to be able to set a different one.

It would be easy to just add another parameter, but the mechanism to set the producer and consumer url itself should be in general a bit more flexible, so that we can also use pulsar instances that must run behind an nginx with an additional prefix url, to support things like:

ws://{server}:{port}/{prefixUrl}/ws/v2/{type}/non-persistent/public/...

so that we can run it for example under https://fancyproject.gfz-potsdam.de/fancyapp/test/ws/v2/...

Discussing it with @daniel-eggert and @matthias-ruester today, the idea was to provide some kind of config object to the constructor:

interface IPulsarConnectionConfig {
   host: string
   port: string
   topic: string
   namespace: string
   prefixUrl: string
}

and then

export default PulsarConnection {
  // ...
  constructor (config: IPulsarConnectionConfig) {
    // ...
}

(Being more a java developer, I would prefer a solution with an interface to provide the those pulsarProducerURL and pulsarConsumerURL urls):

interface IPulsarConnectionUrlProvider {
  pulsarProducerURL: string
  pulsarConsumerURL: string
}

class DigitalEarthConnectionUrlProvider implements IPularConnectionUrlProvider {
  // ...
  constructor (host: string, port: string, topic: string) {
    // ...
  }

  get pulsarProducerURL () : string {
    // same logic as at the moment in the PulsarConnection constructor
  }

  get pulsarConsumerURL () : string {
    // same logic as at the moment in the PulsarConnection constructor
  }
}

export default PulsarConnection {
  // ...
  constructor (connectionUrlProvider: IPularConnectionUrlProvider) {
    // ...
    this.pulsarProducerURL = connectionUrlProvider.pulsarProduerURL
    this.pulsarConsumerURL = connectionUrlProvider.pulsarConsumerUrl
    // and maybe still a seperate step:
    // append subscription to consume url
    this.pulsarConsumerURL += subscriptionName + "?subscriptionType=Exclusive";
    // ...
}

While I can agree that this solution is not typical for typescript, it would follow the open-closed princible: It would allow anyone to provide the connection parameters as the developer wants in the future, without the need to a further change in this library code here.

So I would be able to just create another class that changes the behaviour:

class FancyAppPulsarConnectionUrlProvider implements IPularConnectionUrlProvider {
  get get pulsarProducerURL () {
     return 'ws://fancyproject.gfz-potsdam.de/fancyapp/test/ws/v2...'
  }
}