org.apache.blur.trace.hdfs.HdfsTraceStorage.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.blur.trace.hdfs.HdfsTraceStorage.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.blur.trace.hdfs;

import static org.apache.blur.utils.BlurConstants.BLUR_HDFS_TRACE_PATH;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import org.apache.blur.BlurConfiguration;
import org.apache.blur.log.Log;
import org.apache.blur.log.LogFactory;
import org.apache.blur.trace.Trace.TraceId;
import org.apache.blur.trace.TraceCollector;
import org.apache.blur.trace.TraceStorage;
import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.json.JSONException;
import org.json.JSONObject;

public class HdfsTraceStorage extends TraceStorage {

    private final static Log LOG = LogFactory.getLog(HdfsTraceStorage.class);

    private Path _storePath;
    private BlockingQueue<TraceCollector> _queue = new LinkedBlockingQueue<TraceCollector>();
    private Thread _daemon;
    private FileSystem _fileSystem;

    public HdfsTraceStorage(BlurConfiguration configuration) throws IOException {
        super(configuration);
    }

    public void init(Configuration conf) throws IOException {
        _storePath = new Path(_configuration.get(BLUR_HDFS_TRACE_PATH));
        _fileSystem = _storePath.getFileSystem(conf);
        _fileSystem.mkdirs(_storePath);
        _daemon = new Thread(new Runnable() {
            @Override
            public void run() {
                Random random = new Random();
                while (true) {
                    TraceCollector collector;
                    try {
                        collector = _queue.take();
                    } catch (InterruptedException e) {
                        return;
                    }
                    try {
                        writeCollector(collector, random);
                    } catch (Throwable t) {
                        LOG.error("Unknown error while trying to write collector.", t);
                    }
                }
            }
        });
        _daemon.setDaemon(true);
        _daemon.setName("ZooKeeper Trace Queue Writer");
        _daemon.start();
    }

    @Override
    public void store(TraceCollector collector) {
        try {
            _queue.put(collector);
        } catch (InterruptedException e) {
            LOG.error("Unknown error while trying to add collector on queue", e);
        }
    }

    private void writeCollector(TraceCollector collector, Random random) throws IOException {
        TraceId id = collector.getId();
        String storeId = id.getRootId();
        String requestId = id.getRequestId();
        if (requestId == null) {
            requestId = "";
        }
        Path tracePath = getTracePath(storeId);
        JSONObject jsonObject;
        try {
            jsonObject = collector.toJsonObject();
        } catch (JSONException e) {
            throw new IOException(e);
        }
        storeJson(new Path(tracePath, getRequestIdPathName(requestId, random)), jsonObject);
    }

    private String getRequestIdPathName(String requestId, Random random) {
        return requestId + "_" + random.nextLong();
    }

    public void storeJson(Path storePath, JSONObject jsonObject) throws IOException {
        FSDataOutputStream outputStream = _fileSystem.create(storePath, false);
        try {
            OutputStreamWriter writer = new OutputStreamWriter(outputStream);
            jsonObject.write(writer);
            writer.close();
        } catch (JSONException e) {
            throw new IOException(e);
        }
    }

    private Path getTracePath(String traceId) {
        return new Path(_storePath, traceId);
    }

    @Override
    public void close() throws IOException {
        _fileSystem.close();
    }

    @Override
    public List<String> getTraceIds() throws IOException {
        FileStatus[] listStatus = _fileSystem.listStatus(_storePath);
        List<String> traceIds = new ArrayList<String>();
        for (FileStatus status : listStatus) {
            traceIds.add(status.getPath().getName());
        }
        return traceIds;
    }

    @Override
    public List<String> getRequestIds(String traceId) throws IOException {
        List<String> requestIds = new ArrayList<String>();
        Path tracePath = getTracePath(traceId);
        FileStatus[] listStatus = _fileSystem.listStatus(tracePath);
        for (FileStatus status : listStatus) {
            String name = status.getPath().getName();
            int indexOf = name.lastIndexOf('_');
            if (indexOf > 0) {
                requestIds.add(name.substring(0, indexOf));
            }
        }
        return requestIds;
    }

    @Override
    public String getRequestContentsJson(String traceId, String requestId) throws IOException {
        Path path = findPath(traceId, requestId);
        FSDataInputStream inputStream = _fileSystem.open(path);
        try {
            return IOUtils.toString(inputStream);
        } finally {
            inputStream.close();
        }
    }

    private Path findPath(String traceId, String requestId) throws IOException {
        Path tracePath = getTracePath(traceId);
        if (!_fileSystem.exists(tracePath)) {
            throw new IOException("Trace [" + traceId + "] not found.");
        }
        FileStatus[] listStatus = _fileSystem.listStatus(tracePath);
        for (FileStatus status : listStatus) {
            Path path = status.getPath();
            String name = path.getName();
            int indexOf = name.lastIndexOf('_');
            if (indexOf > 0) {
                if (name.substring(0, indexOf).equals(requestId)) {
                    return path;
                }
            }
        }
        throw new IOException("Request [" + requestId + "] not found.");
    }

    @Override
    public void removeTrace(String traceId) throws IOException {
        Path storePath = getTracePath(traceId);
        _fileSystem.delete(storePath, true);
    }

}