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.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.message.BasicNameValuePair; import org.jdom.Document; import org.jdom.Element; import org.jdom.Namespace; import org.mitre.test.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Test for section creation * * <pre> * 6.2 Operations on the Base URL * * 6.2.2 POST � Parameters:extensionID, path, name * * This operation is used to create a new Section at the root of the document. * The request body is of type �application/xwww-form-urlencoded� and MUST contain * the extensionId, path, and name parameters. The extensionId parameter MAY be * a string that is equal to value of one of the registered <extension> nodes of * the root document of the HDR identified by baseURL. The path MUST be a string * that can be used as a URL path segment. If any parameters are incorrect or * not existent, the server MUST return a status code of 400. * * The system MUST confirm that there is no other section registered as a * child node that uses the same path name. If there is a collision, the * server <B>MUST</B> return a status code of 409. * * Status Code: 201, 400, 406, <B>409</B> * </pre> * * @author Jason Mathews, MITRE Corp. * Date: 2/20/12 10:45 AM */ public class CreateDuplicateSection extends BaseXmlTest { private String sectionPath; private String extensionId; public CreateDuplicateSection() { setProperty(BaseUrlRootXml.class, PROP_KEEP_DOCUMENT_BOOL, Boolean.TRUE); } @NonNull public String getId() { return "6.2.2.3"; } @Override public boolean isRequired() { // If there is a collision, the server *MUST* return a status code of 409 return true; } @NonNull public String getName() { return "If there is a collision in section creation, the server MUST return a status code of 409"; } @NonNull public List<Class<? extends TestUnit>> getDependencyClasses() { return Collections.<Class<? extends TestUnit>> singletonList(BaseUrlRootXml.class); // 6.3.1.1 } public void execute() throws TestException { // pre-conditions: for this test to be executed the prerequisite test BaseUrlRootXml must have passed // with 200 HTTP response and valid root.xml content. TestUnit baseTest = getDependency(BaseUrlRootXml.class); if (baseTest == null) { // assertion failed: this should never be null log.error("Failed to retrieve prerequisite test: BaseUrlRootXml"); setStatus(StatusEnumType.SKIPPED, "Failed to retrieve prerequisite test: 6.3.1.1"); return; } Document doc = ((BaseUrlRootXml)baseTest).getDocument(); if (doc == null) { log.error("Failed to retrieve prerequisite test results: BaseUrlRootXml"); setStatus(StatusEnumType.SKIPPED, "Failed to retrieve prerequisite test results: 6.3.1.1"); return; } /* expecting: <?xml version="1.0" encoding="UTF-8"?> <root xmlns="http://projecthdata.org/hdata/schemas/2009/06/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <extensions> <extension extensionId="1">http://projecthdata.org/extension/c32</extension> <extension extensionId="2">http://projecthdata.org/hdata/schemas/2009/06/allergy</extension> ... <extension extensionId="11">http://projecthdata.org/hdata/schemas/2009/06/social_history</extension> </extensions> ... </root> */ final Namespace ns = Namespace.getNamespace(NAMESPACE_HDATA_SCHEMAS_2009_06_CORE); Element extensionsElt = doc.getRootElement().getChild("extensions", ns); String name = null; if (extensionsElt != null) { for(Object child : extensionsElt.getChildren("extension", ns)) { if (!(child instanceof Element)) continue; Element ext = (Element)child; String id = StringUtils.trimToNull(ext.getAttributeValue("extensionId")); // required if (id == null) continue; String section = ext.getText(); if (StringUtils.isNotBlank(section)) { // find first section with id and path values extensionId = id; sectionPath = section; name = ext.getText(); // prefer non-c32 section if available which may have special handling if (!section.contains("/c32")) break; } } } if (sectionPath == null) { log.error("Failed to retrieve section from prerequisite test results: BaseUrlRootXml"); setStatus(StatusEnumType.SKIPPED, "Failed to find section in prerequisite test results: 6.3.1.1"); return; } final Context context = Loader.getInstance().getContext(); final HttpClient client = context.getHttpClient(); try { URI baseUrl = context.getBaseURL(); if (log.isDebugEnabled()) { System.out.println("\nURL: " + baseUrl); System.out.println("section path=" + sectionPath); System.out.println("extensionID=" + extensionId); } HttpPost post = new HttpPost(baseUrl); List<NameValuePair> formParams = new ArrayList<NameValuePair>(3); formParams.add(new BasicNameValuePair("path", sectionPath)); if (StringUtils.isNotBlank(name)) { formParams.add(new BasicNameValuePair("name", name)); // optional } formParams.add(new BasicNameValuePair("extensionID", extensionId)); post.setEntity(new UrlEncodedFormEntity(formParams)); HttpResponse response = context.executeRequest(client, post); int code = response.getStatusLine().getStatusCode(); if (code != 409) { dumpResponse(post, response, log.isDebugEnabled()); setStatus(StatusEnumType.FAILED, "Expected 409 HTTP status code but was: " + code); if (!log.isDebugEnabled()) { System.out.println("\nURL: " + baseUrl); System.out.println("section path=" + sectionPath); System.out.println("extensionID=" + extensionId); } } else { if (log.isDebugEnabled()) { dumpResponse(post, response); } setStatus(StatusEnumType.SUCCESS); } } catch (IOException e) { throw new TestException(e); } finally { client.getConnectionManager().shutdown(); } } }