Package io.crate.blob.v2

Source Code of io.crate.blob.v2.BlobIndices

/*
* Licensed to CRATE Technology GmbH ("Crate") under one or more contributor
* license agreements.  See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.  Crate 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.
*
* However, if you have executed another commercial license agreement
* with Crate these terms will supersede the license and you may use the
* software solely pursuant to the terms of the relevant commercial agreement.
*/

package io.crate.blob.v2;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import io.crate.blob.BlobEnvironment;
import io.crate.blob.BlobShardFuture;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.create.TransportCreateIndexAction;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.delete.TransportDeleteIndexAction;
import org.elasticsearch.action.admin.indices.settings.put.TransportUpdateSettingsAction;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse;
import org.elasticsearch.cluster.ClusterChangedEvent;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterStateListener;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.Injector;
import org.elasticsearch.common.io.FileSystemUtils;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.service.IndexService;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.indices.IndicesLifecycle;
import org.elasticsearch.indices.IndicesService;

import java.io.File;
import java.util.List;

public class BlobIndices extends AbstractComponent implements ClusterStateListener {

    public static final String SETTING_INDEX_BLOBS_ENABLED = "index.blobs.enabled";
    public static final String SETTING_INDEX_BLOBS_PATH = "index.blobs.path";
    public static final String INDEX_PREFIX = ".blob_";

    private final TransportUpdateSettingsAction transportUpdateSettingsAction;
    private final TransportCreateIndexAction transportCreateIndexAction;
    private final TransportDeleteIndexAction transportDeleteIndexAction;
    private final IndicesService indicesService;
    private final IndicesLifecycle indicesLifecycle;
    private final BlobEnvironment blobEnvironment;

    public static final Predicate<String> indicesFilter = new Predicate<String>() {
        @Override
        public boolean apply(String indexName) {
            return isBlobIndex(indexName);
        }
    };

    public static final Function<String, String> stripPrefix = new Function<String, String>() {
        @Override
        public String apply(String indexName) {
            return indexName(indexName);
        }
    };

    public static final Function<String, String> addPrefix = new Function<String, String>() {
        @Override
        public String apply(String indexName) {
            return fullIndexName(indexName);
        }
    };

    @Inject
    public BlobIndices(Settings settings,
                       TransportCreateIndexAction transportCreateIndexAction,
                       TransportDeleteIndexAction transportDeleteIndexAction,
                       TransportUpdateSettingsAction transportUpdateSettingsAction,
                       IndicesService indicesService,
                       IndicesLifecycle indicesLifecycle,
                       BlobEnvironment blobEnvironment,
                       ClusterService clusterService) {
        super(settings);
        this.transportCreateIndexAction = transportCreateIndexAction;
        this.transportDeleteIndexAction = transportDeleteIndexAction;
        this.transportUpdateSettingsAction = transportUpdateSettingsAction;
        this.indicesService = indicesService;
        this.indicesLifecycle = indicesLifecycle;
        this.blobEnvironment = blobEnvironment;
        clusterService.addLast(this);
        logger.setLevel("debug");
    }

    public BlobShard blobShardSafe(ShardId shardId) {
        return blobShardSafe(shardId.getIndex(), shardId.id());
    }

    /**
     * can be used to alter the number of replicas.
     *
     * @param tableName name of the blob table
     * @param indexSettings updated index settings
     */
    public ListenableFuture<Void> alterBlobTable(String tableName, Settings indexSettings) {
        final SettableFuture<Void> result = SettableFuture.create();
        transportUpdateSettingsAction.execute(
                new UpdateSettingsRequest(indexSettings, fullIndexName(tableName)),
                new ActionListener<UpdateSettingsResponse>() {
                    @Override
                    public void onResponse(UpdateSettingsResponse updateSettingsResponse) {
                        result.set(null);
                    }

                    @Override
                    public void onFailure(Throwable e) {
                        result.setException(e);

                    }
                });
        return result;
    }

    public ListenableFuture<Void> createBlobTable(String tableName,
                                                  Settings indexSettings) {
        ImmutableSettings.Builder builder = ImmutableSettings.builder();
        builder.put(indexSettings);
        builder.put(SETTING_INDEX_BLOBS_ENABLED, true);

        final SettableFuture<Void> result = SettableFuture.create();
        transportCreateIndexAction.execute(new CreateIndexRequest(fullIndexName(tableName), builder.build()), new ActionListener<CreateIndexResponse>() {
            @Override
            public void onResponse(CreateIndexResponse createIndexResponse) {
                assert createIndexResponse.isAcknowledged();
                result.set(null);
            }

            @Override
            public void onFailure(Throwable e) {
                result.setException(e);
            }
        });
        return result;
    }

    public ListenableFuture<Void> dropBlobTable(final String tableName) {
        final SettableFuture<Void> result = SettableFuture.create();
        transportDeleteIndexAction.execute(new DeleteIndexRequest(fullIndexName(tableName)), new ActionListener<DeleteIndexResponse>() {
            @Override
            public void onResponse(DeleteIndexResponse deleteIndexResponse) {
                result.set(null);
            }

            @Override
            public void onFailure(Throwable e) {
                result.setException(e);
            }
        });
        return result;
    }

    public BlobShard blobShard(String index, int shardId) {
        IndexService indexService = indicesService.indexService(index);
        if (indexService != null) {
            Injector injector = indexService.shardInjector(shardId);
            if (injector != null) {
                return injector.getInstance(BlobShard.class);
            }
        }

        return null;
    }

    public BlobShard blobShardSafe(String index, int shardId) {
        if (isBlobIndex(index)) {
            return indicesService.indexServiceSafe(index).shardInjectorSafe(shardId).getInstance(BlobShard.class);
        }
        throw new BlobsDisabledException(index);
    }

    public BlobIndex blobIndex(String index) {
        return indicesService.indexServiceSafe(index).injector().getInstance(BlobIndex.class);
    }

    public ShardId localShardId(String index, String digest) {
        return blobIndex(index).shardId(digest);
    }

    public BlobShard localBlobShard(String index, String digest) {
        return blobShardSafe(localShardId(index, digest));
    }

    public BlobShardFuture blobShardFuture(String index, int shardId) {
        return new BlobShardFuture(this, indicesLifecycle, index, shardId);

    }

    public List<String> indices() {
        return FluentIterable.from(indicesService.indices().keySet())
                .filter(indicesFilter).toList();
    }

    /**
     * check if this index is a blob table
     *
     * This only works for indices that were created via SQL.
     */
    public static boolean isBlobIndex(String indexName) {
        return indexName.startsWith(INDEX_PREFIX);
    }

    /**
     * check if given shard is part of an index that is a blob table
     *
     * This only works for indices that were created via SQL.
     */
    public static boolean isBlobShard(ShardId shardId) {
        return isBlobIndex(shardId.getIndex());
    }

    /**
     * Returns the full index name, adds blob index prefix.
     *
     * @param indexName
     * @return
     */
    public static String fullIndexName(String indexName) {
        if (isBlobIndex(indexName)) {
            return indexName;
        }
        return INDEX_PREFIX + indexName;
    }

    /**
     * Strips the blob index prefix from a full index name
     *
     * @param indexName
     * @return
     */
    public static String indexName(String indexName) {
        if (!isBlobIndex(indexName)) {
            return indexName;
        }
        return indexName.substring(INDEX_PREFIX.length());
    }

    @Override
    public void clusterChanged(ClusterChangedEvent event) {
        if (event.state().blocks().disableStatePersistence()) {
            return;
        }

        MetaData currentMetaData = event.previousState().metaData();
        MetaData newMetaData = event.state().metaData();

        // delete blob indices that were there before, but are deleted now
        if (currentMetaData != null) {
            // only delete indices when we already received a state (currentMetaData != null)
            for (IndexMetaData current : currentMetaData) {
                if (!newMetaData.hasIndex(current.index())) {
                    if (isBlobIndex(current.index())) {
                        File indexLocation = null;
                        File indexBlobsPath = null;
                        if (current.settings().get(BlobIndices.SETTING_INDEX_BLOBS_PATH) != null) {
                            indexBlobsPath = new File(current.settings().get(BlobIndices.SETTING_INDEX_BLOBS_PATH));
                            indexLocation = blobEnvironment.indexLocation(new Index(current.index()), indexBlobsPath);
                        } else if (blobEnvironment.blobsPath() != null) {
                            indexLocation = blobEnvironment.indexLocation(new Index(current.index()));
                        }
                        if (indexLocation != null) {
                            // delete index blob path
                            if (indexLocation.exists()) {
                                logger.debug("[{}] Deleting blob index directory '{}'",
                                        current.index(), indexLocation.getAbsolutePath());
                                FileSystemUtils.deleteRecursively(indexLocation);
                            }

                            // check if custom index blobs path is empty, if so delete whole path
                            if (indexBlobsPath != null
                                    && blobEnvironment.isCustomBlobPathEmpty(indexBlobsPath)) {
                                logger.debug("[{}] Empty per table defined blobs path found, deleting {}",
                                        current.index(), indexBlobsPath.getAbsolutePath());
                                FileSystemUtils.deleteRecursively(indexBlobsPath);
                            }
                        }
                    }
                }
            }
        }
    }

}
TOP

Related Classes of io.crate.blob.v2.BlobIndices

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.