com.amadeus.HTTPClient Maven / Gradle / Ivy
package com.amadeus;
import com.amadeus.client.AccessToken;
import com.amadeus.exceptions.NetworkException;
import com.amadeus.exceptions.ResponseException;
import com.amadeus.resources.Resource;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.logging.Logger;
import lombok.Getter;
/**
* The HTTP part of the Amadeus API client. See the Amadeus class for
* more details on initialization.
*/
public class HTTPClient {
// A cached copy of the Access Token. It will auto refresh for every bearerToken (if needed)
protected AccessToken accessToken = new AccessToken(this);
/**
* The configuration for this API client.
*/
private @Getter Configuration configuration;
protected HTTPClient(Configuration configuration) {
this.configuration = configuration;
}
/**
* A helper module for making generic GET requests calls. It is used by
* every namespaced API GET method.
*
* @see Amadeus#get(String, Params)
*/
public Response get(String path) throws ResponseException {
return request(HttpVerbs.GET, path, null,null);
}
/**
*
* A helper module for making generic GET requests calls. It is used by
* every namespaced API GET method.
*
*
*
* amadeus.referenceData.urls.checkinLinks.get(Params.with("airline", "1X"));
*
*
*
* It can be used to make any generic API call that is automatically
* authenticated using your API credentials:
*
*
*
* amadeus.get("/v2/reference-data/urls/checkin-links", Params.with("airline", "1X"));
*
*
* @param path The full path for the API call
* @param params The optional GET params to pass to the API
* @return a Response object containing the status code, body, and parsed data.
*/
public Response get(String path, Params params) throws ResponseException {
return request(HttpVerbs.GET, path, params, null);
}
/**
*
* A helper module for making generic DELETE requests calls. It is used by
* every namespaced API DELETE method.
*
*
*
* amadeus.booking.flightOrder("eJzTd9f3NjIJdzUGAAp%2fAiY=").delete();
*
*
*
* It can be used to make any generic API call that is automatically
* authenticated using your API credentials:
*
*
*
* amadeus.delete("/v1/foo/bar", Params.with("airline", "1X"));
*
*
* @param path The full path for the API call
* @param params The optional DELETE params to pass to the API
* @return a Response object containing the status code, body, and parsed data.
*/
public Response delete(String path, Params params) throws ResponseException {
return request(HttpVerbs.DELETE, path, params, null);
}
/**
* A helper module for making generic DELETE requests calls. It is used by
* every namespaced API DELETE method.
*
* @see Amadeus#delete(String, Params)
*/
public Response delete(String path) throws ResponseException {
return request(HttpVerbs.DELETE, path, null,null);
}
/**
* A helper module for making generic POST requests calls. It is used by
* every namespaced API POST method.
*
* @see Amadeus#post(String, Params)
*/
public Response post(String path) throws ResponseException {
return request(HttpVerbs.POST, path, null, null);
}
/**
*
* A helper module for making generic POST requests calls. It is used by
* every namespaced API POST method.
*
*
*
* amadeus.foo.bar.post(Params.with("airline", "1X"));
*
*
*
* It can be used to make any generic API call that is automatically
* authenticated using your API credentials:
*
*
*
* amadeus.post("/v1/foo/bar", Params.with("airline", "1X"));
*
*
* @param path The full path for the API call
* @param params The optional POST params to pass to the API
* @return a Response object containing the status code, body, and parsed data.
*/
public Response post(String path, Params params) throws ResponseException {
return request(HttpVerbs.POST, path, params, null);
}
/**
*
* A helper module for making generic POST requests calls. It is used by
* every namespaced API POST method.
*
*
*
* amadeus.foo.bar.post(Params.with("airline", "1X"));
*
*
*
* It can be used to make any generic API call that is automatically
* authenticated using your API credentials:
*
*
*
* amadeus.post("/v1/foo/bar", Params.with("airline", "1X"));
*
*
* @param path The full path for the API call
* @param body The optional POST params to pass to the API
* @return a Response object containing the status code, body, and parsed data.
*/
public Response post(String path, String body) throws ResponseException {
return request(HttpVerbs.POST, path, null, body);
}
/**
*
* A helper module for making generic POST requests calls. It is used by
* every namespaced API POST method.
*
*
*
* It can be used to make any generic API call that is automatically
* authenticated using your API credentials:
*
*
*
* amadeus.post("/v1/foo/bar", { "foo" : "bar" })
*
*
* @param path The full path for the API call
* @param body The POST JsonObject body to pass to the API
* @return a Response object containing the status code, body, and parsed data.
*/
public Response post(String path, JsonObject body) throws ResponseException {
return request(HttpVerbs.POST, path, null, body.toString());
}
/**
*
* A helper module for making generic POST requests calls. It is used by
* every namespaced API POST method.
*
*
*
* It can be used to make any generic API call that is automatically
* authenticated using your API credentials:
*
*
*
* amadeus.post("/v1/foo/bar", Params.with("airline", "1X"), { "foo" : "bar" })
*
*
* @param path The full path for the API call
* @param params The optional POST params to pass to the API
* @param body The POST JsonObject body to pass to the API
* @return a Response object containing the status code, body, and parsed data.
*/
public Response post(String path, Params params, JsonObject body) throws ResponseException {
return request(HttpVerbs.POST, path, params, body.toString());
}
/**
*
* A helper module for making generic POST requests calls. It is used by
* every namespaced API POST method.
*
*
*
* It can be used to make any generic API call that is automatically
* authenticated using your API credentials:
*
*
*
* amadeus.post("/v1/foo/bar", Params.with("airline", "1X"), { "foo" : "bar" })
*
*
* @param path The full path for the API call
* @param params The optional POST params to pass to the API
* @param body The POST String object body to pass to the API
* @return a Response object containing the status code, body, and parsed data.
*/
public Response post(String path, Params params, String body) throws ResponseException {
return request(HttpVerbs.POST, path, params, body);
}
/**
* A generic method for making any authenticated or unauthenticated request,
* passing in the bearer token explicitly. Used primarily by the
* AccessToken to get the first AccessToken.
*
* @hides as only used internally
*/
public Response unauthenticatedRequest(HttpVerbs verb, String path, Params params, String body,
String bearerToken) throws ResponseException {
Request request = buildRequest(verb, path, params, body, bearerToken);
log(request);
return execute(request);
}
/**
* Fetches the previous page for a given response.
* @param response a response object previously received for which includes an array of data
* @return a new response of data
* @throws ResponseException if the page could not be found
*/
public Response previous(Response response) throws ResponseException {
return page(Constants.PREVIOUS, response);
}
/**
* Fetches the previous page for a given response.
* @param resource one of the responses previously received from an API call
* @return a new array of resources of the same type
* @throws ResponseException if the page could not be found
*/
public Resource[] previous(Resource resource) throws ResponseException {
return page(Constants.PREVIOUS, resource);
}
/**
* Fetches the next page for a given response.
* @param response a response object previously received for which includes an array of data
* @return a new response of data
* @throws ResponseException if the page could not be found
*/
public Response next(Response response) throws ResponseException {
return page(Constants.NEXT, response);
}
/**
* Fetches the next page for a given response.
* @param resource one of the responses previously received from an API call
* @return a new array of resources of the same type
* @throws ResponseException if the page could not be found
*/
public Resource[] next(Resource resource) throws ResponseException {
return page(Constants.NEXT, resource);
}
/**
* Fetches the first page for a given response.
* @param response a response object previously received for which includes an array of data
* @return a new response of data
* @throws ResponseException if the page could not be found
*/
public Response first(Response response) throws ResponseException {
return page(Constants.FIRST, response);
}
/**
* Fetches the first page for a given response.
* @param resource one of the responses previously received from an API call
* @return a new array of resources of the same type
* @throws ResponseException if the page could not be found
*/
public Resource[] first(Resource resource) throws ResponseException {
return page(Constants.FIRST, resource);
}
/**
* Fetches the last page for a given response.
* @param response a response object previously received for which includes an array of data
* @return a new response of data
* @throws ResponseException if the page could not be found
*/
public Response last(Response response) throws ResponseException {
return page(Constants.LAST, response);
}
/**
* Fetches the last page for a given response.
* @param resource one of the responses previously received from an API call
* @return a new array of resources of the same type
* @throws ResponseException if the page could not be found
*/
public Resource[] last(Resource resource) throws ResponseException {
return page(Constants.LAST, resource);
}
// A generic method for making requests of any verb.
protected Response request(HttpVerbs verb, String path, Params params, String body)
throws ResponseException {
return unauthenticatedRequest(verb, path, params, body, accessToken.getBearerToken());
}
// Builds a request
protected Request buildRequest(HttpVerbs verb, String path, Params params, String body,
String bearerToken) {
return new Request(verb, path, params, body, bearerToken, this);
}
// A simple log that only triggers if we are in debug mode
private void log(Object object) {
if (getConfiguration().getLogLevel() == "debug") {
Logger logger = getConfiguration().getLogger();
logger.info(object.toString());
}
}
// Executes a request and return a Response
private Response execute(Request request) throws ResponseException {
Response response = new Response(fetch(request));
response.parse(this);
log(response);
response.detectError(this);
return response;
}
// Tries to make an API call. Raises an error if it can't complete the call.
private Request fetch(Request request) throws NetworkException {
try {
request.establishConnection();
write(request);
} catch (IOException e) {
throw new NetworkException(new Response(request));
}
return request;
}
// Writes the parameters to the request.
private void write(Request request) throws IOException {
final String encoding = "UTF-8";
// POST with access token + body + URL parameters
if (request.getVerb() == HttpVerbs.POST && request.getParams() != null
&& request.getBearerToken() != null) {
OutputStream os = request.getConnection().getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, encoding));
// writer.write(request.getParams().toQueryString());
if (request.getBody() != null) {
writer.write(request.getBody());
}
writer.flush();
writer.close();
os.close();
}
// POST with access without token (authentication call)
if (request.getVerb() == HttpVerbs.POST && request.getParams() != null
&& request.getBearerToken() == null) {
OutputStream os = request.getConnection().getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, encoding));
writer.write(request.getParams().toQueryString());
writer.flush();
writer.close();
os.close();
}
// POST with access token + body
if (request.getVerb() == HttpVerbs.POST && request.getParams() == null) {
OutputStream os = request.getConnection().getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, encoding));
if (request.getBody() != null) {
writer.write(request.getBody());
}
writer.flush();
writer.close();
os.close();
}
}
/**
* Fetches the response for another page.
* @hide as ony used internally
*/
protected Response page(String pageName, Response response) throws ResponseException {
JsonObject metaLinks = response.getResult().get("meta")
.getAsJsonObject().get("links").getAsJsonObject();
JsonElement pageElement = metaLinks.get(pageName);
if (pageElement == null) {
return null;
}
String[] parts = pageElement.getAsString().split("page%5Boffset%5D=");
String pageNumber = parts[1].split("&")[0];
Request request = response.getRequest();
Params params = (Params) request.getParams().clone();
params.put("page[offset]", pageNumber);
return request(request.getVerb(), request.getPath(), params, "emptyBody");
}
/**
* Fetches the response for another page.
* @hide as ony used internally
*/
protected Resource[] page(String pageName, Resource resource) throws ResponseException {
Response response = page(pageName, resource.getResponse());
return Resource.fromArray(response, resource.getDeSerializationClass());
}
}