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.jt400;
018    
019    import java.io.IOException;
020    import java.util.concurrent.TimeUnit;
021    
022    import com.ibm.as400.access.AS400;
023    import com.ibm.as400.access.AS400SecurityException;
024    import com.ibm.as400.access.DataQueue;
025    import com.ibm.as400.access.DataQueueEntry;
026    import com.ibm.as400.access.ErrorCompletingRequestException;
027    import com.ibm.as400.access.IllegalObjectTypeException;
028    import com.ibm.as400.access.ObjectDoesNotExistException;
029    
030    import org.apache.camel.Exchange;
031    import org.apache.camel.RuntimeCamelException;
032    import org.apache.camel.component.jt400.Jt400DataQueueEndpoint.Format;
033    import org.apache.camel.impl.DefaultExchange;
034    import org.apache.camel.impl.PollingConsumerSupport;
035    
036    
037    /**
038     * {@link org.apache.camel.PollingConsumer} that polls a data queue for data
039     */
040    public class Jt400DataQueueConsumer extends PollingConsumerSupport {
041    
042        private final Jt400DataQueueEndpoint endpoint;
043    
044        /**
045         * Creates a new consumer instance
046         */
047        protected Jt400DataQueueConsumer(Jt400DataQueueEndpoint endpoint) {
048            super(endpoint);
049            this.endpoint = endpoint;
050        }
051    
052        @Override
053        protected void doStart() throws Exception {
054            if (!endpoint.getSystem().isConnected()) {
055                log.info("Connecting to " + endpoint);
056                endpoint.getSystem().connectService(AS400.DATAQUEUE);
057            }
058        }
059    
060        @Override
061        protected void doStop() throws Exception {
062            if (endpoint.getSystem().isConnected()) {
063                log.info("Disconnecting from " + endpoint);
064                endpoint.getSystem().disconnectAllServices();
065            }
066        }
067    
068        public Exchange receive() {
069            // -1 to indicate a blocking read from data queue
070            return receive(-1);
071        }
072    
073        public Exchange receiveNoWait() {
074            return receive(0);
075        }
076    
077        /**
078         * Receives an entry from a data queue and returns an {@link Exchange} to
079         * send this data If the endpoint's format is set to {@link Format#binary},
080         * the data queue entry's data will be received/sent as a
081         * <code>byte[]</code>. If the endpoint's format is set to
082         * {@link Format#text}, the data queue entry's data will be received/sent as
083         * a <code>String</code>.
084         *
085         * @param timeout time to wait when reading from data queue. A value of -1
086         *            indicates a blocking read.
087         */
088        public Exchange receive(long timeout) {
089            DataQueue queue = endpoint.getDataQueue();
090            try {
091                DataQueueEntry entry;
092                if (timeout >= 0) {
093                    int seconds = (int)timeout / 1000;
094                    if (log.isTraceEnabled()) {
095                        log.trace("Reading from data queue: " + queue.getName() + " with " + seconds + " seconds timeout");
096                    }
097                    entry = queue.read(seconds);
098                } else {
099                    if (log.isTraceEnabled()) {
100                        log.trace("Reading from data queue: " + queue.getName() + " with no timeout");
101                    }
102                    entry = queue.read(-1);
103                }
104    
105                Exchange exchange = new DefaultExchange(endpoint.getCamelContext());
106                if (entry != null) {
107                    if (endpoint.getFormat() == Format.binary) {
108                        exchange.getIn().setBody(entry.getData());
109                    } else {
110                        exchange.getIn().setBody(entry.getString());
111                    }
112                    return exchange;
113                }
114            } catch (AS400SecurityException e) {
115                throw new RuntimeCamelException("Unable to read from data queue: " + queue.getName(), e);
116            } catch (ErrorCompletingRequestException e) {
117                throw new RuntimeCamelException("Unable to read from data queue: " + queue.getName(), e);
118            } catch (IOException e) {
119                throw new RuntimeCamelException("Unable to read from data queue: " + queue.getName(), e);
120            } catch (IllegalObjectTypeException e) {
121                throw new RuntimeCamelException("Unable to read from data queue: " + queue.getName(), e);
122            } catch (InterruptedException e) {
123                throw new RuntimeCamelException("Unable to read from data queue: " + queue.getName(), e);
124            } catch (ObjectDoesNotExistException e) {
125                throw new RuntimeCamelException("Unable to read from data queue: " + queue.getName(), e);
126            }
127            return null;
128        }
129    
130    }