EmissaryResponse.java
package emissary.client;
import emissary.client.response.BaseEntity;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MediaType;
import org.apache.commons.io.IOUtils;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import javax.annotation.Nullable;
@SuppressWarnings("AvoidObjectArrays")
public class EmissaryResponse {
private static final Logger logger = LoggerFactory.getLogger(EmissaryResponse.class);
final int status;
@Nullable
final Object content;
final String contentType;
final Header[] headers;
final ObjectMapper objectMapper = new ObjectMapper();
public EmissaryResponse(ClassicHttpResponse response) {
int tempStatus = response.getCode();
String tempContent;
headers = response.getHeaders();
Header[] contentHeaders = response.getHeaders(HttpHeaders.CONTENT_TYPE);
if (contentHeaders.length > 0) {
contentType = contentHeaders[0].getValue();
if (contentHeaders.length > 1) {
logger.warn("Too many content headers: {}", contentHeaders.length);
if (logger.isDebugEnabled()) {
Arrays.stream(contentHeaders).sequential().forEach(ch -> logger.debug("Header -> {}", ch));
}
}
} else {
logger.debug("No content type header, setting to plain text");
contentType = MediaType.TEXT_PLAIN;
}
try {
HttpEntity entity = response.getEntity();
if (entity == null) {
logger.debug("No entity");
tempContent = "";
} else {
tempContent = IOUtils.toString(entity.getContent(), StandardCharsets.UTF_8);
}
} catch (UnsupportedOperationException | IOException e) {
tempContent = e.getMessage();
tempStatus = 500;
logger.error("There was an issue generating the response", e);
}
logger.debug("response was: {} with content: {}", tempStatus, tempContent);
status = tempStatus;
content = tempContent;
}
public int getStatus() {
return status;
}
public Header[] getHeaders() {
return headers;
}
@Nullable
public String getContentString() {
if (content == null) {
return null;
}
if (status == HttpStatus.SC_OK) {
return content.toString();
} else {
return "Bad request -> status: " + status + " message: " + content;
}
}
public <T extends BaseEntity> T getContent(Class<T> mapper) {
if (content == null) {
return null;
}
try {
if (status == HttpStatus.SC_OK) {
return objectMapper.readValue(content.toString(), mapper);
} else {
return makeErrorEntity(content.toString(), mapper);
}
} catch (IOException e) {
logger.error("Error mapping object to {}", mapper.getCanonicalName(), e);
return makeErrorEntity(content.toString(), mapper);
}
}
private static <T extends BaseEntity> T makeErrorEntity(String msg, Class<T> mapper) {
T r = null;
try {
Object c = Class.forName(mapper.getName()).getDeclaredConstructor().newInstance();
r = mapper.cast(c);
} catch (ReflectiveOperationException e) {
logger.error("Problem creating new {}", mapper.getName(), e);
}
if (r != null) {
r.addError(msg);
}
return r;
}
public static class EmissaryResponseHandler implements HttpClientResponseHandler<EmissaryResponse> {
@Override
public EmissaryResponse handleResponse(ClassicHttpResponse response) throws IOException {
HttpEntity entity = response.getEntity();
EmissaryResponse er = new EmissaryResponse(response);
EntityUtils.consume(entity);
return er;
}
}
}