Search in sources :

Example 1 with DelegatingInputStream

use of org.apache.cxf.io.DelegatingInputStream in project cxf by apache.

the class OneWayProcessorInterceptor method handleMessage.

public void handleMessage(Message message) throws Fault {
    if (message.getExchange().isOneWay() && !isRequestor(message) && message.get(OneWayProcessorInterceptor.class) == null && message.getExchange().get(Executor.class) == null) {
        // one way on server side, fork the rest of this chain onto the
        // workqueue, call the Outgoing chain directly.
        message.put(OneWayProcessorInterceptor.class, this);
        final InterceptorChain chain = message.getInterceptorChain();
        boolean robust = MessageUtils.getContextualBoolean(message, Message.ROBUST_ONEWAY, false);
        boolean useOriginalThread = MessageUtils.getContextualBoolean(message, USE_ORIGINAL_THREAD, false);
        if (!useOriginalThread && !robust) {
            // need to suck in all the data from the input stream as
            // the transport might discard any data on the stream when this
            // thread unwinds or when the empty response is sent back
            DelegatingInputStream in = message.getContent(DelegatingInputStream.class);
            if (in != null) {
                in.cacheInput();
            }
        }
        if (robust) {
            // continue to invoke the chain
            chain.pause();
            chain.resume();
            if (message.getContent(Exception.class) != null) {
                // CXF-5629 fault has been delivered alread in resume()
                return;
            }
        }
        try {
            Message partial = createMessage(message.getExchange());
            partial.remove(Message.CONTENT_TYPE);
            partial.setExchange(message.getExchange());
            Conduit conduit = message.getExchange().getDestination().getBackChannel(message);
            if (conduit != null) {
                message.getExchange().setInMessage(null);
                // for a one-way, the back channel could be
                // null if it knows it cannot send anything.
                conduit.prepare(partial);
                conduit.close(partial);
                message.getExchange().setInMessage(message);
            }
        } catch (IOException e) {
        // IGNORE
        }
        if (!useOriginalThread && !robust) {
            chain.pause();
            try {
                final Object lock = new Object();
                synchronized (lock) {
                    message.getExchange().getBus().getExtension(WorkQueueManager.class).getAutomaticWorkQueue().execute(new Runnable() {

                        public void run() {
                            synchronized (lock) {
                                lock.notifyAll();
                            }
                            chain.resume();
                        }
                    });
                    // wait a few milliseconds for the background thread to start processing
                    // Mostly just to make an attempt at keeping the ordering of the
                    // messages coming in from a client.  Not guaranteed though.
                    lock.wait(20);
                }
            } catch (RejectedExecutionException e) {
                LOG.warning("Executor queue is full, run the oneway invocation task in caller thread." + "  Users can specify a larger executor queue to avoid this.");
                // only block the thread if the prop is unset or set to false, otherwise let it go
                if (!MessageUtils.getContextualBoolean(message, "org.apache.cxf.oneway.rejected_execution_exception", false)) {
                    // the executor queue is full, so run the task in the caller thread
                    chain.unpause();
                }
            } catch (InterruptedException e) {
            // ignore - likely a busy work queue so we'll just let the one-way go
            }
        }
    }
}
Also used : Message(org.apache.cxf.message.Message) DelegatingInputStream(org.apache.cxf.io.DelegatingInputStream) Conduit(org.apache.cxf.transport.Conduit) IOException(java.io.IOException) IOException(java.io.IOException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException)

Example 2 with DelegatingInputStream

use of org.apache.cxf.io.DelegatingInputStream in project cxf by apache.

the class WireTapIn method handleInputStream.

private void handleInputStream(Message message, InputStream is) throws IOException {
    CachedOutputStream bos = new CachedOutputStream();
    if (threshold > 0) {
        bos.setThreshold(threshold);
    }
    // use the appropriate input stream and restore it later
    InputStream bis = is instanceof DelegatingInputStream ? ((DelegatingInputStream) is).getInputStream() : is;
    // only copy up to the limit since that's all we need to log
    // we can stream the rest
    IOUtils.copyAtLeast(bis, bos, limit == -1 ? Integer.MAX_VALUE : limit);
    bos.flush();
    bis = new SequenceInputStream(bos.getInputStream(), bis);
    // restore the delegating input stream or the input stream
    if (is instanceof DelegatingInputStream) {
        ((DelegatingInputStream) is).setInputStream(bis);
    } else {
        message.setContent(InputStream.class, bis);
    }
    message.setContent(CachedOutputStream.class, bos);
}
Also used : SequenceInputStream(java.io.SequenceInputStream) DelegatingInputStream(org.apache.cxf.io.DelegatingInputStream) SequenceInputStream(java.io.SequenceInputStream) InputStream(java.io.InputStream) DelegatingInputStream(org.apache.cxf.io.DelegatingInputStream) CachedOutputStream(org.apache.cxf.io.CachedOutputStream)

Example 3 with DelegatingInputStream

use of org.apache.cxf.io.DelegatingInputStream in project cxf by apache.

the class InternalContextUtils method rebaseResponse.

/**
 * Rebase response on replyTo
 *
 * @param reference the replyTo reference
 * @param inMAPs the inbound MAPs
 * @param inMessage the current message
 */
// CHECKSTYLE:OFF Max executable statement count limitation
public static void rebaseResponse(EndpointReferenceType reference, AddressingProperties inMAPs, final Message inMessage) {
    String namespaceURI = inMAPs.getNamespaceURI();
    if (!ContextUtils.retrievePartialResponseSent(inMessage)) {
        ContextUtils.storePartialResponseSent(inMessage);
        Exchange exchange = inMessage.getExchange();
        Message fullResponse = exchange.getOutMessage();
        Message partialResponse = ContextUtils.createMessage(exchange);
        ensurePartialResponseMAPs(partialResponse, namespaceURI);
        // ensure the inbound MAPs are available in the partial response
        // message (used to determine relatesTo etc.)
        ContextUtils.propogateReceivedMAPs(inMAPs, partialResponse);
        Destination target = inMessage.getDestination();
        if (target == null) {
            return;
        }
        try {
            if (reference == null) {
                reference = ContextUtils.getNoneEndpointReference();
            }
            Conduit backChannel = target.getBackChannel(inMessage);
            Exception exception = inMessage.getContent(Exception.class);
            // TODO:Look at how to refactor
            if (backChannel != null && !inMessage.getExchange().isOneWay() && ContextUtils.isFault(inMessage)) {
                // send the fault message to faultTo Endpoint
                exchange.setOutMessage(ContextUtils.createMessage(exchange));
                exchange.put(ConduitSelector.class, new NullConduitSelector());
                exchange.put("org.apache.cxf.http.no_io_exceptions", true);
                Destination destination = createDecoupledDestination(exchange, reference);
                exchange.setDestination(destination);
                if (ContextUtils.retrieveAsyncPostResponseDispatch(inMessage)) {
                    DelegatingInputStream in = inMessage.getContent(DelegatingInputStream.class);
                    if (in != null) {
                        in.cacheInput();
                    }
                    inMessage.getInterceptorChain().reset();
                    // cleanup pathinfo
                    if (inMessage.get(Message.PATH_INFO) != null) {
                        inMessage.remove(Message.PATH_INFO);
                    }
                    inMessage.getInterceptorChain().doIntercept(inMessage);
                }
                // send the partial response to requester
                partialResponse.put("forced.faultstring", "The server sent HTTP status code :" + inMessage.getExchange().get(Message.RESPONSE_CODE));
                partialResponse.setContent(Exception.class, exception);
                partialResponse.put(org.apache.cxf.message.Message.PROTOCOL_HEADERS, inMessage.get(Message.PROTOCOL_HEADERS));
                partialResponse.put(org.apache.cxf.message.Message.ENCODING, inMessage.get(Message.ENCODING));
                partialResponse.put(ContextUtils.ACTION, inMessage.get(ContextUtils.ACTION));
                partialResponse.put("javax.xml.ws.addressing.context.inbound", inMessage.get("javax.xml.ws.addressing.context.inbound"));
                partialResponse.put("javax.xml.ws.addressing.context.outbound", inMessage.get("javax.xml.ws.addressing.context.outbound"));
                exchange.setOutMessage(partialResponse);
                PhaseInterceptorChain newChian = ((PhaseInterceptorChain) inMessage.getInterceptorChain()).cloneChain();
                partialResponse.setInterceptorChain(newChian);
                exchange.setDestination(target);
                exchange.setOneWay(false);
                exchange.put(ConduitSelector.class, new PreexistingConduitSelector(backChannel, exchange.getEndpoint()));
                if (newChian != null && !newChian.doIntercept(partialResponse) && partialResponse.getContent(Exception.class) != null) {
                    if (partialResponse.getContent(Exception.class) instanceof Fault) {
                        throw (Fault) partialResponse.getContent(Exception.class);
                    }
                    throw new Fault(partialResponse.getContent(Exception.class));
                }
                return;
            }
            if (backChannel != null) {
                partialResponse.put(Message.PARTIAL_RESPONSE_MESSAGE, Boolean.TRUE);
                partialResponse.put(Message.EMPTY_PARTIAL_RESPONSE_MESSAGE, Boolean.TRUE);
                boolean robust = MessageUtils.getContextualBoolean(inMessage, Message.ROBUST_ONEWAY, false);
                if (robust) {
                    BindingOperationInfo boi = exchange.getBindingOperationInfo();
                    // insert the executor in the exchange to fool the OneWayProcessorInterceptor
                    exchange.put(Executor.class, getExecutor(inMessage));
                    // pause dispatch on current thread and resume...
                    inMessage.getInterceptorChain().pause();
                    inMessage.getInterceptorChain().resume();
                    MessageObserver faultObserver = inMessage.getInterceptorChain().getFaultObserver();
                    if (null != inMessage.getContent(Exception.class) && null != faultObserver) {
                        // return the fault over the response fault channel
                        inMessage.getExchange().setOneWay(false);
                        faultObserver.onMessage(inMessage);
                        return;
                    }
                    // restore the BOI for the partial response handling
                    exchange.put(BindingOperationInfo.class, boi);
                }
                // set up interceptor chains and send message
                InterceptorChain chain = fullResponse != null ? fullResponse.getInterceptorChain() : OutgoingChainInterceptor.getOutInterceptorChain(exchange);
                exchange.setOutMessage(partialResponse);
                partialResponse.setInterceptorChain(chain);
                exchange.put(ConduitSelector.class, new PreexistingConduitSelector(backChannel, exchange.getEndpoint()));
                if (ContextUtils.retrieveAsyncPostResponseDispatch(inMessage) && !robust) {
                    // need to suck in all the data from the input stream as
                    // the transport might discard any data on the stream when this
                    // thread unwinds or when the empty response is sent back
                    DelegatingInputStream in = inMessage.getContent(DelegatingInputStream.class);
                    if (in != null) {
                        in.cacheInput();
                    }
                }
                if (chain != null && !chain.doIntercept(partialResponse) && partialResponse.getContent(Exception.class) != null) {
                    if (partialResponse.getContent(Exception.class) instanceof Fault) {
                        throw (Fault) partialResponse.getContent(Exception.class);
                    }
                    throw new Fault(partialResponse.getContent(Exception.class));
                }
                if (chain != null) {
                    chain.reset();
                }
                exchange.put(ConduitSelector.class, new NullConduitSelector());
                if (fullResponse == null) {
                    fullResponse = ContextUtils.createMessage(exchange);
                }
                exchange.setOutMessage(fullResponse);
                Destination destination = createDecoupledDestination(exchange, reference);
                exchange.setDestination(destination);
                if (ContextUtils.retrieveAsyncPostResponseDispatch(inMessage) && !robust) {
                    // cleanup pathinfo
                    if (inMessage.get(Message.PATH_INFO) != null) {
                        inMessage.remove(Message.PATH_INFO);
                    }
                    // pause dispatch on current thread ...
                    inMessage.getInterceptorChain().pause();
                    try {
                        // ... and resume on executor thread
                        getExecutor(inMessage).execute(new Runnable() {

                            public void run() {
                                inMessage.getInterceptorChain().resume();
                            }
                        });
                    } catch (RejectedExecutionException e) {
                        LOG.warning("Executor queue is full, use the caller thread." + "  Users can specify a larger executor queue to avoid this.");
                        // only block the thread if the prop is unset or set to false, otherwise let it go
                        if (!MessageUtils.getContextualBoolean(inMessage, "org.apache.cxf.oneway.rejected_execution_exception")) {
                            // the executor queue is full, so run the task in the caller thread
                            inMessage.getInterceptorChain().resume();
                        }
                    }
                }
            }
        } catch (Exception e) {
            LOG.log(Level.WARNING, "SERVER_TRANSPORT_REBASE_FAILURE_MSG", e);
        }
    }
}
Also used : Destination(org.apache.cxf.transport.Destination) PhaseInterceptorChain(org.apache.cxf.phase.PhaseInterceptorChain) BindingOperationInfo(org.apache.cxf.service.model.BindingOperationInfo) MessageObserver(org.apache.cxf.transport.MessageObserver) Message(org.apache.cxf.message.Message) Fault(org.apache.cxf.interceptor.Fault) WebFault(javax.xml.ws.WebFault) PreexistingConduitSelector(org.apache.cxf.endpoint.PreexistingConduitSelector) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) IOException(java.io.IOException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) NullConduitSelector(org.apache.cxf.endpoint.NullConduitSelector) Exchange(org.apache.cxf.message.Exchange) InterceptorChain(org.apache.cxf.interceptor.InterceptorChain) PhaseInterceptorChain(org.apache.cxf.phase.PhaseInterceptorChain) Conduit(org.apache.cxf.transport.Conduit) DelegatingInputStream(org.apache.cxf.io.DelegatingInputStream)

Example 4 with DelegatingInputStream

use of org.apache.cxf.io.DelegatingInputStream in project cxf by apache.

the class LoggingInInterceptor method logInputStream.

protected void logInputStream(Message message, InputStream is, LoggingMessage buffer, String encoding, String ct) {
    CachedOutputStream bos = new CachedOutputStream();
    if (threshold > 0) {
        bos.setThreshold(threshold);
    }
    try {
        // use the appropriate input stream and restore it later
        InputStream bis = is instanceof DelegatingInputStream ? ((DelegatingInputStream) is).getInputStream() : is;
        // only copy up to the limit since that's all we need to log
        // we can stream the rest
        IOUtils.copyAtLeast(bis, bos, limit == -1 ? Integer.MAX_VALUE : limit);
        bos.flush();
        bis = new SequenceInputStream(bos.getInputStream(), bis);
        // restore the delegating input stream or the input stream
        if (is instanceof DelegatingInputStream) {
            ((DelegatingInputStream) is).setInputStream(bis);
        } else {
            message.setContent(InputStream.class, bis);
        }
        if (bos.getTempFile() != null) {
            // large thing on disk...
            buffer.getMessage().append("\nMessage (saved to tmp file):\n");
            buffer.getMessage().append("Filename: " + bos.getTempFile().getAbsolutePath() + "\n");
        }
        boolean truncated = false;
        if (bos.size() > limit && limit != -1) {
            buffer.getMessage().append("(message truncated to " + limit + " bytes)\n");
            truncated = true;
        }
        writePayload(buffer.getPayload(), bos, encoding, ct, truncated);
        bos.close();
    } catch (Exception e) {
        throw new Fault(e);
    }
}
Also used : SequenceInputStream(java.io.SequenceInputStream) DelegatingInputStream(org.apache.cxf.io.DelegatingInputStream) SequenceInputStream(java.io.SequenceInputStream) InputStream(java.io.InputStream) DelegatingInputStream(org.apache.cxf.io.DelegatingInputStream) CachedOutputStream(org.apache.cxf.io.CachedOutputStream)

Example 5 with DelegatingInputStream

use of org.apache.cxf.io.DelegatingInputStream in project cxf by apache.

the class AbstractHTTPDestination method cacheInput.

/**
 * On first write, we need to make sure any attachments and such that are still on the incoming stream
 * are read in.  Otherwise we can get into a deadlock where the client is still trying to send the
 * request, but the server is trying to send the response.   Neither side is reading and both blocked
 * on full buffers.  Not a good situation.
 * @param outMessage
 */
private void cacheInput(Message outMessage) {
    if (outMessage.getExchange() == null) {
        return;
    }
    Message inMessage = outMessage.getExchange().getInMessage();
    if (inMessage == null) {
        return;
    }
    Object o = inMessage.get("cxf.io.cacheinput");
    DelegatingInputStream in = inMessage.getContent(DelegatingInputStream.class);
    if (PropertyUtils.isTrue(o)) {
        Collection<Attachment> atts = inMessage.getAttachments();
        if (atts != null) {
            for (Attachment a : atts) {
                if (a.getDataHandler().getDataSource() instanceof AttachmentDataSource) {
                    try {
                        ((AttachmentDataSource) a.getDataHandler().getDataSource()).cache(inMessage);
                    } catch (IOException e) {
                        throw new Fault(e);
                    }
                }
            }
        }
        if (in != null) {
            in.cacheInput();
        }
    } else if (in != null) {
        // However, also don't want to consume indefinitely.   We'll limit to 16M.
        try {
            IOUtils.consume(in, 16 * 1024 * 1024);
        } catch (Exception ioe) {
        // ignore
        }
    }
}
Also used : Message(org.apache.cxf.message.Message) DelegatingInputStream(org.apache.cxf.io.DelegatingInputStream) AttachmentDataSource(org.apache.cxf.attachment.AttachmentDataSource) Attachment(org.apache.cxf.message.Attachment) Fault(org.apache.cxf.interceptor.Fault) IOException(java.io.IOException) Base64Exception(org.apache.cxf.common.util.Base64Exception) SuspendedInvocationException(org.apache.cxf.continuations.SuspendedInvocationException) IOException(java.io.IOException)

Aggregations

DelegatingInputStream (org.apache.cxf.io.DelegatingInputStream)6 IOException (java.io.IOException)3 Message (org.apache.cxf.message.Message)3 InputStream (java.io.InputStream)2 SequenceInputStream (java.io.SequenceInputStream)2 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)2 Fault (org.apache.cxf.interceptor.Fault)2 CachedOutputStream (org.apache.cxf.io.CachedOutputStream)2 Exchange (org.apache.cxf.message.Exchange)2 Conduit (org.apache.cxf.transport.Conduit)2 WebFault (javax.xml.ws.WebFault)1 AttachmentDataSource (org.apache.cxf.attachment.AttachmentDataSource)1 Base64Exception (org.apache.cxf.common.util.Base64Exception)1 AuthorizationPolicy (org.apache.cxf.configuration.security.AuthorizationPolicy)1 SuspendedInvocationException (org.apache.cxf.continuations.SuspendedInvocationException)1 NullConduitSelector (org.apache.cxf.endpoint.NullConduitSelector)1 PreexistingConduitSelector (org.apache.cxf.endpoint.PreexistingConduitSelector)1 Interceptor (org.apache.cxf.interceptor.Interceptor)1 InterceptorChain (org.apache.cxf.interceptor.InterceptorChain)1 Attachment (org.apache.cxf.message.Attachment)1