private AssertionError[] assertResponse( RestMessageExchange messageExchange, RestRepresentation.Type type) { List<AssertionError> result = new ArrayList<AssertionError>(); QName responseBodyElementName = getResponseBodyElementName(messageExchange); RestRequestInterface restRequest = messageExchange.getRestRequest(); boolean asserted = false; for (RestRepresentation representation : restRequest.getRepresentations(type, messageExchange.getResponseContentType())) { if (representation.getStatus().isEmpty() || representation.getStatus().contains(messageExchange.getResponseStatusCode())) { SchemaType schemaType = representation.getSchemaType(); if (schemaType != null && representation.getElement().equals(responseBodyElementName)) { try { XmlObject xmlObject = schemaType .getTypeSystem() .parse(messageExchange.getResponseContentAsXml(), schemaType, new XmlOptions()); // create internal error list List<?> list = new ArrayList<Object>(); XmlOptions xmlOptions = new XmlOptions(); xmlOptions.setErrorListener(list); xmlOptions.setValidateTreatLaxAsSkip(); xmlObject.validate(xmlOptions); for (Object o : list) { if (o instanceof XmlError) result.add(new AssertionError((XmlError) o)); else result.add(new AssertionError(o.toString())); } asserted = true; } catch (XmlException e) { SoapUI.logError(e); } } else { asserted = true; } } } if (!asserted && result.isEmpty()) { result.add( new AssertionError( "Missing matching representation for request with contentType [" + messageExchange.getResponseContentType() + "]")); } return result.toArray(new AssertionError[result.size()]); }
protected void validateXmlDocument(XmlObject xmlDocument) { ArrayList<XmlError> validationErrors = new ArrayList<XmlError>(); XmlOptions validationOptions = new XmlOptions(); validationOptions.setErrorListener(validationErrors); xmlDocument.validate(validationOptions); List<String> excludeErrors = new ArrayList<String>(); excludeErrors.add("Expected element '_Feature@http://www.opengis.net/gml' instead of"); excludeErrors.add("Expected element 'InsertionMetadata@http://www.opengis.net/swes/2.0'"); excludeErrors.add( "Expected element 'AbstractFeature@http://www.opengis.net/gml/3.2' instead of 'SF_SpatialSamplingFeature@http://www.opengis.net/samplingSpatial/2.0'"); for (XmlError validationError : validationErrors) { boolean skip = false; for (String excludeError : excludeErrors) { if (validationError.getMessage().startsWith(excludeError)) { skip = true; } } if (!skip) { fail(validationError.getMessage()); } } }
@Override protected void checkMessageStructure() throws MessageValidationException { boolean messageStructureFailure = false; try { // Create a pseudo XML message XmlObject pseudoMessage = XmlObject.Factory.newInstance(); XmlCursor pmCursor = pseudoMessage.newCursor(); pmCursor.toNextToken(); pmCursor.beginElement(profile.getMessageStructureID(), "urn:hl7-org:v2xml"); BufferedReader br = new BufferedReader(new StringReader(message.getMessageAsString())); String line = null; while ((line = br.readLine()) != null) { if (!line.matches("\\s*")) { String fieldSep = ((Er7Message) message).getFieldSeparatorChar(); try { int idx = line.indexOf(fieldSep); if (idx == -1 && line.length() <= 3) { idx = 3; } line = line.substring(0, idx); if (!line.startsWith("Z")) { pmCursor.beginElement(line, "urn:hl7-org:v2xml"); pmCursor.toNextToken(); } } catch (StringIndexOutOfBoundsException e) { if (line.length() > 3) { System.out.println(line); } } } } pmCursor.dispose(); // Create a schema StreamSource xsltStream = new StreamSource( MessageStructureValidationV2Er7.class .getClassLoader() .getResourceAsStream(MessageValidationConstants.XSLT_CHECK_STRUCTURE)); Transformer t = TransformerFactory.newInstance().newTransformer(xsltStream); t.setParameter("groups", "false"); t.setParameter("xml", "false"); StreamSource src = new StreamSource(profile.getDocument().newInputStream()); ByteArrayOutputStream out = new ByteArrayOutputStream(); t.transform(src, new StreamResult(out)); XmlObject schemaDoc = XmlObject.Factory.parse( new ByteArrayInputStream(out.toByteArray()), (new XmlOptions()).setLoadLineNumbers()); // pseudoMessage.save(new File("tmp/mu/PseudoMessage.xml")); // schemaDoc.save(new File("tmp/mu/Schema.xsd")); // Load the schema SchemaTypeLoader sLoader = null; Collection<Object> compErrors = new ArrayList<Object>(); XmlOptions schemaOptions = new XmlOptions(); schemaOptions.setErrorListener(compErrors); XmlObject[] schemas = new XmlObject[1]; schemas[0] = schemaDoc; sLoader = XmlBeans.compileXsd(schemas, sLoader, schemaOptions); // Load the Message XmlObject xobj = sLoader.parse(pseudoMessage.toString(), null, (new XmlOptions()).setLoadLineNumbers()); // Validate the Message against the schema Collection<XmlValidationError> errors = new ArrayList<XmlValidationError>(); xobj.validate(new XmlOptions().setErrorListener(errors)); Iterator<XmlValidationError> it = errors.iterator(); while (it.hasNext()) { XmlValidationError xve = it.next(); messageFailures.add(interpretSchemaError(xve)); messageStructureFailure = true; } } catch (XmlException xmle) { // This type of exception is thrown when the generated schema is // ambiguous MessageFailureV2 mf = new MessageFailureV2(message.getEncoding()); mf.setDescription( "The message validation can't be performed because the profile is ambiguous." + " Possible reasons for this problem include an ambiguous message definition" + " specified in the standard or an ambiguous message definition caused by the" + " user changing the Usage settings for segments during profile creation." + " Remember that a segment with the same name MUST be separated by at least one" + " non-optional segment with a different name."); mf.setFailureSeverity(ErrorSeverityConstants.FATAL); mf.setFailureType(AssertionTypeV2Constants.AMBIGUOUS_PROFILE); messageFailures.add(mf); } catch (Exception e) { throw new MessageValidationException(e.getMessage()); } finally { if (!messageStructureFailure) { MessageFailureV2 mf = new MessageFailureV2(message.getEncoding()); mf.setDescription("The message structure at the segment level is correct."); mf.setFailureSeverity(ErrorSeverityConstants.NORMAL); mf.setFailureType(AssertionTypeV2Constants.CHECKED); messageFailures.add(mf); } } }
/* * TODO Replace this version with a method that uses LaxValidationCases and provides means to access the errors after validating the document */ public static boolean validateDocument(final XmlObject doc) throws OwsExceptionReport { // Create an XmlOptions instance and set the error listener. final LinkedList<XmlError> validationErrors = new LinkedList<XmlError>(); final XmlOptions validationOptions = new XmlOptions() .setErrorListener(validationErrors) .setLoadLineNumbers(XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT); // Validate the GetCapabilitiesRequest XML document final boolean isValid = doc.validate(validationOptions); // Create Exception with error message if the xml document is invalid if (!isValid) { String message = null; // getValidation error and throw service exception for the first // error final Iterator<XmlError> iter = validationErrors.iterator(); final List<XmlError> shouldPassErrors = new LinkedList<XmlError>(); final List<XmlError> errors = new LinkedList<XmlError>(); while (iter.hasNext()) { final XmlError error = iter.next(); boolean shouldPass = false; if (error instanceof XmlValidationError) { for (final LaxValidationCase lvc : LaxValidationCase.values()) { if (lvc.shouldPass((XmlValidationError) error)) { shouldPass = true; LOGGER.debug("Lax validation case found for XML validation error: {}", error); break; } } } if (shouldPass) { shouldPassErrors.add(error); } else { errors.add(error); } } final CompositeOwsException exceptions = new CompositeOwsException(); for (final XmlError error : errors) { // get name of the missing or invalid parameter message = error.getMessage(); if (message != null) { exceptions.add( new InvalidRequestException() .at(message) .withMessage("[XmlBeans validation error:] %s", message)); /* * TODO check if code can be used for validation of SOS * 1.0.0 requests // check, if parameter is missing or value * of parameter // is // invalid to ensure, that correct // * exceptioncode in exception response is used * * // invalid parameter value if * (message.startsWith("The value")) { exCode = * OwsExceptionCode.InvalidParameterValue; * * // split message string to get attribute name String[] * messAndAttribute = message.split("attribute '"); if * (messAndAttribute.length == 2) { parameterName = * messAndAttribute[1].replace("'", ""); } } * * // invalid enumeration value --> InvalidParameterValue * else if * (message.contains("not a valid enumeration value")) { * exCode = OwsExceptionCode.InvalidParameterValue; * * // get attribute name String[] messAndAttribute = * message.split(" "); parameterName = messAndAttribute[10]; * } * * // mandatory attribute is missing --> // * missingParameterValue else if * (message.startsWith("Expected attribute")) { exCode = * OwsExceptionCode.MissingParameterValue; * * // get attribute name String[] messAndAttribute = * message.split("attribute: "); if (messAndAttribute.length * == 2) { String[] attrAndRest = * messAndAttribute[1].split(" in"); if (attrAndRest.length * == 2) { parameterName = attrAndRest[0]; } } } * * // mandatory element is missing --> // * missingParameterValue else if * (message.startsWith("Expected element")) { exCode = * SwesExceptionCode.InvalidRequest; * * // get element name String[] messAndElements = * message.split(" '"); if (messAndElements.length >= 2) { * String elements = messAndElements[1]; if * (elements.contains("offering")) { parameterName = * "offering"; } else if * (elements.contains("observedProperty")) { parameterName = * "observedProperty"; } else if * (elements.contains("responseFormat")) { parameterName = * "responseFormat"; } else if * (elements.contains("procedure")) { parameterName = * "procedure"; } else if * (elements.contains("featureOfInterest")) { parameterName * = "featureOfInterest"; } else { // TODO check if other * elements are invalid } } } // invalidParameterValue else * if (message.startsWith("Element")) { exCode = * OwsExceptionCode.InvalidParameterValue; * * // get element name String[] messAndElements = * message.split(" '"); if (messAndElements.length >= 2) { * String elements = messAndElements[1]; if * (elements.contains("offering")) { parameterName = * "offering"; } else if * (elements.contains("observedProperty")) { parameterName = * "observedProperty"; } else if * (elements.contains("responseFormat")) { parameterName = * "responseFormat"; } else if * (elements.contains("procedure")) { parameterName = * "procedure"; } else if * (elements.contains("featureOfInterest")) { parameterName * = "featureOfInterest"; } else { // TODO check if other * elements are invalid } } } else { // create service * exception OwsExceptionReport se = new * OwsExceptionReport(); * se.addCodedException(SwesExceptionCode.InvalidRequest, * message, "[XmlBeans validation error:] " + message); * LOGGER.error("The request is invalid!", se); throw se; } * * // create service exception OwsExceptionReport se = new * OwsExceptionReport(); se.addCodedException(exCode, * message, "[XmlBeans validation error:] " + message); * LOGGER.error("The request is invalid!", se); throw se; */ } } exceptions.throwIfNotEmpty(); } return isValid; }