From 695ab1f836160d40c4352a2c3127f4f687912817 Mon Sep 17 00:00:00 2001 From: Christof Rabensteiner Date: Mon, 27 May 2019 09:46:36 +0200 Subject: Intercept Incoming DeliveryRequestStatus and Store as byte[] - Add egovutils dependency (Reason: Need DomUtils to serialize / unserialize Soap Message via DOMParser) - Add Incerceptor to MsgClient / -Factory that stores the message content byte-by-byte in the DeliveryRepository. The format is required for successfully validating a DeliveryRequestStatus. - Add SoapUtils, which interacts with byte[] Soap message. - Add CXFMessageUtils, which interacts with CXF Messages from interceptor chains. - Refactor xsd namespaces: Move them out from the PrefixMapper and into a dedicated class. --- .../at/gv/egiz/moazs/util/CXFMessageUtils.java | 92 ++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/main/java/at/gv/egiz/moazs/util/CXFMessageUtils.java (limited to 'src/main/java/at/gv/egiz/moazs/util') diff --git a/src/main/java/at/gv/egiz/moazs/util/CXFMessageUtils.java b/src/main/java/at/gv/egiz/moazs/util/CXFMessageUtils.java new file mode 100644 index 0000000..07fdfb6 --- /dev/null +++ b/src/main/java/at/gv/egiz/moazs/util/CXFMessageUtils.java @@ -0,0 +1,92 @@ +package at.gv.egiz.moazs.util; + +import org.apache.cxf.helpers.IOUtils; +import org.apache.cxf.io.CachedOutputStream; +import org.apache.cxf.io.CachedWriter; +import org.apache.cxf.io.DelegatingInputStream; +import org.apache.cxf.message.Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.SequenceInputStream; + +@Component +public class CXFMessageUtils { + + private static final Logger LOG = LoggerFactory.getLogger(CXFMessageUtils.class); + + /** + * Copy and return content of org.apache.cxf.message.Message; Restore InputStream / Reader from + * message.getContent() after consuming it. + * @param message + * @return + * @throws IOException + */ + public byte[] copyContent(Message message) throws IOException { + + if (message.getContent(InputStream.class) != null) { + return streamMessageContentToByteArray(message); + } else if (message.getContent(Reader.class) != null) { + return readMessageContentToByteArray(message); + } else { + LOG.warn("Message Content is neither Reader nor InputStream; will return empty content."); + return new byte[0]; + } + } + + /** + * Source: Adapted from ApacheCXF 3.3.0 / LoggingInInterceptor.logInputStream() + * @param message + * @return copy of message content + * @throws IOException + */ + private byte[] streamMessageContentToByteArray(Message message) throws IOException { + + var in = message.getContent(InputStream.class); + + try (var out = new CachedOutputStream()) { + + // use the appropriate input stream and restore it later + InputStream bis = in instanceof DelegatingInputStream + ? ((DelegatingInputStream)in).getInputStream() : in; + + //only copy up to the limit since that's all we need to log + //we can stream the rest + IOUtils.copy(bis, out); + out.flush(); + bis = new SequenceInputStream(out.getInputStream(), bis); + + // restore the delegating input stream or the input stream + if (in instanceof DelegatingInputStream) { + ((DelegatingInputStream)in).setInputStream(bis); + } else { + message.setContent(InputStream.class, bis); + } + + return out.getBytes(); + } + + } + + /** + * Source: Adapted from ApacheCXF 3.3.0 / LoggingInInterceptor.logReader() + * @param message + * @return copy of message content + * @throws IOException + */ + private byte[] readMessageContentToByteArray(Message message) throws IOException { + var reader = message.getContent(Reader.class); + var writer = new CachedWriter(); + IOUtils.copyAndCloseInput(reader, writer); + message.setContent(Reader.class, writer.getReader()); + + var buffer = new StringBuilder(); + writer.writeCacheTo(buffer); + return buffer.toString().getBytes(); + } + +} -- cgit v1.2.3