use of com.okta.sdk.impl.http.support.DefaultRequest in project okta-sdk-java by okta.
the class DefaultDataStore method save.
@SuppressWarnings("unchecked")
private <T extends Resource, R extends Resource> R save(String href, final T resource, final T parentResource, HttpHeaders requestHeaders, final Class<? extends R> returnType, final QueryString qs, final boolean create) {
Assert.hasText(href, "href argument cannot be null or empty.");
Assert.notNull(resource, "resource argument cannot be null.");
Assert.notNull(returnType, "returnType class cannot be null.");
Assert.isInstanceOf(AbstractResource.class, resource);
Assert.isTrue(!CollectionResource.class.isAssignableFrom(resource.getClass()), "Collections cannot be persisted.");
final CanonicalUri uri = canonicalize(href, qs);
final AbstractResource abstractResource = (AbstractResource) resource;
// Most Okta endpoints do not support partial update, we can revisit in the future.
final Map<String, Object> props = resourceConverter.convert(abstractResource, false);
FilterChain chain = new DefaultFilterChain(this.filters, req -> {
CanonicalUri uri1 = req.getUri();
String href1 = uri1.getAbsolutePath();
QueryString qs1 = uri1.getQuery();
HttpHeaders httpHeaders = req.getHttpHeaders();
// if this is an Okta user, we must use a PUT and not a POST
HttpMethod method = HttpMethod.POST;
if (!create) {
method = HttpMethod.PUT;
}
InputStream body;
long length = 0;
if (resource instanceof VoidResource) {
body = new ByteArrayInputStream(new byte[0]);
} else {
ByteArrayOutputStream bodyOut = new ByteArrayOutputStream();
mapMarshaller.marshal(bodyOut, req.getData());
body = new ByteArrayInputStream(bodyOut.toByteArray());
length = bodyOut.size();
}
Request request = new DefaultRequest(method, href1, qs1, httpHeaders, body, length);
Response response = execute(request);
Map<String, Object> responseBody = getBody(response);
if (Collections.isEmpty(responseBody)) {
// Okta response with 200 for deactivate requests (i.e. /api/v1/apps/<id>/lifecycle/deactivate)
if (response.getHttpStatus() == 202 || response.getHttpStatus() == 200 || response.getHttpStatus() == 204) {
// 202 means that the request has been accepted for processing, but the processing has not been completed. Therefore we do not have a response body.
responseBody = java.util.Collections.emptyMap();
} else {
throw new IllegalStateException("Unable to obtain resource data from the API server.");
}
}
ResourceAction responseAction = getPostAction(req, response);
return new DefaultResourceDataResult(responseAction, uri1, returnType, responseBody);
});
ResourceAction action = create ? ResourceAction.CREATE : ResourceAction.UPDATE;
ResourceDataRequest request = new DefaultResourceDataRequest(action, uri, canonicalizeParent(parentResource), returnType, getResourceClass(parentResource), props, requestHeaders);
ResourceDataResult result = chain.filter(request);
Map<String, Object> data = result.getData();
// ensure the caller's argument is updated with what is returned from the server if the types are the same:
if (returnType.isAssignableFrom(abstractResource.getClass())) {
abstractResource.setInternalProperties(data);
}
return resourceFactory.instantiate(returnType, data);
}
use of com.okta.sdk.impl.http.support.DefaultRequest in project okta-sdk-java by okta.
the class DefaultDataStore method getResourceData.
@SuppressWarnings("unchecked")
private ResourceDataResult getResourceData(String href, Class<? extends Resource> clazz, Map<String, ?> queryParameters) {
Assert.hasText(href, "href argument cannot be null or empty.");
Assert.notNull(clazz, "Resource class argument cannot be null.");
FilterChain chain = new DefaultFilterChain(this.filters, req -> {
CanonicalUri uri = req.getUri();
Request getRequest = new DefaultRequest(HttpMethod.GET, uri.getAbsolutePath(), uri.getQuery());
Response getResponse = execute(getRequest);
Map<String, ?> body = getBody(getResponse);
if (Collections.isEmpty(body)) {
throw new IllegalStateException("Unable to obtain resource data from the API server or from cache.");
}
return new DefaultResourceDataResult(req.getAction(), uri, req.getResourceClass(), (Map<String, Object>) body);
});
CanonicalUri uri = canonicalize(href, queryParameters);
ResourceDataRequest req = new DefaultResourceDataRequest(ResourceAction.READ, uri, clazz, new HashMap<>());
return chain.filter(req);
}
use of com.okta.sdk.impl.http.support.DefaultRequest in project okta-sdk-java by okta.
the class HttpClientRequestExecutor method executeRequest.
@Override
public Response executeRequest(Request request) throws RestException {
Assert.notNull(request, "Request argument cannot be null.");
int retryCount = 0;
URI redirectUri = null;
HttpEntity entity = null;
RestException exception = null;
// Make a copy of the original request params and headers so that we can
// permute them in the loop and start over with the original every time.
QueryString originalQuery = new QueryString();
originalQuery.putAll(request.getQueryString());
HttpHeaders originalHeaders = new HttpHeaders();
originalHeaders.putAll(request.getHeaders());
while (true) {
if (redirectUri != null) {
request = new DefaultRequest(request.getMethod(), redirectUri.toString(), null, null, request.getBody(), request.getHeaders().getContentLength());
}
if (retryCount > 0) {
request.setQueryString(originalQuery);
request.setHeaders(originalHeaders);
}
// Sign the request
this.requestAuthenticator.authenticate(request);
HttpRequestBase httpRequest = this.httpClientRequestFactory.createHttpClientRequest(request, entity);
if (httpRequest instanceof HttpEntityEnclosingRequest) {
entity = ((HttpEntityEnclosingRequest) httpRequest).getEntity();
}
HttpResponse httpResponse = null;
try {
// before executing the request below.
if (retryCount > 0 && redirectUri == null) {
pauseExponentially(retryCount, exception);
if (entity != null) {
InputStream content = entity.getContent();
if (content.markSupported()) {
content.reset();
}
}
}
// reset redirectUri so that if there is an exception, we will pause on retry
redirectUri = null;
exception = null;
retryCount++;
httpResponse = httpClient.execute(httpRequest);
if (isRedirect(httpResponse)) {
Header[] locationHeaders = httpResponse.getHeaders("Location");
String location = locationHeaders[0].getValue();
log.debug("Redirecting to: {}", location);
redirectUri = URI.create(location);
httpRequest.setURI(redirectUri);
} else {
Response response = toSdkResponse(httpResponse);
int httpStatus = response.getHttpStatus();
if (httpStatus == 429) {
throw new RestException("HTTP 429: Too Many Requests. Exceeded request rate limit in the allotted amount of time.");
}
if ((httpStatus == 503 || httpStatus == 504) && retryCount <= this.numRetries) {
// allow the loop to continue to execute a retry request
continue;
}
return response;
}
} catch (Throwable t) {
log.warn("Unable to execute HTTP request: ", t.getMessage(), t);
if (t instanceof RestException) {
exception = (RestException) t;
}
if (!shouldRetry(httpRequest, t, retryCount)) {
throw new RestException("Unable to execute HTTP request: " + t.getMessage(), t);
}
} finally {
try {
httpResponse.getEntity().getContent().close();
} catch (Throwable ignored) {
// NOPMD
}
}
}
}
use of com.okta.sdk.impl.http.support.DefaultRequest in project okta-sdk-java by okta.
the class DefaultDataStore method doDelete.
private void doDelete(String resourceHref, Class resourceClass, final String possiblyNullPropertyName) {
Assert.hasText(resourceHref, "This resource does not have an href value, therefore it cannot be deleted.");
// if this URL is a partial, then we MUST add the baseUrl
if (resourceHref.startsWith("/")) {
resourceHref = qualify(resourceHref);
}
final String requestHref;
if (Strings.hasText(possiblyNullPropertyName)) {
// delete just that property, not the entire resource:
requestHref = resourceHref + "/" + possiblyNullPropertyName;
} else {
requestHref = resourceHref;
}
FilterChain chain = new DefaultFilterChain(this.filters, request -> {
Request deleteRequest = new DefaultRequest(HttpMethod.DELETE, requestHref);
execute(deleteRequest);
// delete requests have HTTP 204 (no content), so just create an empty body for the result:
return new DefaultResourceDataResult(request.getAction(), request.getUri(), request.getResourceClass(), new HashMap<String, Object>());
});
final CanonicalUri resourceUri = canonicalize(resourceHref, null);
ResourceDataRequest request = new DefaultResourceDataRequest(ResourceAction.DELETE, resourceUri, resourceClass, new HashMap<String, Object>());
chain.filter(request);
}
Aggregations