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 final transient Exchange tracedExchange;
051    
052        /**
053         * Creates a {@link DefaultTraceEventMessage} based on the given node it was traced while processing
054         * the current {@link Exchange}
055         *
056         * @param toNode the node where this trace is intercepted
057         * @param exchange the current {@link Exchange}
058         */
059        public DefaultTraceEventMessage(final Date timestamp, final ProcessorDefinition<?> toNode, final Exchange exchange) {
060            this.tracedExchange = exchange;
061            Message in = exchange.getIn();
062    
063            // need to use defensive copies to avoid Exchange altering after the point of interception
064            this.timestamp = timestamp;
065            this.fromEndpointUri = exchange.getFromEndpoint() != null ? exchange.getFromEndpoint().getEndpointUri() : null;
066            this.previousNode = extractFromNode(exchange);
067            this.toNode = extractToNode(exchange);
068            this.exchangeId = exchange.getExchangeId();
069            this.shortExchangeId = extractShortExchangeId(exchange);
070            this.exchangePattern = exchange.getPattern().toString();
071            this.properties = exchange.getProperties().isEmpty() ? null : exchange.getProperties().toString();
072            this.headers = in.getHeaders().isEmpty() ? null : in.getHeaders().toString();
073            this.body = MessageHelper.extractBodyAsString(in);
074            this.bodyType = MessageHelper.getBodyTypeName(in);
075            if (exchange.hasOut()) {
076                Message out = exchange.getOut();
077                this.outHeaders = out.getHeaders().isEmpty() ? null : out.getHeaders().toString();
078                this.outBody = MessageHelper.extractBodyAsString(out);
079                this.outBodyType = MessageHelper.getBodyTypeName(out);
080            }
081            this.causedByException = exchange.getException() != null ? exchange.getException().toString() : null;
082        }
083    
084        // Implementation
085        //---------------------------------------------------------------
086    
087        private static String extractShortExchangeId(Exchange exchange) {
088            return exchange.getExchangeId().substring(exchange.getExchangeId().indexOf("/") + 1);
089        }
090    
091        private static String extractFromNode(Exchange exchange) {
092            if (exchange.getUnitOfWork() != null) {
093                TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes();
094                RouteNode last = traced.getSecondLastNode();
095                return last != null ? last.getLabel(exchange) : null;
096            }
097            return null;
098        }
099    
100        private static String extractToNode(Exchange exchange) {
101            if (exchange.getUnitOfWork() != null) {
102                TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes();
103                RouteNode last = traced.getLastNode();
104                return last != null ? last.getLabel(exchange) : null;
105            }
106            return null;
107        }
108    
109        // Properties
110        //---------------------------------------------------------------
111    
112        public Date getTimestamp() {
113            return timestamp;
114        }
115    
116        public String getFromEndpointUri() {
117            return fromEndpointUri;
118        }
119    
120        public String getPreviousNode() {
121            return previousNode;
122        }
123    
124        public String getToNode() {
125            return toNode;
126        }
127    
128        public String getExchangeId() {
129            return exchangeId;
130        }
131    
132        public String getShortExchangeId() {
133            return shortExchangeId;
134        }
135    
136        public String getExchangePattern() {
137            return exchangePattern;
138        }
139    
140        public String getProperties() {
141            return properties;
142        }
143    
144        public String getHeaders() {
145            return headers;
146        }
147    
148        public String getBody() {
149            return body;
150        }
151    
152        public String getBodyType() {
153            return bodyType;
154        }
155    
156        public String getOutBody() {
157            return outBody;
158        }
159    
160        public String getOutBodyType() {
161            return outBodyType;
162        }
163    
164        public String getOutHeaders() {
165            return outHeaders;
166        }
167    
168        public void setOutHeaders(String outHeaders) {
169            this.outHeaders = outHeaders;
170        }
171    
172        public String getCausedByException() {
173            return causedByException;
174        }
175    
176        public void setTimestamp(Date timestamp) {
177            this.timestamp = timestamp;
178        }
179    
180        public void setFromEndpointUri(String fromEndpointUri) {
181            this.fromEndpointUri = fromEndpointUri;
182        }
183    
184        public void setPreviousNode(String previousNode) {
185            this.previousNode = previousNode;
186        }
187    
188        public void setToNode(String toNode) {
189            this.toNode = toNode;
190        }
191    
192        public void setExchangeId(String exchangeId) {
193            this.exchangeId = exchangeId;
194        }
195    
196        public void setShortExchangeId(String shortExchangeId) {
197            this.shortExchangeId = shortExchangeId;
198        }
199    
200        public void setExchangePattern(String exchangePattern) {
201            this.exchangePattern = exchangePattern;
202        }
203    
204        public void setProperties(String properties) {
205            this.properties = properties;
206        }
207    
208        public void setHeaders(String headers) {
209            this.headers = headers;
210        }
211    
212        public void setBody(String body) {
213            this.body = body;
214        }
215    
216        public void setBodyType(String bodyType) {
217            this.bodyType = bodyType;
218        }
219    
220        public void setOutBody(String outBody) {
221            this.outBody = outBody;
222        }
223    
224        public void setOutBodyType(String outBodyType) {
225            this.outBodyType = outBodyType;
226        }
227    
228        public void setCausedByException(String causedByException) {
229            this.causedByException = causedByException;
230        }
231    
232        public Exchange getTracedExchange() {
233            return tracedExchange;
234        }
235    
236        @Override
237        public String toString() {
238            return "TraceEventMessage[" + exchangeId + "] on node: " + toNode;
239        }
240    }