001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.processor.interceptor;
018
019import java.io.Serializable;
020import java.util.Date;
021
022import org.apache.camel.Exchange;
023import org.apache.camel.Message;
024import org.apache.camel.RouteNode;
025import org.apache.camel.model.ProcessorDefinition;
026import org.apache.camel.spi.TracedRouteNodes;
027import org.apache.camel.util.MessageHelper;
028
029/**
030 * Default {@link TraceEventMessage}.
031 */
032public final class DefaultTraceEventMessage implements Serializable, TraceEventMessage {
033    private static final long serialVersionUID = -4549012920528941203L;
034
035    private Date timestamp;
036    private String fromEndpointUri;
037    private String previousNode;
038    private String toNode;
039    private String exchangeId;
040    private String shortExchangeId;
041    private String exchangePattern;
042    private String properties;
043    private String headers;
044    private String body;
045    private String bodyType;
046    private String outHeaders;
047    private String outBody;
048    private String outBodyType;
049    private String causedByException;
050    private String routeId;
051    private final transient Exchange tracedExchange;
052
053    /**
054     * Creates a {@link DefaultTraceEventMessage} based on the given node it was traced while processing
055     * the current {@link Exchange}
056     *
057     * @param toNode the node where this trace is intercepted
058     * @param exchange the current {@link Exchange}
059     */
060    public DefaultTraceEventMessage(final Date timestamp, final ProcessorDefinition<?> toNode, final Exchange exchange) {
061        this.tracedExchange = exchange;
062        Message in = exchange.getIn();
063
064        // need to use defensive copies to avoid Exchange altering after the point of interception
065        this.timestamp = timestamp;
066        this.fromEndpointUri = exchange.getFromEndpoint() != null ? exchange.getFromEndpoint().getEndpointUri() : null;
067        this.previousNode = extractFromNode(exchange);
068        this.toNode = extractToNode(exchange);
069        this.exchangeId = exchange.getExchangeId();
070        this.routeId = exchange.getFromRouteId();
071        this.shortExchangeId = extractShortExchangeId(exchange);
072        this.exchangePattern = exchange.getPattern().toString();
073        this.properties = exchange.getProperties().isEmpty() ? null : exchange.getProperties().toString();
074        this.headers = in.getHeaders().isEmpty() ? null : in.getHeaders().toString();
075        // We should not turn the message body into String
076        this.body = MessageHelper.extractBodyForLogging(in, "");
077        this.bodyType = MessageHelper.getBodyTypeName(in);
078        if (exchange.hasOut()) {
079            Message out = exchange.getOut();
080            this.outHeaders = out.getHeaders().isEmpty() ? null : out.getHeaders().toString();
081            this.outBody = MessageHelper.extractBodyAsString(out);
082            this.outBodyType = MessageHelper.getBodyTypeName(out);
083        }
084        this.causedByException = extractCausedByException(exchange);
085    }
086
087    // Implementation
088    //---------------------------------------------------------------
089
090    private static String extractCausedByException(Exchange exchange) {
091        Throwable cause = exchange.getException();
092        if (cause == null) {
093            cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
094        }
095
096        if (cause != null) {
097            return cause.toString();
098        } else {
099            return null;
100        }
101    }
102
103    private static String extractShortExchangeId(Exchange exchange) {
104        return exchange.getExchangeId().substring(exchange.getExchangeId().indexOf("/") + 1);
105    }
106
107    private static String extractFromNode(Exchange exchange) {
108        if (exchange.getUnitOfWork() != null) {
109            TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes();
110            RouteNode last = traced.getSecondLastNode();
111            return last != null ? last.getLabel(exchange) : null;
112        }
113        return null;
114    }
115
116    private static String extractToNode(Exchange exchange) {
117        if (exchange.getUnitOfWork() != null) {
118            TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes();
119            RouteNode last = traced.getLastNode();
120            return last != null ? last.getLabel(exchange) : null;
121        }
122        return null;
123    }
124
125    // Properties
126    //---------------------------------------------------------------
127
128    public Date getTimestamp() {
129        return timestamp;
130    }
131
132    public String getFromEndpointUri() {
133        return fromEndpointUri;
134    }
135
136    public String getPreviousNode() {
137        return previousNode;
138    }
139
140    public String getToNode() {
141        return toNode;
142    }
143
144    public String getExchangeId() {
145        return exchangeId;
146    }
147
148    public String getRouteId() {
149        return routeId;
150    }
151
152    public String getShortExchangeId() {
153        return shortExchangeId;
154    }
155
156    public String getExchangePattern() {
157        return exchangePattern;
158    }
159
160    public String getProperties() {
161        return properties;
162    }
163
164    public String getHeaders() {
165        return headers;
166    }
167
168    public String getBody() {
169        return body;
170    }
171
172    public String getBodyType() {
173        return bodyType;
174    }
175
176    public String getOutBody() {
177        return outBody;
178    }
179
180    public String getOutBodyType() {
181        return outBodyType;
182    }
183
184    public String getOutHeaders() {
185        return outHeaders;
186    }
187
188    public String getCausedByException() {
189        return causedByException;
190    }
191
192    public void setTimestamp(Date timestamp) {
193        this.timestamp = timestamp;
194    }
195
196    public void setFromEndpointUri(String fromEndpointUri) {
197        this.fromEndpointUri = fromEndpointUri;
198    }
199
200    public void setPreviousNode(String previousNode) {
201        this.previousNode = previousNode;
202    }
203
204    public void setToNode(String toNode) {
205        this.toNode = toNode;
206    }
207
208    public void setExchangeId(String exchangeId) {
209        this.exchangeId = exchangeId;
210    }
211
212    public void setRouteId(String routeId) {
213        this.routeId = routeId;
214    }
215
216    public void setShortExchangeId(String shortExchangeId) {
217        this.shortExchangeId = shortExchangeId;
218    }
219
220    public void setExchangePattern(String exchangePattern) {
221        this.exchangePattern = exchangePattern;
222    }
223
224    public void setProperties(String properties) {
225        this.properties = properties;
226    }
227
228    public void setHeaders(String headers) {
229        this.headers = headers;
230    }
231
232    public void setBody(String body) {
233        this.body = body;
234    }
235
236    public void setBodyType(String bodyType) {
237        this.bodyType = bodyType;
238    }
239
240    public void setOutBody(String outBody) {
241        this.outBody = outBody;
242    }
243
244    public void setOutBodyType(String outBodyType) {
245        this.outBodyType = outBodyType;
246    }
247
248    public void setOutHeaders(String outHeaders) {
249        this.outHeaders = outHeaders;
250    }
251
252    public void setCausedByException(String causedByException) {
253        this.causedByException = causedByException;
254    }
255
256    public Exchange getTracedExchange() {
257        return tracedExchange;
258    }
259
260    @Override
261    public String toString() {
262        return "TraceEventMessage[" + exchangeId + "] on node: " + toNode;
263    }
264}