Package org.graylog2.rest.resources.system.indexer

Source Code of org.graylog2.rest.resources.system.indexer.IndicesResource

/**
* This file is part of Graylog2.
*
* Graylog2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Graylog2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Graylog2.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.graylog2.rest.resources.system.indexer;

import com.codahale.metrics.annotation.Timed;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.elasticsearch.action.admin.indices.stats.CommonStats;
import org.elasticsearch.cluster.routing.ShardRouting;
import org.graylog2.indexer.Deflector;
import org.graylog2.indexer.cluster.Cluster;
import org.graylog2.indexer.indices.IndexStatistics;
import org.graylog2.indexer.indices.Indices;
import org.graylog2.indexer.ranges.RebuildIndexRangesJob;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;
import org.graylog2.rest.resources.RestResource;
import org.graylog2.security.RestPermissions;
import org.graylog2.system.jobs.SystemJob;
import org.graylog2.system.jobs.SystemJobConcurrencyException;
import org.graylog2.system.jobs.SystemJobManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Map;
import java.util.Set;

import static com.google.common.base.Strings.nullToEmpty;

@RequiresAuthentication
@Api(value = "Indexer/Indices", description = "Index information")
@Path("/system/indexer/indices")
public class IndicesResource extends RestResource {
    private static final Logger LOG = LoggerFactory.getLogger(IndicesResource.class);

    @Inject
    private RebuildIndexRangesJob.Factory rebuildIndexRangesJobFactory;
    @Inject
    private Indices indices;
    @Inject
    private Cluster cluster;
    @Inject
    private Deflector deflector;
    @Inject
    private SystemJobManager systemJobManager;

    @GET
    @Timed
    @Path("/{index}")
    @ApiOperation(value = "Get information of an index and its shards.")
    @Produces(MediaType.APPLICATION_JSON)
    public Response single(@ApiParam(name = "index") @PathParam("index") String index) {
        checkPermission(RestPermissions.INDICES_READ, index);

        if(!deflector.isGraylog2Index(index)) {
            LOG.info("Index [{}] doesn't look like an index managed by Graylog2.", index);
            return Response.status(Response.Status.NOT_FOUND).build();
        }

        final ImmutableMap.Builder<String, Object> result = ImmutableMap.builder();

        try {
            final IndexStatistics stats = indices.getIndexStats(index);
            if (stats == null) {
                LOG.error("Index [{}] not found.", index);
                return Response.status(404).build();
            }

            final ImmutableList.Builder<Map<String, Object>> routing = ImmutableList.builder();
            for (ShardRouting shardRouting : stats.getShardRoutings()) {
                routing.add(shardRouting(shardRouting));
            }

            result.put("primary_shards", indexStats(stats.getPrimaries()));
            result.put("all_shards", indexStats(stats.getTotal()));
            result.put("routing", routing.build());
            result.put("is_reopened", indices.isReopened(index));
        } catch (Exception e) {
            LOG.error("Could not get indices information.", e);
            return Response.serverError().build();
        }

        return Response.ok().entity(json(result.build())).build();
    }

    @GET
    @Timed
    @Path("/closed")
    @ApiOperation(value = "Get a list of closed indices that can be reopened.")
    @Produces(MediaType.APPLICATION_JSON)
    public Response closed() {
        Set<String> closedIndices;
        try {

            closedIndices = Sets.filter(indices.getClosedIndices(), new Predicate<String>() {
                @Override
                public boolean apply(String indexName) {
                    return isPermitted(RestPermissions.INDICES_READ, indexName);
                }
            });

        } catch (Exception e) {
            LOG.error("Could not get closed indices.", e);
            return Response.serverError().build();
        }

        final Map<String, Object> result = ImmutableMap.of(
                "indices", closedIndices,
                "total", closedIndices.size());

        return Response.ok().entity(json(result)).build();
    }

    @POST
    @Timed
    @Path("/{index}/reopen")
    @ApiOperation(value = "Reopen a closed index. This will also trigger an index ranges rebuild job.")
    @Produces(MediaType.APPLICATION_JSON)
    public Response reopen(@ApiParam(name = "index") @PathParam("index") String index) {
        checkPermission(RestPermissions.INDICES_CHANGESTATE, index);

        if (!deflector.isGraylog2Index(index)) {
            LOG.info("Index [{}] doesn't look like an index managed by Graylog2.", index);
            return Response.status(Response.Status.NOT_FOUND).build();
        }

        indices.reopenIndex(index);

        // Trigger index ranges rebuild job.
        final SystemJob rebuildJob = rebuildIndexRangesJobFactory.create(deflector);
        try {
            systemJobManager.submit(rebuildJob);
        } catch (SystemJobConcurrencyException e) {
            LOG.error("Concurrency level of this job reached: " + e.getMessage());
            throw new WebApplicationException(Response.Status.FORBIDDEN);
        }

        return Response.noContent().build();
    }

    @POST
    @Timed
    @Path("/{index}/close")
    @ApiOperation(value = "Close an index. This will also trigger an index ranges rebuild job.")
    @Produces(MediaType.APPLICATION_JSON)
    @ApiResponses(value = {
            @ApiResponse(code = 403, message = "You cannot close the current deflector target index.")
    })
    public Response close(@ApiParam(name = "index") @PathParam("index") String index) {
        checkPermission(RestPermissions.INDICES_CHANGESTATE, index);

        if(!deflector.isGraylog2Index(index)) {
            LOG.info("Index [{}] doesn't look like an index managed by Graylog2.", index);
            return Response.status(Response.Status.NOT_FOUND).build();
        }

        if (deflector.getCurrentActualTargetIndex().equals(index)) {
            return Response.status(Response.Status.FORBIDDEN).build();
        }

        // Close index.
        indices.close(index);

        // Trigger index ranges rebuild job.
        final SystemJob rebuildJob = rebuildIndexRangesJobFactory.create(deflector);
        try {
            systemJobManager.submit(rebuildJob);
        } catch (SystemJobConcurrencyException e) {
            LOG.error("Concurrency level of this job reached: " + e.getMessage());
            throw new WebApplicationException(Response.Status.FORBIDDEN);
        }

        return Response.noContent().build();
    }

    @DELETE
    @Timed
    @Path("/{index}")
    @ApiOperation(value = "Delete an index. This will also trigger an index ranges rebuild job.")
    @Produces(MediaType.APPLICATION_JSON)
    @ApiResponses(value = {
            @ApiResponse(code = 403, message = "You cannot delete the current deflector target index.")
    })
    public Response delete(@ApiParam(name = "index") @PathParam("index") String index) {
        checkPermission(RestPermissions.INDICES_DELETE, index);

        if(!deflector.isGraylog2Index(index)) {
            LOG.info("Index [{}] doesn't look like an index managed by Graylog2.", index);
            return Response.status(Response.Status.NOT_FOUND).build();
        }

        if (deflector.getCurrentActualTargetIndex().equals(index)) {
            return Response.status(Response.Status.FORBIDDEN).build();
        }

        // Delete index.
        indices.delete(index);

        // Trigger index ranges rebuild job.
        final SystemJob rebuildJob = rebuildIndexRangesJobFactory.create(deflector);
        try {
            systemJobManager.submit(rebuildJob);
        } catch (SystemJobConcurrencyException e) {
            LOG.error("Concurrency level of this job reached: " + e.getMessage());
            throw new WebApplicationException(Response.Status.FORBIDDEN);
        }

        return Response.noContent().build();
    }

    private Map<String, Object> shardRouting(ShardRouting route) {
        final ImmutableMap.Builder<String, Object> result = ImmutableMap.builder();

        result.put("id", route.shardId().getId());
        result.put("state", route.state().name().toLowerCase());
        result.put("active", route.active());
        result.put("primary", route.primary());
        result.put("node_id", route.currentNodeId());
        result.put("node_name", cluster.nodeIdToName(route.currentNodeId()));
        result.put("node_hostname", cluster.nodeIdToHostName(route.currentNodeId()));
        result.put("relocating_to", nullToEmpty(route.relocatingNodeId()));

        return result.build();
    }

    private Map<String, Object> indexStats(final CommonStats stats) {
        final ImmutableMap.Builder<String, Object> result = ImmutableMap.builder();

        result.put("flush", ImmutableMap.<String, Object>of(
                "total", stats.getFlush().getTotal(),
                "time_seconds", stats.getFlush().getTotalTime().getSeconds()
        ));

        result.put("get", ImmutableMap.<String, Object>of(
                "total", stats.getGet().getCount(),
                "time_seconds", stats.getGet().getTime().getSeconds()
        ));

        result.put("index", ImmutableMap.<String, Object>of(
                "total", stats.getIndexing().getTotal().getIndexCount(),
                "time_seconds", stats.getIndexing().getTotal().getIndexTime().getSeconds()
        ));

        result.put("merge", ImmutableMap.<String, Object>of(
                "total", stats.getMerge().getTotal(),
                "time_seconds", stats.getMerge().getTotalTime().getSeconds()
        ));

        result.put("refresh", ImmutableMap.<String, Object>of(
                "total", stats.getRefresh().getTotal(),
                "time_seconds", stats.getRefresh().getTotalTime().getSeconds()
        ));

        result.put("search_query", ImmutableMap.<String, Object>of(
                "total", stats.getSearch().getTotal().getQueryCount(),
                "time_seconds", stats.getSearch().getTotal().getQueryTime().getSeconds()
        ));

        result.put("search_fetch", ImmutableMap.<String, Object>of(
                "total", stats.getSearch().getTotal().getFetchCount(),
                "time_seconds", stats.getSearch().getTotal().getFetchTime().getSeconds()
        ));

        result.put("open_search_contexts", stats.getSearch().getOpenContexts());
        result.put("store_size_bytes", stats.getStore().getSize().getBytes());
        result.put("segments", stats.getSegments().getCount());

        result.put("documents", ImmutableMap.<String, Object>of(
                "count", stats.getDocs().getCount(),
                "deleted", stats.getDocs().getDeleted()
        ));

        return result.build();
    }

}
TOP

Related Classes of org.graylog2.rest.resources.system.indexer.IndicesResource

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.