Search in sources :

Example 1 with RestartPlan

use of org.apache.kafka.connect.runtime.RestartPlan 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 RestartPlan

use of org.apache.kafka.connect.runtime.RestartPlan 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 3 with RestartPlan

use of org.apache.kafka.connect.runtime.RestartPlan 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)

Example 4 with RestartPlan

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

the class StandaloneHerderTest method testRestartConnectorAndTasksOnlyTasks.

@Test
public void testRestartConnectorAndTasksOnlyTasks() throws Exception {
    ConnectorTaskId taskId = new ConnectorTaskId(CONNECTOR_NAME, 0);
    RestartRequest restartRequest = new RestartRequest(CONNECTOR_NAME, false, true);
    RestartPlan restartPlan = PowerMock.createMock(RestartPlan.class);
    ConnectorStateInfo connectorStateInfo = PowerMock.createMock(ConnectorStateInfo.class);
    EasyMock.expect(restartPlan.shouldRestartConnector()).andReturn(false).anyTimes();
    EasyMock.expect(restartPlan.shouldRestartTasks()).andReturn(true).anyTimes();
    EasyMock.expect(restartPlan.restartTaskCount()).andReturn(1).anyTimes();
    EasyMock.expect(restartPlan.totalTaskCount()).andReturn(1).anyTimes();
    EasyMock.expect(restartPlan.taskIdsToRestart()).andReturn(Collections.singletonList(taskId)).anyTimes();
    EasyMock.expect(restartPlan.restartConnectorStateInfo()).andReturn(connectorStateInfo).anyTimes();
    EasyMock.expect(herder.buildRestartPlan(restartRequest)).andReturn(Optional.of(restartPlan)).anyTimes();
    herder.onRestart(taskId);
    EasyMock.expectLastCall();
    connector = PowerMock.createMock(BogusSinkConnector.class);
    expectAdd(SourceSink.SINK);
    Map<String, String> connectorConfig = connectorConfig(SourceSink.SINK);
    Connector connectorMock = PowerMock.createMock(SinkConnector.class);
    expectConfigValidation(connectorMock, true, connectorConfig);
    worker.stopAndAwaitTasks(Collections.singletonList(taskId));
    EasyMock.expectLastCall();
    ClusterConfigState configState = new ClusterConfigState(-1, null, Collections.singletonMap(CONNECTOR_NAME, 1), Collections.singletonMap(CONNECTOR_NAME, connectorConfig), Collections.singletonMap(CONNECTOR_NAME, TargetState.STARTED), Collections.singletonMap(taskId, taskConfig(SourceSink.SINK)), new HashSet<>(), transformer);
    worker.startTask(taskId, configState, connectorConfig, taskConfig(SourceSink.SINK), herder, TargetState.STARTED);
    EasyMock.expectLastCall().andReturn(true);
    PowerMock.replayAll();
    herder.putConnectorConfig(CONNECTOR_NAME, connectorConfig, false, createCallback);
    Herder.Created<ConnectorInfo> connectorInfo = createCallback.get(1000L, TimeUnit.SECONDS);
    assertEquals(createdInfo(SourceSink.SINK), connectorInfo.result());
    FutureCallback<ConnectorStateInfo> restartCallback = new FutureCallback<>();
    herder.restartConnectorAndTasks(restartRequest, restartCallback);
    assertEquals(connectorStateInfo, restartCallback.get(1000L, TimeUnit.MILLISECONDS));
    PowerMock.verifyAll();
}
Also used : SourceConnector(org.apache.kafka.connect.source.SourceConnector) WorkerConnector(org.apache.kafka.connect.runtime.WorkerConnector) Connector(org.apache.kafka.connect.connector.Connector) SinkConnector(org.apache.kafka.connect.sink.SinkConnector) ConnectorTaskId(org.apache.kafka.connect.util.ConnectorTaskId) ConnectorInfo(org.apache.kafka.connect.runtime.rest.entities.ConnectorInfo) RestartRequest(org.apache.kafka.connect.runtime.RestartRequest) RestartPlan(org.apache.kafka.connect.runtime.RestartPlan) Herder(org.apache.kafka.connect.runtime.Herder) ConnectorStateInfo(org.apache.kafka.connect.runtime.rest.entities.ConnectorStateInfo) ClusterConfigState(org.apache.kafka.connect.runtime.distributed.ClusterConfigState) FutureCallback(org.apache.kafka.connect.util.FutureCallback) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 5 with RestartPlan

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

the class DistributedHerder method restartConnectorAndTasks.

@Override
public void restartConnectorAndTasks(RestartRequest request, Callback<ConnectorStateInfo> callback) {
    final String connectorName = request.connectorName();
    addRequest(() -> {
        if (checkRebalanceNeeded(callback)) {
            return null;
        }
        if (!configState.connectors().contains(request.connectorName())) {
            callback.onCompletion(new NotFoundException("Unknown connector: " + connectorName), null);
            return null;
        }
        if (isLeader()) {
            // Write a restart request to the config backing store, to be executed asynchronously in tick()
            configBackingStore.putRestartRequest(request);
            // Compute and send the response that this was accepted
            Optional<RestartPlan> plan = buildRestartPlan(request);
            if (!plan.isPresent()) {
                callback.onCompletion(new NotFoundException("Status for connector " + connectorName + " not found", null), null);
            } else {
                callback.onCompletion(null, plan.get().restartConnectorStateInfo());
            }
        } else {
            callback.onCompletion(new NotLeaderException("Only the leader can process restart requests.", leaderUrl()), null);
        }
        return null;
    }, forwardErrorCallback(callback));
}
Also used : RestartPlan(org.apache.kafka.connect.runtime.RestartPlan) NotFoundException(org.apache.kafka.connect.errors.NotFoundException)

Aggregations

RestartPlan (org.apache.kafka.connect.runtime.RestartPlan)12 RestartRequest (org.apache.kafka.connect.runtime.RestartRequest)10 Test (org.junit.Test)9 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)9 ConnectorTaskId (org.apache.kafka.connect.util.ConnectorTaskId)7 FutureCallback (org.apache.kafka.connect.util.FutureCallback)7 ConnectorStateInfo (org.apache.kafka.connect.runtime.rest.entities.ConnectorStateInfo)6 Connector (org.apache.kafka.connect.connector.Connector)5 ConnectorInfo (org.apache.kafka.connect.runtime.rest.entities.ConnectorInfo)5 SinkConnector (org.apache.kafka.connect.sink.SinkConnector)5 Callback (org.apache.kafka.connect.util.Callback)5 TargetState (org.apache.kafka.connect.runtime.TargetState)4 Herder (org.apache.kafka.connect.runtime.Herder)3 WorkerConnector (org.apache.kafka.connect.runtime.WorkerConnector)3 SourceConnector (org.apache.kafka.connect.source.SourceConnector)3 NotFoundException (org.apache.kafka.connect.errors.NotFoundException)2 HerderConnectorContext (org.apache.kafka.connect.runtime.HerderConnectorContext)2 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1