/** * Convenience method for getting the value of a node, handling the case where the node does not * exist. * * @return the value of the node at {@code xPath} if it exists, else {@code null}. */ public String extractNodeValue(@Nullable Node parentNode, Iterable<String> xPath) { Node node = extractNode(parentNode, xPath); if (node == null || node.getFirstChild() == null) { return null; } return node.getFirstChild().getNodeValue(); }
public RequestInfo.Builder parseMessage(RequestInfo.Builder builder, SOAPMessage soapMessage) { Preconditions.checkNotNull(builder, "Null builder"); Transformer transformer = transformerSupplier.get(); if (soapMessage == null || soapMessage.getSOAPPart() == null || transformer == null) { return builder; } try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { // Some SOAP frameworks don't include SOAP headers when calling SOAPMessage.writeTo. // Use an XML transformer to write the XML content instead. transformer.transform(soapMessage.getSOAPPart().getContent(), new StreamResult(outputStream)); builder.withPayload(outputStream.toString(StandardCharsets.UTF_8.name())); } catch (TransformerException | SOAPException | IOException e) { builder.withPayload("Unable to read request content due to exception: " + e); libLogger.warn("Unable to read request content due to exception.", e); } try { SOAPHeader soapHeader = soapMessage.getSOAPHeader(); builder.withContext(contextName, nodeExtractor.extractNodeValue(soapHeader, contextXPath)); } catch (SOAPException e) { builder.withContext( contextName, "Unable to extract " + contextName + " from request due to exception: " + e); } return builder; } }
public ResponseInfo.Builder parseMessage(ResponseInfo.Builder builder, SOAPMessage soapMessage) { Preconditions.checkNotNull(builder, "Null builder"); if (soapMessage == null) { return builder; } try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { soapMessage.writeTo(outputStream); builder.withPayload(outputStream.toString(StandardCharsets.UTF_8.name())); } catch (SOAPException | IOException e) { builder.withPayload("Unable to read response due to exception: " + e); } try { SOAPHeader soapHeader = soapMessage.getSOAPHeader(); String responseTimeString = nodeExtractor.extractNodeValue(soapHeader, responseTimeXPath); String operationsString = nodeExtractor.extractNodeValue(soapHeader, operationsCountXPath); builder .withRequestId(nodeExtractor.extractNodeValue(soapHeader, requestIdXPath)) .withResponseTimeMillis(Longs.tryParse(Strings.nullToEmpty(responseTimeString))) .withOperationsCount(Longs.tryParse(Strings.nullToEmpty(operationsString))); } catch (SOAPException e) { // Since requestId is arguably the most important value extracted above, put the exception // in the requestId field. Adding the exception to every field of the builder would be // redundant. builder.withRequestId("Unable to extract the requestId due to exception: " + e); } return builder; } }
/** * Convenience method for getting the value of a node, handling the case where the node does not * exist. * * @return the value of the node at {@code xPath} if it exists, else {@code null}. */ public String extractNodeValue(@Nullable Node parentNode, Iterable<String> xPath) { Node node = extractNode(parentNode, xPath); if (node == null || node.getFirstChild() == null) { return null; } return node.getFirstChild().getNodeValue(); }
public RequestInfo.Builder parseMessage(RequestInfo.Builder builder, SOAPMessage soapMessage) { Preconditions.checkNotNull(builder, "Null builder"); Transformer transformer = transformerSupplier.get(); if (soapMessage == null || soapMessage.getSOAPPart() == null || transformer == null) { return builder; } try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { // Some SOAP frameworks don't include SOAP headers when calling SOAPMessage.writeTo. // Use an XML transformer to write the XML content instead. transformer.transform(soapMessage.getSOAPPart().getContent(), new StreamResult(outputStream)); builder.withPayload(outputStream.toString(StandardCharsets.UTF_8.name())); } catch (TransformerException | SOAPException | IOException e) { builder.withPayload("Unable to read request content due to exception: " + e); libLogger.warn("Unable to read request content due to exception.", e); } try { SOAPHeader soapHeader = soapMessage.getSOAPHeader(); builder.withContext(contextName, nodeExtractor.extractNodeValue(soapHeader, contextXPath)); } catch (SOAPException e) { builder.withContext( contextName, "Unable to extract " + contextName + " from request due to exception: " + e); } return builder; } }
@Test public void testXPathExistsMultipleTimesWithoutNamespaces() throws Exception { String xml = "<Header><requestId>123456</requestId><requestId>78910</requestId></Header>"; Document document = DocumentBuilderFactory.newInstance() .newDocumentBuilder() .parse(Streams.wrapString(xml, StandardCharsets.UTF_8)); Node node = nodeExtractor.extractNode(document, Lists.newArrayList("Header", "requestId")); assertEquals( "Given an xpath in the XML, should return its node", "123456", node.getFirstChild().getNodeValue()); }
public ResponseInfo.Builder parseMessage(ResponseInfo.Builder builder, SOAPMessage soapMessage) { Preconditions.checkNotNull(builder, "Null builder"); if (soapMessage == null) { return builder; } try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { soapMessage.writeTo(outputStream); builder.withPayload(outputStream.toString(StandardCharsets.UTF_8.name())); } catch (SOAPException | IOException e) { builder.withPayload("Unable to read response due to exception: " + e); } try { SOAPHeader soapHeader = soapMessage.getSOAPHeader(); String responseTimeString = nodeExtractor.extractNodeValue(soapHeader, responseTimeXPath); String operationsString = nodeExtractor.extractNodeValue(soapHeader, operationsCountXPath); builder .withRequestId(nodeExtractor.extractNodeValue(soapHeader, requestIdXPath)) .withResponseTimeMillis(Longs.tryParse(Strings.nullToEmpty(responseTimeString))) .withOperationsCount(Longs.tryParse(Strings.nullToEmpty(operationsString))); } catch (SOAPException e) { // Since requestId is arguably the most important value extracted above, put the exception // in the requestId field. Adding the exception to every field of the builder would be // redundant. builder.withRequestId("Unable to extract the requestId due to exception: " + e); } return builder; } }
@Test public void testNullParentNode() { Node node = nodeExtractor.extractNode(null, Lists.newArrayList("Foo")); assertNull("Given a null parent node, should return null", node); }
@Test public void testXPathDoesNotExist() throws Exception { String xml = "<Header><requestId>123456</requestId></Header>"; Document document = DocumentBuilderFactory.newInstance() .newDocumentBuilder() .parse(Streams.wrapString(xml, StandardCharsets.UTF_8)); Node node = nodeExtractor.extractNode(document, Lists.newArrayList("Foo")); assertNull("Given an xpath not in the XML, should return null", node); }
@Test public void testXPathExistsWithoutNamespaces() throws Exception { String xml = "<Header><requestId>123456</requestId></Header>"; Document document = DocumentBuilderFactory.newInstance() .newDocumentBuilder() .parse(Streams.wrapString(xml, StandardCharsets.UTF_8)); Node node = nodeExtractor.extractNode(document, Lists.newArrayList("Header", "requestId")); assertEquals( "Given an xpath in the XML, should return its node", "123456", node.getFirstChild().getNodeValue()); }
@Test public void testXPathEmpty() throws Exception { String xml = "<Header><requestId>123456</requestId></Header>"; Document document = DocumentBuilderFactory.newInstance() .newDocumentBuilder() .parse(Streams.wrapString(xml, StandardCharsets.UTF_8)); Node node = nodeExtractor.extractNode(document, Collections.<String>emptyList()); assertNull("Given an empty xpath elements list, should return null", node); } }
@Test public void testNullXPaths_fails() { thrown.expect(NullPointerException.class); thrown.expectMessage("xpath"); nodeExtractor.extractNode(null, null); }
@Test public void testXPathExistsWithNamespaces() throws Exception { String xml = "<?xml version='1.0' encoding='UTF-8'?>" + "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>" + " <soap:Header>" + " <ResponseHeader xmlns='https://adwords.google.com/api/adwords/cm/v209901'>" + " <requestId>123456</requestId>" + " <serviceName>BatchJobService</serviceName>" + " <methodName>mutate</methodName>" + " <operations>1</operations>" + " <responseTime>247</responseTime>" + " </ResponseHeader>" + " </soap:Header>" + "</soap:Envelope>"; DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); Document document = documentBuilderFactory .newDocumentBuilder() .parse(Streams.wrapString(xml, StandardCharsets.UTF_8)); Node node = nodeExtractor.extractNode( document, Lists.newArrayList("Envelope", "Header", "ResponseHeader", "requestId")); assertNotNull(node); assertEquals( "Given an xpath in the XML, should return its node", "123456", node.getFirstChild().getNodeValue()); }