001package org.kuali.common.httplib.api.model; 002 003import static com.google.common.base.Charsets.UTF_8; 004import static com.google.common.base.Optional.absent; 005import static com.google.common.collect.Lists.newArrayList; 006import static com.google.common.io.ByteSource.wrap; 007import static com.google.common.io.Files.asByteSource; 008import static org.kuali.common.httplib.api.model.HttpMethod.DELETE; 009import static org.kuali.common.httplib.api.model.HttpMethod.POST; 010import static org.kuali.common.httplib.api.model.HttpMethod.PUT; 011import static org.kuali.common.httplib.api.model.HttpStatusCodeType.SERVER_ERROR; 012import static org.kuali.common.jute.base.Precondition.checkMin; 013import static org.kuali.common.jute.reflect.Reflection.checkNoNulls; 014 015import java.io.File; 016import java.nio.charset.Charset; 017import java.util.List; 018 019import com.fasterxml.jackson.annotation.JsonSetter; 020import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 021import com.google.common.base.Optional; 022import com.google.common.collect.ImmutableList; 023import com.google.common.collect.Range; 024import com.google.common.io.ByteSource; 025 026@JsonDeserialize(builder = HttpOptions.Builder.class) 027public final class HttpOptions { 028 029 private final Optional<Long> maxBytes; 030 private final Optional<Integer> maxTimeMillis; 031 private final Optional<Integer> connectTimeoutMillis; 032 private final Optional<Integer> retryCount; 033 private final Optional<Integer> retryDelayMillis; 034 private final Optional<ByteSource> upload; 035 private final Optional<File> outputFile; 036 private final boolean cacheResponseInMemory; 037 private final boolean printResponseToStdout; 038 private final boolean followRedirects; 039 private final HttpMethod requestMethod; 040 private final Charset charset; 041 private final boolean ignoreSecurity; 042 private final boolean silent; 043 private final ImmutableList<NameValue> data; 044 private final Range<Integer> keepTryingRange; 045 private final Optional<SecurityContext> security; 046 private final ImmutableList<HeaderPair> headers; 047 private final Optional<String> contentType; 048 049 private HttpOptions(Builder builder) { 050 this.contentType = builder.contentType; 051 this.cacheResponseInMemory = builder.cacheResponseInMemory; 052 this.printResponseToStdout = builder.printResponseToStdout; 053 this.maxTimeMillis = builder.maxTimeMillis; 054 this.connectTimeoutMillis = builder.connectTimeoutMillis; 055 this.retryCount = builder.retryCount; 056 this.retryDelayMillis = builder.retryDelayMillis; 057 this.upload = builder.upload; 058 this.followRedirects = builder.followRedirects; 059 this.requestMethod = builder.requestMethod; 060 this.outputFile = builder.outputFile; 061 this.charset = builder.charset; 062 this.maxBytes = builder.maxBytes; 063 this.ignoreSecurity = builder.ignoreSecurity; 064 this.silent = builder.silent; 065 this.data = ImmutableList.copyOf(builder.data); 066 this.headers = ImmutableList.copyOf(builder.headers); 067 this.keepTryingRange = builder.keepTryingRange; 068 this.security = builder.security; 069 } 070 071 public static HttpOptions build() { 072 return builder().build(); 073 } 074 075 public static Builder builder() { 076 return new Builder(); 077 } 078 079 public static class Builder implements org.apache.commons.lang3.builder.Builder<HttpOptions> { 080 081 private Optional<Long> maxBytes = absent(); 082 private Optional<Integer> maxTimeMillis = absent(); 083 private Optional<Integer> connectTimeoutMillis = absent(); 084 private Optional<Integer> retryCount = absent(); 085 private Optional<Integer> retryDelayMillis = absent(); 086 private Optional<ByteSource> upload = absent(); 087 private boolean followRedirects = true; 088 private HttpMethod requestMethod = HttpMethod.GET; 089 private Optional<File> outputFile = absent(); 090 private Charset charset = UTF_8; 091 private boolean ignoreSecurity = false; 092 private boolean silent = true; 093 private List<NameValue> data = newArrayList(); 094 private Range<Integer> keepTryingRange = SERVER_ERROR.getRange(); 095 private Optional<SecurityContext> security = absent(); 096 private boolean cacheResponseInMemory = true; 097 private boolean printResponseToStdout = false; 098 private List<HeaderPair> headers = newArrayList(); 099 private Optional<String> contentType = absent(); 100 101 private static HttpOptions validate(HttpOptions instance) { 102 checkNoNulls(instance); 103 checkMin(instance.maxBytes, 0, "maxBytes"); 104 checkMin(instance.maxTimeMillis, 0, "maxTimeMillis"); 105 checkMin(instance.connectTimeoutMillis, 0, "connectTimeoutMillis"); 106 checkMin(instance.retryCount, 0, "retryCount"); 107 checkMin(instance.retryDelayMillis, 0, "retryDelayMillis"); 108 return instance; 109 } 110 111 public Builder withContentType(Optional<String> contentType) { 112 this.contentType = contentType; 113 return this; 114 } 115 116 public Builder withContentType(String contentType) { 117 return withContentType(Optional.of(contentType)); 118 } 119 120 public Builder withHeaders(List<HeaderPair> headers) { 121 this.headers = headers; 122 return this; 123 } 124 125 @JsonSetter 126 public Builder withSecurity(Optional<SecurityContext> security) { 127 this.security = security; 128 return this; 129 } 130 131 public Builder withSecurity(SecurityContext security) { 132 return withSecurity(Optional.of(security)); 133 } 134 135 public Builder withCacheResponseInMemory(boolean cacheResponseInMemory) { 136 this.cacheResponseInMemory = cacheResponseInMemory; 137 return this; 138 } 139 140 public Builder cacheResponseInMemory() { 141 return withCacheResponseInMemory(true); 142 } 143 144 public Builder withPrintResponseToStdout(boolean printResponseToStdout) { 145 this.printResponseToStdout = printResponseToStdout; 146 return this; 147 } 148 149 public Builder printResponseToStdout() { 150 return withPrintResponseToStdout(true); 151 } 152 153 @JsonSetter 154 public Builder withOutputFile(Optional<File> outputFile) { 155 this.outputFile = outputFile; 156 return this; 157 } 158 159 public Builder withOutputFile(File outputFile) { 160 return withOutputFile(Optional.of(outputFile)); 161 } 162 163 public Builder withKeepTryingRange(Range<Integer> keepTryingRange) { 164 this.keepTryingRange = keepTryingRange; 165 return this; 166 } 167 168 public Builder withData(List<NameValue> data) { 169 this.data = data; 170 return this; 171 } 172 173 public Builder withSilent(boolean silent) { 174 this.silent = silent; 175 return this; 176 } 177 178 public Builder ignoreSecurity() { 179 return withIgnoreSecurity(true); 180 } 181 182 public Builder withIgnoreSecurity(boolean ignoreSecurity) { 183 this.ignoreSecurity = ignoreSecurity; 184 return this; 185 } 186 187 @JsonSetter 188 public Builder withMaxBytes(Optional<Long> maxBytes) { 189 this.maxBytes = maxBytes; 190 return this; 191 } 192 193 public Builder withMaxBytes(long maxBytes) { 194 return withMaxBytes(Optional.of(maxBytes)); 195 } 196 197 public Builder withCharset(Charset charset) { 198 this.charset = charset; 199 return this; 200 } 201 202 public Builder withEncoding(String encoding) { 203 return withCharset(Charset.forName(encoding)); 204 } 205 206 public Builder post() { 207 return withRequestMethod(POST); 208 } 209 210 public Builder delete() { 211 return withRequestMethod(DELETE); 212 } 213 214 public Builder put() { 215 return withRequestMethod(PUT); 216 } 217 218 public Builder withRequestMethod(HttpMethod requestMethod) { 219 this.requestMethod = requestMethod; 220 return this; 221 } 222 223 @JsonSetter 224 public Builder withRetryCount(Optional<Integer> retries) { 225 this.retryCount = retries; 226 return this; 227 } 228 229 public Builder withRetryCount(int retries) { 230 return withRetryCount(Optional.of(retries)); 231 } 232 233 public Builder withFollowRedirects(boolean followRedirects) { 234 this.followRedirects = followRedirects; 235 return this; 236 } 237 238 public Builder followRedirects() { 239 return withFollowRedirects(true); 240 } 241 242 @JsonSetter 243 public Builder withConnectTimeoutMillis(Optional<Integer> connectTimeoutMillis) { 244 this.connectTimeoutMillis = connectTimeoutMillis; 245 return this; 246 } 247 248 public Builder withConnectTimeoutMillis(int connectTimeoutMillis) { 249 return withConnectTimeoutMillis(Optional.of(connectTimeoutMillis)); 250 } 251 252 @JsonSetter 253 public Builder withMaxTimeMillis(Optional<Integer> maxTimeMillis) { 254 this.maxTimeMillis = maxTimeMillis; 255 return this; 256 } 257 258 public Builder withMaxTimeMillis(int maxTimeMillis) { 259 return withMaxTimeMillis(Optional.of(maxTimeMillis)); 260 } 261 262 @JsonSetter 263 public Builder withRetryDelayMillis(Optional<Integer> retryDelayMillis) { 264 this.retryDelayMillis = retryDelayMillis; 265 return this; 266 } 267 268 public Builder withRetryDelayMillis(int retryDelayMillis) { 269 return withRetryDelayMillis(Optional.of(retryDelayMillis)); 270 } 271 272 @JsonSetter 273 public Builder withUpload(Optional<ByteSource> upload) { 274 this.upload = upload; 275 return this; 276 } 277 278 public Builder withUpload(ByteSource upload) { 279 return withUpload(Optional.of(upload)); 280 } 281 282 public Builder upload(File file) { 283 return withUpload(asByteSource(file)); 284 } 285 286 public Builder upload(String content, Charset charset) { 287 return withUpload(wrap(content.getBytes(charset))); 288 } 289 290 @Override 291 public HttpOptions build() { 292 return validate(new HttpOptions(this)); 293 } 294 295 } 296 297 public Optional<Integer> getMaxTimeMillis() { 298 return maxTimeMillis; 299 } 300 301 public Optional<Integer> getConnectTimeoutMillis() { 302 return connectTimeoutMillis; 303 } 304 305 public Optional<Integer> getRetries() { 306 return retryCount; 307 } 308 309 public Optional<Integer> getRetryDelayMillis() { 310 return retryDelayMillis; 311 } 312 313 public Optional<ByteSource> getUpload() { 314 return upload; 315 } 316 317 public boolean isFollowRedirects() { 318 return followRedirects; 319 } 320 321 public HttpMethod getMethod() { 322 return requestMethod; 323 } 324 325 public Optional<Integer> getRetryCount() { 326 return retryCount; 327 } 328 329 public HttpMethod getRequestMethod() { 330 return requestMethod; 331 } 332 333 public Optional<Long> getMaxBytes() { 334 return maxBytes; 335 } 336 337 public boolean isIgnoreSecurity() { 338 return ignoreSecurity; 339 } 340 341 public boolean isSilent() { 342 return silent; 343 } 344 345 public List<NameValue> getData() { 346 return data; 347 } 348 349 public Charset getCharset() { 350 return charset; 351 } 352 353 public Range<Integer> getKeepTryingRange() { 354 return keepTryingRange; 355 } 356 357 public Optional<File> getOutputFile() { 358 return outputFile; 359 } 360 361 public boolean isCacheResponseInMemory() { 362 return cacheResponseInMemory; 363 } 364 365 public Optional<SecurityContext> getSecurity() { 366 return security; 367 } 368 369 public boolean isPrintResponseToStdout() { 370 return printResponseToStdout; 371 } 372 373 public List<HeaderPair> getHeaders() { 374 return headers; 375 } 376 377 public Optional<String> getContentType() { 378 return contentType; 379 } 380 381}