package com.indeed.proctor.webapp.controllers;
import com.google.common.collect.ImmutableMap;
import com.indeed.proctor.common.model.TestDefinition;
import com.indeed.proctor.common.model.TestMatrixVersion;
import com.indeed.proctor.store.ProctorStore;
import com.indeed.proctor.store.Revision;
import com.indeed.proctor.store.StoreException;
import com.indeed.proctor.webapp.db.Environment;
import com.indeed.proctor.webapp.model.WebappConfiguration;
import org.apache.log4j.Logger;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* @author parker
*/
public class AbstractController {
private static final Logger LOGGER = Logger.getLogger(AbstractController.class);
private final WebappConfiguration configuration;
private final Map<Environment, ProctorStore> stores;
public AbstractController(final WebappConfiguration configuration,
final ProctorStore trunkStore,
final ProctorStore qaStore,
final ProctorStore productionStore) {
this.configuration = configuration;
stores = ImmutableMap.of(
Environment.WORKING, trunkStore,
Environment.QA, qaStore,
Environment.PRODUCTION, productionStore
);
}
protected static String printThrowable(final Throwable t) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
pw.close();
return sw.toString();
}
protected static boolean isAJAXRequest(final HttpServletRequest request) {
final String xhrHeader = request.getHeader("X-Requested-With");
if ("XMLHttpRequest".equals(xhrHeader)) {
return true;
}
// For redirects in an AJAX request, it's common to append parameter
final String xhrParameter = request.getParameter("X-Requested-With");
return "XMLHttpRequest".equals(xhrHeader);
}
protected Environment determineEnvironmentFromParameter(String branch) {
final Environment b = Environment.fromName(branch);
return b != null ? b : Environment.WORKING;
}
protected WebappConfiguration getConfiguration() {
return configuration;
}
protected ProctorStore determineStoreFromEnvironment(final Environment branch) {
final ProctorStore store = stores.get(branch);
if (store == null) {
throw new RuntimeException("Unknown store for branch " + branch);
}
return store;
}
protected TestMatrixVersion getCurrentMatrix(final Environment branch) {
try {
return determineStoreFromEnvironment(branch).getCurrentTestMatrix();
} catch (StoreException e) {
return null;
}
}
protected List<Revision> queryMatrixHistory(final Environment branch, final int start, final int limit) throws StoreException {
return determineStoreFromEnvironment(branch).getMatrixHistory(start, limit);
}
protected TestMatrixVersion queryMatrixFromBranchOrRevision(final String branchOrRevision) throws StoreException {
final BranchOrRevision bor = new BranchOrRevision(branchOrRevision);
return bor.queryTestMatrixVersion();
}
protected TestDefinition queryTestDefinition(final String branchOrRevision, final String testName) throws StoreException {
final BranchOrRevision bor = new BranchOrRevision(branchOrRevision);
return bor.queryTestDefinition(testName);
}
protected List<Revision> queryTestDefinitionHistory(final String branchOrRevision, final String testName, final int start, final int limit) throws StoreException {
final BranchOrRevision bor = new BranchOrRevision(branchOrRevision);
return bor.queryTestDefinitionHistory(testName, start, limit);
}
private class BranchOrRevision {
final String stringValue;
final Environment branch;
private BranchOrRevision(final String branchOrRevision) throws StoreException {
stringValue = branchOrRevision;
branch = Environment.fromName(stringValue);
}
private boolean isBranch() {
return null != branch;
}
@Nullable
private TestMatrixVersion queryTestMatrixVersion() throws StoreException {
if (isBranch()) {
return determineStoreFromEnvironment(branch).getCurrentTestMatrix();
} else {
return queryMatrixFromRevision(stringValue);
}
}
@Nullable
private TestDefinition queryTestDefinition(final String testName) throws StoreException {
final TestMatrixVersion testMatrixVersion = queryTestMatrixVersion();
if (testMatrixVersion == null) {
return null;
}
return testMatrixVersion.getTestMatrixDefinition().getTests().get(testName);
}
private List<Revision> queryTestDefinitionHistory(final String testName, final int start, final int limit) throws StoreException {
if (isBranch()) {
return determineStoreFromEnvironment(branch).getHistory(testName, start, limit);
} else {
return queryTestHistoryFromRevision(testName, stringValue, start, limit);
}
}
private TestMatrixVersion queryMatrixFromRevision(final String revision) {
for (final ProctorStore store : stores.values()) {
try {
final TestMatrixVersion testMatrix = store.getTestMatrix(revision);
if (testMatrix != null) {
return testMatrix;
}
} catch (final StoreException e) {
LOGGER.info(String.format("Failed to find revision %s in %s", revision, store.getName()));
}
}
return null;
}
private List<Revision> queryTestHistoryFromRevision(final String testName, final String revision, final int start, final int limit) throws StoreException {
for (final ProctorStore store : stores.values()) {
final Map<String, List<Revision>> allHistories = store.getAllHistories();
if (allHistories.containsKey(testName)) {
for (final Revision r : allHistories.get(testName)) {
if (revision.equals(r.getRevision())) {
LOGGER.debug(String.format("Found revision [%s] in history of test [%s] in store [%s]", revision, testName, store.getName()));
return store.getHistory(testName, revision, start, limit);
}
}
}
}
LOGGER.info(String.format("Can not find revision %s in any of stores", revision));
return Collections.emptyList();
}
}
}