org.apache.druid.rpc.indexing.OverlordClientImpl Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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.apache.druid.rpc.indexing;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import org.apache.druid.client.JsonParserIterator;
import org.apache.druid.client.indexing.IndexingTotalWorkerCapacityInfo;
import org.apache.druid.client.indexing.IndexingWorkerInfo;
import org.apache.druid.client.indexing.TaskPayloadResponse;
import org.apache.druid.client.indexing.TaskStatusResponse;
import org.apache.druid.common.guava.FutureUtils;
import org.apache.druid.indexer.TaskStatus;
import org.apache.druid.indexer.TaskStatusPlus;
import org.apache.druid.indexer.report.TaskReport;
import org.apache.druid.indexing.overlord.supervisor.SupervisorStatus;
import org.apache.druid.java.util.common.StringUtils;
import org.apache.druid.java.util.common.jackson.JacksonUtils;
import org.apache.druid.java.util.common.parsers.CloseableIterator;
import org.apache.druid.java.util.http.client.response.BytesFullResponseHandler;
import org.apache.druid.java.util.http.client.response.InputStreamResponseHandler;
import org.apache.druid.java.util.http.client.response.StringFullResponseHandler;
import org.apache.druid.metadata.LockFilterPolicy;
import org.apache.druid.rpc.IgnoreHttpResponseHandler;
import org.apache.druid.rpc.RequestBuilder;
import org.apache.druid.rpc.ServiceClient;
import org.apache.druid.rpc.ServiceRetryPolicy;
import org.apache.druid.server.compaction.CompactionProgressResponse;
import org.apache.druid.server.compaction.CompactionStatusResponse;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.joda.time.Interval;
import javax.annotation.Nullable;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Production implementation of {@link OverlordClient}.
*/
public class OverlordClientImpl implements OverlordClient
{
private final ServiceClient client;
private final ObjectMapper jsonMapper;
public OverlordClientImpl(final ServiceClient client, final ObjectMapper jsonMapper)
{
this.client = Preconditions.checkNotNull(client, "client");
this.jsonMapper = Preconditions.checkNotNull(jsonMapper, "jsonMapper");
}
@Override
public ListenableFuture findCurrentLeader()
{
return FutureUtils.transform(
client.asyncRequest(
new RequestBuilder(HttpMethod.GET, "/druid/indexer/v1/leader"),
new StringFullResponseHandler(StandardCharsets.UTF_8)
),
holder -> {
try {
return new URI(holder.getContent());
}
catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
);
}
@Override
public ListenableFuture runTask(final String taskId, final Object taskObject)
{
return FutureUtils.transform(
client.asyncRequest(
new RequestBuilder(HttpMethod.POST, "/druid/indexer/v1/task")
.jsonContent(jsonMapper, taskObject),
new BytesFullResponseHandler()
),
holder -> {
final Map map =
JacksonUtils.readValue(jsonMapper, holder.getContent(), JacksonUtils.TYPE_REFERENCE_MAP_STRING_OBJECT);
final String returnedTaskId = (String) map.get("task");
Preconditions.checkState(
taskId.equals(returnedTaskId),
"Got a different taskId[%s]. Expected taskId[%s]",
returnedTaskId,
taskId
);
return null;
}
);
}
@Override
public ListenableFuture cancelTask(final String taskId)
{
final String path = StringUtils.format("/druid/indexer/v1/task/%s/shutdown", StringUtils.urlEncode(taskId));
return client.asyncRequest(
new RequestBuilder(HttpMethod.POST, path),
IgnoreHttpResponseHandler.INSTANCE
);
}
@Override
public ListenableFuture> taskStatuses(
@Nullable String state,
@Nullable String dataSource,
@Nullable Integer maxCompletedTasks
)
{
final StringBuilder pathBuilder = new StringBuilder("/druid/indexer/v1/tasks");
int params = 0;
if (state != null) {
pathBuilder.append('?').append("state=").append(StringUtils.urlEncode(state));
params++;
}
if (dataSource != null) {
pathBuilder.append(params == 0 ? '?' : '&').append("datasource=").append(StringUtils.urlEncode(dataSource));
params++;
}
if (maxCompletedTasks != null) {
pathBuilder.append(params == 0 ? '?' : '&').append("max=").append(maxCompletedTasks);
}
return FutureUtils.transform(
client.asyncRequest(
new RequestBuilder(HttpMethod.GET, pathBuilder.toString()),
new InputStreamResponseHandler()
),
in -> asJsonParserIterator(in, TaskStatusPlus.class)
);
}
@Override
public ListenableFuture
© 2015 - 2025 Weber Informatics LLC | Privacy Policy