vlsi opened a new issue, #5946:
URL: https://github.com/apache/jmeter/issues/5946

   ### Use case
   
   Currently, JMeter has two approaches for creating test elements:
   * `implements TestBean`
   * `implements TestElement`
   
   `TestBean`-based elements do not mange `JMeterProperty` themselves, and they 
rely on `Introspector` and `BeanInfo` to manage the properties.
   
   `TestElement`-based elements (e.g. the ones that extend 
`AbstractTestElement`) have manage their properties on their own.
   There are several issues with that:
   1. The is no clear way to see which properties are "well-known". Sometimes 
the elements declare something like `public static final String PORT = 
"HTTPSampler.port"`, however, it is unclear what is the expected property type, 
the default value is not there, and sometimes the strings are even `private` 
(see `TestPlan`, `private static final String FUNCTIONAL_MODE = 
"TestPlan.functional_mode";`)
   2. Currently, the default value should be passed on every property get and 
set. For instance, see `ResultCollector`, 
`getPropertyAsBoolean(SUCCESS_ONLY_LOGGING,false)`. In that case, all users of 
`SUCCESS_ONLY_LOGGING` should pass the same `false` default value.
   3. Test elements often provide getters and setters for primitive values 
only. For instance, `org.apache.jmeter.testelement.TestPlan#isSerialized() 
return boolean` and 
`org.apache.jmeter.testelement.TestPlan#setSerialized(boolean)` accept only 
`boolean` values, and they do not allow users to configure `FunctionProperty` 
for `isSerialized` property.
   
   ### Possible solution
   
   Add API so the plugin authors could configure schema for their elements:
   
   ```kotlin
   public interface PropertyDescriptor {
       public val propertyName: String
       public val defaultValue: Any?
   }
   
   public data class BooleanPropertyDescriptor(
       public override val propertyName: String,
       /** Default value, null means there's no default */
       public override val defaultValue: Boolean?
   ): PropertyDescriptor
   
   public data class StringPropertyDescriptor(
       public override val propertyName: String,
       /** Default value, null means there's no default */
       public override val defaultValue: String?
   ): PropertyDescriptor
   ```
   
   ```kotlin
   /** Similar to Java's Object */
   public abstract class JMeterElementClass {
       private val propertyDescriptors: MutableMap<String, PropertyDescriptor> 
= mutableMapOf()
       protected fun string(name: String): StringPropertyDescriptor =
           StringPropertyDescriptor(name, null).also {
               propertyDescriptors[name] = it
           }
   
       @JvmOverloads
       protected fun boolean(name: String, default: Boolean? = null): 
BooleanPropertyDescriptor =
           BooleanPropertyDescriptor(name, null).also {
               propertyDescriptors[name] = it
           }
   }
   
   
   public open class AbstractTestElementClass protected constructor(): 
JMeterElementClass() {
       public companion object {
           @JvmField
           public val INSTANCE: AbstractTestElementClass = 
AbstractTestElementClass()
       }
       public val name: StringPropertyDescriptor = string("TestElement.name")
       public val comments: StringPropertyDescriptor = 
string("TestElement.comments")
       public val guiClass: StringPropertyDescriptor = 
string("TestElement.gui_class")
       public val testClass: StringPropertyDescriptor = 
string("TestElement.testClass")
       public val enabled: BooleanPropertyDescriptor = 
boolean("TestElement.enabled", default = true)
   }
   
   public open class TestPlanClass protected constructor() : 
AbstractTestElementClass() {
       public companion object {
           @JvmField
           public val INSTANCE: TestPlanClass = TestPlanClass()
       }
       public val isSerialized: BooleanPropertyDescriptor = 
boolean("isserialized")
   }
   ```
   
   Then users would be able to access the properties like 
`TestPlanClass.INSTANCE.isSerialized` or `TestPlanClass.INSTANCE.comments`.
   
   `AbstractTestElement` could expose `JMeterElementClass` as well.
   
   For instance:
   
   ```java
   class AbstractTestElement {
       public JMeterElementClass getType() {
           return AbstractTestElementClass.INSTANCE;
       }
   }
   
   ...
   
   class TestPlan extends AbstractTestElement {
       public TestPlanClass getType() {
           return TestPlanClass.INSTANCE;
       }
   }
   ```
   
   Then it would be slightly easier to access the corresponding `JMeterClass`:
   
   ```java
   // kotlin
   val testPlan: TestPlan = ...;
   // type would return TestPlanClass, so IDE would autocomplete the possible 
property names
   testPlan.type.isSerialized
   ```
   
   ### Possible workarounds
   
   _No response_
   
   ### JMeter Version
   
   5.5
   
   ### Java Version
   
   _No response_
   
   ### OS Version
   
   _No response_


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@jmeter.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to