com.mesosphere.dcos.cassandra.executor.tasks.Repair.java Source code

Java tutorial

Introduction

Here is the source code for com.mesosphere.dcos.cassandra.executor.tasks.Repair.java

Source

/*
 * Copyright 2016 Mesosphere
 *
 * Licensed 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 com.mesosphere.dcos.cassandra.executor.tasks;

import com.mesosphere.dcos.cassandra.common.tasks.repair.RepairTask;
import com.mesosphere.dcos.cassandra.executor.CassandraDaemonProcess;
import org.apache.cassandra.repair.RepairParallelism;
import org.apache.cassandra.repair.messages.RepairOption;
import org.apache.mesos.ExecutorDriver;
import org.apache.mesos.Protos;
import org.apache.mesos.executor.ExecutorTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Future;

/**
 * Implements anti-entropy, primary range, sequential repair by executing
 * RepairTask by delegating repair to the CassandraDaemonProcess.
 */
public class Repair implements ExecutorTask {
    private static final Logger LOGGER = LoggerFactory.getLogger(Repair.class);

    private final CassandraDaemonProcess daemon;
    private final ExecutorDriver driver;
    private final RepairTask task;

    private List<String> getKeySpaces() {
        if (task.getRepairContext().getKeySpaces().isEmpty()) {
            return daemon.getNonSystemKeySpaces();
        } else {
            return task.getRepairContext().getKeySpaces();
        }
    }

    private List<String> getColumnFamilies() {
        return task.getRepairContext().getColumnFamilies();
    }

    private void repairKeyspace(String keyspace, List<String> columnFamilies) throws Exception {
        LOGGER.info("Starting repair : keySpace = {}, columnFamilies = {}", keyspace, columnFamilies);

        Map<String, String> options = new HashMap<>();
        options.put(RepairOption.PRIMARY_RANGE_KEY, "true");
        options.put(RepairOption.COLUMNFAMILIES_KEY, String.join(",", columnFamilies));
        options.put(RepairOption.PARALLELISM_KEY, RepairParallelism.SEQUENTIAL.getName());
        options.put(RepairOption.INCREMENTAL_KEY, "true");

        String result = daemon.repair(keyspace, options);

        LOGGER.info("Repair output = {}", result);
        LOGGER.info("Completed repair : keySpace = {}, columnFamilies = {}", keyspace, columnFamilies);

        sendStatus(driver, Protos.TaskState.TASK_RUNNING,
                String.format("Completed repair : keySpace = %s, columnFamilies = %s", keyspace, columnFamilies));
    }

    /**
     * Creates a new Repair.
     *
     * @param driver The ExecutorDriver used to send status updates.
     * @param daemon The CassandraDaemonProcess used to execute the repair.
     * @param task   The RepairTask that will be executed.
     */
    public Repair(final ExecutorDriver driver, final CassandraDaemonProcess daemon, final RepairTask task) {
        this.driver = driver;
        this.daemon = daemon;
        this.task = task;
    }

    @Override
    public void run() {
        try {
            // Send TASK_RUNNING
            final List<String> keySpaces = getKeySpaces();
            final List<String> columnFamilies = getColumnFamilies();
            sendStatus(driver, Protos.TaskState.TASK_RUNNING, String.format(
                    "Starting repair: keySpaces = %s, " + "columnFamilies = %s", keySpaces, columnFamilies));

            for (String keyspace : keySpaces) {
                repairKeyspace(keyspace, columnFamilies);
            }

            // Send TASK_FINISHED
            sendStatus(driver, Protos.TaskState.TASK_FINISHED, String.format(
                    "Completed repair: keySpaces = %s, " + "columnFamilies = %s", keySpaces, columnFamilies));
        } catch (Throwable t) {
            // Send TASK_FAILED
            LOGGER.error("Repair failed", t);
            sendStatus(driver, Protos.TaskState.TASK_FAILED, t.getMessage());
        }
    }

    private void sendStatus(ExecutorDriver driver, Protos.TaskState state, String message) {
        Protos.TaskStatus status = task.createStatus(state, Optional.of(message)).getTaskStatus();
        driver.sendStatusUpdate(status);
    }

    @Override
    public void stop(Future<?> future) {
        future.cancel(true);
    }
}