/******************************************************************************* * Copyright 2020 Graz University of Technology * MOA ZS has been developed in a cooperation between EGIZ * and Graz University of Technology. * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. *******************************************************************************/ 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; /** * @author Christof Rabensteiner * */ @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(); } }