Package org.elasticsearch.action.view

Source Code of org.elasticsearch.action.view.TransportViewAction

/*
* Licensed to Elastic Search and Shay Banon under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Elastic Search 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.elasticsearch.action.view;

import org.elasticsearch.ElasticSearchException;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.ElasticSearchParseException;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.TransportSearchAction;
import org.elasticsearch.action.support.single.shard.TransportShardSingleOperationAction;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.cluster.routing.ShardIterator;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.get.GetResult;
import org.elasticsearch.index.service.IndexService;
import org.elasticsearch.index.shard.service.IndexShard;
import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.view.exception.ElasticSearchViewNotFoundException;
import org.elasticsearch.view.ViewContext;
import org.elasticsearch.view.ViewResult;
import org.elasticsearch.view.ViewService;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class TransportViewAction extends TransportShardSingleOperationAction<ViewRequest, ViewResponse> {

    private final ViewService viewService;
    private final IndicesService indicesService;
    private final TransportSearchAction searchAction;

    @Inject
    public TransportViewAction(Settings settings, ThreadPool threadPool,
                               ClusterService clusterService,
                               TransportService transportService,
                               IndicesService indicesService,
                               ViewService viewService,
                               TransportSearchAction searchAction) {
        super(settings, threadPool, clusterService, transportService);
        this.indicesService = indicesService;
        this.viewService = viewService;
        this.searchAction = searchAction;
    }

    @Override
    protected String executor() {
        return ThreadPool.Names.GENERIC;
    }

    @Override
    protected ViewRequest newRequest() {
        return new ViewRequest();
    }

    @Override
    protected ViewResponse newResponse() {
        return new ViewResponse();
    }

    @Override
    protected String transportAction() {
        return ViewAction.NAME;
    }

    @Override
    protected ClusterBlockException checkGlobalBlock(ClusterState state, ViewRequest request) {
        return state.blocks().globalBlockedException(ClusterBlockLevel.READ);
    }

    @Override
    protected ClusterBlockException checkRequestBlock(ClusterState state, ViewRequest request) {
        return state.blocks().indexBlockedException(ClusterBlockLevel.READ, request.index());
    }

    @Override
    protected ShardIterator shards(ClusterState state, ViewRequest request) {
        return clusterService.operationRouting()
                .getShards(clusterService.state(), request.index(), request.type(), request.id(), null, null);
    }

    @Override
    protected ViewResponse shardOperation(ViewRequest request, int shardId) throws ElasticSearchException {

        // Get the doc first
        IndexService indexService = indicesService.indexService(request.index());
        IndexShard indexShard = indexService.shardSafe(shardId);
        GetResult getResult = indexShard.getService().get(request.type(), request.id(), null, false);

        if (!getResult.exists()) {
            throw new ElasticSearchIllegalArgumentException("Document not found, cannot render view");
        }

        // Try to get a view stored at document level
        ViewContext viewContext = extract(getResult.sourceAsMap(), request.format());

        if (viewContext == null) {
            // Then, get the view stored in the mapping _meta field
            MappingMetaData mappingMetaData = clusterService.state().metaData().index(request.index()).mapping(request.type());
            if (mappingMetaData != null) {
                try {
                    Map<String, Object> mapping = mappingMetaData.sourceAsMap();
                    viewContext = extract(mapping, request.format());
                } catch (IOException e) {
                    throw new ElasticSearchParseException("Failed to parse mapping content to map", e);
                }
            }
        }

        if (viewContext == null) {
            throw new ElasticSearchViewNotFoundException("No view [" + request.format() + "] found for document type [" + request.type() + "]");
        }

        // Set some org.elasticsearch.test.integration.views.mappings.data required for view rendering
        viewContext.index(getResult.index())
                .type(getResult.type())
                .id(getResult.id())
                .version(getResult.version())
                .source(getResult.sourceAsMap());

        // Ok, let's render it with a ViewEngineService
        ViewResult result = viewService.render(viewContext);

        return new ViewResponse(result.contentType(), result.content());
    }

    private ViewContext extract(Map<String, Object> sourceAsMap, String format) {
        if (sourceAsMap != null) {
            for (String key : sourceAsMap.keySet()) {
                Object views = null;

                // When searching in a mapping
                if ("_meta".equals(key)) {
                    Object meta = sourceAsMap.get(key);
                    if (meta instanceof Map) {
                        views = ((Map) meta).get("views");
                    }
                }

                // When searching in the document content
                if ("views".equals(key)) {
                    views = sourceAsMap.get(key);
                }

                if ((views != null) && (views instanceof Map)) {
                    Map mapViews = (Map) views;
                    Object candidate = null;

                    // Try to load a specific view
                    if (format != null) {
                        candidate = mapViews.get(format);
                    } else if (!mapViews.isEmpty()) {
                        // Try to load the "default" view
                        Object defaultView = mapViews.get(ViewRequest.DEFAULT_VIEW);
                        if (defaultView != null) {
                            candidate = defaultView;
                        }
                    }
                    if ((candidate != null) && (candidate instanceof Map)) {
                        Map mapCandidate = (Map) candidate;

                        // ViewContext holds the org.elasticsearch.test.integration.views.mappings.data for view rendering
                        ViewContext viewContext = new ViewContext((String) mapCandidate.get("view_lang"), (String) mapCandidate.get("view"), (String) mapCandidate.get("content_type"));

                        Object queries = mapCandidate.get("queries");
                        Map<String, Object> mapQueries = null;

                        if (queries != null) {
                            if (queries instanceof List) {
                                List listQueries = (List) queries;
                                mapQueries = new HashMap<String, Object>(listQueries.size());
                                for (Object query : listQueries) {
                                    if (query instanceof Map) {
                                        Map q = (Map) query;
                                        for (Object queryName : q.keySet()) {
                                            if (queryName instanceof String) {
                                                mapQueries.put((String) queryName, q.get(queryName));
                                            }
                                        }
                                    }
                                }
                            } else if (queries instanceof Map) {
                                mapQueries = (Map) queries;
                            }
                        }

                        if (mapQueries != null) {
                            for (String queryName : mapQueries.keySet()) {
                                try {
                                    Map<String, Object> mapQuery = (Map) mapQueries.get(queryName);

                                    String[] indices = null;
                                    if (mapQuery.get("indices") instanceof List) {
                                        indices = (String[]) ((List) mapQuery.get("indices")).toArray(new String[0]);
                                    } else if (mapQuery.get("indices") instanceof String) {
                                        indices = new String[]{((String) mapQuery.get("indices"))};
                                    }

                                    String[] types = null;
                                    if (mapQuery.get("types") instanceof List) {
                                        types = (String[]) ((List) mapQuery.get("types")).toArray(new String[0]);
                                    } else if (mapQuery.get("types") instanceof String) {
                                        types = new String[]{((String) mapQuery.get("types"))};
                                    }

                                    SearchSourceBuilder searchSourceBuilder = null;
                                    if (mapQuery.get("sort") instanceof List) {
                                        if (searchSourceBuilder == null) {
                                            searchSourceBuilder = new SearchSourceBuilder();
                                        }
                                        for (Object sort : (List) mapQuery.get("sort")) {
                                            if (sort instanceof String) {
                                                searchSourceBuilder.sort((String) sort);
                                            } else if (sort instanceof Map) {
                                                for (Object field : ((Map) sort).keySet()) {
                                                    String sortField = (String) field;
                                                    String reverse = (String) ((Map) sort).get(field);
                                                    if ("asc".equals(reverse)) {
                                                        searchSourceBuilder.sort(sortField, SortOrder.ASC);
                                                    } else if ("desc".equals(reverse)) {
                                                        searchSourceBuilder.sort(sortField, SortOrder.DESC);
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    if (mapQuery.get("fields") instanceof List) {
                                        if (searchSourceBuilder == null) {
                                            searchSourceBuilder = new SearchSourceBuilder();
                                        }
                                        for (Object field : (List) mapQuery.get("fields")) {
                                            if (field instanceof String) {
                                                searchSourceBuilder.field((String) field);
                                            }
                                        }
                                    }

                                    SearchRequest searchRequest = new SearchRequest();
                                    if (indices != null) {
                                        searchRequest.indices(indices);
                                    }
                                    if (types != null) {
                                        searchRequest.types(types);
                                    }

                                    ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
                                    builder.put("query", (Map) mapQuery.get("query"));
                                    searchRequest.source(builder.build());

                                    if (searchSourceBuilder != null) {
                                        searchRequest.extraSource(searchSourceBuilder);
                                    }

                                    SearchResponse searchResponse = searchAction.execute(searchRequest).get();
                                    viewContext.queriesAndHits(queryName, searchResponse.hits());

                                } catch (Exception e) {
                                    viewContext.queriesAndHits(queryName, null);
                                }
                            }
                        }
                        return viewContext;
                    }
                }
            }
        }
        return null;
    }
}
TOP

Related Classes of org.elasticsearch.action.view.TransportViewAction

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.