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.util; 018 019import java.util.ArrayList; 020import java.util.Collections; 021import java.util.List; 022 023import org.apache.camel.Exchange; 024import org.apache.camel.Route; 025import org.apache.camel.spi.Synchronization; 026import org.apache.camel.spi.SynchronizationRouteAware; 027import org.apache.camel.spi.UnitOfWork; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030 031/** 032 * Utility methods for {@link org.apache.camel.spi.UnitOfWork} 033 * 034 * @version 035 */ 036public final class UnitOfWorkHelper { 037 038 private static final Logger LOG = LoggerFactory.getLogger(UnitOfWorkHelper.class); 039 040 private UnitOfWorkHelper() { 041 } 042 043 /** 044 * Creates a new {@link UnitOfWork}. 045 * 046 * @param exchange the exchange 047 * @return the created unit of work (is not started) 048 * @deprecated use {@link org.apache.camel.CamelContext#getUnitOfWorkFactory()} instead. 049 */ 050 @Deprecated 051 public static UnitOfWork createUoW(Exchange exchange) { 052 return exchange.getContext().getUnitOfWorkFactory().createUnitOfWork(exchange); 053 } 054 055 /** 056 * Done and stop the {@link UnitOfWork}. 057 * 058 * @param uow the unit of work 059 * @param exchange the exchange (will unset the UoW on the exchange) 060 */ 061 public static void doneUow(UnitOfWork uow, Exchange exchange) { 062 // unit of work is done 063 try { 064 if (uow != null) { 065 uow.done(exchange); 066 } 067 } catch (Throwable e) { 068 LOG.warn("Exception occurred during done UnitOfWork for Exchange: " + exchange 069 + ". This exception will be ignored.", e); 070 } 071 try { 072 if (uow != null) { 073 uow.stop(); 074 } 075 } catch (Throwable e) { 076 LOG.warn("Exception occurred during stopping UnitOfWork for Exchange: " + exchange 077 + ". This exception will be ignored.", e); 078 } 079 080 // remove uow from exchange as its done 081 exchange.setUnitOfWork(null); 082 } 083 084 public static void doneSynchronizations(Exchange exchange, List<Synchronization> synchronizations, Logger log) { 085 boolean failed = exchange.isFailed(); 086 087 if (synchronizations != null && !synchronizations.isEmpty()) { 088 // work on a copy of the list to avoid any modification which may cause ConcurrentModificationException 089 List<Synchronization> copy = new ArrayList<Synchronization>(synchronizations); 090 091 // reverse so we invoke it FILO style instead of FIFO 092 Collections.reverse(copy); 093 // and honor if any was ordered by sorting it accordingly 094 copy.sort(OrderedComparator.get()); 095 096 // invoke synchronization callbacks 097 for (Synchronization synchronization : copy) { 098 try { 099 if (failed) { 100 log.trace("Invoking synchronization.onFailure: {} with {}", synchronization, exchange); 101 synchronization.onFailure(exchange); 102 } else { 103 log.trace("Invoking synchronization.onComplete: {} with {}", synchronization, exchange); 104 synchronization.onComplete(exchange); 105 } 106 } catch (Throwable e) { 107 // must catch exceptions to ensure all synchronizations have a chance to run 108 log.warn("Exception occurred during onCompletion. This exception will be ignored.", e); 109 } 110 } 111 } 112 } 113 114 public static void beforeRouteSynchronizations(Route route, Exchange exchange, List<Synchronization> synchronizations, Logger log) { 115 if (synchronizations != null && !synchronizations.isEmpty()) { 116 // work on a copy of the list to avoid any modification which may cause ConcurrentModificationException 117 List<Synchronization> copy = new ArrayList<Synchronization>(synchronizations); 118 119 // reverse so we invoke it FILO style instead of FIFO 120 Collections.reverse(copy); 121 // and honor if any was ordered by sorting it accordingly 122 copy.sort(OrderedComparator.get()); 123 124 // invoke synchronization callbacks 125 for (Synchronization synchronization : copy) { 126 if (synchronization instanceof SynchronizationRouteAware) { 127 try { 128 log.trace("Invoking synchronization.onBeforeRoute: {} with {}", synchronization, exchange); 129 ((SynchronizationRouteAware) synchronization).onBeforeRoute(route, exchange); 130 } catch (Throwable e) { 131 // must catch exceptions to ensure all synchronizations have a chance to run 132 log.warn("Exception occurred during onBeforeRoute. This exception will be ignored.", e); 133 } 134 } 135 } 136 } 137 } 138 139 public static void afterRouteSynchronizations(Route route, Exchange exchange, List<Synchronization> synchronizations, Logger log) { 140 if (synchronizations != null && !synchronizations.isEmpty()) { 141 // work on a copy of the list to avoid any modification which may cause ConcurrentModificationException 142 List<Synchronization> copy = new ArrayList<Synchronization>(synchronizations); 143 144 // reverse so we invoke it FILO style instead of FIFO 145 Collections.reverse(copy); 146 // and honor if any was ordered by sorting it accordingly 147 copy.sort(OrderedComparator.get()); 148 149 // invoke synchronization callbacks 150 for (Synchronization synchronization : copy) { 151 if (synchronization instanceof SynchronizationRouteAware) { 152 try { 153 log.trace("Invoking synchronization.onAfterRoute: {} with {}", synchronization, exchange); 154 ((SynchronizationRouteAware) synchronization).onAfterRoute(route, exchange); 155 } catch (Throwable e) { 156 // must catch exceptions to ensure all synchronizations have a chance to run 157 log.warn("Exception occurred during onAfterRoute. This exception will be ignored.", e); 158 } 159 } 160 } 161 } 162 } 163 164}