View Javadoc
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 ClientConfig clientConfig;
33  
34  	private final IRestProxyFactory restProxyFactory;
35  
36  	private final ListingService listingService;
37  
38  	/**
39  	 * Constructs a client with the specified token.
40  	 *
41  	 * @param token the token to access the API.
42  	 * @param interceptors the interceptors to intercept the requests.
43  	 */
44  	public ResCUVividSeatsClient(String token, Interceptor... interceptors) {
45  		this(DEFAULT_BASE_URL, token, interceptors);
46  	}
47  
48  	/**
49  	 * Constructs a client with the specified base URL and token.
50  	 *
51  	 * @param baseUrl the base URL of the API.
52  	 * @param token the token to access the API.
53  	 * @param interceptors the interceptors to intercept the requests.
54  	 */
55  	public ResCUVividSeatsClient(String baseUrl, String token, Interceptor... interceptors) {
56  		this(baseUrl, () -> token, interceptors);
57  	}
58  
59  	/**
60  	 * Constructs a client with the specified token.
61  	 *
62  	 * @param token the token to access the API.
63  	 * @param interceptors the interceptors to intercept the requests.
64  	 */
65  	public ResCUVividSeatsClient(Supplier<String> token, Interceptor... interceptors) {
66  		this(DEFAULT_BASE_URL, token, interceptors);
67  	}
68  
69  	/**
70  	 * Constructs a client with the specified base URL and token.
71  	 *
72  	 * @param baseUrl the base URL of the API.
73  	 * @param tokenSupplier the token supplier to access the API.
74  	 * @param interceptors the interceptors to intercept the requests.
75  	 */
76  	public ResCUVividSeatsClient(String baseUrl, Supplier<String> tokenSupplier, Interceptor... interceptors) {
77  		this(baseUrl, tokenSupplier, BandwidthsStore.ofDefaults(), interceptors);
78  	}
79  
80  	/**
81  	 * Constructs a client with the specified base URL, token supplier, bandwidths store and interceptors.
82  	 *
83  	 * @param baseUrl the base URL of the API.
84  	 * @param tokenSupplier the token supplier to access the API.
85  	 * @param bandwidthsStore the bandwidths store to store the bandwidth.
86  	 * @param interceptors the interceptors to intercept the requests.
87  	 */
88  	public ResCUVividSeatsClient(String baseUrl, Supplier<String> tokenSupplier, BandwidthsStore<String> bandwidthsStore, Interceptor... interceptors) {
89  		this.baseUrl = baseUrl;
90  
91  		JacksonObjectMapperFactory jacksonObjectMapperFactory = new DefaultJacksonObjectMapperFactory() {
92  
93  			@Override
94  			public void configureObjectMapper(ObjectMapper objectMapper) {
95  				super.configureObjectMapper(objectMapper);
96  				objectMapper.registerModule(new JavaTimeModule());
97  				objectMapper.setSerializationInclusion(Include.NON_ABSENT);
98  				objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
99  				objectMapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
100 				objectMapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
101 			}
102 
103 		};
104 
105 		this.clientConfig = new ClientConfig();
106 		clientConfig.addDefaultParam(HeaderParam.class, "Api-token", new Object() {
107 
108 			@Override
109 			public String toString() {
110 				return tokenSupplier.get();
111 			}
112 
113 		});
114 		clientConfig.setJacksonObjectMapperFactory(jacksonObjectMapperFactory);
115 
116 		this.restProxyFactory = new RestProxyFactorySingletonImpl(new RestProxyFactoryImpl());
117 
118 		this.listingService = new ListingServiceImpl(createProxy(ListingResource.class, bandwidthsStore, interceptors));
119 	}
120 
121 	@Override
122 	public ListingService getListingService() {
123 		return this.listingService;
124 	}
125 
126 	protected <I> I createProxy(Class<I> restInterface, BandwidthsStore<String> bandwidthsStore, Interceptor... interceptors) {
127 		var rateLimiterInterceptor = new RateLimiterInterceptor(bandwidthsStore);
128 		return createProxy(restInterface, ArrayUtils.add(interceptors, rateLimiterInterceptor));
129 	}
130 
131 	protected <I> I createProxy(Class<I> restInterface, Interceptor... interceptors) {
132 		return this.restProxyFactory.createProxy(restInterface, baseUrl, this.clientConfig, interceptors);
133 	}
134 
135 }