package org.mitre.rhex;
import edu.umd.cs.findbugs.annotations.NonNull;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
import org.jdom.Document;
import org.jdom.JDOMException;
import org.mitre.test.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
import java.util.List;
/**
* Test for document GET. This test assumes the patient document is an well-formed XML document.
*
* <pre>
* 6.5 baseURL/sectionpath/documentname
*
* 6.5.1 GET
*
* This operation returns a representation of the document that is identified by documentname
* within the section identified by sectionpath. The documentname is typically assigned by the
* underlying system and is not guaranteed to be identical across two different systems.
*
* Status Code: 200
* </pre>
*
* @author Jason Mathews, MITRE Corp.
* Date: 6/26/12 3:41 PM
*/
public class DocumentGet extends BaseXmlTest {
private URI documentURL;
private boolean dumped;
@NonNull
public String getId() {
return "6.5.1.1";
}
@NonNull
public String getName() {
return "GET operation returns a representation of the document that is identified by documentname in URL";
}
@NonNull
public List<Class<? extends TestUnit>> getDependencyClasses() {
return Collections.emptyList();
}
@Override
public boolean isRequired() {
return true;
}
@Override
public void execute() throws TestException {
final Context context = Loader.getInstance().getContext();
documentURL = context.getPropertyAsURI("document.url");
if (documentURL == null) {
// check pre-conditions and setup
log.error("Failed to specify valid document/url property in configuration");
setStatus(StatusEnumType.SKIPPED, "Failed to specify valid document/url property in configuration");
return;
}
String content = context.getString("document.content");
if (StringUtils.isBlank(content)) {
// check pre-conditions and setup
log.error("Failed to specify valid document/content property in configuration");
setStatus(StatusEnumType.SKIPPED, "Failed to specify valid document/content property in configuration");
return;
}
HttpClient client = context.getHttpClient();
HttpGet req = new HttpGet(documentURL);
req.setHeader("Accept", MIME_APPLICATION_XML);
if (log.isDebugEnabled()) {
System.out.println("\nURL: " + req.getURI());
for(Header header : req.getAllHeaders()) {
System.out.println(" " + header.getName() + ": " + header.getValue());
}
}
HttpResponse response = null;
try {
response = context.executeRequest(client, req);
validateContent(context, req, response, content);
setResponse(response);
setStatus(StatusEnumType.SUCCESS);
} catch (IOException e) {
if (response != null) dumpResponse(req, response, false);
throw new TestException(e);
} finally {
client.getConnectionManager().shutdown();
}
}
private void validateContent(Context context, HttpGet req, HttpResponse response, String content)
throws IOException, TestException
{
int code = response.getStatusLine().getStatusCode();
if (code != 200 || log.isDebugEnabled()) {
dumpResponse(req, response, false);
}
assertEquals(200, code);
final HttpEntity entity = response.getEntity();
if (entity == null) {
// no document body
dumpResponse(req, response, false);
log.error("no BODY in response for document: " + documentURL.getPath());
throw new TestException("encountered non-body in document response");
}
long len = entity.getContentLength();
if (len <= 0) {
dumpResponse(req, response, true);
throw new TestException("Document content length=" + len + ", expecting len > 0");
}
final String contentType = ClientHelper.getContentType(entity);
// expect content-type = text/xml OR application/xml OR application/atom+xml
if (!ClientHelper.isXmlContentType(contentType)) {
dumpResponse(req, response, true);
throw new TestException("expected XML content in response body: type=" + contentType);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
entity.writeTo(bos);
try {
String bodyText = bos.toString("UTF-8");
if (bodyText == null || !bodyText.contains(content)) {
log.error("Content:\n\t{}", bodyText);
throw new TestException("Failed to match expected content in response");
}
log.debug("XXX: expected content found in response:\n\t{}", bodyText); // success so far
Document doc = getDefaultDocument(context, bos);
if (keepDocument) setDocument(doc);
} catch (JDOMException e) {
if (!log.isDebugEnabled()) {
dumpResponse(req, response, false);
System.out.println("Response body:\n" + bos.toString());
}
addWarning(e.getMessage());
log.warn("", e);
}
}
protected void dumpResponse(HttpRequestBase req, HttpResponse response, boolean dumpEntity) {
if (!dumped) {
dumped = true;
if (!log.isDebugEnabled()) {
System.out.println("\nURL: " + req.getURI());
}
super.dumpResponse(req, response, dumpEntity);
}
}
public URI getDocumentURL() {
return documentURL;
}
}