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.impl;
018    
019    import java.util.concurrent.ConcurrentHashMap;
020    import java.util.concurrent.atomic.AtomicInteger;
021    
022    import org.apache.camel.Endpoint;
023    import org.apache.camel.Exchange;
024    import org.apache.camel.spi.InflightRepository;
025    import org.apache.commons.logging.Log;
026    import org.apache.commons.logging.LogFactory;
027    
028    /**
029     * Default implement which just uses a counter
030     *
031     * @version $Revision: 892587 $
032     */
033    public class DefaultInflightRepository extends ServiceSupport implements InflightRepository  {
034    
035        private static final transient Log LOG = LogFactory.getLog(DefaultInflightRepository.class);
036        private final AtomicInteger totalCount = new AtomicInteger();
037        // us endpoint key as key so endpoints with lenient properties is registered using the same key (eg dynamic http endpoints)
038        private final ConcurrentHashMap<String, AtomicInteger> endpointCount = new ConcurrentHashMap<String, AtomicInteger>();
039    
040        public void add(Exchange exchange) {
041            int count = totalCount.incrementAndGet();
042            if (LOG.isTraceEnabled()) {
043                LOG.trace("Total " + count + " inflight exchanges. Last added: " + exchange.getExchangeId());
044            }
045    
046            if (exchange.getFromEndpoint() == null) {
047                return;
048            }
049    
050            String key = exchange.getFromEndpoint().getEndpointKey();
051            AtomicInteger existing = endpointCount.putIfAbsent(key, new AtomicInteger(1));
052            if (existing != null) {
053                existing.addAndGet(1);
054            }
055        }
056    
057        public void remove(Exchange exchange) {
058            int count = totalCount.decrementAndGet();
059            if (LOG.isTraceEnabled()) {
060                LOG.trace("Total " + count + " inflight exchanges. Last removed: " + exchange.getExchangeId());
061            }
062    
063            if (exchange.getFromEndpoint() == null) {
064                return;
065            }
066    
067            String key = exchange.getFromEndpoint().getEndpointKey();
068            AtomicInteger existing = endpointCount.get(key);
069            if (existing != null) {
070                existing.addAndGet(-1);
071            }
072        }
073    
074        public int size() {
075            return totalCount.get();
076        }
077    
078        public int size(Endpoint endpoint) {
079            AtomicInteger answer = endpointCount.get(endpoint.getEndpointKey());
080            return answer != null ? answer.get() : 0;
081        }
082    
083        @Override
084        protected void doStart() throws Exception {
085        }
086    
087        @Override
088        protected void doStop() throws Exception {
089            int count = size();
090            if (count > 0) {
091                LOG.warn("Shutting down while there are still " + count + " in flight exchanges.");
092            } else {
093                LOG.info("Shutting down with no inflight exchanges.");
094            }
095            endpointCount.clear();
096        }
097    }