Package io.druid.server.http

Source Code of io.druid.server.http.InfoResource

/*
* Druid - a distributed column store.
* Copyright (C) 2012, 2013  Metamarkets Group Inc.
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

package io.druid.server.http;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import io.druid.client.DruidDataSource;
import io.druid.client.DruidServer;
import io.druid.client.InventoryView;
import io.druid.client.indexing.IndexingServiceClient;
import io.druid.metadata.MetadataRuleManager;
import io.druid.metadata.MetadataSegmentManager;
import io.druid.server.coordinator.DruidCoordinator;
import io.druid.server.coordinator.rules.LoadRule;
import io.druid.server.coordinator.rules.Rule;
import io.druid.timeline.DataSegment;
import org.joda.time.Interval;

import javax.annotation.Nullable;
import javax.ws.rs.Consumes;
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.QueryParam;
import javax.ws.rs.core.Response;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**
*/
@Deprecated
@Path("/info")
public class InfoResource
{
  private static final Function<DruidServer, Map<String, Object>> simplifyClusterFn =
      new Function<DruidServer, Map<String, Object>>()
      {
        @Override
        public Map<String, Object> apply(DruidServer server)
        {
          return new ImmutableMap.Builder<String, Object>()
              .put("host", server.getHost())
              .put("type", server.getType())
              .put("tier", server.getTier())
              .put("currSize", server.getCurrSize())
              .put("maxSize", server.getMaxSize())
              .put(
                  "segments",
                  Collections2.transform(
                      server.getSegments().values(),
                      new Function<DataSegment, Map<String, Object>>()
                      {
                        @Override
                        public Map<String, Object> apply(DataSegment segment)
                        {
                          return new ImmutableMap.Builder<String, Object>()
                              .put("id", segment.getIdentifier())
                              .put("dataSource", segment.getDataSource())
                              .put("interval", segment.getInterval().toString())
                              .put("version", segment.getVersion())
                              .put("size", segment.getSize())
                              .build();
                        }
                      }
                  )
              )
              .build();
        }
      };

  private final DruidCoordinator coordinator;
  private final InventoryView serverInventoryView;
  private final MetadataSegmentManager metadataSegmentManager;
  private final MetadataRuleManager metadataRuleManager;
  private final IndexingServiceClient indexingServiceClient;

  private final ObjectMapper jsonMapper;

  @Inject
  public InfoResource(
      DruidCoordinator coordinator,
      InventoryView serverInventoryView,
      MetadataSegmentManager metadataSegmentManager,
      MetadataRuleManager metadataRuleManager,
      @Nullable
      IndexingServiceClient indexingServiceClient,
      ObjectMapper jsonMapper
  )
  {
    this.coordinator = coordinator;
    this.serverInventoryView = serverInventoryView;
    this.metadataSegmentManager = metadataSegmentManager;
    this.metadataRuleManager = metadataRuleManager;
    this.indexingServiceClient = indexingServiceClient;
    this.jsonMapper = jsonMapper;
  }

  @GET
  @Path("/coordinator")
  @Produces("application/json")
  public Response getMaster()
  {
    return Response.status(Response.Status.OK)
                   .entity(coordinator.getCurrentLeader())
                   .build();
  }


  @GET
  @Path("/cluster")
  @Produces("application/json")
  public Response getClusterInfo(
      @QueryParam("full") String full
  )
  {
    if (full != null) {
      return Response.ok(serverInventoryView.getInventory())
                     .build();
    }
    return Response.ok(
        Lists.newArrayList(
            Iterables.transform(
                serverInventoryView.getInventory(),
                simplifyClusterFn
            )
        )
    ).build();
  }

  @GET
  @Path("/servers")
  @Produces("application/json")
  public Response getClusterServers(
      @QueryParam("full") String full
  )
  {
    Response.ResponseBuilder builder = Response.status(Response.Status.OK);
    if (full != null) {
      return builder.entity(Lists.newArrayList(serverInventoryView.getInventory())).build();
    }

    return builder.entity(
        Lists.newArrayList(
            Iterables.transform(
                serverInventoryView.getInventory(),
                new Function<DruidServer, String>()
                {
                  @Override
                  public String apply(DruidServer druidServer)
                  {
                    return druidServer.getHost();
                  }
                }
            )
        )
    ).build();
  }

  @GET
  @Path("/servers/{serverName}")
  @Produces("application/json")
  public Response getServer(
      @PathParam("serverName") String serverName
  )
  {
    Response.ResponseBuilder builder = Response.status(Response.Status.OK);
    DruidServer server = serverInventoryView.getInventoryValue(serverName);
    if (server == null) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    return builder.status(Response.Status.OK)
                  .entity(server)
                  .build();
  }

  @GET
  @Path("/servers/{serverName}/segments")
  @Produces("application/json")
  public Response getServerSegments(
      @PathParam("serverName") String serverName,
      @QueryParam("full") String full
  )
  {
    Response.ResponseBuilder builder = Response.status(Response.Status.OK);
    DruidServer server = serverInventoryView.getInventoryValue(serverName);
    if (server == null) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    if (full != null) {
      return builder.entity(server.getSegments().values()).build();
    }

    return builder.entity(
        Collections2.transform(
            server.getSegments().values(),
            new Function<DataSegment, String>()
            {
              @Override
              public String apply(@Nullable DataSegment segment)
              {
                return segment.getIdentifier();
              }
            }
        )
    ).build();
  }

  @GET
  @Path("/servers/{serverName}/segments/{segmentId}")
  @Produces("application/json")
  public Response getServerSegment(
      @PathParam("serverName") String serverName,
      @PathParam("segmentId") String segmentId
  )
  {
    DruidServer server = serverInventoryView.getInventoryValue(serverName);
    if (server == null) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    DataSegment segment = server.getSegment(segmentId);
    if (segment == null) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    return Response.status(Response.Status.OK).entity(segment).build();
  }

  @GET
  @Path("/segments")
  @Produces("application/json")
  public Response getClusterSegments(
      @QueryParam("full") String full
  )
  {
    Response.ResponseBuilder builder = Response.status(Response.Status.OK);
    if (full != null) {
      return builder.entity(
          Lists.newArrayList(
              Iterables.concat(
                  Iterables.transform(
                      serverInventoryView.getInventory(),
                      new Function<DruidServer, Iterable<DataSegment>>()
                      {
                        @Override
                        public Iterable<DataSegment> apply(@Nullable DruidServer druidServer)
                        {
                          return druidServer.getSegments().values();
                        }
                      }
                  )
              )
          )
      ).build();
    }

    return builder.entity(
        Lists.newArrayList(
            Iterables.concat(
                Iterables.transform(
                    serverInventoryView.getInventory(),
                    new Function<DruidServer, Iterable<String>>()
                    {
                      @Override
                      public Iterable<String> apply(@Nullable DruidServer druidServer)
                      {
                        return Collections2.transform(
                            druidServer.getSegments().values(),
                            new Function<DataSegment, String>()
                            {
                              @Override
                              public String apply(@Nullable DataSegment segment)
                              {
                                return segment.getIdentifier();
                              }
                            }
                        );
                      }
                    }
                )
            )
        )
    ).build();
  }

  @GET
  @Path("/segments/{segmentId}")
  @Produces("application/json")
  public Response getClusterSegment(
      @PathParam("segmentId") String segmentId
  )
  {
    for (DruidServer server : serverInventoryView.getInventory()) {
      if (server.getSegments().containsKey(segmentId)) {
        return Response.status(Response.Status.OK)
                       .entity(server.getSegments().get(segmentId))
                       .build();
      }
    }

    return Response.status(Response.Status.NOT_FOUND).build();
  }

  @GET
  @Path("/tiers")
  @Produces("application/json")
  public Response getTiers()
  {
    Set<String> tiers = Sets.newHashSet();
    for (DruidServer server : serverInventoryView.getInventory()) {
      tiers.add(server.getTier());
    }
    return Response.status(Response.Status.OK)
                   .entity(tiers)
                   .build();
  }

  @GET
  @Path("/rules")
  @Produces("application/json")
  public Response getRules()
  {
    // FUGLY, backwards compatibility
    // This will def. be removed as part of the next release
    return Response.ok().entity(
        Maps.transformValues(
            metadataRuleManager.getAllRules(),
            new Function<List<Rule>, Object>()
            {
              @Override
              public Object apply(List<Rule> rules)
              {
                return Lists.transform(
                    rules,
                    new Function<Rule, Object>()
                    {
                      @Override
                      public Object apply(Rule rule)
                      {
                        if (rule instanceof LoadRule) {
                          Map<String, Object> newRule = jsonMapper.convertValue(
                              rule, new TypeReference<Map<String, Object>>()
                              {
                              }
                          );
                          Set<String> tiers = Sets.newHashSet(((LoadRule) rule).getTieredReplicants().keySet());
                          tiers.remove(DruidServer.DEFAULT_TIER);
                          String tier = DruidServer.DEFAULT_TIER;
                          if (!tiers.isEmpty()) {
                            tier = tiers.iterator().next();
                          }

                          newRule.put("tier", tier);
                          newRule.put("replicants", ((LoadRule) rule).getNumReplicants(tier));

                          return newRule;
                        }
                        return rule;
                      }
                    }
                );
              }
            }
        )
    ).build();
  }

  @GET
  @Path("/rules/{dataSourceName}")
  @Produces("application/json")
  public Response getDatasourceRules(
      @PathParam("dataSourceName") final String dataSourceName,
      @QueryParam("full") final String full

  )
  {
    if (full != null) {
      return Response.ok(metadataRuleManager.getRulesWithDefault(dataSourceName))
                     .build();
    }
    return Response.ok(metadataRuleManager.getRules(dataSourceName))
                   .build();
  }

  @POST
  @Path("/rules/{dataSourceName}")
  @Consumes("application/json")
  public Response setDatasourceRules(
      @PathParam("dataSourceName") final String dataSourceName,
      final List<Rule> rules
  )
  {
    if (metadataRuleManager.overrideRule(dataSourceName, rules)) {
      return Response.status(Response.Status.OK).build();
    }
    return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
  }

  @GET
  @Path("/datasources")
  @Produces("application/json")
  public Response getQueryableDataSources(
      @QueryParam("full") String full
  )
  {
    Response.ResponseBuilder builder = Response.status(Response.Status.OK);
    if (full != null) {
      return builder.entity(getDataSources()).build();
    }

    return builder.entity(
        Lists.newArrayList(
            Iterables.transform(
                getDataSources(),
                new Function<DruidDataSource, String>()
                {
                  @Override
                  public String apply(@Nullable DruidDataSource dataSource)
                  {
                    return dataSource.getName();
                  }
                }
            )
        )
    ).build();
  }

  @GET
  @Path("/datasources/{dataSourceName}")
  @Produces("application/json")
  public Response getTheDataSource(
      @PathParam("dataSourceName") final String dataSourceName
  )
  {
    DruidDataSource dataSource = getDataSource(dataSourceName.toLowerCase());
    if (dataSource == null) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    return Response.ok(dataSource).build();
  }


  @DELETE
  @Path("/datasources/{dataSourceName}")
  public Response deleteDataSource(
      @PathParam("dataSourceName") final String dataSourceName,
      @QueryParam("kill") final String kill,
      @QueryParam("interval") final String interval
  )
  {
    // This is weird enough to have warranted some sort of T0D0 comment at one point, but it will likely be all
    // rewritten once Guice introduced, and that's the brunt of the information that was in the original T0D0 too.
    if (indexingServiceClient == null) {
      return Response.status(Response.Status.OK).entity(ImmutableMap.of("error", "no indexing service found")).build();
    }
    if (kill != null && Boolean.valueOf(kill)) {
      indexingServiceClient.killSegments(dataSourceName, new Interval(interval));
    } else {
      if (!metadataSegmentManager.removeDatasource(dataSourceName)) {
        return Response.status(Response.Status.NOT_FOUND).build();
      }
    }

    return Response.status(Response.Status.OK).build();
  }

  @POST
  @Path("/datasources/{dataSourceName}")
  @Consumes("application/json")
  public Response enableDataSource(
      @PathParam("dataSourceName") final String dataSourceName
  )
  {
    if (!metadataSegmentManager.enableDatasource(dataSourceName)) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    return Response.status(Response.Status.OK).build();
  }

  @GET
  @Path("/datasources/{dataSourceName}/segments")
  @Produces("application/json")
  public Response getSegmentDataSourceSegments(
      @PathParam("dataSourceName") String dataSourceName,
      @QueryParam("full") String full
  )
  {
    DruidDataSource dataSource = getDataSource(dataSourceName.toLowerCase());
    if (dataSource == null) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    Response.ResponseBuilder builder = Response.status(Response.Status.OK);
    if (full != null) {
      return builder.entity(dataSource.getSegments()).build();
    }

    return builder.entity(
        Iterables.transform(
            dataSource.getSegments(),
            new Function<DataSegment, Object>()
            {
              @Override
              public Object apply(@Nullable DataSegment segment)
              {
                return segment.getIdentifier();
              }
            }
        )
    ).build();
  }

  @GET
  @Path("/datasources/{dataSourceName}/segments/{segmentId}")
  @Produces("application/json")
  public Response getSegmentDataSourceSegment(
      @PathParam("dataSourceName") String dataSourceName,
      @PathParam("segmentId") String segmentId
  )
  {
    DruidDataSource dataSource = getDataSource(dataSourceName.toLowerCase());
    if (dataSource == null) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    for (DataSegment segment : dataSource.getSegments()) {
      if (segment.getIdentifier().equalsIgnoreCase(segmentId)) {
        return Response.status(Response.Status.OK).entity(segment).build();
      }
    }
    return Response.status(Response.Status.NOT_FOUND).build();
  }

  @DELETE
  @Path("/datasources/{dataSourceName}/segments/{segmentId}")
  public Response deleteDatasourceSegment(
      @PathParam("dataSourceName") String dataSourceName,
      @PathParam("segmentId") String segmentId
  )
  {
    if (!metadataSegmentManager.removeSegment(dataSourceName, segmentId)) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    return Response.status(Response.Status.OK).build();
  }

  @POST
  @Path("/datasources/{dataSourceName}/segments/{segmentId}")
  @Consumes("application/json")
  public Response enableDatasourceSegment(
      @PathParam("dataSourceName") String dataSourceName,
      @PathParam("segmentId") String segmentId
  )
  {
    if (!metadataSegmentManager.enableSegment(segmentId)) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    return Response.status(Response.Status.OK).build();
  }

  private DruidDataSource getDataSource(final String dataSourceName)
  {
    Iterable<DruidDataSource> dataSources =
        Iterables.concat(
            Iterables.transform(
                serverInventoryView.getInventory(),
                new Function<DruidServer, DruidDataSource>()
                {
                  @Override
                  public DruidDataSource apply(@Nullable DruidServer input)
                  {
                    return input.getDataSource(dataSourceName);
                  }
                }
            )
        );

    List<DruidDataSource> validDataSources = Lists.newArrayList();
    for (DruidDataSource dataSource : dataSources) {
      if (dataSource != null) {
        validDataSources.add(dataSource);
      }
    }
    if (validDataSources.isEmpty()) {
      return null;
    }

    Map<String, DataSegment> segmentMap = Maps.newHashMap();
    for (DruidDataSource dataSource : validDataSources) {
      if (dataSource != null) {
        Iterable<DataSegment> segments = dataSource.getSegments();
        for (DataSegment segment : segments) {
          segmentMap.put(segment.getIdentifier(), segment);
        }
      }
    }

    return new DruidDataSource(
        dataSourceName,
        ImmutableMap.<String, String>of()
    ).addSegments(segmentMap);
  }

  private Set<DruidDataSource> getDataSources()
  {
    TreeSet<DruidDataSource> dataSources = Sets.newTreeSet(
        new Comparator<DruidDataSource>()
        {
          @Override
          public int compare(DruidDataSource druidDataSource, DruidDataSource druidDataSource1)
          {
            return druidDataSource.getName().compareTo(druidDataSource1.getName());
          }
        }
    );
    dataSources.addAll(
        Lists.newArrayList(
            Iterables.concat(
                Iterables.transform(
                    serverInventoryView.getInventory(),
                    new Function<DruidServer, Iterable<DruidDataSource>>()
                    {
                      @Override
                      public Iterable<DruidDataSource> apply(@Nullable DruidServer input)
                      {
                        return input.getDataSources();
                      }
                    }
                )
            )
        )
    );
    return dataSources;
  }

  @GET
  @Path("/metadata/datasources")
  @Produces("application/json")
  public Response getDatabaseDataSources(
      @QueryParam("full") String full,
      @QueryParam("includeDisabled") String includeDisabled
  )
  {
    Response.ResponseBuilder builder = Response.status(Response.Status.OK);
    if (includeDisabled != null) {
      return builder.entity(metadataSegmentManager.getAllDatasourceNames()).build();
    }
    if (full != null) {
      return builder.entity(metadataSegmentManager.getInventory()).build();
    }

    List<String> dataSourceNames = Lists.newArrayList(
        Iterables.transform(
            metadataSegmentManager.getInventory(),
            new Function<DruidDataSource, String>()
            {
              @Override
              public String apply(@Nullable DruidDataSource dataSource)
              {
                return dataSource.getName();
              }
            }
        )
    );

    Collections.sort(dataSourceNames);

    return builder.entity(dataSourceNames).build();
  }

  @GET
  @Path("/metadata/datasources/{dataSourceName}")
  @Produces("application/json")
  public Response getDatabaseSegmentDataSource(
      @PathParam("dataSourceName") final String dataSourceName
  )
  {
    DruidDataSource dataSource = metadataSegmentManager.getInventoryValue(dataSourceName);
    if (dataSource == null) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    return Response.status(Response.Status.OK).entity(dataSource).build();
  }

  @GET
  @Path("/metadata/datasources/{dataSourceName}/segments")
  @Produces("application/json")
  public Response getDatabaseSegmentDataSourceSegments(
      @PathParam("dataSourceName") String dataSourceName,
      @QueryParam("full") String full
  )
  {
    DruidDataSource dataSource = metadataSegmentManager.getInventoryValue(dataSourceName);
    if (dataSource == null) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    Response.ResponseBuilder builder = Response.status(Response.Status.OK);
    if (full != null) {
      return builder.entity(dataSource.getSegments()).build();
    }

    return builder.entity(
        Iterables.transform(
            dataSource.getSegments(),
            new Function<DataSegment, Object>()
            {
              @Override
              public Object apply(@Nullable DataSegment segment)
              {
                return segment.getIdentifier();
              }
            }
        )
    ).build();
  }

  @GET
  @Path("/metadata/datasources/{dataSourceName}/segments/{segmentId}")
  @Produces("application/json")
  public Response getDatabaseSegmentDataSourceSegment(
      @PathParam("dataSourceName") String dataSourceName,
      @PathParam("segmentId") String segmentId
  )
  {
    DruidDataSource dataSource = metadataSegmentManager.getInventoryValue(dataSourceName);
    if (dataSource == null) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }

    for (DataSegment segment : dataSource.getSegments()) {
      if (segment.getIdentifier().equalsIgnoreCase(segmentId)) {
        return Response.status(Response.Status.OK).entity(segment).build();
      }
    }
    return Response.status(Response.Status.NOT_FOUND).build();
  }
}
TOP

Related Classes of io.druid.server.http.InfoResource

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.