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.hdfs;
018    
019    import java.io.Closeable;
020    import java.io.IOException;
021    import java.util.concurrent.atomic.AtomicLong;
022    import javax.xml.ws.Holder;
023    
024    import org.apache.hadoop.fs.Path;
025    import org.apache.hadoop.io.IOUtils;
026    
027    public class HdfsInputStream {
028    
029        private HdfsFileType fileType;
030        private String actualPath;
031        private String suffixedPath;
032        private Closeable in;
033        private boolean opened;
034        private int chunkSize;
035        private final AtomicLong numOfReadBytes = new AtomicLong(0L);
036        private final AtomicLong numOfReadMessages = new AtomicLong(0L);
037    
038        protected HdfsInputStream() {
039        }
040    
041        public static HdfsInputStream createInputStream(String hdfsPath, HdfsConfiguration configuration) throws IOException {
042            HdfsInputStream ret = new HdfsInputStream();
043            ret.fileType = configuration.getFileType();
044            ret.actualPath = hdfsPath;
045            ret.suffixedPath = ret.actualPath + '.' + configuration.getOpenedSuffix();
046            ret.chunkSize = configuration.getChunkSize();
047            HdfsInfo info = new HdfsInfo(ret.actualPath);
048            info.getFileSystem().rename(new Path(ret.actualPath), new Path(ret.suffixedPath));
049            ret.in = ret.fileType.createInputStream(ret.suffixedPath, configuration);
050            ret.opened = true;
051            return ret;
052        }
053    
054        public final void close() throws IOException {
055            if (opened) {
056                IOUtils.closeStream(in);
057                HdfsInfo info = new HdfsInfo(actualPath);
058                info.getFileSystem().rename(new Path(suffixedPath), new Path(actualPath + '.' + HdfsConstants.DEFAULT_READ_SUFFIX));
059                opened = false;
060            }
061        }
062    
063        public final long next(Holder<Object> key, Holder<Object> value) {
064            long nb = fileType.next(this, key, value);
065            if (nb > 0) {
066                numOfReadBytes.addAndGet(nb);
067                numOfReadMessages.incrementAndGet();
068            }
069            return nb;
070        }
071    
072        public final long getNumOfReadBytes() {
073            return numOfReadBytes.longValue();
074        }
075    
076        public final long getNumOfReadMessages() {
077            return numOfReadMessages.longValue();
078        }
079    
080        public final String getActualPath() {
081            return actualPath;
082        }
083    
084        public final int getChunkSize() {
085            return chunkSize;
086        }
087    
088        public final Closeable getIn() {
089            return in;
090        }
091    
092    }