Clients and Connections
A FilesClient holds everything its requests need: the API root of your site, credentials, a
workspace, time limits, retries and the connections its requests use. Build one with
FilesClient.builder(), reach each resource's operations from it, such as client.users(), and
close it when you are done.
Its settings never change once it is built, so several clients, for different users, sites or
workspaces, can work at the same time. What a client returns keeps using that client and the
request options it was requested with: saving a returned User, or loading the next page of a
listing, sends the same credentials to the same site, whatever you change afterward. A client is
safe to use from many threads.
The Static Methods
The static methods, such as User.list(), use FilesClient.defaultClient(): a client with the
static settings FilesClient.apiKey, FilesClient.session, FilesClient.workspaceId,
FilesClient.language and the FilesClient.setProperty properties as they are when each call is
made. Objects and listings the static methods return keep the settings they were requested
with, so changing FilesClient.apiKey later affects only later calls. The default client reads
maxNetworkRetries (or upstreamMaxAttempts), initialRetryDelayMillis and
maximumRetrySeconds again before each attempt of a request, so a change also reaches a request
already retrying; uploads and downloads keep the values they started with.
An object you construct yourself, such as new User(attributes), uses the default client until
you give it another with setClient.
Request Options
Each operation also takes a map of request options for that one call:
api_keyorsession_idauthenticates with other credentials.workspace_idacts in another workspace;nullsends none.api_rootsends the call to another site, such ashttps://OTHER-SUBDOMAIN.files.com; the client's own API root does not change.cancellationis aCancellationTokenthat stops the call.timeoutis ajava.time.Duration: the time limit of the call, across all its attempts.max_retriesis anIntegerthat replaces the client's retry limit.
The maps you pass are copied, so changing them afterward changes nothing. Objects a call
returns keep its api_key, session_id, workspace_id and api_root; a listing also keeps the
other options for the pages it requests.
Retries
A request that fails in a way that may be temporary is sent again, up to maxRetries times
(3 by default, and 0 to send each request once): after a connection or read failure, HTTP 429,
HTTP 502 or above, or HTTP 500 in answer to a GET. HTTP 501 is never retried, and neither is
HTTP 500 in answer to another method. The first retry waits retryDelay (100 ms), and each later one
twice as long as the one before, up to maxRetryDelay (10 seconds). After HTTP 429 or 503, a
longer Retry-After within that maximum is waited instead.
A request is not retried when it cannot be sent as written, such as a URL without a host or with a scheme other than HTTP or HTTPS, when the server's certificate or name does not verify, or when its redirects loop or go past the limit. Other TLS and protocol failures are retried. A retried request that changes data may take effect twice when an earlier attempt reached Files.com but its answer was lost.
A retry is logged at WARN with its number, its wait and why it was needed, such as
Retrying the GET request (retry 1 of 3) in 100 ms after HTTP status 503. A failure without a
response is described by its kind, such as the connection could not be made (ConnectException),
in logs and in the exception's message; the message of the underlying exception, which can repeat
URLs or other details, is logged only at DEBUG. The exception's message then names the request
by its method and path, without its query or host, such as (response to GET /api/rest/v1/users/1),
as does the message of an error response without a structured error.
Site Regions
Some sites must be reached through a server of their own. When Files.com answers a request with
a not-authenticated/lockout-region-mismatch error naming that server, the client sends the
request there instead, as one of its retries, and sends the rest of that call's requests there,
such as those of an upload. When the request used the client's own credentials, the client keeps
sending its later requests there too; a call with its own api_key or session_id, or one that
creates a session, moves only itself, and the next such call starts at the client's server
again, unless it continues an upload, with the same options, from the part that call returned,
as FileUploadPart.putInputStream does. By default it does so only for Files.com's own servers,
whose names end in files.com, over HTTPS; the credentials never go anywhere else.
RegionRelocationPolicy.DISABLED reports the error instead, as LockoutRegionMismatchException,
and a policy of your own can approve your custom domain. For the static methods, set the
regionRelocation property to false to disable it.
Time Limits and Cancellation
A client waits up to connectTimeout (30 seconds) to connect, readTimeout (80 seconds) for
the next bytes of a response, both while waiting for its headers and while reading its body,
and connectionAcquisitionTimeout (10 seconds) for a connection from its pool. callTimeout,
or the timeout request option, limits a whole call, its retries and waits included.
A call stops when its CancellationToken is cancelled, its time limit passes, the thread
making it is interrupted, or its client is closed. Its request is aborted, even while it waits
for the server or reads a response, and the call throws OperationCancelledException, whose
getReason() is CANCELLED, TIMED_OUT or INTERRUPTED. An interrupted thread keeps its
interrupt status, and a call made on a thread that is already interrupted stops at once.
One exception: a read of your own stream, such as an attachment's, cannot be interrupted in Java 8. The call stops as soon as that read returns.
Connections
Each client has an HttpTransport of its own, an Apache HttpClient with its connection pool,
unless you give it one to share. Give a client HttpTransport.builder() settings to configure
its own transport, which it closes when it is closed. Build a transport yourself and give it to
several clients to share its connections: closing a client leaves it open, and you close it once
no client uses it.
customize adjusts the Apache HttpClientBuilder, for a proxy, credentials for it,
interceptors for instrumentation or default headers. sslContext sets trusted certificates or a
client certificate; connectionManager uses a pool you manage. Whatever you customize, the SDK
turns off Apache's own retries, so each request stays within the client's retry limit, and it
removes Files.com credentials from every request, first or redirected, that is not sent to the
API root its call started at. It does so as each request is written to its connection, so replacing the HTTP
processor, request executor or redirect strategy does not change it.
Closing a client cancels its calls and transfers still running and waits for them to stop, even
if the closing thread is interrupted, which then keeps its interrupt status; a second close
waits the same way. A transfer blocked reading your own stream stops once that read returns. A
close from within a call or transfer, such as in a progress listener, cancels the same way but
returns at once, since the work it would wait for may be waiting for it. Afterward the client, and
what it returned, throw IllegalStateException for new requests.