Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-44892

Ability to override reflective metadata in DescribableModel

    XMLWordPrintable

Details

    • structs 1.18

    Description

      Following up an old semi-suggestion on the dev list with daspilker and in discussion with stephenconnolly, I propose a new API in symbol-annotation (so that it could be used from core, not just plugins) that would allow a Describable author to completely customize how instantiate and uninstantiate work, if the POJO-style reflective metadata is not quite right. DescribableModel would then delegate to the custom implementation, which would in turn be able to partly delegate back to the standard implementations where desired.

      Rough  API sketch:

      @Retention(RUNTIME)
      @Target({TYPE}) // TBD: on Descriptor, or its clazz?
      @Documented
      public @interface CustomDescription {
          Class<CustomDescribableModel> value();
      }
      public interface CustomDescribableModel<T> {
          Class<T> getType();
          T instantiate(Map<String, Object> arguments, StandardInstantiator standard);
          Map<String, Object> uninstantiate(T object, StandardUninstantiator standard);
      }
      public interface StandardInstantiator {
          <T> T instantiate(Class<T> type, Map<String, Object> arguments);
      }
      public interface StandardUninstantiator {
          Map<String, Object> uninstantiate(Object object);
      }
      

      TBD:

      • How to deal with UninstantiatedDescribable, defined in the plugin not the annotation library, and which is necessary to support symbols?
      • Is it necessary to be able to override other behaviors of DescribableModel that are currently hard-coded to use reflection, such as the soleRequiredParameter?
      • Can a CustomDescribableModel implementation really be used from, say, job-dsl, given that the implementation would reside in a plugin and might link to any classes in Jenkins? Currently job-dsl runs in-process in the master JVM, but other similar tools run out of process. This is the downside of a procedural override as opposed to annotations.

      Use cases:

      • GerritTrigger could call the standard implementations but rename map entries with keys like gerritBuildFailedCodeReviewValue to something more concise.
      • ChoiceParameterDefinition could correct the type of choices from the PoV of scripts.
      • SCMSourceRetriever in workflow-cps-global-lib could delete .scm.id from uninstantiation results, so that Pipeline Syntax would not offer a random UUID for this form of the library step. (In this use case the SCMSource is never given an owner or otherwise persisted, so its id is irrelevant.) Note that StandardUninstantiator may be called on any object, not necessarily the root object passed into CustomDescribableModel.
      • When refactoring describables into new structures, existing fields, getters, and setters could be retained at the Java level, while providing only the new, recommended form to Pipeline Syntax and similar tools.

      Attachments

        Issue Links

          Activity

            jglick Jesse Glick added a comment -

            structs PR 18 proposes a new or overloaded annotation just to handle the common case of parameter aliasing. Would require these calls to look up an annotation on a method, field, or constructor parameter, as well as some other changes to handle instantiation with aliased constructor parameters.

            For StepDescriptor it is not critical since you can already override newInstance and uninstantiate, which handles both build runtimes and the dynamic snippet generator, though the static reference documentation knows nothing of your override and will not reflect the alias.

            jglick Jesse Glick added a comment - structs PR 18 proposes a new or overloaded annotation just to handle the common case of parameter aliasing. Would require these calls to look up an annotation on a method, field, or constructor parameter, as well as some other changes to handle instantiation with aliased constructor parameters. For StepDescriptor it is not critical since you can already override newInstance and uninstantiate , which handles both build runtimes and the dynamic snippet generator, though the static reference documentation knows nothing of your override and will not reflect the alias.
            jglick Jesse Glick added a comment -

            Besides Pipeline and Job DSL, the other major potential consumer of this sort of API would be the configuration-as-code plugin, for YAML-based global configuration. Unfortunately it does not use structs / DescribableModel for whatever reason, so it would not be able to honor these customizations unless that were changed. CC ewel ndeloof

            jglick Jesse Glick added a comment - Besides Pipeline and Job DSL, the other major potential consumer of this sort of API would be the configuration-as-code plugin, for YAML-based global configuration. Unfortunately it does not use structs / DescribableModel for whatever reason, so it would not be able to honor these customizations unless that were changed. CC ewel ndeloof
            jglick Jesse Glick added a comment -

            JEP-205 is another proposal to define a new standard for databinding. It is strictly declarative, which has some obvious advantages—certainly kinds of tools can be written which rely on it, and introspection can happen outside the Jenkins JVM—but which also renders it impractical for solving particular customizations such as for JENKINS-51638.

            jglick Jesse Glick added a comment - JEP-205 is another proposal to define a new standard for databinding. It is strictly declarative, which has some obvious advantages—certainly kinds of tools can be written which rely on it, and introspection can happen outside the Jenkins JVM—but which also renders it impractical for solving particular customizations such as for JENKINS-51638 .
            jglick Jesse Glick added a comment -

            daspilker I have proposed an API and would like feedback on whether you think it makes sense for Job DSL.

            jglick Jesse Glick added a comment - daspilker I have proposed an API and would like feedback on whether you think it makes sense for Job DSL.
            dnusbaum Devin Nusbaum added a comment -

            The new CustomDescribableModel API was just released in version 1.18 of Structs.

            dnusbaum Devin Nusbaum added a comment - The new CustomDescribableModel API was just released in version 1.18 of Structs.

            People

              jglick Jesse Glick
              jglick Jesse Glick
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: