Class LicenseManager

java.lang.Object
io.confluent.license.LicenseManager

public class LicenseManager extends Object
A license manager that can validate and store Confluent licenses in a topic in one Kafka cluster.

This manager is supplied configurations for an admin client to create the topic if necessary, a consumer to read the contents of that topic, and a producer to store the updated license information, if such is supplied when registering and validating licenses. Additional admin client configurations can be provided for Kafka clusters that the license manager should consider when validating a license.

Types of Licenses

This license manager deal with three types of licenses:
  1. Enterprise License is a license that is generated by Confluent for enterprise customers, and which expires after a specfied period of time. Customers can renew their license, and the new license should be stored in the topic, either by updating a component with that license or by directly writing it.
  2. 30 Day Trial License allows users to download and evaluate Confluent products by for up to 30 days before the license expires and the components stop working.
  3. Free Forever Single Node Cluster License allows users to download and evaluate Confluent products for an unlimited time as long as they run at most one broker in their Kafka clusters. This type of license only applies if there is not already another type of license stored in the topic (even if expired), and is considered valid only when the clusters have only one broker.

Usage

To use the LicenseManager, instantiate it with the correct configurations for the primary Kafka cluster where the license topic exists. If the licensed component uses more than one Kafka cluster, also supply admin client configurations for the additional cluster(s) so that the license manager can ensure that the restrictions of the Free Forever license are followed, if that license is used.

The next step is to read the license information from the component's configuration, or use a blank string if the user did not provide a license, and call registerOrValidateLicense(String) to register the new license or, if it is blank, attempt to read a previously-stored license. This method will thrown an InvalidLicenseException if the license is not valid or has expired. Otherwise, a valid license exists and is returned for use by the application.

Note that the registerOrValidateLicense(String) logs information about the license, either at WARN level if the license expires within 10 days, or at INFO level otherwise. The message includes the type of license, the number of days until the license expires, and the expiration date.

Finally, when the application stops, call stop() so the LicenseManager can release any resources it might have created.

Here is an example:

   // Read the license string from the application or component's configuration
   String licenseStr = ...

   // Start the license manager
   String topicName = ...
   Map<String, Object> producerConfig = ...
   Map<String, Object> consumerConfig = ...
   Map<String, Object> adminConfig = ...

   LicenseManager licenseMgr = new LicenseManager(
       producerConfig,
       consumerConfig,
       adminConfig);
   License license = licenseMgr.registerOrValidateLicense(licenseStr);

   // At some point stop the license manager
   licenseMgr.stop();
 
  • Constructor Details

  • Method Details

    • addCluster

      public void addCluster(String key, Map<String,Object> adminConfig)
      Add another Kafka cluster to be considered when validating a license. The cluster is defined with the AdminClientConfig for the cluster, and the principal requires privilege to read the cluster metadata.

      This method is safe to be called whether or not the license manager is running.

      Parameters:
      adminConfig - the admin client configurations for another Kafka clusters that should be considered during license validation; may be null or empty
    • addCluster

      public void addCluster(String key, io.confluent.license.LicenseManager.ClusterClient client)
      Add another Kafka cluster to be considered when validating a license. The cluster is defined with the supplied LicenseManager.ClusterClient function, allowing callers to fully control how the license manager determines the size of a cluster.

      This method is safe to be called whether or not the license manager is running.

      Parameters:
      key - the unique key for the cluster client; may not be null
      client - the cluster client function that should be used to determine the size of a cluster during license validation; may be null or empty
    • removeCluster

      public boolean removeCluster(String key)
      Remove the Kafka cluster client with the specific name from being considered when validating a license.

      This method is safe to be called whether or not the license manager is running.

      Returns:
      true if the admin config was removed, or false otherwise
    • addListener

      public boolean addListener(Consumer<LicenseChanged> listener)
      Add a listener for subsequent license changes.
      Parameters:
      listener - the function that is to be called when license changes are detected
      Returns:
      true if the listener was added, or false if the listener was null or was already a listener
      See Also:
    • removeListener

      public boolean removeListener(Consumer<LicenseChanged> listener)
      Remove a previously registered license change listener.
      Parameters:
      listener - the function that is no longer to be called when license changes are detected
      Returns:
      true if the listener was removed, or false if the listener was not previously registered
      See Also:
    • start

      public void start()
      Begin running this license manager's check on a daily schedule, or more frequently if the license is expired or has less than 1 day remaining. The first check will be scheduled for 24 hours after this method is called, since the calling application is expected to explicitly check the license once upon startup before this method is called.

      This is useful for automatically detecting changes in the license and notifying the listeners.

      See Also:
    • setSchedulingStrategy

      public void setSchedulingStrategy(Function<List<License>,License> selectionFunction)
    • start

      public void start(long initialDelay, long period, TimeUnit timeUnit)
      Begin running this license manager's check with a configurable initial delay and period.
      Parameters:
      initialDelay - the initial delay period for the first check
      period - the frequency of the following checks
      timeUnit - the timeunit used for the initialDelay and the period
    • stop

      public void stop()
      Stop this license manager, close any resources, and remove any scheduled license checks. It is safe to call this method if this license manager was not started.
      See Also:
    • configuredLicense

      public License configuredLicense()
    • registerOrValidateAddOnLicense

      public License registerOrValidateAddOnLicense(String license) throws InvalidLicenseException
      Validate the supplied license, or if blank register a new trial license. It is intended to be used by AddonLicenseManager or licenseManager licensePurpose is not PRIMARY.
      Parameters:
      license - the new license string to be persisted in the topic; may be empty if there is no updated license
      Returns:
      the summary of the current license; never null
      Throws:
      ExpiredLicenseException - if the supplied or stored license has expired
      InvalidLicenseException - if the supplied or stored license is not valid
    • registerOrValidateLicense

      public License registerOrValidateLicense(String license) throws InvalidLicenseException
      Validates a supplied CP or 'CP for CC' license and persists it in LicenseStore. If no input is provided, selects a valid stored license or generates a TRIAL/DEV CP license if allowed. When input is provided: - Valid CP → stored under CP if have greater expiry (does not overwrite 'CP for CC'); used as active. - Valid 'CP for CC' → stored under 'CP for CC' if have greater expiry (does not overwrite CP); used as active. - Invalid → throws InvalidLicenseException, which can occur due to: - input JWT claims is invalid - input signed JWT with invalid expiry format → falls back to stored licenses; if none active, throws InvalidLicenseException. - Returns the valid stored CP license; otherwise the valid stored 'CP for CC' license. When input is not provided: - Returns the valid stored CP license; otherwise the valid stored 'CP for CC' license. - If neither exists and no CP license was ever stored, generates and persists a TRIAL/DEV CP license, then returns it.
      Parameters:
      license - CP or CP for CC license string; may be blank
      Returns:
      The active primary license to use, preferring CP over 'CP for CC'; never null
      Throws:
      ExpiredLicenseException - if the no active license provided and all stored licenses are expired
      InvalidLicenseException - if the license is invalid or all stored licenses are invalid
    • registerOrValidateMultiLicense

      public List<License> registerOrValidateMultiLicense(String license, boolean skipTrialLicenseGeneration) throws InvalidLicenseException
      Validates a supplied CP or 'CP for CC' license, persists it in LicenseStore. and returns all active primary licenses. Optionally skips TRIAL/DEV license generation. Verification and storage: - Accepts CP or 'CP for CC' license; validates and stores under its scope. - Invalid input → throws InvalidLicenseException. - Signed JWT with invalid expiry format → falls back to stored licenses; if none active, throws InvalidLicenseException. Trial/Dev generation: - Generates and persists a TRIAL/DEV CP license only when skipTrialLicenseGeneration is false, and no CP license was ever stored, and no active CP license is configured. Return: - Immutable list of active primary licenses: CP only, CP for CC only, or both. It will never be empty. It will throw an InvalidLicenseException if no active license found.
      Parameters:
      license - CP or 'CP for CC' license; may be blank
      skipTrialLicenseGeneration - when true, never generates a TRIAL/DEV license
      Returns:
      immutable list of active primary licenses; never null or empty list
      Throws:
      ExpiredLicenseException - if Stored CP license is expired and no other active license is available.
      InvalidLicenseException - if the configured license is invalid, or Stored CP license is invalid and no other active license is available.
    • loadPublicKey

      public static PublicKey loadPublicKey()
    • timeUntilLicenseExpirationMs

      public void timeUntilLicenseExpirationMs(long timeMs)
    • timeUntilLicenseExpirationMs

      public long timeUntilLicenseExpirationMs()