55
66import com .anduril .core .ClientOptions ;
77import com .anduril .core .Environment ;
8+ import java .util .HashMap ;
9+ import java .util .Map ;
10+ import java .util .Optional ;
811import okhttp3 .OkHttpClient ;
912
10- public final class AsyncLatticeBuilder {
11- private ClientOptions .Builder clientOptionsBuilder = ClientOptions .builder ();
13+ public class AsyncLatticeBuilder {
14+ private Optional <Integer > timeout = Optional .empty ();
15+
16+ private Optional <Integer > maxRetries = Optional .empty ();
17+
18+ private final Map <String , String > customHeaders = new HashMap <>();
1219
1320 private String token = null ;
1421
1522 private Environment environment = Environment .DEFAULT ;
1623
24+ private OkHttpClient httpClient ;
25+
1726 /**
1827 * Sets token
1928 */
@@ -36,29 +45,158 @@ public AsyncLatticeBuilder url(String url) {
3645 * Sets the timeout (in seconds) for the client. Defaults to 60 seconds.
3746 */
3847 public AsyncLatticeBuilder timeout (int timeout ) {
39- this .clientOptionsBuilder . timeout (timeout );
48+ this .timeout = Optional . of (timeout );
4049 return this ;
4150 }
4251
4352 /**
4453 * Sets the maximum number of retries for the client. Defaults to 2 retries.
4554 */
4655 public AsyncLatticeBuilder maxRetries (int maxRetries ) {
47- this .clientOptionsBuilder . maxRetries (maxRetries );
56+ this .maxRetries = Optional . of (maxRetries );
4857 return this ;
4958 }
5059
5160 /**
5261 * Sets the underlying OkHttp client
5362 */
5463 public AsyncLatticeBuilder httpClient (OkHttpClient httpClient ) {
55- this .clientOptionsBuilder . httpClient ( httpClient ) ;
64+ this .httpClient = httpClient ;
5665 return this ;
5766 }
5867
68+ /**
69+ * Add a custom header to be sent with all requests.
70+ * For headers that need to be computed dynamically or conditionally, use the setAdditional() method override instead.
71+ *
72+ * @param name The header name
73+ * @param value The header value
74+ * @return This builder for method chaining
75+ */
76+ public AsyncLatticeBuilder addHeader (String name , String value ) {
77+ this .customHeaders .put (name , value );
78+ return this ;
79+ }
80+
81+ protected ClientOptions buildClientOptions () {
82+ ClientOptions .Builder builder = ClientOptions .builder ();
83+ setEnvironment (builder );
84+ setAuthentication (builder );
85+ setHttpClient (builder );
86+ setTimeouts (builder );
87+ setRetries (builder );
88+ for (Map .Entry <String , String > header : this .customHeaders .entrySet ()) {
89+ builder .addHeader (header .getKey (), header .getValue ());
90+ }
91+ setAdditional (builder );
92+ return builder .build ();
93+ }
94+
95+ /**
96+ * Sets the environment configuration for the client.
97+ * Override this method to modify URLs or add environment-specific logic.
98+ *
99+ * @param builder The ClientOptions.Builder to configure
100+ */
101+ protected void setEnvironment (ClientOptions .Builder builder ) {
102+ builder .environment (this .environment );
103+ }
104+
105+ /**
106+ * Override this method to customize authentication.
107+ * This method is called during client options construction to set up authentication headers.
108+ *
109+ * @param builder The ClientOptions.Builder to configure
110+ *
111+ * Example:
112+ * <pre>{@code
113+ * @Override
114+ * protected void setAuthentication(ClientOptions.Builder builder) {
115+ * super.setAuthentication(builder); // Keep existing auth
116+ * builder.addHeader("X-API-Key", this.apiKey);
117+ * }
118+ * }</pre>
119+ */
120+ protected void setAuthentication (ClientOptions .Builder builder ) {
121+ if (this .token != null ) {
122+ builder .addHeader ("Authorization" , "Bearer " + this .token );
123+ }
124+ }
125+
126+ /**
127+ * Sets the request timeout configuration.
128+ * Override this method to customize timeout behavior.
129+ *
130+ * @param builder The ClientOptions.Builder to configure
131+ */
132+ protected void setTimeouts (ClientOptions .Builder builder ) {
133+ if (this .timeout .isPresent ()) {
134+ builder .timeout (this .timeout .get ());
135+ }
136+ }
137+
138+ /**
139+ * Sets the retry configuration for failed requests.
140+ * Override this method to implement custom retry strategies.
141+ *
142+ * @param builder The ClientOptions.Builder to configure
143+ */
144+ protected void setRetries (ClientOptions .Builder builder ) {
145+ if (this .maxRetries .isPresent ()) {
146+ builder .maxRetries (this .maxRetries .get ());
147+ }
148+ }
149+
150+ /**
151+ * Sets the OkHttp client configuration.
152+ * Override this method to customize HTTP client behavior (interceptors, connection pools, etc).
153+ *
154+ * @param builder The ClientOptions.Builder to configure
155+ */
156+ protected void setHttpClient (ClientOptions .Builder builder ) {
157+ if (this .httpClient != null ) {
158+ builder .httpClient (this .httpClient );
159+ }
160+ }
161+
162+ /**
163+ * Override this method to add any additional configuration to the client.
164+ * This method is called at the end of the configuration chain, allowing you to add
165+ * custom headers, modify settings, or perform any other client customization.
166+ *
167+ * @param builder The ClientOptions.Builder to configure
168+ *
169+ * Example:
170+ * <pre>{@code
171+ * @Override
172+ * protected void setAdditional(ClientOptions.Builder builder) {
173+ * builder.addHeader("X-Request-ID", () -> UUID.randomUUID().toString());
174+ * builder.addHeader("X-Client-Version", "1.0.0");
175+ * }
176+ * }</pre>
177+ */
178+ protected void setAdditional (ClientOptions .Builder builder ) {}
179+
180+ /**
181+ * Override this method to add custom validation logic before the client is built.
182+ * This method is called at the beginning of the build() method to ensure the configuration is valid.
183+ * Throw an exception to prevent client creation if validation fails.
184+ *
185+ * Example:
186+ * <pre>{@code
187+ * @Override
188+ * protected void validateConfiguration() {
189+ * super.validateConfiguration(); // Run parent validations
190+ * if (tenantId == null || tenantId.isEmpty()) {
191+ * throw new IllegalStateException("tenantId is required");
192+ * }
193+ * }
194+ * }</pre>
195+ */
196+ protected void validateConfiguration () {}
197+
59198 public AsyncLattice build () {
60- this .clientOptionsBuilder .addHeader ("Authorization" , "Bearer " + this .token );
61- clientOptionsBuilder .environment (this .environment );
62- return new AsyncLattice (clientOptionsBuilder .build ());
199+ validateConfiguration ();
200+ return new AsyncLattice (buildClientOptions ());
63201 }
64202}
0 commit comments