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(); } }