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