package com.sequenceiq.cloudbreak.service.cluster.flow;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.ecwid.consul.v1.ConsulClient;
import com.sequenceiq.cloudbreak.service.StackBasedStatusCheckerTask;
import com.sequenceiq.cloudbreak.service.cluster.PluginFailureException;
import com.sequenceiq.cloudbreak.service.stack.flow.ConsulUtils;
@Component
public class ConsulKVCheckerTask extends StackBasedStatusCheckerTask<ConsulKVCheckerContext> {
private static final Logger LOGGER = LoggerFactory.getLogger(ConsulKVCheckerTask.class);
@Override
public boolean checkStatus(ConsulKVCheckerContext context) {
List<String> keys = context.getKeys();
String expectedValue = context.getExpectedValue();
String failValue = context.getFailValue();
ConsulClient client = context.getConsulClient();
LOGGER.info("Checking if keys in Consul's key-value store have the expected value '{}'", expectedValue);
Set<String> failedKeys = new HashSet<>();
int matchingKeys = 0;
int notFoundKeys = 0;
for (String key : keys) {
String value = ConsulUtils.getKVValue(Collections.singletonList(client), key, null);
if (value != null) {
if (value.equals(failValue)) {
failedKeys.add(key);
} else if (value.equals(expectedValue)) {
matchingKeys++;
}
} else {
notFoundKeys++;
}
}
LOGGER.info("Keys: [Total: {}, {}: {}, Not {}: {}, Not found: {}, {}: {}]",
keys.size(),
expectedValue, matchingKeys,
expectedValue, keys.size() - matchingKeys - notFoundKeys - failedKeys.size(),
notFoundKeys,
failValue, failedKeys.size());
if (!failedKeys.isEmpty()) {
throw new PluginFailureException(String.format("Found failure signal at keys: %s", failedKeys));
}
return matchingKeys == keys.size();
}
@Override
public void handleTimeout(ConsulKVCheckerContext ctx) {
throw new PluginFailureException(String.format("Operation timed out. Keys not found or don't have the expected value '%s'.", ctx.getExpectedValue()));
}
@Override
public String successMessage(ConsulKVCheckerContext ctx) {
return String.format("All %s keys found and have the expected value '%s'.", ctx.getKeys().size(), ctx.getExpectedValue());
}
}