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 org.apache.camel.AsyncCallback;
020import org.apache.camel.AsyncProcessor;
021import org.apache.camel.Endpoint;
022import org.apache.camel.Exchange;
023import org.apache.camel.ExchangePattern;
024import org.apache.camel.Producer;
025import org.apache.camel.util.ServiceHelper;
026
027/**
028 * A {@link Producer} that defers being started, until {@link org.apache.camel.CamelContext} has been started, this
029 * ensures that the producer is able to adapt to changes that may otherwise occur during starting
030 * CamelContext. If we do not defer starting the producer it may not adapt to those changes, and
031 * send messages to wrong endpoints.
032 */
033public class DeferProducer extends org.apache.camel.support.ServiceSupport implements Producer, AsyncProcessor {
034
035    private Producer delegate;
036    private final Endpoint endpoint;
037
038    public DeferProducer(Endpoint endpoint) {
039        this.endpoint = endpoint;
040    }
041
042    @Override
043    public Exchange createExchange() {
044        if (delegate == null) {
045            throw new IllegalStateException("Not started");
046        }
047        return delegate.createExchange();
048    }
049
050    @Override
051    public Exchange createExchange(ExchangePattern pattern) {
052        if (delegate == null) {
053            throw new IllegalStateException("Not started");
054        }
055        return delegate.createExchange(pattern);
056    }
057
058    @Override
059    @Deprecated
060    public Exchange createExchange(Exchange exchange) {
061        if (delegate == null) {
062            throw new IllegalStateException("Not started");
063        }
064        return delegate.createExchange(exchange);
065    }
066
067    @Override
068    public void process(Exchange exchange) throws Exception {
069        if (delegate == null) {
070            throw new IllegalStateException("Not started");
071        }
072        delegate.process(exchange);
073    }
074
075    @Override
076    public boolean process(Exchange exchange, AsyncCallback callback) {
077        if (delegate == null) {
078            exchange.setException(new IllegalStateException("Not started"));
079            callback.done(true);
080            return true;
081        }
082
083        if (delegate instanceof AsyncProcessor) {
084            return ((AsyncProcessor) delegate).process(exchange, callback);
085        }
086
087        // fallback to sync mode
088        try {
089            process(exchange);
090        } catch (Exception e) {
091            exchange.setException(e);
092        }
093
094        callback.done(true);
095        return true;
096    }
097
098    @Override
099    protected void doStart() throws Exception {
100        // need to lookup endpoint again as it may be intercepted
101        Endpoint lookup = endpoint.getCamelContext().getEndpoint(endpoint.getEndpointUri());
102
103        delegate = lookup.createProducer();
104        ServiceHelper.startService(delegate);
105    }
106
107    @Override
108    protected void doStop() throws Exception {
109        ServiceHelper.stopService(delegate);
110    }
111
112    @Override
113    public boolean isSingleton() {
114        if (delegate != null) {
115            return delegate.isSingleton();
116        } else {
117            // assume singleton by default
118            return true;
119        }
120    }
121
122    @Override
123    public Endpoint getEndpoint() {
124        if (delegate != null) {
125            return delegate.getEndpoint();
126        } else {
127            return endpoint;
128        }
129    }
130
131    @Override
132    public String toString() {
133        if (delegate != null) {
134            return delegate.toString();
135        } else {
136            return "DelegateProducer[" + endpoint + "]";
137        }
138    }
139
140}