use of com.datastax.fallout.service.core.User in project fallout by datastax.
the class FalloutServerlessCommand method parseUserCredentials.
protected UserCredentialsFactory.UserCredentials parseUserCredentials(Validator validator, Path credsYamlPath) {
final var objectMapper = JacksonUtils.getYamlObjectMapper();
final User user;
try {
user = objectMapper.readValue(readString(credsYamlPath), User.class);
} catch (JsonProcessingException e) {
throw new UserError("Couldn't read user credentials from '%s': %s", credsYamlPath, e.getMessage());
}
final var errors = validator.validate(user);
if (!errors.isEmpty()) {
throw new UserError("User credentials in '%s' are not valid:\n %s", credsYamlPath, errors.stream().map(error -> String.format("%s %s", error.getPropertyPath(), error.getMessage())).collect(Collectors.joining("\n ")));
}
return new UserCredentialsFactory.UserCredentials(user, Optional.empty());
}
use of com.datastax.fallout.service.core.User in project fallout by datastax.
the class EnsembleFalloutTest method createActiveTestRunBuilder.
public ActiveTestRunBuilder createActiveTestRunBuilder() {
User testUser = getTestUser();
UserCredentials userCredentials = new UserCredentials(testUser, Optional.empty());
// secret is needed for example yamls to be valid
testUser.addGenericSecret("MY_ASTRA_TOKEN", "dummy_astra_token");
JobFileLoggers loggers = new JobFileLoggers(testRunArtifactPath(), true, userCredentials);
return ActiveTestRunBuilder.create().withTestRunScratchSpace(persistentTestScratchSpace()).withTestRunArtifactPath(testRunArtifactPath()).withTestRunIdentifier(Fakes.TEST_RUN_IDENTIFIER).withLoggers(loggers).withFalloutConfiguration(falloutConfiguration()).withTestRunStatusUpdater(new TestRunAbortedStatusUpdater(new InMemoryTestRunStateStorage(TestRun.State.CREATED))).withUserCredentials(userCredentials).withCommandExecutor(new Java8LocalCommandExecutor()).destroyEnsembleAfterTest(true);
}
use of com.datastax.fallout.service.core.User in project fallout by datastax.
the class TestResource method searchTestsApi.
@GET
@Path("/search")
@Timed
@Produces(MediaType.APPLICATION_JSON)
public List<Test> searchTestsApi(@Auth User user, @QueryParam("testName") String testName, @QueryParam("owner") String owner, @QueryParam("tags") List<String> tags, @QueryParam("created") String created) {
if (tags == null)
throw new WebApplicationException(Response.Status.BAD_REQUEST);
Date dateCreated = (created == null) ? null : Date.from(LocalDate.parse(created).atStartOfDay(ZoneId.systemDefault()).toInstant());
List<Test> result = testDAO.getTestsFromTag(tags);
result = result.stream().filter(t -> testName == null || t.getName().equals(testName)).filter(t -> owner == null || t.getOwner().equals(owner)).filter(t -> dateCreated == null || t.getCreatedAt().after(dateCreated)).toList();
return result;
}
use of com.datastax.fallout.service.core.User in project fallout by datastax.
the class FalloutServiceBase method getAuthFilters.
private List<AuthFilter<String, User>> getAuthFilters(FC conf, UserDAO userDAO) {
List<AuthFilter<String, User>> filters = new ArrayList<>();
// This will only be applied to methods/classes annotated with RolesAllowed
final Authorizer<User> adminAuthorizer = (user, role) -> user.isAdmin() && role.equals("ADMIN");
AuthFilter<String, User> oauthCredentialAuthFilter = new OAuthCredentialAuthFilter.Builder<User>().setAuthenticator(new FalloutTokenAuthenticator(userDAO, OAUTH_REALM)).setAuthorizer(adminAuthorizer).setPrefix(OAUTH_BEARER_TOKEN_TYPE).setRealm(OAUTH_REALM).buildAuthFilter();
filters.add(oauthCredentialAuthFilter);
AuthFilter<String, User> uiAuthFilter;
if (conf.getAuthenticationMode() == FalloutConfiguration.AuthenticationMode.SINGLE_USER) {
if (conf.getAdminUserCreds().isEmpty()) {
throw new RuntimeException(String.format("Cannot use %s authentication mode without specifying %s in the environment", FalloutConfiguration.AuthenticationMode.SINGLE_USER, FalloutConfiguration.ADMIN_CREDS_ENV_VAR));
}
uiAuthFilter = new SingleUserAuthFilter(() -> userDAO.getUser(conf.getAdminUserCreds().get().email()));
} else {
uiAuthFilter = new FalloutCookieAuthFilter.Builder().setAuthenticator(new FalloutTokenAuthenticator(userDAO, COOKIE_NAME)).setAuthorizer(adminAuthorizer).setPrefix(OAUTH_BEARER_TOKEN_TYPE).setRealm(OAUTH_REALM).buildAuthFilter();
}
filters.add(uiAuthFilter);
return filters;
}
use of com.datastax.fallout.service.core.User in project fallout by datastax.
the class FalloutServiceBase method runServer.
private void runServer(FC conf, Environment environment, CreateAbortableTestRunExecutorFactory createTestRunExecutorFactory, SchemaMode schemaMode) throws Exception {
final LifecycleManager m = new LifecycleManager(environment);
final ResourceReservationLocks resourceReservationLocks = new ResourceReservationLocks();
cassandraDriverManager = m.manage(new CassandraDriverManager(conf.getCassandraHost(), conf.getCassandraPort(), conf.getKeyspace(), schemaMode, preCreateSchemaCallback));
SecurityUtil securityUtil = new SecurityUtil(conf.getSecureRandomAlgorithm());
final var userGroupMapper = createUserGroupMapper();
UserDAO userDAO = m.manage(new UserDAO(cassandraDriverManager, securityUtil, conf.getAdminUserCreds(), userGroupMapper));
TestRunDAO testRunDAO = m.manage(new TestRunDAO(cassandraDriverManager));
TestDAO testDAO = m.manage(new TestDAO(cassandraDriverManager, testRunDAO));
PerformanceReportDAO reportDAO = m.manage(new PerformanceReportDAO(cassandraDriverManager));
ActiveTestRunFactory activeTestRunFactory = createActiveTestRunFactory(conf);
UserMessenger mailer = HtmlMailUserMessenger.create(conf);
UserCredentialsFactory userCredentialsFactory = (testRun) -> {
User user = userDAO.getUser(testRun.getOwner());
if (user == null) {
throw new RuntimeException(String.format("Couldn't find User with email '%s'", testRun.getOwner()));
}
return new UserCredentials(user, userDAO.getCIUserByUser(user));
};
QueuingTestRunner testRunner = m.manageStartOnly(new QueuingTestRunner(testRunDAO::update, testDAO::updateLastRunAt, new PersistentPendingQueue(testRunDAO::getQueued), userCredentialsFactory, createTestRunExecutorFactory.create(conf, m, mailer, testDAO, testRunDAO, activeTestRunFactory), testRun -> activeTestRunFactory.getResourceRequirements(testRun, userCredentialsFactory), resourceReservationLocks, conf.getResourceLimits(), conf.getStartPaused()));
// monitor queue metrics
QueueMetricsManager.registerMetrics(environment.metrics(), testRunDAO);
runningTestRunsCount = testRunner::getRunningTestRunsCount;
// Make sure the performance_reports dir exists
FileUtils.createDirs(Paths.get(conf.getArtifactPath(), "performance_reports"));
final HashedWheelTimer timer = m.manage(new HashedWheelTimer(new NamedThreadFactory("ServiceTimer")), HashedWheelTimer::stop);
Path artifactPath = Paths.get(conf.getArtifactPath());
final var runningTaskLock = new ReentrantLock();
ArtifactScrubber artifactScrubber = m.manage(new ArtifactScrubber(conf.getStartPaused(), timer, runningTaskLock, Duration.hours(0), Duration.hours(24), artifactPath, testRunDAO, userDAO));
ArtifactCompressor artifactCompressor = m.manage(new ArtifactCompressor(conf.getStartPaused(), timer, runningTaskLock, Duration.hours(12), Duration.hours(24), artifactPath, testRunDAO, testDAO));
TestRunReaper testRunReaper = m.manage(new TestRunReaper(conf.getStartPaused(), timer, runningTaskLock, Duration.hours(18), Duration.days(7), testRunDAO, reportDAO, testDAO, mailer, SlackUserMessenger.create(conf.getSlackToken(), m.manage(FalloutClientBuilder.forComponent(SlackUserMessenger.class).build(), Client::close)), conf.getExternalUrl()));
QueueAdminTask queueAdminTask = new QueueAdminTask(testRunner, List.of(artifactScrubber, artifactCompressor, testRunReaper));
environment.admin().addTask(queueAdminTask);
final var artifactUsageAdminTask = new ArtifactUsageAdminTask(testRunDAO);
environment.admin().addTask(artifactUsageAdminTask);
environment.admin().addTask(new ArtifactCompressorAdminTask(artifactCompressor));
environment.admin().addTask(new ShutdownTask(this::shutdown));
truncateTrailingSlashesInUrls(conf);
final RewriteHandler rewriteHandler = new RewriteHandler();
conf.getServerFactory().insertHandler(rewriteHandler);
addArtifactServlet(conf, environment, rewriteHandler);
// Add CORS headers so that fallout API can be consumed from other than the main URL
// The `CrossOriginFilter` comes with the required default settings: allow any origin
environment.servlets().addFilter("CORS", CrossOriginFilter.class).addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
// Register our exception mappers: note that we must use concrete (i.e. non-generic) classes, otherwise
// the convoluted exception mapping code in Jersey will fail with an HTTP 500 error.
// Dropwizard registers several helpful exception mappers on server start in its ExceptionMapperBinder; one of
// these provides a helper logging method for detecting a particular developer error when POSTing
// forms. Unfortunately, this intercepts _all_ IllegalStateExceptions. We insert our IllegalStateException
// mapper here to pre-empt it, whilest keeping the helper logic.
environment.jersey().register(new FalloutExceptionMapper<IllegalStateException>() {
private final IllegalStateExceptionMapper dropWizardIllegalStateExceptionMapper = new IllegalStateExceptionMapper();
/**
* If the helper code in {@link IllegalStateExceptionMapper} applies, use that
*/
@Override
public Response toResponse(IllegalStateException exception) {
if (LocalizationMessages.FORM_PARAM_CONTENT_TYPE_ERROR().equals(exception.getMessage())) {
return dropWizardIllegalStateExceptionMapper.toResponse(exception);
}
return super.toResponse(exception);
}
});
// This is our default exception mapper.
environment.jersey().register(new FalloutExceptionMapper<>() {
});
environment.jersey().register(new AuthDynamicFeature(new ChainedAuthFilter(getAuthFilters(conf, userDAO))));
// Enable @RolesAllowed annotations
environment.jersey().register(new RolesAllowedDynamicFeature());
// If you want to use @Auth to inject a custom Principal type into your resource
environment.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));
final ComponentResource componentResource = new ComponentResource(conf, componentFactory);
MainView mainView = new MainView(componentResource.getComponentTypes(), testRunner, addVersionedAssetsRewriteRule(rewriteHandler), conf::hideDisplayedEmailDomains);
componentResource.setMainView(mainView);
CommandExecutor commandExecutor = new LocalCommandExecutor();
environment.jersey().register(new StatusResource(testRunner));
environment.jersey().register(new HomeResource(conf, userDAO, testRunDAO, testRunner, conf.getResourceLimits(), mainView, userGroupMapper));
environment.jersey().register(new AdminResource(testRunner, queueAdminTask, artifactUsageAdminTask, mainView));
environment.jersey().register(new AccountResource(userDAO, conf, mailer, mainView, securityUtil, userGroupMapper));
environment.jersey().register(new TestResource(conf, testDAO, testRunDAO, activeTestRunFactory, userCredentialsFactory, reportDAO, testRunner, mainView, userGroupMapper));
environment.jersey().register(componentResource);
environment.jersey().register(new PerformanceToolResource(testDAO, testRunDAO, reportDAO, conf.getArtifactPath(), mainView, userGroupMapper));
registerOptionalResources(conf, environment, testRunDAO, commandExecutor);
// Using SSE (which is what LiveResource uses) doesn't work unless we prevent the
// GZIP output filter from flushing-on-demand (if we don't do this, data is queued up until the
// GZIP implementation decides it's a good time to flush: see java.util.zip.Deflater#SYNC_FLUSH).
((DefaultServerWithHandlerFactory) conf.getServerFactory()).getGzipFilterFactory().setSyncFlush(true);
final ArtifactWatcher artifactWatcher = new ArtifactWatcher(Paths.get(conf.getArtifactPath()), timer, conf.getArtifactWatcherCoalescingIntervalSeconds());
environment.lifecycle().manage(artifactWatcher);
final ServerSentEvents serverSentEvents = m.manageStartOnly(new ServerSentEvents(timer, conf.getServerSentEventsHeartBeatIntervalSeconds()));
environment.jersey().register(new LiveResource(testRunDAO, artifactWatcher, serverSentEvents));
setShutdownHandler(environment, testRunner, serverSentEvents);
}
Aggregations