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.cometd;
018    
019    import org.apache.camel.Exchange;
020    import org.apache.camel.impl.DefaultProducer;
021    import org.cometd.bayeux.server.BayeuxServer;
022    import org.cometd.bayeux.server.ServerChannel;
023    import org.cometd.bayeux.server.ServerSession;
024    import org.cometd.server.AbstractService;
025    import org.cometd.server.BayeuxServerImpl;
026    import org.slf4j.Logger;
027    import org.slf4j.LoggerFactory;
028    
029    /**
030     * A Producer to send messages using Cometd and Bayeux protocol.
031     */
032    public class CometdProducer extends DefaultProducer implements CometdProducerConsumer {
033        private static final transient Logger LOG = LoggerFactory.getLogger(CometdProducer.class);
034    
035        private BayeuxServerImpl bayeux;
036        private ProducerService service;
037        private final CometdEndpoint endpoint;
038    
039        public CometdProducer(CometdEndpoint endpoint) {
040            super(endpoint);
041            this.endpoint = endpoint;
042        }
043    
044        @Override
045        public void start() throws Exception {
046            super.start();
047            // must connect first
048            endpoint.connect(this);
049            service = new ProducerService(getBayeux(), endpoint.getPath(), this);
050        }
051    
052        @Override
053        public void stop() throws Exception {
054            super.stop();
055            endpoint.disconnect(this);
056        }
057    
058        public void process(final Exchange exchange) {
059            service.process(exchange);
060        }
061    
062        public CometdEndpoint getEndpoint() {
063            return endpoint;
064        }
065    
066        public BayeuxServerImpl getBayeux() {
067            return bayeux;
068        }
069    
070        public void setBayeux(BayeuxServerImpl bayeux) {
071            this.bayeux = bayeux;
072        }
073    
074        public static class ProducerService extends AbstractService {
075    
076            private final CometdProducer producer;
077    
078            public ProducerService(BayeuxServer bayeux, String channel, CometdProducer producer) {
079                super(bayeux, channel);
080                this.producer = producer;
081            }
082    
083            public void process(final Exchange exchange) {
084                String channelName = producer.getEndpoint().getPath();
085                BayeuxServerImpl bayeux = producer.getBayeux();
086                ServerChannel channel = bayeux.getChannel(channelName);
087                ServerSession serverSession = getServerSession();
088    
089                if (channel != null) {
090                    logDelivery(exchange, channel);
091                    channel.publish(serverSession, exchange.getIn().getBody(), null);
092                }
093            }
094    
095            private void logDelivery(Exchange exchange, ServerChannel channel) {
096                if (LOG.isTraceEnabled()) {
097                    LOG.trace(String.format("Delivering to clients %s path: %s exchange: %s",
098                            channel.getSubscribers(), channel, exchange));
099                }
100            }
101        }
102    }