Package com.pannous.es.reindex

Source Code of com.pannous.es.reindex.ReIndexWithCreate

package com.pannous.es.reindex;

import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
import org.elasticsearch.action.count.CountRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.hppc.cursors.ObjectCursor;
import org.elasticsearch.common.hppc.cursors.ObjectObjectCursor;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.rest.*;

import java.io.IOException;

import static org.elasticsearch.rest.RestRequest.Method.POST;
import static org.elasticsearch.rest.RestRequest.Method.PUT;
import static org.elasticsearch.rest.RestStatus.OK;
import static org.elasticsearch.rest.action.support.RestXContentBuilder.restContentBuilder;

/**
* @author Peter Karich
*/
public class ReIndexWithCreate extends BaseRestHandler {

    private ReIndexAction reindexAction;

    @Inject public ReIndexWithCreate(Settings settings, Client client, RestController controller) {
        super(settings, client);

        // Define REST endpoints to do a reindex
        controller.registerHandler(PUT, "/_reindex", this);
        controller.registerHandler(POST, "/_reindex", this);

        // give null controller as argument to avoid registering twice
        // which would lead to an assert exception
        reindexAction = new ReIndexAction(settings, client, null);
    }

    @Override public void handleRequest(RestRequest request, RestChannel channel) {
        logger.info("ReIndexWithCreate.handleRequest [{}]", request.toString());
        try {
            XContentBuilder builder = restContentBuilder(request);
            // required parameters
            String newIndexName = request.param("index");
            if (newIndexName.isEmpty()) {
                channel.sendResponse(new StringRestResponse(RestStatus.EXPECTATION_FAILED, "parameter index missing"));
                return;
            }
            String type = request.param("type", "");
            if (type.isEmpty()) {
                channel.sendResponse(new StringRestResponse(RestStatus.EXPECTATION_FAILED, "parameter type missing"));
                return;
            }
            String searchIndexName = request.param("searchIndex");
            if (searchIndexName.isEmpty()) {
                channel.sendResponse(new StringRestResponse(RestStatus.EXPECTATION_FAILED, "parameter searchIndex missing"));
                return;
            }
            int newShards = request.paramAsInt("newIndexShards", -1);
            try {
                if(client.admin().indices().exists(new IndicesExistsRequest(newIndexName)).actionGet().isExists()) {
                    logger.info("target index already exists, skip creation: " + newIndexName);
                }
                else {
                    createIdenticalIndex(searchIndexName, type, newIndexName, newShards);
                }
            } catch (Exception ex) {
                String str = "Problem while creating index " + newIndexName + " from " + searchIndexName + " " + ex.getMessage();
                logger.error(str, ex);
                channel.sendResponse(new StringRestResponse(RestStatus.INTERNAL_SERVER_ERROR, str));
                return;
            }

            // TODO: what if queries goes to the old index while we reindexed?
            // now reindex
       
            if(type.equals("*")) {

                IndexMetaData indexData = client.admin().cluster().state(new ClusterStateRequest()).
                        actionGet().getState().metaData().indices().get(searchIndexName);
                Settings searchIndexSettings = indexData.settings();

                for(ObjectCursor<String> mapKeyCursor : indexData.mappings().keys()) {
                    reindexAction.handleRequest(request, channel, mapKeyCursor.value, true);
                }
            }
            else {
                reindexAction.handleRequest(request, channel, type, true);
            }

            boolean delete = request.paramAsBoolean("delete", false);
            if (delete) {
           
                // make sure to refresh the index here
                // (e.g. the index may be paused or refreshing with a very long interval):
                logger.info("refreshing " + searchIndexName);
                client.admin().indices().refresh(new RefreshRequest(newIndexName)).actionGet();
           
                long oldCount = client.count(new CountRequest(searchIndexName)).actionGet().getCount();
                long newCount = client.count(new CountRequest(newIndexName)).actionGet().getCount();
                if (oldCount == newCount) {
                    logger.info("deleting " + searchIndexName);
                    client.admin().indices().delete(new DeleteIndexRequest(searchIndexName)).actionGet();
                }
            }

            boolean copyAliases = request.paramAsBoolean("copyAliases", false);
            if (copyAliases)
                copyAliases(request);
               
            channel.sendResponse(new XContentRestResponse(request, OK, builder));
               
        } catch (Exception ex) { // also catch the RuntimeException thrown by ReIndexAction
            try {
                channel.sendResponse(new XContentThrowableRestResponse(request, ex));
            } catch (Exception ex2) {
                logger.error("problem while rolling index", ex2);
            }
        }
    }

    /**
     * Creates a new index out of the settings from the old index.
     */
    private void createIdenticalIndex(String oldIndex, String type,
            String newIndex, int newIndexShards) throws IOException {
        IndexMetaData indexData = client.admin().cluster().state(new ClusterStateRequest()).
                actionGet().getState().metaData().indices().get(oldIndex);
        Settings searchIndexSettings = indexData.settings();
        ImmutableSettings.Builder settingBuilder = ImmutableSettings.settingsBuilder().put(searchIndexSettings);
        if (newIndexShards > 0)
            settingBuilder.put("index.number_of_shards", newIndexShards);
           
        CreateIndexRequest createReq;
       
        if(type.equals("*")) {
            createReq = new CreateIndexRequest(newIndex);
            for(ObjectObjectCursor<String, MappingMetaData> mapCursor : indexData.mappings()) {
                createReq.mapping(mapCursor.key, mapCursor.value.sourceAsMap());
            }
            createReq.settings(settingBuilder.build());
        }
        else {
            MappingMetaData mappingMeta = indexData.mapping(type);
            createReq = new CreateIndexRequest(newIndex).
                mapping(type, mappingMeta.sourceAsMap()).
                settings(settingBuilder.build());
        }

        client.admin().indices().create(createReq).actionGet();
    }

    private void copyAliases(RestRequest request) {
        String index = request.param("index");
        String searchIndexName = request.param("searchIndex");
        IndexMetaData meta = client.admin().cluster().state(new ClusterStateRequest()).
                actionGet().getState().metaData().index(searchIndexName);
        IndicesAliasesRequest aReq = new IndicesAliasesRequest();
        boolean empty = true;
        if(meta != null && meta.aliases() != null) {
            for (ObjectCursor<String> oldAliasCursor : meta.aliases().keys() ) {
                empty = false;
                aReq.addAlias(index, oldAliasCursor.value);
            }
        }
        boolean aliasIncludeIndex = request.paramAsBoolean("addOldIndexAsAlias", false);
        if (aliasIncludeIndex) {
            if (client.admin().indices().exists(new IndicesExistsRequest(searchIndexName)).actionGet().isExists()) {
                logger.warn("Cannot add old index name (" + searchIndexName + ") as alias to index "
                        + index + " - as old index still exists");
            }
            else {
                aReq.addAlias(index, searchIndexName);
                empty = false;
            }
        }
        if(!empty) //!aReq.aliasActions().isEmpty())
            client.admin().indices().aliases(aReq).actionGet();
    }
}
TOP

Related Classes of com.pannous.es.reindex.ReIndexWithCreate

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.