1 package com.guinetik.rr;
2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.Set;
6
7 /**
8 * Configuration options for RocketRest API clients.
9 *
10 * <p>This class provides a type-safe, centralized container for all configurable options
11 * across different client implementations. Options are stored as key-value pairs and
12 * can be retrieved with type-specific methods.
13 *
14 * <h2>Available Options</h2>
15 * <table border="1">
16 * <caption>Configuration options for RocketRest clients</caption>
17 * <tr><th>Option</th><th>Type</th><th>Default</th><th>Description</th></tr>
18 * <tr><td>{@link #RETRY_ENABLED}</td><td>Boolean</td><td>true</td><td>Enable automatic retry on failure</td></tr>
19 * <tr><td>{@link #MAX_RETRIES}</td><td>Integer</td><td>3</td><td>Maximum number of retry attempts</td></tr>
20 * <tr><td>{@link #RETRY_DELAY}</td><td>Long</td><td>1000</td><td>Delay between retries in milliseconds</td></tr>
21 * <tr><td>{@link #LOGGING_ENABLED}</td><td>Boolean</td><td>true</td><td>Enable request/response logging</td></tr>
22 * <tr><td>{@link #LOG_REQUEST_BODY}</td><td>Boolean</td><td>false</td><td>Log request body content</td></tr>
23 * <tr><td>{@link #LOG_RESPONSE_BODY}</td><td>Boolean</td><td>false</td><td>Log response body content</td></tr>
24 * <tr><td>{@link #ASYNC_POOL_SIZE}</td><td>Integer</td><td>4</td><td>Thread pool size for async operations</td></tr>
25 * </table>
26 *
27 * <h2>Usage</h2>
28 * <pre class="language-java"><code>
29 * // Configure via RocketRestConfig builder
30 * RocketRestConfig config = RocketRestConfig.builder("https://api.example.com")
31 * .defaultOptions(options -> {
32 * options.set(RocketRestOptions.RETRY_ENABLED, true);
33 * options.set(RocketRestOptions.MAX_RETRIES, 5);
34 * options.set(RocketRestOptions.LOG_REQUEST_BODY, true);
35 * })
36 * .build();
37 *
38 * // Or configure directly on client
39 * RocketRest client = new RocketRest(config);
40 * client.configure(RocketRestOptions.RETRY_DELAY, 2000L);
41 * </code></pre>
42 *
43 * <h2>Reading Options</h2>
44 * <pre class="language-java"><code>
45 * RocketRestOptions options = new RocketRestOptions();
46 * boolean retryEnabled = options.getBoolean(RocketRestOptions.RETRY_ENABLED, false);
47 * int maxRetries = options.getInt(RocketRestOptions.MAX_RETRIES, 3);
48 * long delay = options.getLong(RocketRestOptions.RETRY_DELAY, 1000L);
49 * </code></pre>
50 *
51 * @author guinetik <guinetik@gmail.com>
52 * @see RocketRestConfig
53 * @see RocketRest#configure(String, Object)
54 * @since 1.0.0
55 */
56 public class RocketRestOptions {
57 // Common options
58 public static final String RETRY_ENABLED = "retry.enabled";
59 public static final String MAX_RETRIES = "retry.max";
60 public static final String RETRY_DELAY = "retry.delay";
61 public static final String LOGGING_ENABLED = "logging.enabled";
62 public static final String TIMING_ENABLED = "timing.enabled";
63 public static final String LOG_REQUEST_BODY = "logging.request.body";
64 public static final String LOG_RESPONSE_BODY = "logging.response.body";
65 public static final String LOG_RAW_RESPONSE = "logging.response.raw";
66 public static final String MAX_LOGGED_BODY_LENGTH = "logging.body.maxlength";
67
68 // Async options
69 public static final String ASYNC_POOL_SIZE = "async.pool.size";
70
71 // Token refresh URL option
72 public static final String TOKEN_URL = "tokenUrl";
73
74 private final Map<String, Object> options = new HashMap<>();
75
76 /**
77 * Creates a new ClientOptions with default values.
78 */
79 public RocketRestOptions() {
80 // Set defaults
81 options.put(RETRY_ENABLED, Boolean.TRUE);
82 options.put(MAX_RETRIES, 3);
83 options.put(RETRY_DELAY, 1000L);
84 options.put(LOGGING_ENABLED, Boolean.TRUE);
85 options.put(TIMING_ENABLED, Boolean.TRUE);
86 options.put(LOG_REQUEST_BODY, Boolean.FALSE);
87 options.put(LOG_RESPONSE_BODY, Boolean.FALSE);
88 options.put(LOG_RAW_RESPONSE, Boolean.TRUE);
89 options.put(MAX_LOGGED_BODY_LENGTH, 4000);
90 options.put(ASYNC_POOL_SIZE, 4);
91 }
92
93 /**
94 * Sets an option value.
95 *
96 * @param key The option key.
97 * @param value The option value.
98 * @return This option instance for method chaining.
99 */
100 public RocketRestOptions set(String key, Object value) {
101 options.put(key, value);
102 return this;
103 }
104
105 /**
106 * Gets all option keys.
107 *
108 * @return Set of all option keys.
109 */
110 public Set<String> getKeys() {
111 return options.keySet();
112 }
113
114 /**
115 * Gets the raw option value without type casting.
116 *
117 * @param key The option key.
118 * @return The raw option value, or null if not set.
119 */
120 public Object getRaw(String key) {
121 return options.get(key);
122 }
123
124 /**
125 * Gets an option value.
126 *
127 * @param <T> The expected type of the option value.
128 * @param key The option key.
129 * @param defaultValue The default value to return if the option is not set.
130 * @return The option value, or the default value if not set.
131 */
132 @SuppressWarnings("unchecked")
133 public <T> T get(String key, T defaultValue) {
134 Object value = options.get(key);
135 if (defaultValue != null && defaultValue.getClass().isInstance(value)) {
136 return (T) value;
137 }
138 return defaultValue;
139 }
140
141 /**
142 * Gets a boolean option value.
143 *
144 * @param key The option key.
145 * @param defaultValue The default value to return if the option is not set.
146 * @return The boolean option value.
147 */
148 public boolean getBoolean(String key, boolean defaultValue) {
149 Object value = options.get(key);
150 if (value instanceof Boolean) {
151 return (Boolean) value;
152 }
153 return defaultValue;
154 }
155
156 /**
157 * Gets an integer option value.
158 *
159 * @param key The option key.
160 * @param defaultValue The default value to return if the option is not set.
161 * @return The integer option value.
162 */
163 public int getInt(String key, int defaultValue) {
164 Object value = options.get(key);
165 if (value instanceof Number) {
166 return ((Number) value).intValue();
167 }
168 return defaultValue;
169 }
170
171 /**
172 * Gets a long option value.
173 *
174 * @param key The option key.
175 * @param defaultValue The default value to return if the option is not set.
176 * @return The long option value.
177 */
178 public long getLong(String key, long defaultValue) {
179 Object value = options.get(key);
180 if (value instanceof Number) {
181 return ((Number) value).longValue();
182 }
183 return defaultValue;
184 }
185
186 public boolean contains(String feature) {
187 return this.options.containsKey(feature);
188 }
189
190 public String getString(String feature, String defaultValue) {
191 Object value = options.get(feature);
192 if (value instanceof String) {
193 return (String) value;
194 }
195 return defaultValue;
196 }
197 }