Uploaded image for project: 'Kafka'
  1. Kafka
  2. KAFKA-3049

VerifiableProperties does not respect 'default' properties of underlying java.util.Properties instance

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Minor
    • Resolution: Unresolved
    • 0.10.0.0, 0.11.0.0, 1.0.0
    • None
    • config, core

    Description

      When retrieving values from the underlying Properties instance with the getString, get<Type>, etc. methods of a VerifiableProperties instance, a call to the underlying Properties.containsKey method is made. This method will not search the default properties values of the instance, rendering any default properties defined on the Properties instance useless.

      A practical example is shown below:

      // suppose we have a base, default set of properties to supply to all consumer groups
      val baseProps = new Properties
      baseProps.setProperty("zookeeper.connect", "localhost:2181/kafka")
      baseProps.setProperty("zookeeper.connection.timeout.ms", "2000")
      
      // additional we have discrete properties instances for each consumer group that utilize these defaults
      val groupProps1 = new Properties(baseProps)
      groupProps1.setProperty("group.id", "test-1")
      
      val groupProps2 = new Properties(baseProps)
      groupProps2.setProperty("group.id", "test-2")
      
      // when attempting to create an instance of a high-level Consumer with the above properties an exception will be thrown due to the aforementioned problem description
      java.lang.IllegalArgumentException: requirement failed: Missing required property 'zookeeper.connect'
              at scala.Predef$.require(Predef.scala:233)
              at kafka.utils.VerifiableProperties.getString(VerifiableProperties.scala:177)
              at kafka.utils.ZKConfig.<init>(ZkUtils.scala:879)
              at kafka.consumer.ConsumerConfig.<init>(ConsumerConfig.scala:100)
              at kafka.consumer.ConsumerConfig.<init>(ConsumerConfig.scala:104)
      
      // however, the groupProps instances will return the correct value for "zookeeper.connect" when using `Properties.getProperty`
      assert(groupProps1.getProperty("zookeeper.connect", "localhost:2181/kafka"))
      assert(groupProps2.getProperty("zookeeper.connect", "localhost:2181/kafka"))
      

      I believe it is worthwhile for Kafka to respect the default properties feature of java.util.Properties, and further, that Kafka should discourage the use of the methods on Properties that are inherited from Hashtable (e.g. containsKey). One can argue that VerifiableProperties is not 'correct' due to this behavior, but a user can always workaround this by creating discrete instances of Properties with a set of default properties manually added to each instance. However, this is inconvenient and may only encourage the use of the discouraged Hashtable methods like putAll.

      Two proposed solutions follow:
      1. Do not delegate to the Properties.containsKey method during the invocation of VerifiableProperties.containsKey. One can use a null check in conjunction with getProperty in its place.
      2. Treat the underlying Properties instance as immutable and assign the result of Properties.stringPropertyNames() to a member of VerifiableProperties. One can check this set of known, available property names, which respects the optional default properties, when VerifiableProperties.containsKey is invoked.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              olchovy@gmail.com Jeffrey Olchovy
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated: