All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.captaingoldfish.scim.sdk.client.response.ServerResponse Maven / Gradle / Ivy

There is a newer version: 1.26.0
Show newest version
// Generated by delombok at Sat Oct 07 17:30:34 CEST 2023
package de.captaingoldfish.scim.sdk.client.response;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import de.captaingoldfish.scim.sdk.client.http.HttpResponse;
import de.captaingoldfish.scim.sdk.common.constants.AttributeNames;
import de.captaingoldfish.scim.sdk.common.constants.SchemaUris;
import de.captaingoldfish.scim.sdk.common.resources.base.ScimObjectNode;
import de.captaingoldfish.scim.sdk.common.response.ErrorResponse;
import de.captaingoldfish.scim.sdk.common.utils.JsonHelper;


/**
 * represents a response from the server
*
* create at: 01.05.2020 * * @author Pascal Knüppel */ public class ServerResponse { @java.lang.SuppressWarnings("all") private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ServerResponse.class); /** * the original http response object */ private final HttpResponse httpResponse; /** * if the response was succesful */ private final boolean success; /** * the resource that should represent this response */ private T resource; /** * will be instantiated if the field {@link #success} is false and {@link #isValidScimResponse()} is true */ private ErrorResponse errorResponse; /** * if this response is a valid scim response */ private Boolean validScimResponse; /** * the expected response type */ private Class type; /** * an implementation provided by a request builder that tells this response if the response body may be parsed * into a resource object */ private Function isResponseParseable; /** * these headers are expected within the response in order to make sure that the content-type of a response * matches a scim response */ private Map requiredResponseHeaders; public ServerResponse(HttpResponse httpResponse, boolean expectedResponseCode, Class type, Function isResponseParseable, Map requiredResponseHeaders) { this.httpResponse = httpResponse; this.requiredResponseHeaders = requiredResponseHeaders; this.success = expectedResponseCode && isValidScimResponse(); this.type = type; this.isResponseParseable = isResponseParseable; } /** * tries to resolve the returned resource as scim object * * @return the parsed resource that should be returned * @throws de.captaingoldfish.scim.sdk.common.exceptions.IOException if the response body is not a valid json * document */ public T getResource() { boolean isSuccessResponse = resource == null && success && StringUtils.isNotBlank(getResponseBody()) && isValidScimResponse(); Boolean result = isResponseParseable.apply(httpResponse); boolean isParseable = result != null && result; if (isParseable || isSuccessResponse) { resource = getResource(type); } return resource; } /** * tries to resolve the returned resource as scim object * * @param responseType the type of the node which might be of type * {@link de.captaingoldfish.scim.sdk.common.resources.User}, * {@link de.captaingoldfish.scim.sdk.common.resources.Group}, * {@link de.captaingoldfish.scim.sdk.common.response.BulkResponse} or any other type that extends * {@link ScimObjectNode} * @return the parsed resource that should be returned * @throws de.captaingoldfish.scim.sdk.common.exceptions.IOException if the response body is not a valid json * document */ public R getResource(Class responseType) { return JsonHelper.readJsonDocument(getResponseBody(), responseType); } /** * if this response is a valid scim response */ public boolean isValidScimResponse() { if (validScimResponse == null) { validScimResponse = doesHeaderMapContain(getHttpHeaders(), requiredResponseHeaders) && ((getResponseBody() != null && JsonHelper.isValidJson(getResponseBody())) || getResponseBody() == null); } return validScimResponse; } /** * will be instantiated if the response contains a scim json structure with a schemas-element that contains * the value {@link SchemaUris#ERROR_URI} */ public ErrorResponse getErrorResponse() { if (errorResponse == null && !success && StringUtils.isNotBlank(getResponseBody()) && isValidScimResponse() && isUriInSchemasElement(SchemaUris.ERROR_URI)) { errorResponse = JsonHelper.readJsonDocument(getResponseBody(), ErrorResponse.class); } return errorResponse; } /** * the headers of the response */ public Map getHttpHeaders() { return httpResponse.getResponseHeaders(); } /** * the body of the response */ public String getResponseBody() { return httpResponse.getResponseBody(); } /** * the status code of the response */ public int getHttpStatus() { return httpResponse.getHttpStatusCode(); } /** * checks (with a case-insensitive check on the given header name) that the value is equal to the expected * value * * @param headerName the header name that should be present * @param expectedValue the value that should be found under the given header * @return true if the header exists, false else */ private boolean doesHeaderMapContain(Map httpHeaders, Map expectedHttpHeaders) { boolean allHeadersPresent = true; for ( Map.Entry keyValue : expectedHttpHeaders.entrySet() ) { String headerName = keyValue.getKey(); String expectedValue = keyValue.getValue(); List headerNameList = httpHeaders.keySet() .stream() .filter(name -> name.equalsIgnoreCase(headerName)) .collect(Collectors.toList()); if (headerNameList.size() > 1) { log.info("Could not validate header value for duplicate headerName found in response: {} -> {}", headerName, String.join(", ", headerNameList)); } boolean isHeaderPresent = headerNameList.size() == 1 && StringUtils.startsWithIgnoreCase(httpHeaders.get(headerNameList.get(0)), expectedValue); if (isHeaderPresent) { log.trace("Successfully validated {} header with value \'{}\'", headerName, expectedValue); } else { log.info("Expected header {} was not found in response \'{}\'", headerName, expectedValue); allHeadersPresent = false; } } return allHeadersPresent; } /** * checks if the given uri is in the schemas element of the current http response body * * @param uri the schema uri that should be present within the body * @return true, if the uri is present false else */ private boolean isUriInSchemasElement(String uri) { if (!isValidScimResponse() || StringUtils.isBlank(getResponseBody())) { return false; } ScimObjectNode scimObjectNode = JsonHelper.readJsonDocument(getResponseBody(), ScimObjectNode.class); ArrayNode schemasNode = (ArrayNode)scimObjectNode.get(AttributeNames.RFC7643.SCHEMAS); if (schemasNode == null || schemasNode.isEmpty()) { return false; } for ( JsonNode jsonNode : schemasNode ) { if (uri.equals(jsonNode.textValue())) { return true; } } return false; } /** * if the response was succesful */ @java.lang.SuppressWarnings("all") public boolean isSuccess() { return this.success; } /** * the expected response type */ @java.lang.SuppressWarnings("all") protected Class getType() { return this.type; } /** * these headers are expected within the response in order to make sure that the content-type of a response * matches a scim response */ @java.lang.SuppressWarnings("all") protected Map getRequiredResponseHeaders() { return this.requiredResponseHeaders; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy