Search in sources :

Example 1 with RestartRequest

use of org.apache.kafka.connect.runtime.RestartRequest in project kafka by apache.

the class DistributedHerder method doRestartConnectorAndTasks.

/**
 * Builds and executes a restart plan for the connector and its tasks from <code>request</code>.
 * Execution of a plan involves triggering the stop of eligible connector/tasks and then queuing the start for eligible connector/tasks.
 *
 * @param request the request to restart connector and tasks
 */
protected synchronized void doRestartConnectorAndTasks(RestartRequest request) {
    String connectorName = request.connectorName();
    Optional<RestartPlan> maybePlan = buildRestartPlan(request);
    if (!maybePlan.isPresent()) {
        log.debug("Skipping restart of connector '{}' since no status is available: {}", connectorName, request);
        return;
    }
    RestartPlan plan = maybePlan.get();
    log.info("Executing {}", plan);
    // If requested, stop the connector and any tasks, marking each as restarting
    final ExtendedAssignment currentAssignments = assignment;
    final Collection<ConnectorTaskId> assignedIdsToRestart = plan.taskIdsToRestart().stream().filter(taskId -> currentAssignments.tasks().contains(taskId)).collect(Collectors.toList());
    final boolean restartConnector = plan.shouldRestartConnector() && currentAssignments.connectors().contains(connectorName);
    final boolean restartTasks = !assignedIdsToRestart.isEmpty();
    if (restartConnector) {
        worker.stopAndAwaitConnector(connectorName);
        onRestart(connectorName);
    }
    if (restartTasks) {
        // Stop the tasks and mark as restarting
        worker.stopAndAwaitTasks(assignedIdsToRestart);
        assignedIdsToRestart.forEach(this::onRestart);
    }
    // Now restart the connector and tasks
    if (restartConnector) {
        try {
            startConnector(connectorName, (error, targetState) -> {
                if (error == null) {
                    log.info("Connector '{}' restart successful", connectorName);
                } else {
                    log.error("Connector '{}' restart failed", connectorName, error);
                }
            });
        } catch (Throwable t) {
            log.error("Connector '{}' restart failed", connectorName, t);
        }
    }
    if (restartTasks) {
        log.debug("Restarting {} of {} tasks for {}", plan.restartTaskCount(), plan.totalTaskCount(), request);
        plan.taskIdsToRestart().forEach(taskId -> {
            try {
                if (startTask(taskId)) {
                    log.info("Task '{}' restart successful", taskId);
                } else {
                    log.error("Task '{}' restart failed", taskId);
                }
            } catch (Throwable t) {
                log.error("Task '{}' restart failed", taskId, t);
            }
        });
        log.debug("Restarted {} of {} tasks for {} as requested", plan.restartTaskCount(), plan.totalTaskCount(), request);
    }
    log.info("Completed {}", plan);
}
Also used : Worker(org.apache.kafka.connect.runtime.Worker) SinkUtils(org.apache.kafka.connect.util.SinkUtils) Arrays(java.util.Arrays) TimeoutException(java.util.concurrent.TimeoutException) AlreadyExistsException(org.apache.kafka.connect.errors.AlreadyExistsException) KeyGenerator(javax.crypto.KeyGenerator) SessionKey(org.apache.kafka.connect.runtime.SessionKey) ConnectorInfo(org.apache.kafka.connect.runtime.rest.entities.ConnectorInfo) RestartRequest(org.apache.kafka.connect.runtime.RestartRequest) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) LogContext(org.apache.kafka.common.utils.LogContext) Map(java.util.Map) UriBuilder(javax.ws.rs.core.UriBuilder) ThreadUtils(org.apache.kafka.common.utils.ThreadUtils) RestClient(org.apache.kafka.connect.runtime.rest.RestClient) ConfigDef(org.apache.kafka.common.config.ConfigDef) CommonClientConfigs(org.apache.kafka.clients.CommonClientConfigs) Sensor(org.apache.kafka.common.metrics.Sensor) Time(org.apache.kafka.common.utils.Time) WakeupException(org.apache.kafka.common.errors.WakeupException) Collection(java.util.Collection) CumulativeSum(org.apache.kafka.common.metrics.stats.CumulativeSum) Set(java.util.Set) NavigableSet(java.util.NavigableSet) ConfigValue(org.apache.kafka.common.config.ConfigValue) Collectors(java.util.stream.Collectors) AbstractHerder(org.apache.kafka.connect.runtime.AbstractHerder) Executors(java.util.concurrent.Executors) Objects(java.util.Objects) CONNECT_PROTOCOL_V0(org.apache.kafka.connect.runtime.distributed.ConnectProtocol.CONNECT_PROTOCOL_V0) ConnectorStateInfo(org.apache.kafka.connect.runtime.rest.entities.ConnectorStateInfo) CloseableConnectorContext(org.apache.kafka.connect.runtime.CloseableConnectorContext) List(java.util.List) EAGER(org.apache.kafka.connect.runtime.distributed.ConnectProtocolCompatibility.EAGER) ConnectMetrics(org.apache.kafka.connect.runtime.ConnectMetrics) SourceConnectorConfig(org.apache.kafka.connect.runtime.SourceConnectorConfig) Response(javax.ws.rs.core.Response) Optional(java.util.Optional) TargetState(org.apache.kafka.connect.runtime.TargetState) SecretKey(javax.crypto.SecretKey) BadRequestException(org.apache.kafka.connect.runtime.rest.errors.BadRequestException) ConnectorClientConfigOverridePolicy(org.apache.kafka.connect.connector.policy.ConnectorClientConfigOverridePolicy) ConnectorConfig(org.apache.kafka.connect.runtime.ConnectorConfig) TaskStatus(org.apache.kafka.connect.runtime.TaskStatus) Max(org.apache.kafka.common.metrics.stats.Max) Connector(org.apache.kafka.connect.connector.Connector) Exit(org.apache.kafka.common.utils.Exit) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) ConnectorTaskId(org.apache.kafka.connect.util.ConnectorTaskId) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) Callable(java.util.concurrent.Callable) NotFoundException(org.apache.kafka.connect.errors.NotFoundException) ConfigBackingStore(org.apache.kafka.connect.storage.ConfigBackingStore) AtomicReference(java.util.concurrent.atomic.AtomicReference) TOPIC_TRACKING_ENABLE_CONFIG(org.apache.kafka.connect.runtime.WorkerConfig.TOPIC_TRACKING_ENABLE_CONFIG) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) CONNECT_PROTOCOL_V2(org.apache.kafka.connect.runtime.distributed.IncrementalCooperativeConnectProtocol.CONNECT_PROTOCOL_V2) CONNECT_PROTOCOL_V1(org.apache.kafka.connect.runtime.distributed.IncrementalCooperativeConnectProtocol.CONNECT_PROTOCOL_V1) MetricGroup(org.apache.kafka.connect.runtime.ConnectMetrics.MetricGroup) NoSuchElementException(java.util.NoSuchElementException) ExecutorService(java.util.concurrent.ExecutorService) SinkConnector(org.apache.kafka.connect.sink.SinkConnector) Utils(org.apache.kafka.common.utils.Utils) HerderConnectorContext(org.apache.kafka.connect.runtime.HerderConnectorContext) Callback(org.apache.kafka.connect.util.Callback) RestartPlan(org.apache.kafka.connect.runtime.RestartPlan) Logger(org.slf4j.Logger) InternalRequestSignature(org.apache.kafka.connect.runtime.rest.InternalRequestSignature) HerderRequest(org.apache.kafka.connect.runtime.HerderRequest) SinkConnectorConfig(org.apache.kafka.connect.runtime.SinkConnectorConfig) ConnectRestException(org.apache.kafka.connect.runtime.rest.errors.ConnectRestException) ConnectMetricsRegistry(org.apache.kafka.connect.runtime.ConnectMetricsRegistry) TaskInfo(org.apache.kafka.connect.runtime.rest.entities.TaskInfo) StatusBackingStore(org.apache.kafka.connect.storage.StatusBackingStore) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) ConcurrentSkipListSet(java.util.concurrent.ConcurrentSkipListSet) Avg(org.apache.kafka.common.metrics.stats.Avg) ConnectException(org.apache.kafka.connect.errors.ConnectException) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) Collections(java.util.Collections) ConnectorTaskId(org.apache.kafka.connect.util.ConnectorTaskId) RestartPlan(org.apache.kafka.connect.runtime.RestartPlan)

Example 2 with RestartRequest

use of org.apache.kafka.connect.runtime.RestartRequest in project kafka by apache.

the class ConnectorsResource method restartConnector.

@POST
@Path("/{connector}/restart")
public Response restartConnector(@PathParam("connector") final String connector, @Context final HttpHeaders headers, @DefaultValue("false") @QueryParam("includeTasks") final Boolean includeTasks, @DefaultValue("false") @QueryParam("onlyFailed") final Boolean onlyFailed, @QueryParam("forward") final Boolean forward) throws Throwable {
    RestartRequest restartRequest = new RestartRequest(connector, onlyFailed, includeTasks);
    String forwardingPath = "/connectors/" + connector + "/restart";
    if (restartRequest.forceRestartConnectorOnly()) {
        // For backward compatibility, just restart the connector instance and return OK with no body
        FutureCallback<Void> cb = new FutureCallback<>();
        herder.restartConnector(connector, cb);
        completeOrForwardRequest(cb, forwardingPath, "POST", headers, null, forward);
        return Response.noContent().build();
    }
    // In all other cases, submit the async restart request and return connector state
    FutureCallback<ConnectorStateInfo> cb = new FutureCallback<>();
    herder.restartConnectorAndTasks(restartRequest, cb);
    Map<String, String> queryParameters = new HashMap<>();
    queryParameters.put("includeTasks", includeTasks.toString());
    queryParameters.put("onlyFailed", onlyFailed.toString());
    ConnectorStateInfo stateInfo = completeOrForwardRequest(cb, forwardingPath, "POST", headers, queryParameters, null, new TypeReference<ConnectorStateInfo>() {
    }, new IdentityTranslator<>(), forward);
    return Response.accepted().entity(stateInfo).build();
}
Also used : HashMap(java.util.HashMap) RestartRequest(org.apache.kafka.connect.runtime.RestartRequest) FutureCallback(org.apache.kafka.connect.util.FutureCallback) ConnectorStateInfo(org.apache.kafka.connect.runtime.rest.entities.ConnectorStateInfo) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST)

Example 3 with RestartRequest

use of org.apache.kafka.connect.runtime.RestartRequest in project kafka by apache.

the class DistributedHerderTest method testDoRestartConnectorAndTasksOnlyTasks.

@Test
public void testDoRestartConnectorAndTasksOnlyTasks() {
    ConnectorTaskId taskId = new ConnectorTaskId(CONN1, 0);
    RestartRequest restartRequest = new RestartRequest(CONN1, false, true);
    RestartPlan restartPlan = PowerMock.createMock(RestartPlan.class);
    EasyMock.expect(restartPlan.shouldRestartConnector()).andReturn(true).anyTimes();
    EasyMock.expect(restartPlan.shouldRestartTasks()).andReturn(true).anyTimes();
    EasyMock.expect(restartPlan.taskIdsToRestart()).andReturn(Collections.singletonList(taskId)).anyTimes();
    EasyMock.expect(restartPlan.restartTaskCount()).andReturn(1).anyTimes();
    EasyMock.expect(restartPlan.totalTaskCount()).andReturn(1).anyTimes();
    EasyMock.expect(herder.buildRestartPlan(restartRequest)).andReturn(Optional.of(restartPlan)).anyTimes();
    herder.assignment = PowerMock.createMock(ExtendedAssignment.class);
    EasyMock.expect(herder.assignment.connectors()).andReturn(Collections.emptyList()).anyTimes();
    EasyMock.expect(herder.assignment.tasks()).andReturn(Collections.singletonList(taskId)).anyTimes();
    worker.stopAndAwaitTasks(Collections.singletonList(taskId));
    PowerMock.expectLastCall();
    herder.onRestart(taskId);
    EasyMock.expectLastCall();
    worker.startTask(EasyMock.eq(TASK0), EasyMock.anyObject(), EasyMock.anyObject(), EasyMock.anyObject(), EasyMock.eq(herder), EasyMock.anyObject(TargetState.class));
    PowerMock.expectLastCall().andReturn(true);
    PowerMock.replayAll();
    herder.doRestartConnectorAndTasks(restartRequest);
    PowerMock.verifyAll();
}
Also used : TargetState(org.apache.kafka.connect.runtime.TargetState) ConnectorTaskId(org.apache.kafka.connect.util.ConnectorTaskId) RestartPlan(org.apache.kafka.connect.runtime.RestartPlan) RestartRequest(org.apache.kafka.connect.runtime.RestartRequest) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 4 with RestartRequest

use of org.apache.kafka.connect.runtime.RestartRequest in project kafka by apache.

the class DistributedHerderTest method testRestartConnectorAndTasksUnknownStatus.

@Test
public void testRestartConnectorAndTasksUnknownStatus() throws Exception {
    RestartRequest restartRequest = new RestartRequest(CONN1, false, true);
    EasyMock.expect(herder.buildRestartPlan(restartRequest)).andReturn(Optional.empty()).anyTimes();
    configBackingStore.putRestartRequest(restartRequest);
    PowerMock.expectLastCall();
    // get the initial assignment
    EasyMock.expect(member.memberId()).andStubReturn("leader");
    EasyMock.expect(member.currentProtocolVersion()).andStubReturn(CONNECT_PROTOCOL_V0);
    expectRebalance(1, Collections.emptyList(), Collections.emptyList());
    expectPostRebalanceCatchup(SNAPSHOT);
    member.poll(EasyMock.anyInt());
    PowerMock.expectLastCall();
    // now handle the connector restart
    member.wakeup();
    PowerMock.expectLastCall();
    member.ensureActive();
    PowerMock.expectLastCall();
    member.poll(EasyMock.anyInt());
    PowerMock.expectLastCall();
    PowerMock.replayAll();
    herder.tick();
    FutureCallback<ConnectorStateInfo> callback = new FutureCallback<>();
    herder.restartConnectorAndTasks(restartRequest, callback);
    herder.tick();
    ExecutionException ee = assertThrows(ExecutionException.class, () -> callback.get(1000L, TimeUnit.MILLISECONDS));
    assertTrue(ee.getCause() instanceof NotFoundException);
    assertTrue(ee.getMessage().contains("Status for connector"));
    PowerMock.verifyAll();
}
Also used : RestartRequest(org.apache.kafka.connect.runtime.RestartRequest) NotFoundException(org.apache.kafka.connect.errors.NotFoundException) ExecutionException(java.util.concurrent.ExecutionException) ConnectorStateInfo(org.apache.kafka.connect.runtime.rest.entities.ConnectorStateInfo) FutureCallback(org.apache.kafka.connect.util.FutureCallback) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 5 with RestartRequest

use of org.apache.kafka.connect.runtime.RestartRequest in project kafka by apache.

the class DistributedHerderTest method testDoRestartConnectorAndTasksOnlyConnector.

@Test
public void testDoRestartConnectorAndTasksOnlyConnector() {
    ConnectorTaskId taskId = new ConnectorTaskId(CONN1, 0);
    RestartRequest restartRequest = new RestartRequest(CONN1, false, true);
    RestartPlan restartPlan = PowerMock.createMock(RestartPlan.class);
    EasyMock.expect(restartPlan.shouldRestartConnector()).andReturn(true).anyTimes();
    EasyMock.expect(restartPlan.shouldRestartTasks()).andReturn(true).anyTimes();
    EasyMock.expect(restartPlan.taskIdsToRestart()).andReturn(Collections.singletonList(taskId)).anyTimes();
    EasyMock.expect(herder.buildRestartPlan(restartRequest)).andReturn(Optional.of(restartPlan)).anyTimes();
    herder.assignment = PowerMock.createMock(ExtendedAssignment.class);
    EasyMock.expect(herder.assignment.connectors()).andReturn(Collections.singletonList(CONN1)).anyTimes();
    EasyMock.expect(herder.assignment.tasks()).andReturn(Collections.emptyList()).anyTimes();
    worker.stopAndAwaitConnector(CONN1);
    PowerMock.expectLastCall();
    Capture<Callback<TargetState>> stateCallback = newCapture();
    worker.startConnector(EasyMock.eq(CONN1), EasyMock.anyObject(), EasyMock.anyObject(), EasyMock.eq(herder), EasyMock.anyObject(TargetState.class), capture(stateCallback));
    herder.onRestart(CONN1);
    EasyMock.expectLastCall();
    PowerMock.replayAll();
    herder.doRestartConnectorAndTasks(restartRequest);
    PowerMock.verifyAll();
}
Also used : TargetState(org.apache.kafka.connect.runtime.TargetState) FutureCallback(org.apache.kafka.connect.util.FutureCallback) Callback(org.apache.kafka.connect.util.Callback) ConnectorTaskId(org.apache.kafka.connect.util.ConnectorTaskId) RestartPlan(org.apache.kafka.connect.runtime.RestartPlan) RestartRequest(org.apache.kafka.connect.runtime.RestartRequest) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Aggregations

RestartRequest (org.apache.kafka.connect.runtime.RestartRequest)29 Test (org.junit.Test)27 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)27 ConnectorStateInfo (org.apache.kafka.connect.runtime.rest.entities.ConnectorStateInfo)13 FutureCallback (org.apache.kafka.connect.util.FutureCallback)13 RestartPlan (org.apache.kafka.connect.runtime.RestartPlan)10 Callback (org.apache.kafka.connect.util.Callback)9 ConnectorTaskId (org.apache.kafka.connect.util.ConnectorTaskId)7 Connector (org.apache.kafka.connect.connector.Connector)6 NotFoundException (org.apache.kafka.connect.errors.NotFoundException)6 ConnectorInfo (org.apache.kafka.connect.runtime.rest.entities.ConnectorInfo)6 SinkConnector (org.apache.kafka.connect.sink.SinkConnector)6 ExecutionException (java.util.concurrent.ExecutionException)5 Herder (org.apache.kafka.connect.runtime.Herder)5 WorkerConnector (org.apache.kafka.connect.runtime.WorkerConnector)5 SourceConnector (org.apache.kafka.connect.source.SourceConnector)5 TargetState (org.apache.kafka.connect.runtime.TargetState)4 HashMap (java.util.HashMap)3 Response (javax.ws.rs.core.Response)3 ConsumerRecord (org.apache.kafka.clients.consumer.ConsumerRecord)3