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