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 */ 017package org.apache.camel.processor.interceptor; 018 019import java.util.Date; 020import java.util.HashMap; 021import java.util.Map; 022 023import org.apache.camel.Endpoint; 024import org.apache.camel.Exchange; 025import org.apache.camel.Processor; 026import org.apache.camel.Producer; 027import org.apache.camel.Service; 028import org.apache.camel.impl.DefaultExchange; 029import org.apache.camel.model.ProcessorDefinition; 030import org.apache.camel.util.IntrospectionSupport; 031import org.apache.camel.util.ObjectHelper; 032import org.apache.camel.util.ServiceHelper; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035 036@Deprecated 037public class DefaultTraceEventHandler implements TraceEventHandler, Service { 038 private static final Logger LOG = LoggerFactory.getLogger(DefaultTraceEventHandler.class); 039 040 private Producer traceEventProducer; 041 private Class<?> jpaTraceEventMessageClass; 042 private String jpaTraceEventMessageClassName; 043 044 private final Tracer tracer; 045 046 public DefaultTraceEventHandler(Tracer tracer) { 047 this.tracer = tracer; 048 } 049 050 private synchronized void loadJpaTraceEventMessageClass(Exchange exchange) { 051 if (jpaTraceEventMessageClass == null) { 052 jpaTraceEventMessageClassName = tracer.getJpaTraceEventMessageClassName(); 053 } 054 if (jpaTraceEventMessageClass == null) { 055 jpaTraceEventMessageClass = exchange.getContext().getClassResolver().resolveClass(jpaTraceEventMessageClassName); 056 if (jpaTraceEventMessageClass == null) { 057 throw new IllegalArgumentException("Cannot find class: " + jpaTraceEventMessageClassName 058 + ". Make sure camel-jpa.jar is in the classpath."); 059 } 060 } 061 } 062 063 private synchronized Producer getTraceEventProducer(Exchange exchange) throws Exception { 064 if (traceEventProducer == null) { 065 // create producer when we have access the the camel context (we dont in doStart) 066 Endpoint endpoint = tracer.getDestination() != null ? tracer.getDestination() : exchange.getContext().getEndpoint(tracer.getDestinationUri()); 067 traceEventProducer = endpoint.createProducer(); 068 ServiceHelper.startService(traceEventProducer); 069 } 070 return traceEventProducer; 071 } 072 073 @Override 074 public void traceExchange(ProcessorDefinition<?> node, Processor target, TraceInterceptor traceInterceptor, Exchange exchange) throws Exception { 075 if (tracer.getDestination() != null || tracer.getDestinationUri() != null) { 076 077 // create event exchange and add event information 078 Date timestamp = new Date(); 079 Exchange event = new DefaultExchange(exchange); 080 event.setProperty(Exchange.TRACE_EVENT_NODE_ID, node.getId()); 081 event.setProperty(Exchange.TRACE_EVENT_TIMESTAMP, timestamp); 082 // keep a reference to the original exchange in case its needed 083 event.setProperty(Exchange.TRACE_EVENT_EXCHANGE, exchange); 084 085 // create event message to sent as in body containing event information such as 086 // from node, to node, etc. 087 TraceEventMessage msg = new DefaultTraceEventMessage(timestamp, node, exchange); 088 089 // should we use ordinary or jpa objects 090 if (tracer.isUseJpa()) { 091 if (LOG.isTraceEnabled()) { 092 LOG.trace("Using class: " + this.jpaTraceEventMessageClassName + " for tracing event messages"); 093 } 094 095 // load the jpa event message class 096 loadJpaTraceEventMessageClass(exchange); 097 // create a new instance of the event message class 098 Object jpa = ObjectHelper.newInstance(jpaTraceEventMessageClass); 099 100 // copy options from event to jpa 101 Map<String, Object> options = new HashMap<String, Object>(); 102 IntrospectionSupport.getProperties(msg, options, null); 103 IntrospectionSupport.setProperties(exchange.getContext().getTypeConverter(), jpa, options); 104 // and set the timestamp as its not a String type 105 IntrospectionSupport.setProperty(exchange.getContext().getTypeConverter(), jpa, "timestamp", msg.getTimestamp()); 106 107 event.getIn().setBody(jpa); 108 } else { 109 event.getIn().setBody(msg); 110 } 111 112 // marker property to indicate its a tracing event being routed in case 113 // new Exchange instances is created during trace routing so we can check 114 // for this marker when interceptor also kick in during routing of trace events 115 event.setProperty(Exchange.TRACE_EVENT, Boolean.TRUE); 116 try { 117 // process the trace route 118 getTraceEventProducer(exchange).process(event); 119 } catch (Exception e) { 120 // log and ignore this as the original Exchange should be allowed to continue 121 LOG.error("Error processing trace event (original Exchange will continue): " + event, e); 122 } 123 } 124 } 125 126 @Override 127 public Object traceExchangeIn(ProcessorDefinition<?> node, Processor target, TraceInterceptor traceInterceptor, Exchange exchange) throws Exception { 128 traceExchange(node, target, traceInterceptor, exchange); 129 return null; 130 } 131 132 @Override 133 public void traceExchangeOut(ProcessorDefinition<?> node, Processor target, TraceInterceptor traceInterceptor, Exchange exchange, Object traceState) throws Exception { 134 traceExchange(node, target, traceInterceptor, exchange); 135 } 136 137 @Override 138 public void start() throws Exception { 139 traceEventProducer = null; 140 } 141 142 @Override 143 public void stop() throws Exception { 144 if (traceEventProducer != null) { 145 ServiceHelper.stopService(traceEventProducer); 146 } 147 } 148 149}