package org.talend.esb.policy.compression.impl; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.Collection; import java.util.Scanner; import java.util.logging.Logger; import java.util.regex.MatchResult; import java.util.zip.GZIPInputStream; import javax.xml.stream.XMLStreamException; import org.apache.commons.codec.binary.Base64; import org.apache.cxf.common.logging.LogUtils; import org.apache.cxf.helpers.IOUtils; import org.apache.cxf.interceptor.AttachmentInInterceptor; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.io.CachedOutputStream; import org.apache.cxf.message.Message; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import org.apache.cxf.ws.policy.AssertionInfo; import org.apache.cxf.ws.policy.AssertionInfoMap; import org.talend.esb.policy.compression.impl.internal.CompressionConstants; import org.talend.esb.policy.compression.impl.internal.CompressionHelper; /** * Interceptor that uncompresses those incoming messages. */ public class CompressionInInterceptor extends AbstractPhaseInterceptor<Message> { private static final Logger LOG = LogUtils .getL7dLogger(CompressionInInterceptor.class); public CompressionInInterceptor() { super(Phase.RECEIVE); addBefore(AttachmentInInterceptor.class.getName()); } public void handleMessage(Message message) throws Fault { try { // Perform compression decompressMessage(message); // Confirm policy processing confirmPolicyProcessing(message); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new Fault(e); } } protected void confirmPolicyProcessing(Message message) { AssertionInfoMap aim = message.get(AssertionInfoMap.class); if (aim != null) { Collection<AssertionInfo> ais = aim .get(CompressionPolicyBuilder.COMPRESSION); if (ais != null) { for (AssertionInfo ai : ais) { if (ai.getAssertion() instanceof CompressionAssertion) { ai.setAsserted(true); } } } } } public void decompressMessage(Message message) throws Fault { if (isGET(message)) { return; } try { LOG.fine("Uncompressing response"); // Original stream with compressed body InputStream is = message.getContent(InputStream.class); if (is == null) { return; } // Loading content of original InputStream to cache CachedOutputStream cache = new CachedOutputStream(); IOUtils.copy(is, cache); is.close(); // Loading SOAP body content to separate stream CachedOutputStream soapBodyContent = new CachedOutputStream(); Scanner scanner = new Scanner(cache.getInputStream()); MatchResult bodyPosition = null; try { bodyPosition = CompressionHelper.loadSoapBodyContent(soapBodyContent, scanner, CompressionConstants.COMPRESSED_SOAP_BODY_PATTERN); } catch (XMLStreamException e) { throw new Fault("Can not read compressed SOAP Body", LOG, e, e.getMessage()); } if (bodyPosition==null) { // compressed SOAP body content is not found // skipping decompression InputStream istream = cache.getInputStream(); istream.reset(); message.setContent(InputStream.class, istream); } else { // compressed SOAP body content is found // apply Base64 decoding for encoded soap body content final byte[] base64DecodedSoapBody = (new Base64()) .decode(soapBodyContent.getBytes()); // uncompress soap body GZIPInputStream decompressedBody = new GZIPInputStream( new ByteArrayInputStream(base64DecodedSoapBody)); // replace original soap body by compressed one CachedOutputStream decompressedSoapMessage = new CachedOutputStream(); CompressionHelper.replaceBodyInSOAP(cache.getBytes(), bodyPosition, decompressedBody, decompressedSoapMessage, null, null, true); message.setContent(InputStream.class, decompressedSoapMessage.getInputStream()); } } catch (Exception ex) { throw new Fault("SOAP Body decompresion failed", LOG, ex); } } }