Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.testfabrik.webmate.javasdk;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Optional;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
/**
* API client for interacting with the webmate API.
*/
public class WebmateApiClient {
protected static final long MAX_WAITING_TIME_MILLIS = 300_000; // 5 Minutes
protected static final long MAX_LONG_WAITING_TIME_MILLIS = 600_000; // 10 Minutes
protected static final long MAX_SHORT_WAITING_TIME_MILLIS = 60_000; // 1 Minute
protected static final long WAITING_POLLING_INTERVAL_MILLIS = 3_000; // 3 seconds
protected static final long WAITING_SHORT_POLLING_INTERVAL_MILLIS = 1_000; // 3 seconds
protected static final long WAITING_LONG_POLLING_INTERVAL_MILLIS = 20_000; // 20 seconds
private final static Logger LOG = LoggerFactory.getLogger(WebmateApiClient.class);
private final static String WEBMATE_JAVASDK_USERAGENT = "webmate-javasdk";
private final static String WEBMATE_USER_HEADERKEY = "webmate.user";
private final static String WEBMATE_APITOKEN_HEADERKEY = "webmate.api-token";
private final HttpClient httpClient;
private final HttpClientBuilder httpClientBuilder;
private final WebmateAuthInfo authInfo;
private final WebmateEnvironment environment;
/**
* Constructor for WebmateAPIClient. Uses default HTTP connection strategy.
*
* @param authInfo webmate authentication information
* @param environment webmate environment to be used.
*/
public WebmateApiClient(WebmateAuthInfo authInfo, WebmateEnvironment environment) {
this(authInfo, environment, HttpClientBuilder.create());
}
/**
* Constructor for WebmateAPIClient that takes an additional client builder if the user needs more
* influence over the HTTP connection.
*
* @param authInfo webmate authentication information
* @param environment webmate environment to be used.
* @param httpClientBuilder Client builder used to create HTTP connections
*/
public WebmateApiClient(WebmateAuthInfo authInfo, WebmateEnvironment environment, HttpClientBuilder httpClientBuilder) {
this.httpClient = makeHttpClient(authInfo, environment, httpClientBuilder);
this.httpClientBuilder = httpClientBuilder;
this.authInfo = authInfo;
this.environment = environment;
}
/**
* Returns the configured and built HttpClient with default "application/json" content type header.
*
* @return Configured and built HttpClient.
*/
private HttpClient getHttpClient() {
return this.httpClient;
}
/**
* Creates a new HttpClient with the given content type header as default header.
* There is no easy mechanism to replace or override a default header. Therefore, we instantiate a
* new http client with the passed content type header. Another solution would be to create a
* custom HttpRequestInterceptor that handles http headers.
*
* @param contentType Content type header set as default header.
* @return New HttpClient to be used by Service clients.
*/
private HttpClient getHttpClientAndOverrideContentHeader(Header contentType) {
return makeHttpClient(this.authInfo, this.environment, this.httpClientBuilder, contentType);
}
/**
* Creates new HttpClient for interacting with webmate API.
*
* @param authInfo Authentication information (email address + token)
* @param environment API endpoint address
* @return New HttpClient to be used by Service clients.
*/
private static HttpClient makeHttpClient(WebmateAuthInfo authInfo, WebmateEnvironment environment,
HttpClientBuilder httpClientBuilder) {
return makeHttpClient(authInfo, environment, httpClientBuilder, new BasicHeader(HttpHeaders.CONTENT_TYPE,
"application/json"));
}
private static HttpClient makeHttpClient(WebmateAuthInfo authInfo, WebmateEnvironment environment,
HttpClientBuilder httpClientBuilder, Header contentType) {
List headers = new ArrayList<>();
headers.add(new BasicHeader(WEBMATE_USER_HEADERKEY, authInfo.emailAddress));
headers.add(new BasicHeader(WEBMATE_APITOKEN_HEADERKEY, authInfo.apiKey));
headers.add(contentType);
httpClientBuilder.setUserAgent(WEBMATE_JAVASDK_USERAGENT);
httpClientBuilder.setDefaultHeaders(headers);
return httpClientBuilder.build();
}
private void checkErrors(HttpResponse httpResponse, Optional endpointName) {
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode < 200 || statusCode >= 300) {
String entityContent;
try {
entityContent = EntityUtils.toString(httpResponse.getEntity());
} catch (IOException e) {
entityContent = "n/a";
}
if (endpointName.isPresent()) {
throw new WebmateApiClientException("An error occurred during '" + endpointName.get() + "' request: " +
httpResponse.getStatusLine().getReasonPhrase() + ": " + entityContent);
} else {
throw new WebmateApiClientException("An error occurred during request: " +
httpResponse.getStatusLine().getReasonPhrase() + ": " + entityContent);
}
}
}
protected UUID readUUIDFromResponse(HttpResponse res) throws IOException {
String json = EntityUtils.toString(res.getEntity());
ObjectMapper mapper = new ObjectMapper();
String imageIdStr = mapper.readValue(json, new TypeReference(){});
return UUID.fromString(imageIdStr);
}
/**
* Sends a Post to the Uri in schema using params to populate the schema. The body of the request is a Json Node.
*
* @param schema The Uri schema that will become the target of the Post
* @param params The params that should be used in the schema
* @param body The json node that is supposed to be sent in the body
* @return The response of the API
*/
public ApiResponse sendPOST(UriTemplate schema, Map params, JsonNode body) {
HttpResponse httpResponse = sendPOSTUnchecked(schema, params, body);
checkErrors(httpResponse, schema.name);
return new ApiResponse(httpResponse);
}
/**
* Sends a Post to the Uri in schema using params to populate the schema. The body of the request is empty.
*
* @param schema The Uri schema that will become the target of the Post
* @param params The params that should be used in the schema
* @return The response of the API
*/
public ApiResponse sendPOST(UriTemplate schema, Map params) {
HttpResponse httpResponse = sendPOSTUnchecked(schema, params);
checkErrors(httpResponse, schema.name);
return new ApiResponse(httpResponse);
}
/**
* Sends a Post to the Uri in schema using params to populate the schema. Once the schema is built, a query String
* will also be appended. The body of the request is empty.
*
* @param schema The Uri schema that will become the target of the Post
* @param params The params that should be used in the schema
* @param query The query String that should be appended
* @return The response of the API
*/
public ApiResponse sendPOST(UriTemplate schema, Map params, String query) {
HttpResponse httpResponse = sendPOSTUnchecked(schema, params, query);
checkErrors(httpResponse, schema.name);
return new ApiResponse(httpResponse);
}
/**
* Sends a Post to the Uri in schema using params to populate the schema. The body of the request is a Json Node.
* After template replacement the query string will be appended.
*
* @param schema The Uri schema that will become the target of the Post
* @param params The params that should be used in the schema
* @param query The query String that should be appended
* @param body The json node that is supposed to be sent in the body
* @return The response of the API
*/
public ApiResponse sendPOST(UriTemplate schema, Map params, String query, JsonNode body) {
HttpResponse httpResponse = sendPOSTUnchecked(schema, params, query, body);
checkErrors(httpResponse, schema.name);
return new ApiResponse(httpResponse);
}
/**
* Sends a Post to the Uri in schema using params to populate the schema. The body of the request is a byte array.
*
* @param schema The Uri schema that will become the target of the Post
* @param params The params that should be used in the schema
* @param byteParam The byte array that is supposed to be sent in the body
* @return The response of the API
*/
public ApiResponse sendPOST(UriTemplate schema, Map params, byte[] byteParam,
Optional contentType) {
HttpResponse httpResponse = sendPOSTUnchecked(schema, params, byteParam, contentType);
checkErrors(httpResponse, schema.name);
return new ApiResponse(httpResponse);
}
public ApiResponse sendPOST(UriTemplate schema, Map params, byte[] byteParam,
Optional contentType, List urlParams) {
HttpResponse httpResponse = sendPOSTUnchecked(schema, params, byteParam, contentType, urlParams);
checkErrors(httpResponse, schema.name);
return new ApiResponse(httpResponse);
}
protected HttpResponse sendPOSTUnchecked(UriTemplate schema, Map params, JsonNode body) {
try {
HttpPost req = new HttpPost(schema.buildUri(environment.baseURI, params));
req.setEntity(new StringEntity(body.toString(), "UTF-8"));
return sendPOSTUnchecked(this.getHttpClient(), req);
} catch (Exception e) {
throw new WebmateApiClientException("Error sending POST to webmate API", e);
}
}
protected HttpResponse sendPOSTUnchecked(UriTemplate schema, Map params, String query, JsonNode body) {
try {
HttpPost req = new HttpPost(schema.buildUri(environment.baseURI, params, query));
req.setEntity(new StringEntity(body.toString(), "UTF-8"));
return sendPOSTUnchecked(this.getHttpClient(), req);
} catch (Exception e) {
throw new WebmateApiClientException("Error sending POST to webmate API", e);
}
}
protected HttpResponse sendPOSTUnchecked(UriTemplate schema, Map params) {
HttpPost req = new HttpPost(schema.buildUri(environment.baseURI, params));
return sendPOSTUnchecked(this.getHttpClient(), req);
}
protected HttpResponse sendPOSTUnchecked(UriTemplate schema, Map params,
List urlParams) {
try {
HttpPost req = new HttpPost(schema.buildUri(environment.baseURI, params));
req.setEntity(new UrlEncodedFormEntity(urlParams));
return sendPOSTUnchecked(this.getHttpClient(), req);
} catch (IOException e) {
throw new WebmateApiClientException("Error sending POST to webmate API", e);
}
}
private HttpResponse sendPostUnchecked(byte[] byteParam, Optional contentType, HttpPost req) {
HttpClient httpClient;
if (contentType.isPresent()) {
req.setEntity(new ByteArrayEntity(byteParam, ContentType.create(contentType.get())));
httpClient = this.getHttpClientAndOverrideContentHeader(new BasicHeader(HttpHeaders.CONTENT_TYPE, contentType.get()));
} else {
req.setEntity(new ByteArrayEntity(byteParam));
httpClient = this.getHttpClient();
}
return sendPOSTUnchecked(httpClient, req);
}
protected HttpResponse sendPOSTUnchecked(UriTemplate schema, Map params, byte[] byteParam,
Optional contentType) {
HttpPost req = new HttpPost(schema.buildUri(environment.baseURI, params));
return sendPostUnchecked(byteParam, contentType, req);
}
protected HttpResponse sendPOSTUnchecked(UriTemplate schema, Map params, byte[] byteParam,
Optional contentType, List urlParams) {
HttpPost req = new HttpPost(schema.buildUri(environment.baseURI, params, urlParams));
return sendPostUnchecked(byteParam, contentType, req);
}
protected HttpResponse sendPOSTUnchecked(UriTemplate schema, Map params, String queryString) {
HttpPost req = new HttpPost(schema.buildUri(environment.baseURI, params, queryString));
return sendPOSTUnchecked(this.getHttpClient(), req);
}
protected HttpResponse sendPOSTUnchecked(HttpClient httpClient, HttpPost req) {
HttpResponse httpResponse;
try {
httpResponse = httpClient.execute(req);
// Buffer the response entity in memory, so we can release the connection safely
HttpEntity old = httpResponse.getEntity();
EntityUtils.updateEntity(httpResponse, new StringEntity(EntityUtils.toString(old)));
req.releaseConnection();
} catch (IOException e) {
throw new WebmateApiClientException("Error sending POST to webmate API", e);
}
return httpResponse;
}
public ApiResponse sendPUT(UriTemplate schema, Map params, JsonNode body) {
HttpResponse httpResponse = sendPUTUnchecked(schema, params, body);
checkErrors(httpResponse, schema.name);
return new ApiResponse(httpResponse);
}
protected HttpResponse sendPUTUnchecked(UriTemplate schema, Map params, JsonNode body) {
try {
HttpPut req = new HttpPut(schema.buildUri(environment.baseURI, params));
req.setEntity(new StringEntity(body.toString(), "UTF-8"));
return sendPUTUnchecked(this.getHttpClient(), req);
} catch (Exception e) {
throw new WebmateApiClientException("Error sending PUT to webmate API", e);
}
}
protected HttpResponse sendPUTUnchecked(HttpClient httpClient, HttpPut req) {
HttpResponse httpResponse;
try {
httpResponse = httpClient.execute(req);
// Buffer the response entity in memory, so we can release the connection safely
HttpEntity old = httpResponse.getEntity();
EntityUtils.updateEntity(httpResponse, new StringEntity(EntityUtils.toString(old)));
req.releaseConnection();
} catch (IOException e) {
throw new WebmateApiClientException("Error sending PUT to webmate API", e);
}
return httpResponse;
}
public ApiResponse sendGET(UriTemplate schema, Map params) {
HttpResponse httpResponse = sendGETUnchecked(schema, params);
checkErrors(httpResponse, schema.name);
return new ApiResponse(httpResponse);
}
public ApiResponse sendGET(UriTemplate schema, Map params, List queryParams) {
HttpResponse httpResponse = sendGETUnchecked(schema, params, queryParams);
checkErrors(httpResponse, schema.name);
return new ApiResponse(httpResponse);
}
protected HttpResponse sendGETUnchecked(UriTemplate schema, Map params) {
return sendGETUnchecked(schema, params, null);
}
protected HttpResponse sendGETUnchecked(UriTemplate schema, Map params, List queryParams) {
HttpResponse httpResponse;
try {
HttpGet req;
if (queryParams != null) {
req = new HttpGet(schema.buildUri(environment.baseURI, params, queryParams));
} else {
req = new HttpGet(schema.buildUri(environment.baseURI, params));
}
httpResponse = this.getHttpClient().execute(req);
// Buffer the response entity in memory, so we can release the connection safely
HttpEntity old = httpResponse.getEntity();
EntityUtils.updateEntity(httpResponse, new StringEntity(EntityUtils.toString(old)));
req.releaseConnection();
} catch (IOException e) {
throw new WebmateApiClientException("Error sending GET to webmate API", e);
}
return httpResponse;
}
/**
* Sends an HTTP DELETE to the Uri in schema using params to populate the schema. The body of the request is empty.
*
* @param schema The Uri schema that will become the target of the Post
* @param params The params that should be used in the schema
* @return The response of the API
*/
public ApiResponse sendDELETE(UriTemplate schema, Map params) {
HttpResponse httpResponse;
try {
HttpDelete req = new HttpDelete(schema.buildUri(environment.baseURI, params));
httpResponse = this.getHttpClient().execute(req);
// Buffer the response entity in memory, so we can release the connection safely
HttpEntity old = httpResponse.getEntity();
EntityUtils.updateEntity(httpResponse, new StringEntity(EntityUtils.toString(old)));
req.releaseConnection();
} catch (IOException e) {
throw new WebmateApiClientException("Error sending DELETE to webmate API", e);
}
checkErrors(httpResponse, schema.name);
return new ApiResponse(httpResponse);
}
/**
* Template for API URI, e.g. "/browsersessions/${browserSessionId}"
*/
protected static class UriTemplate {
public final Optional name;
public final String schema;
public final Map templateParams;
public UriTemplate(String name, String schema, Map templateParams) {
this.name = Optional.fromNullable(name);
this.schema = schema;
this.templateParams = templateParams;
}
public UriTemplate(String schema, Map templateParams) {
this.name = Optional.absent();
this.schema = schema;
this.templateParams = templateParams;
}
public UriTemplate(String schema) {
this(schema, new HashMap());
}
public UriTemplate(String name, String schema) {
this(name, schema, new HashMap());
}
private static String replaceParamsInTemplate(String template, Map params) {
final String paramPrologue = "${";
final String paramEpilogue = "}";
for (String paramKey : params.keySet()) {
template = template.replace(paramPrologue + paramKey + paramEpilogue, params.get(paramKey));
}
if (template.contains(paramPrologue)) { // there should be no parameters left
final String errorMsg = "At least one parameter of [" + params.keySet() + "] could not be matched in schema " + template;
LOG.error(errorMsg);
throw new WebmateApiClientException(errorMsg);
}
return template;
}
URI buildUri(URI baseUri, Map params) {
String schemaAfterReplacements = replaceParamsInTemplate(schema, params);
URIBuilder builder = new URIBuilder();
builder.setScheme(baseUri.getScheme());
return buildUriWithBuilder(baseUri, params, schemaAfterReplacements, builder);
}
URI buildUri(URI baseUri, Map params, String query) {
String schemaAfterReplacements = replaceParamsInTemplate(schema, params);
URIBuilder builder = new URIBuilder();
builder.setScheme(baseUri.getScheme());
builder.setCustomQuery(query);
return buildUriWithBuilder(baseUri, params, schemaAfterReplacements, builder);
}
URI buildUri(URI baseUri, Map params, List queryParams) {
String schemaAfterReplacements = replaceParamsInTemplate(schema, params);
URIBuilder builder = new URIBuilder();
builder.setScheme(baseUri.getScheme());
builder.addParameters(queryParams);
return buildUriWithBuilder(baseUri, params, schemaAfterReplacements, builder);
}
private URI buildUriWithBuilder(URI baseUri, Map params, String schemaAfterReplacements, URIBuilder builder) {
builder.setHost(baseUri.getHost());
builder.setPort(baseUri.getPort());
String path = baseUri.normalize().getPath() + schemaAfterReplacements;
builder.setPath(path.replaceAll("//", "/")); // Replace double slashes
for (String templateParamKey : templateParams.keySet()) {
String templateParamKeyAfterReplacements = replaceParamsInTemplate(templateParamKey, params);
String templateParamValueAfterReplacements = replaceParamsInTemplate(templateParams.get(templateParamKey), params);
builder.setParameter(templateParamKeyAfterReplacements, templateParamValueAfterReplacements);
}
URI result;
try {
result = builder.build();
} catch (URISyntaxException e) {
throw new WebmateApiClientException("Could not build valid API URL", e);
}
return result;
}
}
public static class ApiResponse {
private final Optional optHttpResponse;
public ApiResponse(HttpResponse httpResponse) {
this.optHttpResponse = Optional.fromNullable(httpResponse);
}
public Optional getOptHttpResponse() {
return optHttpResponse;
}
}
}