Show Table of Contents
Chapter 21. Debugging
21.1. Message Tracing
Message tracing provides a view of the content and context of a message exchange on the SwitchYard bus. Message tracing prints exchange information to the log. An exchange interceptor that generates the trace, is triggered at the following points:
- Immediately after the consumer sends the request message. For example, In the case of a service which is invoked from a service binding, this is the point at which the gateway binding puts the message onto the bus.
- Immediately before the service provider is invoked.
- Immediately after the service provider is invoked.
- At completion of the exchange before the message is returned to the consumer.
21.1.1. Trace Output Example
Trace output includes details on the metadata, context properties, payload, and attachments for a message exchange. Here is an example of a trace entry:
12:48:25,038 INFO [org.switchyard.handlers.MessageTraceHandler]
------- Begin Message Trace -------
Consumer -> {urn:switchyard-quickstart:bean-service:0.1.0}OrderService
Provider -> [unassigned]
Operation -> submitOrder
MEP -> IN_OUT
Phase -> IN
State -> OK
Exchange Context ->
org.switchyard.bus.camel.consumer : ServiceReference [name={urn:switchyard-quickstart:bean-service:0.1.0}OrderService, interface=BaseServiceInterface [type=wsdl, operations=[submitOrder : IN_OUT : [{urn:switchyard-quickstart:bean-service:1.0}submitOrder, {urn:switchyard-quickstart:bean-service:1.0}submitOrderResponse, null]]], domain=ServiceDomain [name=org.switchyard.domains.root]]
org.switchyard.exchangeGatewayName : _OrderService_soap_1
org.switchyard.bus.camel.securityContext : SecurityContext[credentials=[ConfidentialityCredential [confidential=false]], securityDomainsToSubjects={}]
org.switchyard.exchangeInitiatedNS : 1375980505021790000
CamelCreatedTimestamp : Thu Aug 08 12:48:25 EDT 2013
org.switchyard.bus.camel.phase : IN
org.switchyard.bus.camel.dispatcher : org.switchyard.bus.camel.ExchangeDispatcher@b4aa453
org.switchyard.bus.camel.labels : {org.switchyard.exchangeGatewayName=[org.switchyard.label.behavior.transient]}
CamelToEndpoint : direct://%7Burn:switchyard-quickstart:bean-service:0.1.0%7DOrderService
org.switchyard.bus.camel.contract : org.switchyard.metadata.BaseExchangeContract@2176feaf
org.switchyard.bus.camel.replyHandler : org.switchyard.component.common.SynchronousInOutHandler@516a4aef
CamelFilterMatched : false
Message Context ->
org.switchyard.bus.camel.labels : {org.switchyard.contentType=[org.switchyard.label.behavior.transient], org.switchyard.bus.camel.messageSent=[org.switchyard.label.behavior.transient]}
org.switchyard.messageId : ID-kookaburra-local-49858-1375980502093-0-1
org.switchyard.bus.camel.messageSent : true
org.switchyard.soap.messageName : submitOrder
org.switchyard.contentType : {urn:switchyard-quickstart:bean-service:1.0}submitOrder
breadcrumbId : ID-kookaburra-local-49858-1375980502093-0-1
Message Content ->
<?xml version="1.0" encoding="UTF-8"?><orders:submitOrder xmlns:orders="urn:switchyard-quickstart:bean-service:1.0">
<order>
<orderId>PO-19838-XYZ</orderId>
<itemId>BUTTER</itemId>
<quantity>200</quantity>
</order>
</orders:submitOrder>
------ End Message Trace -------21.1.2. Enabling Message Tracing
You can enable message tracing within JBoss Developer Studio.
- When using the SwitchYard visual editor to view the
switchyard.xmlfile, select the tab to view the Domain Settings, then select the Enable Message Trace check box.
This sets the value of the org.switchyard.handlers.messageTrace.enabled property to
true in your application domain. This is captured by the <sy:domain> element in the switchyard.xml source file.
21.2. Exchange Interceptors
Exchange Interceptors provide a mechanism for injecting logic into the message path of the SwitchYard exchange bus. You can use an interceptor to read or update message content and context properties, which makes interceptors useful for debugging and for applying logic outside a traditional service implementation in SwitchYard.
21.2.1. Implementing an Exchange Interceptor
The Java class
ExchangeInterceptor has the following properties:
- Implements the org.switchyard.ExchangeInterceptor interface.
- Is annotated with @Named so that it can be discovered as a CDI bean.
The
ExchangeInterceptor interface looks like this:
public interface ExchangeInterceptor {
String CONSUMER = "Consumer";
String PROVIDER = "Provider";
void before(String target, Exchange exchange) throws HandlerException;
void after(String target, Exchange exchange) throws HandlerException;
List<String> getTargets();
}
An interceptor is invoked for all message exchanges in an application, so if you only care about a specific service you will want to add a conditional to before() and after() to check for service name. You can restrict the interception points used through the getTargets() method. The CONSUMER and PROVIDER string constants are provided for use with getTargets() to restrict interception to the consumer, provider, or both. The CONSUMER target maps to an injection point just after the consumer sends a request and just before the reply is handed back. The PROVIDER target maps to an injection point just before the provider is called with a request and just after it produces a response.
Here is an example ExchangeInterceptor implementation from the bean-service quickstart:
package org.switchyard.quickstarts.bean.service;
import java.util.Arrays;
import java.util.List;
import javax.inject.Named;
import org.switchyard.Exchange;
import org.switchyard.ExchangeInterceptor;
import org.switchyard.ExchangeState;
import org.switchyard.HandlerException;
/**
* This is an example of an exchange interceptor which can be used to inject code
* around targets during a message exchange. This example updates the content of
* OrderAck after the provider has generated a response.
*/
@Named("UpdateStatus")
public class OrderInterceptor implements ExchangeInterceptor {
@Override
public void before(String target, Exchange exchange) throws HandlerException {
// Not interested in doing anything before the provider is invoked
}
@Override
public void after(String target, Exchange exchange) throws HandlerException {
// We only want to intercept successful replies from OrderService
if (exchange.getProvider().getName().getLocalPart().equals("OrderService")
&& ExchangeState.OK.equals(exchange.getState())) {
OrderAck orderAck = exchange.getMessage().getContent(OrderAck.class);
orderAck.setStatus(orderAck.getStatus() + " [intercepted]");
}
}
@Override
public List<String> getTargets() {
return Arrays.asList(PROVIDER);
}
}
Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.