1 package org.oxerr.vividseats.client.rescu.impl;
2
3 import java.util.function.Supplier;
4
5 import org.apache.commons.lang3.ArrayUtils;
6 import org.oxerr.rescu.ext.singleton.RestProxyFactorySingletonImpl;
7 import org.oxerr.vividseats.client.ListingService;
8 import org.oxerr.vividseats.client.VividSeatsClient;
9 import org.oxerr.vividseats.client.rescu.resource.ListingResource;
10
11 import com.fasterxml.jackson.annotation.JsonInclude.Include;
12 import com.fasterxml.jackson.databind.DeserializationFeature;
13 import com.fasterxml.jackson.databind.ObjectMapper;
14 import com.fasterxml.jackson.databind.SerializationFeature;
15 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
16
17 import io.github.poshjosh.ratelimiter.store.BandwidthsStore;
18 import jakarta.ws.rs.HeaderParam;
19 import si.mazi.rescu.ClientConfig;
20 import si.mazi.rescu.IRestProxyFactory;
21 import si.mazi.rescu.Interceptor;
22 import si.mazi.rescu.RestProxyFactoryImpl;
23 import si.mazi.rescu.serialization.jackson.DefaultJacksonObjectMapperFactory;
24 import si.mazi.rescu.serialization.jackson.JacksonObjectMapperFactory;
25
26 public class ResCUVividSeatsClient implements VividSeatsClient {
27
28 private static final String DEFAULT_BASE_URL = "https://brokers.vividseats.com/webservices";
29
30 private final String baseUrl;
31
32 private final IRestProxyFactory restProxyFactory;
33
34 private final ListingService listingService;
35
36
37
38
39
40
41
42 public ResCUVividSeatsClient(String token, Interceptor... interceptors) {
43 this(DEFAULT_BASE_URL, token, interceptors);
44 }
45
46
47
48
49
50
51
52
53 public ResCUVividSeatsClient(String baseUrl, String token, Interceptor... interceptors) {
54 this(baseUrl, () -> token, interceptors);
55 }
56
57
58
59
60
61
62
63 public ResCUVividSeatsClient(Supplier<String> token, Interceptor... interceptors) {
64 this(DEFAULT_BASE_URL, token, interceptors);
65 }
66
67
68
69
70
71
72
73
74 public ResCUVividSeatsClient(String baseUrl, Supplier<String> tokenSupplier, Interceptor... interceptors) {
75 this(baseUrl, tokenSupplier, BandwidthsStore.ofDefaults(), interceptors);
76 }
77
78
79
80
81
82
83
84
85
86 public ResCUVividSeatsClient(String baseUrl, Supplier<String> tokenSupplier, BandwidthsStore<String> bandwidthsStore, Interceptor... interceptors) {
87 this.baseUrl = baseUrl;
88 JacksonObjectMapperFactory jacksonObjectMapperFactory = createJacksonObjectMapperFactory();
89 var clientConfigV1 = createClientConfigV1(jacksonObjectMapperFactory);
90 var clientConfig = createClientConfig(jacksonObjectMapperFactory, tokenSupplier);
91 this.restProxyFactory = new RestProxyFactorySingletonImpl(new RestProxyFactoryImpl());
92 this.listingService = new ListingServiceImpl(
93 tokenSupplier,
94 this.restProxyFactory.createProxy(org.oxerr.vividseats.client.rescu.resource.v1.ListingResource.class, baseUrl, clientConfigV1, interceptors),
95 createProxy(ListingResource.class, clientConfig, bandwidthsStore, interceptors)
96 );
97 }
98
99 @Override
100 public ListingService getListingService() {
101 return this.listingService;
102 }
103
104 protected <I> I createProxy(Class<I> restInterface, ClientConfig clientConfig, BandwidthsStore<String> bandwidthsStore, Interceptor... interceptors) {
105 var rateLimiterInterceptor = new RateLimiterInterceptor(bandwidthsStore);
106 return createProxy(restInterface, clientConfig, ArrayUtils.add(interceptors, rateLimiterInterceptor));
107 }
108
109 protected <I> I createProxy(Class<I> restInterface, ClientConfig clientConfig, Interceptor... interceptors) {
110 return this.restProxyFactory.createProxy(restInterface, baseUrl, clientConfig, interceptors);
111 }
112
113 protected ClientConfig createClientConfigV1(JacksonObjectMapperFactory jacksonObjectMapperFactory) {
114 var clientConfig = new ClientConfig();
115 clientConfig.setJacksonObjectMapperFactory(jacksonObjectMapperFactory);
116 return clientConfig;
117 }
118
119 protected ClientConfig createClientConfig(JacksonObjectMapperFactory jacksonObjectMapperFactory, Supplier<String> tokenSupplier) {
120 var clientConfig = new ClientConfig();
121 clientConfig.addDefaultParam(HeaderParam.class, "Api-token", new Object() {
122
123 @Override
124 public String toString() {
125 return tokenSupplier.get();
126 }
127
128 });
129 clientConfig.setJacksonObjectMapperFactory(jacksonObjectMapperFactory);
130 return clientConfig;
131 }
132
133 protected JacksonObjectMapperFactory createJacksonObjectMapperFactory() {
134 return new DefaultJacksonObjectMapperFactory() {
135
136 @Override
137 public void configureObjectMapper(ObjectMapper objectMapper) {
138 super.configureObjectMapper(objectMapper);
139 objectMapper.registerModule(new JavaTimeModule());
140 objectMapper.setSerializationInclusion(Include.NON_ABSENT);
141 objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
142 objectMapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
143 objectMapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
144 }
145
146 };
147 }
148
149 }