Package org.elasticsearch.transport.couchbase.capi

Source Code of org.elasticsearch.transport.couchbase.capi.ElasticSearchCouchbaseBehavior

/**
* Copyright (c) 2012 Couchbase, Inc. 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.
*/
package org.elasticsearch.transport.couchbase.capi;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.elasticsearch.action.ListenableActionFuture;
import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequestBuilder;
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
import org.elasticsearch.action.admin.cluster.state.ClusterStateRequestBuilder;
import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequestBuilder;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.get.GetRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest.OpType;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.cache.Cache;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.hppc.cursors.ObjectCursor;
import org.elasticsearch.common.logging.ESLogger;

import com.couchbase.capi.CouchbaseBehavior;

public class ElasticSearchCouchbaseBehavior implements CouchbaseBehavior {

    protected Client client;
    protected ESLogger logger;
    protected String checkpointDocumentType;
    protected Cache<String, String> bucketUUIDCache;

    public ElasticSearchCouchbaseBehavior(Client client, ESLogger logger, String checkpointDocumentType, Cache<String, String> bucketUUIDCache) {
        this.client = client;
        this.logger = logger;
        this.checkpointDocumentType = checkpointDocumentType;
        this.bucketUUIDCache = bucketUUIDCache;
    }

    @Override
    public List<String> getPools() {
        List<String> result = new ArrayList<String>();
        result.add("default");
        return result;
    }

    @Override
    public String getPoolUUID(String pool) {
        ClusterStateRequestBuilder builder = client.admin().cluster().prepareState();
        ClusterStateResponse response = builder.execute().actionGet();
        ClusterName name = response.getClusterName();
        return UUID.nameUUIDFromBytes(name.toString().getBytes()).toString().replace("-", "");
    }

    @Override
    public Map<String, Object> getPoolDetails(String pool) {
        if("default".equals(pool)) {
            Map<String, Object> bucket = new HashMap<String, Object>();
            bucket.put("uri", "/pools/" + pool + "/buckets?uuid=" + getPoolUUID(pool));

            Map<String, Object> responseMap = new HashMap<String, Object>();
            responseMap.put("buckets", bucket);

            List<Object> nodes = getNodesServingPool(pool);
            responseMap.put("nodes", nodes);

            return responseMap;
        }
        return null;
    }

    @Override
    public List<String> getBucketsInPool(String pool) {
        if("default".equals(pool)) {
            List<String> bucketNameList = new ArrayList<String>();

            ClusterStateRequestBuilder stateBuilder = client.admin().cluster().prepareState();
            ClusterStateResponse response = stateBuilder.execute().actionGet();
            ImmutableOpenMap<String, IndexMetaData> indices = response.getState().getMetaData().getIndices();
            for (ObjectCursor<String> index : indices.keys()) {
                bucketNameList.add(index.value);
                IndexMetaData indexMetaData = indices.get(index.value);
                ImmutableOpenMap<String, AliasMetaData> aliases = indexMetaData.aliases();
                for(ObjectCursor<String> alias : aliases.keys()) {
                    bucketNameList.add(alias.value);
                }
            }

            return bucketNameList;
        }
        return null;
    }

    protected String getUUIDFromCheckpointDocSource(Map<String, Object> source) {
        Map<String,Object> docMap = (Map<String,Object>)source.get("doc");
        String uuid = (String)docMap.get("uuid");
        return uuid;
    }

    protected String lookupUUID(String bucket, String id) {
        GetRequestBuilder builder = client.prepareGet();
        builder.setIndex(bucket);
        builder.setId(id);
        builder.setType(this.checkpointDocumentType);
        builder.setFetchSource(true);

        String bucketUUID = null;
        GetResponse response;
        ListenableActionFuture<GetResponse> laf = builder.execute();
        if(laf != null) {
            response = laf.actionGet();
            if(response.isExists()) {
            Map<String,Object> responseMap = response.getSourceAsMap();
            bucketUUID = this.getUUIDFromCheckpointDocSource(responseMap);
            }
        }

        return bucketUUID;
    }

    protected void storeUUID(String bucket, String id, String uuid) {
        Map<String,Object> doc = new HashMap<String, Object>();
        doc.put("uuid", uuid);
        Map<String, Object> toBeIndexed = new HashMap<String, Object>();
        toBeIndexed.put("doc", doc);

        IndexRequestBuilder builder = client.prepareIndex();
        builder.setIndex(bucket);
        builder.setId(id);
        builder.setType(this.checkpointDocumentType);
        builder.setSource(toBeIndexed);
        builder.setOpType(OpType.CREATE);

        IndexResponse response;
        ListenableActionFuture<IndexResponse> laf = builder.execute();
        if(laf != null) {
            response = laf.actionGet();
            if(!response.isCreated()) {
                logger.error("did not succeed creating uuid");
            }
        }
    }

    @Override
    public String getBucketUUID(String pool, String bucket) {
        // first look for bucket UUID in cache
        String bucketUUID = this.bucketUUIDCache.getIfPresent(bucket);
        if (bucketUUID != null) {
            logger.debug("found bucket UUID in cache");
            return bucketUUID;
        }

        logger.debug("bucket UUID not in cache, looking up");
        IndicesExistsRequestBuilder existsBuilder = client.admin().indices().prepareExists(bucket);
        IndicesExistsResponse response = existsBuilder.execute().actionGet();
        if(response.isExists()) {
            int tries = 0;
            bucketUUID = this.lookupUUID(bucket, "bucketUUID");
            while(bucketUUID == null && tries < 100) {
                logger.debug("bucket UUID doesn't exist yet, creaating, attempt: {}", tries+1);
                String newUUID = UUID.randomUUID().toString().replace("-", "");
                storeUUID(bucket, "bucketUUID", newUUID);
                bucketUUID = this.lookupUUID(bucket, "bucketUUID");
                tries++;
            }

            if(bucketUUID != null) {
                // store it in the cache
                bucketUUIDCache.put(bucket, bucketUUID);
                return bucketUUID;
            }
        }
        throw new RuntimeException("failed to find/create bucket uuid");
    }

    @Override
    public List<Object> getNodesServingPool(String pool) {
        if("default".equals(pool)) {

            NodesInfoRequestBuilder infoBuilder = client.admin().cluster().prepareNodesInfo((String[]) null);
            NodesInfoResponse infoResponse = infoBuilder.execute().actionGet();

            // extract what we need from this response
            List<Object> nodes = new ArrayList<Object>();
            for (NodeInfo nodeInfo : infoResponse.getNodes()) {

                // FIXME there has to be a better way than
                // parsing this string
                // but so far I have not found it
                if (nodeInfo.getServiceAttributes() != null) {
                    for (Map.Entry<String, String> nodeAttribute : nodeInfo
                            .getServiceAttributes().entrySet()) {
                        if (nodeAttribute.getKey().equals(
                                "couchbase_address")) {
                            int start = nodeAttribute
                                    .getValue()
                                    .lastIndexOf("/");
                            int end = nodeAttribute
                                    .getValue()
                                    .lastIndexOf("]");
                            String hostPort = nodeAttribute
                                    .getValue().substring(
                                            start + 1, end);
                            String[] parts = hostPort.split(":");

                            Map<String, Object> nodePorts = new HashMap<String, Object>();
                            nodePorts.put("direct", Integer.parseInt(parts[1]));

                            Map<String, Object> node = new HashMap<String, Object>();
                            node.put("couchApiBase", String.format("http://%s/", hostPort));
                            node.put("hostname", hostPort);
                            node.put("ports", nodePorts);

                            nodes.add(node);
                        }
                    }
                }
            }
            return nodes;

        }
        return null;
    }

    @Override
    public Map<String, Object> getStats() {
        Map<String, Object> result = new HashMap<String, Object>();
        return result;
    }

}
TOP

Related Classes of org.elasticsearch.transport.couchbase.capi.ElasticSearchCouchbaseBehavior

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.