package com.cyngn.chrono.storage;
import com.cyngn.chrono.data.SampleMapper;
import com.cyngn.chrono.storage.entity.Payload;
import com.cyngn.chrono.storage.entity.UrlPackage;
import com.cyngn.vertx.async.promise.Promise;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.HttpMethod;
import java.util.List;
import java.util.function.Consumer;
/**
* Handles making sure Cassandra has all the data needed for running tests.
*
* @author truelove@cyngn.com (Jeremy Truelove) 9/12/14
*/
public class Bootstrap {
private static final Logger logger = LoggerFactory.getLogger(Bootstrap.class);
public static String DEFAULT_BATCH_NAME = "test_batch";
private final StorageManager storageManager;
public Bootstrap(StorageManager storageManager, Consumer<Boolean> onComplete, String baseUrl) {
this.storageManager = storageManager;
bootstrap(onComplete, baseUrl);
}
private void bootstrap(Consumer<Boolean> onComplete, String baseUrl) {
Promise.newInstance(storageManager.session.getVertx()).all(
(context, onResult) -> setupPayloads(onResult),
(context, onResult) -> handleDefaultUrls(baseUrl, onResult))
.except(context -> onComplete.accept(false))
.done(context -> onComplete.accept(true))
.timeout(5000)
.eval();
}
private void setupPayloads(Consumer<Boolean> whenDone) {
storageManager.payloadStorage.getSupportedPayloads((success, payloads) -> {
if (success) {
verifyUpdateAndPayload(SampleMapper.KB_UNIT, SampleMapper.getInstance().supportedKbPayloads, payloads);
verifyUpdateAndPayload(SampleMapper.MB_UNIT, SampleMapper.getInstance().supportedMbPayloads, payloads);
}
whenDone.accept(success);
});
}
private void verifyUpdateAndPayload(String unit, int[] supportedPayloads, List<Payload> results) {
for(int size : supportedPayloads) {
if (!resultsContainPayload(results, unit, size)) {
logger.info("cassandra missing payload unit: {}, size: {}", unit, size);
savePayload(unit, size);
} else { logger.info("Found payload unit: {}, size: {}", unit, size); }
}
}
private boolean resultsContainPayload(List<Payload> results, String unit, int size) {
boolean result = false;
for (Payload payload : results) {
if (StringUtils.equals(payload.unit, unit) && payload.size == size) {
result = true;
break;
}
}
return result;
}
private void savePayload(String unit, int size) {
storageManager.payloadStorage.createPayload(unit, size, SampleMapper.getInstance().getPayload(unit, size),
success -> {
if(success) { logger.info("Persisted payload unit: {} size: {}", unit, size); }
else { logger.info("Failed to persist payload unit: {} size: {}", unit, size); }
});
}
private void handleDefaultUrls(String baseUrl, Consumer<Boolean> whenDone) {
String statusKey = "status";
Promise.newInstance(storageManager.session.getVertx())
.then((context, onComplete) -> storageManager.batchStorage.getTestBatch(DEFAULT_BATCH_NAME, (success, testBatch) -> {
if(success) {
context.put(statusKey, testBatch != null ? "found" : "missing");
onComplete.accept(true);
} else {
logger.info("Encountered error locating test batch");
context.put(statusKey, "error");
onComplete.accept(false);
}
}))
.except(context -> whenDone.accept(false))
.done(context -> {
String status = context.getString(statusKey);
// populate some defaults if none are there
if ("missing".equals(status)) {
List<UrlPackage> packages = Lists.newArrayList(
new UrlPackage(HttpMethod.GET,
Sets.newHashSet(
baseUrl + "/api/v1/timing/static?unit=kb&size=1",
baseUrl + "/api/v1/timing/static_cached?unit=kb&size=1",
baseUrl + "/api/v1/timing/dynamic?unit=kb&size=1",
baseUrl + "/api/v1/timing/dynamic_cached?unit=kb&size=1"
)),
new UrlPackage(HttpMethod.POST,
Sets.newHashSet(
baseUrl + "/api/v1/timing/store?unit=kb&size=1",
baseUrl + "/api/v1/timing/store_mem?unit=kb&size=1"
)));
storageManager.batchStorage.createTestBatch(DEFAULT_BATCH_NAME, packages, whenDone);
} else { whenDone.accept(true); }
})
.eval();
}
}