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