Uploaded image for project: 'camunda BPM'
  1. camunda BPM
  2. CAM-9972

Auto Configuration for Java8/JSR-310 Date-Time types in Spring Boot

      Currently users have to write code in order to enable java 8 date/time types in Spin

      The idea behind this feature request would be to provide spring boot auto configuration that did this - triggered by a maven dependency.
      The exact configuration could then be done be done as (spring boot) yaml parameters.

      For reference, this is what a user would do:

      1 - add the maven dependency

      <dependency>
            <groupId>org.camunda.spin</groupId>
            <artifactId>camunda-spin-dataformat-json-jackson</artifactId>
            <version>1.6.5</version>
      </dependency>
      

      2 - register javatimemodule through a DataFormatConfigurator

      @Component
      public class CamundaJacksonFormatConfigurator implements DataFormatConfigurator<JacksonJsonDataFormat> {
        @Override
        public Class<JacksonJsonDataFormat> getDataFormatClass() {
          return JacksonJsonDataFormat.class;
        }
      
        @Override
        public void configure(JacksonJsonDataFormat dataFormat) {
      
          final ObjectMapper mapper = dataFormat.getObjectMapper();
          final JavaTimeModule javaTimeModule = new JavaTimeModule();
          mapper.registerModule(javaTimeModule);
        }
      }
      

      3 - create file entry in META-INF/services/org.camunda.spin.spi.DataFormatConfigurator in order to register component (CamundaJacksonFormatConfigurator )

        This is the controller panel for Smart Panels app

            [CAM-9972] Auto Configuration for Java8/JSR-310 Date-Time types in Spring Boot

            Consider also using the other Java8 modules for Jackson out of the box, see https://github.com/FasterXML/jackson-modules-java8

            Thorben Lindhauer added a comment - Consider also using the other Java8 modules for Jackson out of the box, see https://github.com/FasterXML/jackson-modules-java8

            Design decisions:

            1. Add the camunda-spin-dataformat-json-jackson dependency as optional. This way, the user will need to explicitly declare it for the dependency to be added on the classpath;
            2. Create a CamundaJacksonFormatConfigurator bean on the condition that the JacksonJsonDataFormat class is present on the classpath. The class is available from the above-mentioned dependency;
            3. Register the Jackson Java8 modules in the new CamundaJacksonFormatConfigurator class.
            4. We don't need to use SPI since the configuration will be registered through the CamundaBpmAutoConfiguration class in the spring.factories file. See the spring docs [here](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html#boot-features-class-conditions) for why a separate class with a Configuration annotation is needed.
            5. Spring Boot already provides Jackson configuration properties. See [here](https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-customize-the-jackson-objectmapper) for more details.

            Nikola Koevski added a comment - Design decisions: Add the camunda-spin-dataformat-json-jackson dependency as optional. This way, the user will need to explicitly declare it for the dependency to be added on the classpath; Create a CamundaJacksonFormatConfigurator bean on the condition that the JacksonJsonDataFormat class is present on the classpath. The class is available from the above-mentioned dependency; Register the Jackson Java8 modules in the new CamundaJacksonFormatConfigurator class. We don't need to use SPI since the configuration will be registered through the CamundaBpmAutoConfiguration class in the spring.factories file. See the spring docs [here] ( https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html#boot-features-class-conditions ) for why a separate class with a Configuration annotation is needed. Spring Boot already provides Jackson configuration properties. See [here] ( https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-customize-the-jackson-objectmapper ) for more details.

            Design decisions:

            Spin uses the Java SPI ServiceLoader class to load additional DataFormat configurations (through the org.camunda.spin.spi.DataFormatConfigurator interface). The loading is performed through the DataFormats class, in a singleton instance, which makes extending the DataFormats class complicated. In addition, the ServiceLoader class is incompatible with the META-INF/spring.factories file, and we can't use "Spring" syntax to ensure auto-configuration.

            To resolve the problem, the following things were performed:

            1. Modify the Spin#DataFormats class to accept a list of DataFormatConfigurator instances when loading DataFormats;
            2. Extend the SpinProcessEnginePlugin to pass the above mentioned list;
            3. Provide separate DataFormatConfigurator beans for the Jackson Java 8 modules, in the Spring Boot auto-configuration classes. These are then passed as arguments when the DataFormats are loaded in the SpringBootSpinProcessEnginePlugin.

            Nikola Koevski added a comment - Design decisions: Spin uses the Java SPI ServiceLoader class to load additional DataFormat configurations (through the org.camunda.spin.spi.DataFormatConfigurator interface). The loading is performed through the DataFormats class, in a singleton instance, which makes extending the DataFormats class complicated. In addition, the ServiceLoader class is incompatible with the META-INF/spring.factories file, and we can't use "Spring" syntax to ensure auto-configuration. To resolve the problem, the following things were performed: Modify the Spin#DataFormats class to accept a list of DataFormatConfigurator instances when loading DataFormats; Extend the SpinProcessEnginePlugin to pass the above mentioned list; Provide separate DataFormatConfigurator beans for the Jackson Java 8 modules, in the Spring Boot auto-configuration classes. These are then passed as arguments when the DataFormats are loaded in the SpringBootSpinProcessEnginePlugin .

            Implemented the review hints.

            • The getAvailableDataFormatsMap getter method was added for a previous solution that wasn't used. Since it remained unused, I removed it now;
            • The new applyConfigurators method is protected, and only used internally by the methods of the DataFormats class. We shouldn't cover it in tests explicitly;
            • I added tests for the new registerDataFormats and loadDataFormats methods.
              • The registerDataFormats method is only used by the new loadDataFormats method. However, since the other variant is Public API, I decided to make it public as well.

            Nikola Koevski added a comment - Implemented the review hints. The getAvailableDataFormatsMap getter method was added for a previous solution that wasn't used. Since it remained unused, I removed it now; The new applyConfigurators method is protected, and only used internally by the methods of the DataFormats class. We shouldn't cover it in tests explicitly; I added tests for the new registerDataFormats and loadDataFormats methods. The registerDataFormats method is only used by the new loadDataFormats method. However, since the other variant is Public API, I decided to make it public as well.

            I merged all pull requests. You can proceed with releasing spin.

            Tassilo Weidner added a comment - I merged all pull requests. You can proceed with releasing spin.

              Unassigned Unassigned
              meyer Daniel Meyer
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved: