PubSub+ Connector Manager for PubSub+ Self-Managed Connectors

As you have your Self-Managed Connectors running, managing and monitoring them is crucial to ensure the smooth functioning of your data pipeline. PubSub+ Connector Manager fills in this gap to facilitate this. The Connector Manager:

  • acts as a central configuration source for all Self-Managed Connector instances, making it easier to manage them in a consistent manner.

  • provides real-time monitoring and reporting on Self-Managed Connector performance. This includes all metrics configured and shared through the management interface, such as data throughput, latency, and error rates. You can use this information to identify potential issues in a Self-Managed Connector deployment and troubleshoot and resolve them.

  • provides configuration version control by maintaining the version history of each Self-Managed Connector's configuration, allowing you to identify changes and roll back to previous versions if needed. This ensures that changes are made in a controlled and traceable manner.

To understand how to use Connector Manager, see the following sections:

The following sections show how to use Connector for IBM MQ as an example (that is provided in the archive file (ZIP) in the Connector Manager package) as a reference example.

Installing the Connector Manager

To set up and install the Connector Manager, you must download the package from the Solace product website. The Connector Manager is available with a subscription to a support plan from Solace. The Connector Manager download is an archive file (ZIP) of a Docker (or Podman) container.

Starting the Connector Manager

The extracted archive has the following structure:

.
├──pubsubplus-connector-manager-1.1.0
├── LICENSE.pdf
├── README.md
├── licenses.txt
├── pubsubplus-connector-manager-1.1.0.jar
└── samples
	├── connectors
	│   ├── connector.sh
	│   ├── applications
	│   ├── connectors-configs
	│   │   └── ibmmq
	│   │       └── application.yml
	│   ├── libs
	│   └── security
	│       └── demo.jks
	└── manager
	    ├── README.md
	    ├── config
	    │   ├── application-operator.yml
	    │   └── application.yml
           ├── cloud-configs
           │   └── ibmmq.yml
	    ├── docker
	    │   ├── README.md
	    │   └── docker-compose.yml
	    └── start.sh

This bundle contains a nested samples folder, which includes various examples of Connector Manager configurations, along with shell scripts to initiate their operation. In this folder, there are two subfolders:

  • connectors-<description> contains all the necessary example configurations and startup script for sample Self-Managed Connectors that are meant to be started with the Connector Manager (with the connector.sh shell script).

  • manager contains the initial configuration for the Connector Manager (with the start.sh shell script).

Before you use the accompanying scripts, you must verify and set the appropriate permissions. If the execution bit is missing, you can fix it by running these commands:

chmod +x ./manager/start.sh
chmod +x ./connectors/connector.sh

Other subfolders in the samples directory contain necessary configuration files, as well as a security keystore. For example, the provided Connector Manager archive has a pre-generated keystore called demo.jks, which is used solely for demonstration purposes.

Starting the Connector Manager with Shell Script

The shell script to start the Connector Manager allows you to initiate a Connector Manager instance and pre-configure it with essential parameters (see Script Shell Parameters). This script is stored in the samples/manager folder.

To start the Connector Manager with shell script, run:

# working directory is set to: [./samples/manager]

$> ./start.sh -j ../../pubsubplus-connector-manager-1.1.0.jar

The previous command:

  • sets the configuration folder for the Connector Manager to samples/manager/config

  • sets the remote configurations folder to samples/manager/cloud-configs and initializes it as a Git repository

  • initiates the Java JAR artifact with the name pubsubplus-connector-manager-1.1.0.jar

You can now access the Connector Manager on the local machine at port 9500 with the default credentials (user as the username and pass as the password):

java -jar <...ABSOLUTE_PATH...>/pubsubplus-connector-manager-1.1.0.jar  \
      --spring.config.additional-location=./config/ \
      --spring.cloud.config.server.git.uri=file://<...ABSOLUTE_PATH...>/samples/manager/cloud-configs/

This is a full list of the parameters that you can use with shell script for the Connector Manager:

Parameter Description

-p or --profile

The profile to be used with the Connector Manager configuration. The application-<profile>.ymlconfiguration file is used. The default value is empty, which means that the Connector Manager will look for a configuration file called application.yml.

-U or --username

Defines a username for authentication purposes. If not provided, it is set to user.

-P or --password

Defines a password for authentication purposes. If not provided, it is set to pass.

-c or --config

The path to the folder that contains the configuration files to be applied during Self-Managed Connector startup for the chosen profile. By default, it is set to the current folder and automatically looks in nested and sibling config folders (if any), as well as in the current and parent folders.

-C or --configs

A link to the remote storage with configuration. This should include a reference to the protocol used to access resources (for example, file://, ssh://, or http://). If the prefix is not defined, it will be treated as a local file with an appropriate protocol.

-H or --host

Predefined host value to be passed into the server.host application parameter.

-P or --port

Predefined port value to be passed into the server.port application parameter.

-j or --jar

The path to the specified JAR file to start the Connector Manager. If not specified, the default JAR file from the current folder is used.

-o or --options

Specifies the JVM options that are used when starting the Connector Manager (for example, -Xms64M -Xmx1G). Use single/double quotes to specify parameters.

-b or --background

Runs the Connector Manager in the background. No logs are displayed, and the Connector Manager continues to run in detached mode.

-s or --show

Prints the start CLI command in raw format and exits.

-h or --help

Prints this help page and exits.

Examples

These examples show how to start the Connector Manager with various configurations and options. All scripts must be run from the samples/manager folder for the Connector Manager and from the samples/connectors folder for the Self-Managed Connectors.

To start the Connector Manager with different credentials:

$> ./start.sh -j ../../pubsubplus-connector-manager-1.1.0.jar -U admin -P admin

To start the Connector Manager on a different port:

$> ./start.sh -j ../../pubsubplus-connector-manager-1.1.0.jar --port 9100

To start the Connector Manager with a different profile:

$> ./start.sh -j ../../pubsubplus-connector-manager-1.1.0.jar -p operator

To start the Connector Manager with a different config folder:

$> ./start.sh -j ../../pubsubplus-connector-manager-1.1.0.jar -c different/config/folder

To start the Connector Manager with a different cloud config repository:

$> ./start.sh -j ../../pubsubplus-connector-manager-1.1.0.jar -C different/config/repo

The cloud config repository must be initiated as a Git repository. By default, this script initializes the provided folder as a Git repository (if it doesn't contain the .git folder) and commits all changes as an initial commit. However, it does this only for folders that can be accessed locally (not through SSH or HTTP/HTTPS protocols).

Show start CLI command:

This script prints the CLI commands to be executed during the script run. To do this, add -s as a parameter to the script input:

$> ./start.sh -j ../../pubsubplus-connector-manager-1.1.0.jar -p operator -C different/config/repo -U admin -P admin -H 10.0.0.100 --port 8000 -s

This command doesn't start the Connector Manager, but prints out the following CLI command:

java -Dspring.profiles.active=operator -jar <...ABSOLUTE_PATH...>/pubsubplus-connector-manager-1.1.0.jar  --spring.cloud.config.server.git.uri=file://<...ABSOLUTE_PATH...>/samples/manager/different/config/repo/ --solace.connector-manager.security.users[0].name=admin --solace.connector-manager.security.users[0].password=admin --server.host=10.0.0.100 --server.port=8000 --spring.config.additional-location=./config/

This might be useful if you want to use your own generated keystore file to encrypt values but not leave that functionality enabled permanently.

Starting the Connector Manager as a Docker (or Podman) Container

The Connector Manager Docker (or Podman) container contains all necessary dependencies as well as the archive. Before you start the Connector Manager as a container, you must bind a volume with the configuration file and provide access to the folder containing configurations for the Self-Managed Connectors.

To start the Connector Manager as a container, run:

docker run -p 9500:9500 \
-v <CONNECTOR MANAGER CONFIGURATION>:/config \
-v <CONFIGURATION STORAGE FOLDER>:<CONFIGURATION STORAGE FOLDER> \
pubsubplus-connector-manager:1.1.0;

The previous command starts the container and binds two volumes: 

  • One volume contains the configuration file (which is mapped to an internal folder called config) for the Connector Manager, where the Connector Manager reads your configuration.

  • One volume is the folder that contains the configuration files for the Self-Managed Connectors.

If the configuration folder with the configuration files is stored remotely, the container might need to access it via the ssh protocol. In this case, you must generate a separate key pair using the ssh-keygen command and provide access to it:

docker run -p 9500:9500 \
-v <CONNECTOR MANAGER CONFIGURATION>:/config \ # mandatory
-v <FOLDER WITH SSH KEYS>:/root/.ssh \           # optional
pubsubplus-connector-manager:1.1.0

Starting the Connector Manager Using Docker Compose

You can use Docker Compose to start the Connector Manager. An example of the docker-compose.yml file can be found in the samples/manager/docker/ folder. By default, it uses:

  • ../config/application.yml as the configuration file for the Connector Manager.

  • ../cloud-configs as the main configuration storage.

Before you start the Connector Manager using Docker Compose, you must initiate a Git repository in the configuration storage and commit configuration files for Self-Managed Connectors that are used.

To start the Connector Manager using Docker Compose, run:

# change folder  
cd ../cloud-configs  
  
# initiate git repository  
git init  
  
# commit changes  
git add .
git commit -m "initial commit" 
  
# go back to this folder  
cd -

Configuring the Connector Manager

To allow the Connector Manager to start and serve different Self-Managed Connectors properly, you must configure some parameters in the Connector Manager configuration file. By default, Solace provides an example of the configuration file, which can be found in a zip archive in the Connector Manager package under the samples/manager/config folder.

Creating Users

As the Connector Manager currently supports Basic Authentication, it requires a username and a password.

To configure authentication, create the following section in the Connector Manager's config file:

solace:
  connector-manager:
    security:
      users:
        - name: user
          password: pass
          roles:
            - user

Where user is the username and pass is the password. You can create more than one user by assigning different roles.

Setting up Configuration Storage

Configuration storage is the folder that contains all configuration files for the Self-Managed Connectors that run with the Connector Manager. You must make this folder path accessible to the Connector Manager, although Self-Managed Connectors don't need to access it.

You can set up configuration storage in a few different ways with the relevant Git commands. However, it must be a Git repository.

To set up configuration storage (for a local or self-hosted git repository): 

  • Run git init after you create a folder anywhere on your local or remote system.

  • Add necessary configurations for the Self-Managed Connectors, and include them in the commit (so that the Connector Manager has access to them).

To set up configuration storage as a hosted repo (on GitHub, Gitlab, BitBucket, and so on), see Git Backend for Configuration Storage.

To point the Connector Manager to the configuration storage folder, expose its path using one of the following mechanisms:

  • A configuration file:

    spring:
      cloud:
        config:
          server:
            git:
              uri: 'file:///${user.home}/configurations'
  • over SSH:

    spring:
      cloud:
        config:
          server:
            git:
              uri: 'ssh://server:/home/server/configurations'
  • over HTTP/HTTPS:

    spring:
      cloud:
        config:
          server:
            git:
              uri: 'https://server.com:/home/server/configurations'

In case you are providing access to configuration storage over SSH or HTTP/HTTPS for the Connector Manager, you must configure key pairs. The Connector Manager uses the system SSH configuration, or provides credentials in the connection string.

Using HTTPS Connections

By default, the Connector Manager works over HTTP. You can configure the Connector Manager to switch to HTTP/HTTPS to secure communication between the Connector Manager and the Self-Managed Connectors served by it, and between the Connector Manager and your browser view.

To enable security, configure this key in the Connector Manager:

server:
  ssl:
    enabled: true

Enabling TLS might require configuring other parameters such as protocol type, keystore, and trust store. In this example, a custom configuration is provided for the keystore (in the zip archive under samples) and a default configuration is provided for the trust store (under the cert location that was generated, because TLS connection is set up using a self-signed certificate:

server:  
  ssl:  
    enabled: true  
    protocol: TLS  
    key-store-type: PKCS12  
    key-store: 'file:./operator/security/server.p12'  
    key-store-password: 'configserver'  
    
    trust-store: 'file:/Library/Java/JavaVirtualMachines/jdk-17.0.3.1.jdk/Contents/Home/lib/security/cacerts'  
    trust-store-type: PKCS12  
    trust-store-password: 'changeit'

This is the default configuration for any Spring Boot application. For more information, see Configure SSL.

Encrypting Values for Cloud Configurations

To create encrypted values for cloud configuration files, you must start the Connector Manager in local mode (completely isolated from any production environment with the keystore file that is generated for this purpose) with enabled encryption, or as a localhost. Solace recommends using the Cloud server encryption and decryption until this functionality is provided by Solace (Versions after 2.7.10 of Sprint CLI and Spring Cloud CLI don't have this functionality).

You can encrypt any value using the Connector Manager, as it provides two API endpoints by default: /encrypt for encrypting messages, and /decrypt for decrypting messages.

To encrypt any value, send a POST request to the appropriate API with these parameters:

curl --location --request POST 'http://10.0.0.100:9500/config/encrypt' \
--header 'Content-Type: text/plain' \
--data-raw '<...something to encrypt...>'

Where <...data to be encrypted...> is the request body. The response is an encrypted value that can be used as a configuration parameter.

At this point, all dependencies must be already pre-configured in the application.yml|properties file, so the Spring Cloud Config Server knows which ciphers to use for encryption.

By default, the encryption and decryption functionality is disabled in the Connector Manager (to provide security for publicly accessed values). You can enable these endpoints at start time by providing these CLI parameters to the application: 

--encrypt.keyStore.location=file://<...path to keystore file...> 
--encrypt.keyStore.password=password 
--encrypt.keyStore.alias=configserver 
--encrypt.keyStore.secret=password

These parameters are not configurable through the startup script for security reasons.

Solace recommends using the Cloud server encryption and decryption until this functionality is provided by Solace (Versions after 2.7.10 of Sprint CLI and Spring Cloud CLI don't have this functionality).

To start the local instance of the Connector Manager

  • Use the -s configuration option (to obtain the shell CLI command and use it together with the parameters above):

    # use script to generate CLI command
    ./start.sh -j ../../pubsubplus-connector-manager-1.1.0.jar -s

    The expected result (command) is:

    java -jar <...ABSOLUTE_PATH...>/pubsubplus-connector-manager-1.1.0.jar --spring.cloud.config.server.git.uri=file://<...ABSOLUTE_PATH...>/samples/manager/cloud-configs/ --spring.config.additional-location=config/
  • Add the encryption parameters, so the full command looks this:

    $> java -jar <...ABSOLUTE_PATH...>/pubsubplus-connector-manager-1.1.0.jar --spring.cloud.config.server.git.uri=file://<...ABSOLUTE_PATH...>/samples/manager/cloud-configs/ --spring.config.additional-location=config/ \
        --encrypt.keyStore.location=file:security/demo.jks \
        --encrypt.keyStore.password=password \
        --encrypt.keyStore.alias=configserver \
        --encrypt.keyStore.secret=password

    The demo.jks file that is provided in the samples/connectors/security is generated with this command:

    $> keytool -genkeypair -alias configserver -keyalg RSA \
    -dname "CN=CM,OU=CM,O=Solace,L=Kanata,S=ON,C=Canada" \
    -keypass password -keystore demo.jks -storepass password

    Because the demo.jks file is generated with this command, some encrypted variables are taken from configuration. Having these parameters enables the /encrypt and /decrypt endpoints and allows you to encrypt and decrypt your sensitive information using the key pair under alias, which is stored in the keystore called demo.jks.

After generating encrypted values for cloud configurations, it is important to stop this Connector Manager instance and start it normally in production mode. This is so it doesn't have a pointer to the keystore file and all secrets stay safe without the possibility to decrypt them on the server side.

Obtaining Logfiles from Remote PubSub+ Self-Managed Connectors

Currently, remotely running Self-Managed Connectors provide data about the relative local path of their logfiles to enable reading, and the Connector Manager has limited access to these logfiles. To address this limitation, one option is to mount the remote filesystem onto the local filesystem and grant access to the logfile.

PubSub+ Self-Managed Connector Configuration

After starting the Connector Manager, you must make your Self-Managed Connector's configuration adjustable with the Connector Framework. To do this: 

  • Move your Self-Managed Connector config file to the configuration repository on the Connector Manager side.

  • Include the parameters needed to connect to the Connector Manager in the local configuration file.

 

You can store the current configuration of your Self-Managed Connector in the Git repository, which should be used as a configuration storage after that. Remember to commit the changes that you made because the Connector Manager operates on the Git repository.

The file name must be equal to the value of the spring.application.name configuration parameter (see Configuring Minimal Requirements).

Use encryption for any sensitive data on the remote configuration storage.

Configuring Minimal Requirements

After setting up the configuration storage and moving Self-Managed Connector configuration to it, you must change the local configuration for the Self-Managed Connector (it should be empty). The Self-Managed Connector configuration stores the data needed to connect to the Connector Manager (see PubSub+ Self-Managed Connector Configuration).

This is an example of the Self-Managed Connector configuration file:

# parameters defying which config to get and where from.  
# Must be enabled if application relies on Connector Manager's distributed configuration  
# In case operator would like to ignore these parameters, full operator's configuration  
# should be provided locally, withing this configuration file  
spring.application.name: ibmmq
spring.config.import: 'optional:configserver:http://127.0.0.1:9500/config/'  
# credentials to connect to the config server and get configuration  
# should be specified here, in operator's configuration as they  
# are intended to be modified by operator  
spring.cloud.config:  
  import-check.enabled: true  
  username: user  
  password: pass  
  # this section enables security and TLS for config-server together with the  
  # new [BlockingRegistrationClient] used to register application in Connector Manager  
  # [BlockingRegistrationClient] should have access to thess fields directly  
  # and should be instantiated before Spring Boot Admin native client  tls:  
    enabled: false  
#    key-store-type: PKCS12  
#    key-store: 'file://connectors/ibmmq-connector/operators-data/keystore/server.p12'  
#    key-store-password: configserver  
#    key-password: configserver  
#    trust-store: 'file:/Library/Java/JavaVirtualMachines/jdk-17.0.3.1.jdk/Contents/Home/lib/security/cacerts'  
#    trust-store-type: PKCS12  
#    trust-store-password: 'changeit'  
  
# these parameters are necessary to decrypt configuration from the server on the client  
# please note that [encrypt.keyStore.location] should point out to the same file used  
# for encryption otherwise the value won't be decrypted at all  
encrypt.keyStore.location: "file:security/demo.jks"  
encrypt.keyStore.password: password  
encrypt.keyStore.alias: configserver  
encrypt.keyStore.secret: password  

# this section defines service URL used by Connector Manager to back access the Connector  
# in case it would be omitted, Connector Manager will try to resolve it, however in case of enabled HTTPS  
# it will do it improperly and specify a different port, not related to the [management.server.port] section  
spring.boot.admin.client.instance:  
  service-host-type: ip  
  service-url: 'http://127.0.0.1:9009/'  
  management-url: 'http://127.0.0.1:9009/actuator'  
  health-url: 'http://127.0.0.1:9009/actuator/health'  
# This section enables TLS for actuator endpoints used to be accessed from the Connector Manager  
# They used to be enabled separately, as they secure only /actuator endpoint access. In case security  
# is enabled, operator MUST specify separate port for this endpoint and configure access to it  
# within the [spring.boot.admin.client.instance] section  
management:  
  server:  
    # sets a different port to server the actuator endpoint  
    port: 9009  
    # if this parameter is present operator must have [enabled] set to false|true  
    # otherwise this parameter should be disabled    #    ssl:  
    # if ssl is enabled, all other parameters must also be configured  
#      enabled: true  
#      protocol: TLSv1.2  
#      key-store-type: PKCS12  
#      key-store: 'file:./keystore/server.p12'  
#      key-store-password: configserver  
#      key-password: configserver  
#      trust-store: 'file:/Library/Java/JavaVirtualMachines/jdk-17.0.3.1.jdk/Contents/Home/lib/security/cacerts'  
#      trust-store-type: PKCS12  
#      trust-store-password: 'changeit'

The Connector Manager has two primary entry points for the management interface:

  • / for communication with the UI and the Connector Manager.

  • /config for communication with the configuration storage.

These APIs are secured using different security techniques, which requires separate security configurations. For the / API, authentication credentials are managed in spring.boot.admin.client.instance, and for the /config API, authentication credentials are configured through the spring.cloud.config section. In the example above, the two APIs have the same authentication credentials, but it's possible for the authentication credentials to be different.

The name of the configuration file (which is stored in the configuration storage) must match the spring.application.name parameter, with the addition of any profile name (if used) separated by a dash. In the example above, this might look like ibmmq-operator.yml, where the application name is set to ibmmq and the profile name is operator.

In the example above, port 9500 (which is set by default) is used for the management interface, and port 9009 is used for the data interface. It is important to keep all links updated according to this data:

# data interface URL and port to update
spring.boot.admin.client.instance.service-url: 'http://127.0.0.1:9009/'
spring.boot.admin.client.instance.management-url: 'http://127.0.0.1:9009/actuator'  
spring.boot.admin.client.instance.health-url: 'http://127.0.0.1:9009/actuator/health'  

# management interface URL and port to update
spring.config.import: 'optional:configserver:http://127.0.0.1:9500/config/'  
spring.boot.admin.client.url: "http://127.0.0.1:9500/"  

The Connector Manager uses some specific APIs to retrieve data from every Self-Managed Connector. Most of these APIs are standard Spring Boot Actuator APIs. However, to be able to properly manage workflows, you must enable a few additional APIs through the configuration file:

management:
  endpoints:
    web:
      exposure:
        include: "health,metrics,loggers,logfile,env,workflows,leaderelection,bindings,channels"

Enabling TLS

Enabling TLS for the Connector Manager happens on the Self-Managed Connector's side. TLS must be configured through these two ports:

  • / enables TLS for all requests circulating between the Self-Managed Connector and Connector Manager, including UI.

  • /config enables TLS for all configurations retrieved from configuration storage.

For optimal security, enable TLS for both of these ports at the same time.

To configure the / and /config ports, use these configuration sections:

spring.cloud.config:
  tls:  
    enabled: true  
    key-store-type: PKCS12  
    key-store: 'file:./keystore/server.p12'  
    key-store-password: configserver  
    key-password: configserver  
    
    trust-store: 'file:/Library/Java/JavaVirtualMachines/jdk-17.0.3.1.jdk/Contents/Home/lib/security/cacerts'  
    trust-store-type: PKCS12  
    trust-store-password: 'changeit'  

management:  
  server:  
# sets a different port to server the actuator endpoint  
    port: 9009  
    ssl:
      enabled: true  
      key-store-type: PKCS12  
      key-store: 'file:./keystore/server.p12'  
      key-store-password: configserver  
      key-password: configserver  
      
      trust-store: 'file:/Library/Java/JavaVirtualMachines/jdk-17.0.3.1.jdk/Contents/Home/lib/security/cacerts'  
      trust-store-type: PKCS12  
      trust-store-password: 'changeit'

Using Profiles

Configuration for the Connector Manager can come in an application.properties or application.yml file. You can use profiling to start up the Connector Manager. In this case, the configuration file must follow the same name pattern and include the profile name as a suffix after the word application separated by a hyphen (for example, application-operator.yml).

If you want to use profiling to start up the Connector Manager, you must also provide an additional parameter to the JAR file --spring.profiles.active=<PROFILE NAME>.