View Javadoc
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 -&gt; {
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 &lt;guinetik@gmail.com&gt;
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 }