com.yahoo.ycsb.db.RadosClient.java Source code

Java tutorial

Introduction

Here is the source code for com.yahoo.ycsb.db.RadosClient.java

Source

/**
 * Copyright (c) 2016 YCSB contributors. All rights reserved.
 *
 * Licensed 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. See accompanying
 * LICENSE file.
 */

package com.yahoo.ycsb.db;

import com.ceph.rados.Rados;
import com.ceph.rados.IoCTX;
import com.ceph.rados.jna.RadosObjectInfo;
import com.ceph.rados.ReadOp;
import com.ceph.rados.ReadOp.ReadResult;
import com.ceph.rados.exceptions.RadosException;

import com.yahoo.ycsb.ByteIterator;
import com.yahoo.ycsb.DB;
import com.yahoo.ycsb.DBException;
import com.yahoo.ycsb.Status;
import com.yahoo.ycsb.StringByteIterator;

import java.io.File;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;

import org.json.JSONObject;

/**
 * YCSB binding for <a href="http://ceph.org/">RADOS of Ceph</a>.
 *
 * See {@code rados/README.md} for details.
 */
public class RadosClient extends DB {

    private Rados rados;
    private IoCTX ioctx;

    public static final String CONFIG_FILE_PROPERTY = "rados.configfile";
    public static final String CONFIG_FILE_DEFAULT = "/etc/ceph/ceph.conf";
    public static final String ID_PROPERTY = "rados.id";
    public static final String ID_DEFAULT = "admin";
    public static final String POOL_PROPERTY = "rados.pool";
    public static final String POOL_DEFAULT = "data";

    private boolean isInited = false;

    public void init() throws DBException {
        Properties props = getProperties();

        String configfile = props.getProperty(CONFIG_FILE_PROPERTY);
        if (configfile == null) {
            configfile = CONFIG_FILE_DEFAULT;
        }

        String id = props.getProperty(ID_PROPERTY);
        if (id == null) {
            id = ID_DEFAULT;
        }

        String pool = props.getProperty(POOL_PROPERTY);
        if (pool == null) {
            pool = POOL_DEFAULT;
        }

        // try {
        // } catch (UnsatisfiedLinkError e) {
        //   throw new DBException("RADOS library is not loaded.");
        // }

        rados = new Rados(id);
        try {
            rados.confReadFile(new File(configfile));
            rados.connect();
            ioctx = rados.ioCtxCreate(pool);
        } catch (RadosException e) {
            throw new DBException(e.getMessage() + ": " + e.getReturnValue());
        }

        isInited = true;
    }

    public void cleanup() throws DBException {
        if (isInited) {
            rados.shutDown();
            rados.ioCtxDestroy(ioctx);
            isInited = false;
        }
    }

    @Override
    public Status read(String table, String key, Set<String> fields, HashMap<String, ByteIterator> result) {
        byte[] buffer;

        try {
            RadosObjectInfo info = ioctx.stat(key);
            buffer = new byte[(int) info.getSize()];

            ReadOp rop = ioctx.readOpCreate();
            ReadResult readResult = rop.queueRead(0, info.getSize());
            // TODO: more size than byte length possible;
            // rop.operate(key, Rados.OPERATION_NOFLAG); // for rados-java 0.3.0
            rop.operate(key, 0);
            // readResult.raiseExceptionOnError("Error ReadOP(%d)", readResult.getRVal()); // for rados-java 0.3.0
            if (readResult.getRVal() < 0) {
                throw new RadosException("Error ReadOP", readResult.getRVal());
            }
            if (info.getSize() != readResult.getBytesRead()) {
                return new Status("ERROR", "Error the object size read");
            }
            readResult.getBuffer().get(buffer);
        } catch (RadosException e) {
            return new Status("ERROR-" + e.getReturnValue(), e.getMessage());
        }

        JSONObject json = new JSONObject(new String(buffer, java.nio.charset.StandardCharsets.UTF_8));
        Set<String> fieldsToReturn = (fields == null ? json.keySet() : fields);

        for (String name : fieldsToReturn) {
            result.put(name, new StringByteIterator(json.getString(name)));
        }

        return result.isEmpty() ? Status.ERROR : Status.OK;
    }

    @Override
    public Status insert(String table, String key, HashMap<String, ByteIterator> values) {
        JSONObject json = new JSONObject();
        for (final Entry<String, ByteIterator> e : values.entrySet()) {
            json.put(e.getKey(), e.getValue().toString());
        }

        try {
            ioctx.write(key, json.toString());
        } catch (RadosException e) {
            return new Status("ERROR-" + e.getReturnValue(), e.getMessage());
        }
        return Status.OK;
    }

    @Override
    public Status delete(String table, String key) {
        try {
            ioctx.remove(key);
        } catch (RadosException e) {
            return new Status("ERROR-" + e.getReturnValue(), e.getMessage());
        }
        return Status.OK;
    }

    @Override
    public Status update(String table, String key, HashMap<String, ByteIterator> values) {
        Status rtn = delete(table, key);
        if (rtn.equals(Status.OK)) {
            return insert(table, key, values);
        }
        return rtn;
    }

    @Override
    public Status scan(String table, String startkey, int recordcount, Set<String> fields,
            Vector<HashMap<String, ByteIterator>> result) {
        return Status.NOT_IMPLEMENTED;
    }
}