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.impl; 018 019import java.util.AbstractMap; 020import java.util.AbstractSet; 021import java.util.Arrays; 022import java.util.Iterator; 023import java.util.Map; 024import java.util.Set; 025import java.util.concurrent.ConcurrentHashMap; 026 027import org.apache.camel.CamelContext; 028import org.apache.camel.Endpoint; 029import org.apache.camel.spi.EndpointRegistry; 030import org.apache.camel.util.CamelContextHelper; 031import org.apache.camel.util.CompoundIterator; 032import org.apache.camel.util.LRUCache; 033import org.apache.camel.util.LRUCacheFactory; 034import org.apache.camel.util.ServiceHelper; 035 036/** 037 * Default implementation of {@link org.apache.camel.spi.EndpointRegistry} 038 */ 039public class DefaultEndpointRegistry extends AbstractMap<EndpointKey, Endpoint> implements EndpointRegistry<EndpointKey> { 040 private static final long serialVersionUID = 1L; 041 private Map<EndpointKey, Endpoint> dynamicMap; 042 private Map<EndpointKey, Endpoint> staticMap; 043 private final CamelContext context; 044 private int maxCacheSize; 045 046 public DefaultEndpointRegistry(CamelContext context) { 047 this.maxCacheSize = CamelContextHelper.getMaximumEndpointCacheSize(context); 048 // do not stop on eviction, as the validator may still be in use 049 this.dynamicMap = LRUCacheFactory.newLRUCache(maxCacheSize, maxCacheSize, false); 050 // static map to hold endpoints we do not want to be evicted 051 this.staticMap = new ConcurrentHashMap<>(); 052 this.context = context; 053 } 054 055 public DefaultEndpointRegistry(CamelContext context, Map<EndpointKey, Endpoint> endpoints) { 056 this(context); 057 putAll(endpoints); 058 } 059 060 @Override 061 public void start() throws Exception { 062 if (dynamicMap instanceof LRUCache) { 063 ((LRUCache) dynamicMap).resetStatistics(); 064 } 065 } 066 067 @Override 068 public Endpoint get(Object o) { 069 // try static map first 070 Endpoint answer = staticMap.get(o); 071 if (answer == null) { 072 answer = dynamicMap.get(o); 073 if (answer != null && (context.isSetupRoutes() || context.isStartingRoutes())) { 074 dynamicMap.remove(o); 075 staticMap.put((EndpointKey) o, answer); 076 } 077 } 078 return answer; 079 } 080 081 @Override 082 public Endpoint put(EndpointKey key, Endpoint endpoint) { 083 // at first we must see if the key already exists and then replace it back, so it stays the same spot 084 Endpoint answer = staticMap.remove(key); 085 if (answer != null) { 086 // replace existing 087 staticMap.put(key, endpoint); 088 return answer; 089 } 090 091 answer = dynamicMap.remove(key); 092 if (answer != null) { 093 // replace existing 094 dynamicMap.put(key, endpoint); 095 return answer; 096 } 097 098 // we want endpoints to be static if they are part of setting up or starting routes 099 if (context.isSetupRoutes() || context.isStartingRoutes()) { 100 answer = staticMap.put(key, endpoint); 101 } else { 102 answer = dynamicMap.put(key, endpoint); 103 } 104 105 return answer; 106 } 107 108 @Override 109 public boolean containsKey(Object o) { 110 return staticMap.containsKey(o) || dynamicMap.containsKey(o); 111 } 112 113 @Override 114 public boolean containsValue(Object o) { 115 return staticMap.containsValue(o) || dynamicMap.containsValue(o); 116 } 117 118 @Override 119 public int size() { 120 return staticMap.size() + dynamicMap.size(); 121 } 122 123 public int staticSize() { 124 return staticMap.size(); 125 } 126 127 @Override 128 public int dynamicSize() { 129 return dynamicMap.size(); 130 } 131 132 @Override 133 public boolean isEmpty() { 134 return staticMap.isEmpty() && dynamicMap.isEmpty(); 135 } 136 137 @Override 138 public Endpoint remove(Object o) { 139 Endpoint answer = staticMap.remove(o); 140 if (answer == null) { 141 answer = dynamicMap.remove(o); 142 } 143 return answer; 144 } 145 146 @Override 147 public void clear() { 148 staticMap.clear(); 149 dynamicMap.clear(); 150 } 151 152 @Override 153 public Set<Entry<EndpointKey, Endpoint>> entrySet() { 154 return new AbstractSet<Entry<EndpointKey, Endpoint>>() { 155 @Override 156 public Iterator<Entry<EndpointKey, Endpoint>> iterator() { 157 return new CompoundIterator<>(Arrays.asList( 158 staticMap.entrySet().iterator(), dynamicMap.entrySet().iterator() 159 )); 160 } 161 162 @Override 163 public int size() { 164 return staticMap.size() + dynamicMap.size(); 165 } 166 }; 167 } 168 169 @Override 170 public int getMaximumCacheSize() { 171 return maxCacheSize; 172 } 173 174 /** 175 * Purges the cache 176 */ 177 @Override 178 public void purge() { 179 // only purge the dynamic part 180 dynamicMap.clear(); 181 } 182 183 @Override 184 public void cleanUp() { 185 if (dynamicMap instanceof LRUCache) { 186 ((LRUCache) dynamicMap).cleanUp(); 187 } 188 } 189 190 @Override 191 public boolean isStatic(String key) { 192 return staticMap.containsKey(new EndpointKey(key)); 193 } 194 195 @Override 196 public boolean isDynamic(String key) { 197 return dynamicMap.containsKey(new EndpointKey(key)); 198 } 199 200 @Override 201 public void stop() throws Exception { 202 ServiceHelper.stopServices(staticMap.values()); 203 ServiceHelper.stopServices(values()); 204 purge(); 205 } 206 207 @Override 208 public String toString() { 209 return "EndpointRegistry for " + context.getName() + ", capacity: " + maxCacheSize; 210 } 211}