View Javadoc
1   /*
2    * Copyright (C) 2023 B3Partners B.V.
3    *
4    * SPDX-License-Identifier: MIT
5    */
6   package org.tailormap.api.configuration;
7   
8   import ch.rasc.sse.eventbus.DataObjectConverter;
9   import ch.rasc.sse.eventbus.DefaultDataObjectConverter;
10  import ch.rasc.sse.eventbus.DefaultSubscriptionRegistry;
11  import ch.rasc.sse.eventbus.DistributedEventBus;
12  import ch.rasc.sse.eventbus.JacksonDataObjectConverter;
13  import ch.rasc.sse.eventbus.ReplayStore;
14  import ch.rasc.sse.eventbus.SseEventBus;
15  import ch.rasc.sse.eventbus.SubscriptionRegistry;
16  import ch.rasc.sse.eventbus.config.EnableSseEventBus;
17  import ch.rasc.sse.eventbus.config.SseEventBusConfigurer;
18  import ch.rasc.sse.eventbus.observation.SseEventBusObservationConvention;
19  import io.micrometer.observation.ObservationRegistry;
20  import java.util.ArrayList;
21  import java.util.List;
22  import java.util.Locale;
23  import org.jspecify.annotations.Nullable;
24  import org.springframework.beans.factory.annotation.Autowired;
25  import org.springframework.beans.factory.annotation.Value;
26  import org.springframework.boot.context.properties.ConfigurationProperties;
27  import org.springframework.boot.context.properties.EnableConfigurationProperties;
28  import org.springframework.context.annotation.Bean;
29  import org.springframework.context.annotation.Configuration;
30  import org.springframework.scheduling.annotation.EnableScheduling;
31  import org.springframework.web.servlet.LocaleResolver;
32  import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
33  import tools.jackson.databind.ObjectMapper;
34  
35  @Configuration
36  @EnableConfigurationProperties
37  @ConfigurationProperties(prefix = "tailormap-api")
38  @EnableSseEventBus
39  @EnableScheduling
40  public class TailormapConfig {
41    private int timeout;
42  
43    @Value("${tailormap-api.default-language:en}")
44    private String defaultLanguage;
45  
46    public int getTimeout() {
47      return timeout;
48    }
49  
50    public TailormapConfig setTimeout(int timeout) {
51      this.timeout = timeout;
52      return this;
53    }
54  
55    @Bean
56    public LocaleResolver localeResolver() {
57      AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
58      resolver.setDefaultLocale(Locale.of(defaultLanguage));
59      return resolver;
60    }
61  
62    /**
63     * Define a new viewer SseEventBus bean for viewer-specific SSE traffic.
64     *
65     * @return the viewerSseEventBus instance
66     */
67    @Bean("viewerSseEventBus")
68    public SseEventBus viewerSseEventBus(
69        @Autowired(required = false) @Nullable SseEventBusConfigurer configurer,
70        @Autowired(required = false) @Nullable ObjectMapper objectMapper,
71        @Autowired(required = false) @Nullable List<DataObjectConverter> dataObjectConverters,
72        @Autowired(required = false) @Nullable SubscriptionRegistry subscriptionRegistry,
73        @Autowired(required = false) @Nullable ReplayStore replayStore,
74        @Autowired(required = false) @Nullable ObservationRegistry observationRegistry,
75        @Autowired(required = false) @Nullable SseEventBusObservationConvention observationConvention,
76        @Autowired(required = false) @Nullable DistributedEventBus distributedEventBus) {
77  
78      // Apply same defaults as DefaultSseEventBusConfiguration
79      SseEventBusConfigurer config = configurer != null
80          ? configurer
81          : new SseEventBusConfigurer() {
82            /* defaults */
83          };
84  
85      SubscriptionRegistry registry =
86          subscriptionRegistry != null ? subscriptionRegistry : new DefaultSubscriptionRegistry();
87  
88      ReplayStore store = replayStore != null ? replayStore : config.replayStore();
89  
90      List<DataObjectConverter> converters =
91          dataObjectConverters != null ? new ArrayList<>(dataObjectConverters) : new ArrayList<>();
92      if (converters.isEmpty()) {
93        if (objectMapper != null) {
94          converters.add(new JacksonDataObjectConverter(objectMapper));
95        } else {
96          converters.add(new DefaultDataObjectConverter());
97        }
98      }
99  
100     return new SseEventBus(
101         config, registry, converters, store, observationRegistry, observationConvention, distributedEventBus);
102   }
103 }