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.component.directvm;
018
019 import java.util.Map;
020 import java.util.concurrent.ConcurrentHashMap;
021 import java.util.concurrent.ConcurrentMap;
022 import java.util.concurrent.atomic.AtomicInteger;
023
024 import org.apache.camel.Endpoint;
025 import org.apache.camel.impl.DefaultComponent;
026
027 /**
028 * Represents the component that manages {@link DirectVmEndpoint}. It holds the
029 * list of named direct-vm endpoints.
030 */
031 public class DirectVmComponent extends DefaultComponent {
032
033 private static final AtomicInteger START_COUNTER = new AtomicInteger();
034
035 // must keep a map of consumers on the component to ensure endpoints can lookup old consumers
036 // later in case the DirectVmEndpoint was re-created due the old was evicted from the endpoints LRUCache
037 // on DefaultCamelContext
038 private static final ConcurrentMap<String, DirectVmConsumer> CONSUMERS = new ConcurrentHashMap<String, DirectVmConsumer>();
039
040 @Override
041 protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
042 DirectVmEndpoint answer = new DirectVmEndpoint(uri, this);
043 answer.configureProperties(parameters);
044 return answer;
045 }
046
047 public DirectVmConsumer getConsumer(DirectVmEndpoint endpoint) {
048 String key = getConsumerKey(endpoint.getEndpointUri());
049 return CONSUMERS.get(key);
050 }
051
052 public void addConsumer(DirectVmEndpoint endpoint, DirectVmConsumer consumer) {
053 String key = getConsumerKey(endpoint.getEndpointUri());
054 DirectVmConsumer existing = CONSUMERS.putIfAbsent(key, consumer);
055 if (existing != null) {
056 String contextId = existing.getEndpoint().getCamelContext().getName();
057 throw new IllegalStateException("A consumer " + existing + " already exists from CamelContext: " + contextId + ". Multiple consumers not supported");
058 }
059 }
060
061 public void removeConsumer(DirectVmEndpoint endpoint, DirectVmConsumer consumer) {
062 String key = getConsumerKey(endpoint.getEndpointUri());
063 CONSUMERS.remove(key);
064 }
065
066 private static String getConsumerKey(String uri) {
067 if (uri.contains("?")) {
068 // strip parameters
069 uri = uri.substring(0, uri.indexOf('?'));
070 }
071 return uri;
072 }
073
074 @Override
075 protected void doStart() throws Exception {
076 super.doStart();
077 START_COUNTER.incrementAndGet();
078 }
079
080 @Override
081 protected void doStop() throws Exception {
082 if (START_COUNTER.decrementAndGet() <= 0) {
083 // clear queues when no more direct-vm components in use
084 CONSUMERS.clear();
085 }
086 super.doStop();
087 }
088
089 }