use of io.codekvast.common.customer.CustomerData in project codekvast by crispab.
the class AgentServiceImpl method updateAgentState.
private boolean updateAgentState(CustomerData customerData, String jvmUuid) {
long customerId = customerData.getCustomerId();
Instant now = Instant.now();
// Disable all agents that have been dead for more than two file import intervals...
int updated = jdbcTemplate.update("UPDATE agent_state SET enabled = FALSE " + "WHERE customerId = ? AND nextPollExpectedAt < ? AND enabled = TRUE ", customerId, Timestamp.from(now.minusSeconds(settings.getQueuePathPollIntervalSeconds() * 2)));
if (updated > 0) {
logger.info("Disabled {} dead agents for {}", updated, customerData);
}
Timestamp nextExpectedPollTimestamp = Timestamp.from(now.plusSeconds(customerData.getPricePlan().getPollIntervalSeconds()));
updated = jdbcTemplate.update("UPDATE agent_state SET lastPolledAt = ?, nextPollExpectedAt = ? WHERE customerId = ? AND jvmUuid = ?", Timestamp.from(now), nextExpectedPollTimestamp, customerId, jvmUuid);
if (updated == 0) {
logger.info("The agent {}:{} has started", customerId, jvmUuid);
jdbcTemplate.update("INSERT INTO agent_state(customerId, jvmUuid, lastPolledAt, nextPollExpectedAt, enabled) VALUES (?, ?, ?, ?, ?)", customerId, jvmUuid, Timestamp.from(now), nextExpectedPollTimestamp, Boolean.TRUE);
} else {
logger.debug("The agent {}:{} has polled", customerId, jvmUuid);
}
Integer numOtherEnabledLiveAgents = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM agent_state " + "WHERE enabled = TRUE AND customerId = ? AND nextPollExpectedAt >= ? AND jvmUuid != ? ", Integer.class, customerId, Timestamp.from(now.minusSeconds(10)), jvmUuid);
String planName = customerData.getPricePlan().getName();
int maxNumberOfAgents = customerData.getPricePlan().getMaxNumberOfAgents();
boolean enabled = numOtherEnabledLiveAgents < maxNumberOfAgents;
if (!enabled) {
logger.warn("Customer {} has already {} live agents (max for price plan '{}' is {})", customerId, numOtherEnabledLiveAgents, planName, maxNumberOfAgents);
} else {
logger.debug("Customer {} now has {} live agents (max for price plan '{}' is {})", customerId, numOtherEnabledLiveAgents + 1, planName, maxNumberOfAgents);
}
jdbcTemplate.update("UPDATE agent_state SET enabled = ? WHERE jvmUuid = ?", enabled, jvmUuid);
CustomerData cd = customerService.registerAgentDataPublication(customerData, now);
if (cd.isTrialPeriodExpired(now)) {
logger.info("Trial period expired for {}", cd);
enabled = false;
}
return enabled;
}
use of io.codekvast.common.customer.CustomerData in project codekvast by crispab.
the class CustomerServiceImpl method deleteCustomerByExternalId.
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CUSTOMERS_CACHE, allEntries = true)
public void deleteCustomerByExternalId(@NonNull String source, String externalId) {
CustomerData customerData = getCustomerDataByExternalId(source, externalId);
long customerId = customerData.getCustomerId();
deleteFromTable("invocations", customerId);
deleteFromTable("method_locations", customerId);
deleteFromTable("methods", customerId);
deleteFromTable("jvms", customerId);
deleteFromTable("environments", customerId);
deleteFromTable("applications", customerId);
deleteFromTable("users", customerId);
deleteFromTable("agent_state", customerId);
deleteFromTable("price_plan_overrides", customerId);
deleteFromTable("heroku_details", customerId);
deleteFromTable("facts", customerId);
deleteFromTable("customers", customerId);
eventService.send(CustomerDeletedEvent.builder().customerId(customerId).name(customerData.getCustomerName()).displayName(customerData.getDisplayName()).source(customerData.getSource()).plan(customerData.getPricePlan().getName()).build());
slackService.sendNotification("Deleted `" + customerData + "`", SlackService.Channel.BUSINESS_EVENTS);
logger.info("Deleted customer {}", customerData);
}
use of io.codekvast.common.customer.CustomerData in project codekvast by crispab.
the class CustomerServiceImpl method changePlanForExternalId.
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CUSTOMERS_CACHE, allEntries = true)
public void changePlanForExternalId(String source, @NonNull String externalId, @NonNull String newPlanName) {
CustomerData customerData = getCustomerDataByExternalId(source, externalId);
PricePlan oldEffectivePricePlan = customerData.getPricePlan();
String oldPlanName = oldEffectivePricePlan.getName();
if (newPlanName.equals(oldPlanName)) {
logger.info("{} is already on plan '{}'", customerData, newPlanName);
return;
}
int count = jdbcTemplate.update("UPDATE customers SET plan = ? WHERE source = ? AND externalId = ? ORDER BY id ", newPlanName, source, externalId);
if (count == 0) {
logger.error("Failed to change plan for customer {} from '{}' to '{}'", customerData.getDisplayName(), oldPlanName, newPlanName);
return;
}
String logMessage = String.format("Changed plan for customer %s from '%s' to '%s'", customerData.getDisplayName(), oldPlanName, newPlanName);
logger.info(logMessage);
slackService.sendNotification(logMessage, SlackService.Channel.BUSINESS_EVENTS);
eventService.send(PlanChangedEvent.builder().customerId(customerData.getCustomerId()).oldPlan(oldPlanName).newPlan(newPlanName).build());
count = jdbcTemplate.update("DELETE FROM price_plan_overrides WHERE customerId = ?", customerData.getCustomerId());
if (count > 0) {
PricePlan newEffectivePricePlan = PricePlan.of(PricePlanDefaults.ofDatabaseName(newPlanName));
eventService.send(PlanOverridesDeletedEvent.builder().customerId(customerData.getCustomerId()).oldEffectivePlan(oldEffectivePricePlan).newEffectivePlan(newEffectivePricePlan).build());
String pricePlanOverridesMessage = String.format("Removed price plan overrides for customer %s, effective price plan changed from `%s` to `%s`", customerData.getDisplayName(), oldEffectivePricePlan, newEffectivePricePlan);
slackService.sendNotification(pricePlanOverridesMessage, SlackService.Channel.BUSINESS_EVENTS);
logger.warn(pricePlanOverridesMessage);
}
}
use of io.codekvast.common.customer.CustomerData in project codekvast by crispab.
the class SecurityServiceImpl method doHerokuSingleSignOn.
@Override
@Transactional(rollbackFor = Exception.class)
public String doHerokuSingleSignOn(String token, String externalId, String email, long timestampSeconds, String salt) throws AuthenticationException {
String expectedToken = makeHerokuSsoToken(externalId, timestampSeconds, salt);
logger.debug("id={}, token={}, timestamp={}, expectedToken={}", externalId, maskSecondHalf(token), timestampSeconds, maskSecondHalf(expectedToken));
long nowSeconds = Instant.now().getEpochSecond();
if (timestampSeconds > nowSeconds + 60) {
throw new NonceExpiredException("Timestamp is too far into the future");
}
if (timestampSeconds < nowSeconds - 5 * 60) {
throw new NonceExpiredException("Timestamp is too old");
}
if (!expectedToken.equals(token)) {
throw new BadCredentialsException("Invalid token");
}
CustomerData customerData = customerService.getCustomerDataByExternalId(CustomerService.Source.HEROKU, externalId);
customerService.registerLogin(CustomerService.LoginRequest.builder().customerId(customerData.getCustomerId()).source(CustomerService.Source.HEROKU).email(email).build());
return createCodeForWebappToken(customerData.getCustomerId(), WebappCredentials.builder().customerName(customerData.getCustomerName()).email(email).source(CustomerService.Source.HEROKU).build());
}
use of io.codekvast.common.customer.CustomerData in project codekvast by crispab.
the class DashboardIntegrationTest method should_reject_publication_invalid_licenseKey.
@Test(expected = AuthenticationCredentialsNotFoundException.class)
@Sql(scripts = "/sql/base-data.sql")
public void should_reject_publication_invalid_licenseKey() {
CustomerData customerData = customerService.getCustomerDataByLicenseKey("undefined");
customerService.assertPublicationSize(customerData, 10);
}
Aggregations