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            // false because we don't want to introduce side effects
060            Message out = exchange.getOut(false);
061    
062            // need to use defensive copies to avoid Exchange altering after the point of interception
063            this.timestamp = timestamp;
064            this.fromEndpointUri = exchange.getFromEndpoint() != null ? exchange.getFromEndpoint().getEndpointUri() : null;
065            this.previousNode = extractPreviousNode(exchange);
066            this.toNode = extractNode(toNode);
067            this.exchangeId = exchange.getExchangeId();
068            this.shortExchangeId = extractShortExchangeId(exchange);
069            this.exchangePattern = exchange.getPattern().toString();
070            this.properties = exchange.getProperties().isEmpty() ? null : exchange.getProperties().toString();
071            this.headers = in.getHeaders().isEmpty() ? null : in.getHeaders().toString();
072            this.body = MessageHelper.extractBodyAsString(in);
073            this.bodyType = MessageHelper.getBodyTypeName(in);
074            if (out != null) {
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        private String extractNode(ProcessorDefinition node) {
085            return node.getShortName() + "(" + node.getLabel() + ")";
086        }
087    
088        private String extractShortExchangeId(Exchange exchange) {
089            return exchange.getExchangeId().substring(exchange.getExchangeId().indexOf("/") + 1);
090        }
091    
092        private String extractPreviousNode(Exchange exchange) {
093            if (exchange.getUnitOfWork() instanceof TraceableUnitOfWork) {
094                TraceableUnitOfWork tuow = (TraceableUnitOfWork) exchange.getUnitOfWork();
095                ProcessorDefinition last = tuow.getLastInterceptedNode();
096                return last != null ? extractNode(last) : null;
097            }
098            return null;
099        }
100    
101        // Properties
102        //---------------------------------------------------------------
103    
104        public Date getTimestamp() {
105            return timestamp;
106        }
107    
108        public String getFromEndpointUri() {
109            return fromEndpointUri;
110        }
111    
112        public String getPreviousNode() {
113            return previousNode;
114        }
115    
116        public String getToNode() {
117            return toNode;
118        }
119    
120        public String getExchangeId() {
121            return exchangeId;
122        }
123    
124        public String getShortExchangeId() {
125            return shortExchangeId;
126        }
127    
128        public String getExchangePattern() {
129            return exchangePattern;
130        }
131    
132        public String getProperties() {
133            return properties;
134        }
135    
136        public String getHeaders() {
137            return headers;
138        }
139    
140        public String getBody() {
141            return body;
142        }
143    
144        public String getBodyType() {
145            return bodyType;
146        }
147    
148        public String getOutBody() {
149            return outBody;
150        }
151    
152        public String getOutBodyType() {
153            return outBodyType;
154        }
155    
156        public String getOutHeaders() {
157            return outHeaders;
158        }
159    
160        public void setOutHeaders(String outHeaders) {
161            this.outHeaders = outHeaders;
162        }
163    
164        public String getCausedByException() {
165            return causedByException;
166        }
167    
168        public void setTimestamp(Date timestamp) {
169            this.timestamp = timestamp;
170        }
171    
172        public void setFromEndpointUri(String fromEndpointUri) {
173            this.fromEndpointUri = fromEndpointUri;
174        }
175    
176        public void setPreviousNode(String previousNode) {
177            this.previousNode = previousNode;
178        }
179    
180        public void setToNode(String toNode) {
181            this.toNode = toNode;
182        }
183    
184        public void setExchangeId(String exchangeId) {
185            this.exchangeId = exchangeId;
186        }
187    
188        public void setShortExchangeId(String shortExchangeId) {
189            this.shortExchangeId = shortExchangeId;
190        }
191    
192        public void setExchangePattern(String exchangePattern) {
193            this.exchangePattern = exchangePattern;
194        }
195    
196        public void setProperties(String properties) {
197            this.properties = properties;
198        }
199    
200        public void setHeaders(String headers) {
201            this.headers = headers;
202        }
203    
204        public void setBody(String body) {
205            this.body = body;
206        }
207    
208        public void setBodyType(String bodyType) {
209            this.bodyType = bodyType;
210        }
211    
212        public void setOutBody(String outBody) {
213            this.outBody = outBody;
214        }
215    
216        public void setOutBodyType(String outBodyType) {
217            this.outBodyType = outBodyType;
218        }
219    
220        public void setCausedByException(String causedByException) {
221            this.causedByException = causedByException;
222        }
223    
224        @Override
225        public String toString() {
226            return "TraceEventMessage[" + exchangeId + "] on node: " + toNode;
227        }
228    }