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 */
017 package org.apache.camel.processor.interceptor;
018
019 import java.io.Serializable;
020 import java.util.Date;
021
022 import org.apache.camel.Exchange;
023 import org.apache.camel.Message;
024 import org.apache.camel.RouteNode;
025 import org.apache.camel.model.ProcessorDefinition;
026 import org.apache.camel.spi.TracedRouteNodes;
027 import org.apache.camel.util.MessageHelper;
028
029 /**
030 * Default {@link TraceEventMessage}.
031 */
032 public 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 this.body = MessageHelper.extractBodyAsString(in);
076 this.bodyType = MessageHelper.getBodyTypeName(in);
077 if (exchange.hasOut()) {
078 Message out = exchange.getOut();
079 this.outHeaders = out.getHeaders().isEmpty() ? null : out.getHeaders().toString();
080 this.outBody = MessageHelper.extractBodyAsString(out);
081 this.outBodyType = MessageHelper.getBodyTypeName(out);
082 }
083 this.causedByException = extractCausedByException(exchange);
084 }
085
086 // Implementation
087 //---------------------------------------------------------------
088
089 private static String extractCausedByException(Exchange exchange) {
090 Throwable cause = exchange.getException();
091 if (cause == null) {
092 cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
093 }
094
095 if (cause != null) {
096 return cause.toString();
097 } else {
098 return null;
099 }
100 }
101
102 private static String extractShortExchangeId(Exchange exchange) {
103 return exchange.getExchangeId().substring(exchange.getExchangeId().indexOf("/") + 1);
104 }
105
106 private static String extractFromNode(Exchange exchange) {
107 if (exchange.getUnitOfWork() != null) {
108 TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes();
109 RouteNode last = traced.getSecondLastNode();
110 return last != null ? last.getLabel(exchange) : null;
111 }
112 return null;
113 }
114
115 private static String extractToNode(Exchange exchange) {
116 if (exchange.getUnitOfWork() != null) {
117 TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes();
118 RouteNode last = traced.getLastNode();
119 return last != null ? last.getLabel(exchange) : null;
120 }
121 return null;
122 }
123
124 // Properties
125 //---------------------------------------------------------------
126
127 public Date getTimestamp() {
128 return timestamp;
129 }
130
131 public String getFromEndpointUri() {
132 return fromEndpointUri;
133 }
134
135 public String getPreviousNode() {
136 return previousNode;
137 }
138
139 public String getToNode() {
140 return toNode;
141 }
142
143 public String getExchangeId() {
144 return exchangeId;
145 }
146
147 public String getRouteId() {
148 return routeId;
149 }
150
151 public String getShortExchangeId() {
152 return shortExchangeId;
153 }
154
155 public String getExchangePattern() {
156 return exchangePattern;
157 }
158
159 public String getProperties() {
160 return properties;
161 }
162
163 public String getHeaders() {
164 return headers;
165 }
166
167 public String getBody() {
168 return body;
169 }
170
171 public String getBodyType() {
172 return bodyType;
173 }
174
175 public String getOutBody() {
176 return outBody;
177 }
178
179 public String getOutBodyType() {
180 return outBodyType;
181 }
182
183 public String getOutHeaders() {
184 return outHeaders;
185 }
186
187 public String getCausedByException() {
188 return causedByException;
189 }
190
191 public void setTimestamp(Date timestamp) {
192 this.timestamp = timestamp;
193 }
194
195 public void setFromEndpointUri(String fromEndpointUri) {
196 this.fromEndpointUri = fromEndpointUri;
197 }
198
199 public void setPreviousNode(String previousNode) {
200 this.previousNode = previousNode;
201 }
202
203 public void setToNode(String toNode) {
204 this.toNode = toNode;
205 }
206
207 public void setExchangeId(String exchangeId) {
208 this.exchangeId = exchangeId;
209 }
210
211 public void setRouteId(String routeId) {
212 this.routeId = routeId;
213 }
214
215 public void setShortExchangeId(String shortExchangeId) {
216 this.shortExchangeId = shortExchangeId;
217 }
218
219 public void setExchangePattern(String exchangePattern) {
220 this.exchangePattern = exchangePattern;
221 }
222
223 public void setProperties(String properties) {
224 this.properties = properties;
225 }
226
227 public void setHeaders(String headers) {
228 this.headers = headers;
229 }
230
231 public void setBody(String body) {
232 this.body = body;
233 }
234
235 public void setBodyType(String bodyType) {
236 this.bodyType = bodyType;
237 }
238
239 public void setOutBody(String outBody) {
240 this.outBody = outBody;
241 }
242
243 public void setOutBodyType(String outBodyType) {
244 this.outBodyType = outBodyType;
245 }
246
247 public void setOutHeaders(String outHeaders) {
248 this.outHeaders = outHeaders;
249 }
250
251 public void setCausedByException(String causedByException) {
252 this.causedByException = causedByException;
253 }
254
255 public Exchange getTracedExchange() {
256 return tracedExchange;
257 }
258
259 @Override
260 public String toString() {
261 return "TraceEventMessage[" + exchangeId + "] on node: " + toNode;
262 }
263 }