use of org.bf2.srs.fleetmanager.storage.RegistryStorageConflictException in project srs-fleet-manager by bf2fc6cc711aee1a0c2a.
the class ScheduleRegistryWorker method execute.
@Transactional
@Override
public void execute(Task aTask, WorkerContext ctl) throws RegistryStorageConflictException {
ScheduleRegistryTask task = (ScheduleRegistryTask) aTask;
Optional<RegistryData> registryOptional = storage.getRegistryById(task.getRegistryId());
if (registryOptional.isEmpty()) {
// NOTE: Failure point 1
ctl.retry();
}
RegistryData registry = registryOptional.get();
List<RegistryDeploymentData> eligibleRegistryDeployments = storage.getAllRegistryDeployments().stream().filter(rd -> RegistryDeploymentStatusValue.of(rd.getStatus().getValue()) == RegistryDeploymentStatusValue.AVAILABLE).collect(toList());
if (eligibleRegistryDeployments.isEmpty()) {
// NOTE: Failure point 2
// TODO How to report it better?
log.warn("Could not schedule registry with ID {}. No deployments are available.", registry.getId());
// We can wait here longer, somebody needs to create a deployment
ctl.retry(100);
}
// Schedule to a random registry deployment
// TODO Improve & use a specific scheduling strategy
RegistryDeploymentData registryDeployment = eligibleRegistryDeployments.get(ThreadLocalRandom.current().nextInt(eligibleRegistryDeployments.size()));
// TODO only available
log.info("Scheduling {} to {}.", registry, registryDeployment);
registry.setRegistryDeployment(registryDeployment);
registry.setStatus(RegistryStatusValueDto.PROVISIONING.value());
// NOTE: Failure point 3
storage.createOrUpdateRegistry(registry);
ctl.delay(() -> tasks.submit(ProvisionRegistryTenantTask.builder().registryId(registry.getId()).build()));
}
use of org.bf2.srs.fleetmanager.storage.RegistryStorageConflictException in project srs-fleet-manager by bf2fc6cc711aee1a0c2a.
the class PanacheResourceStorage method createOrUpdateRegistry.
@Override
public boolean createOrUpdateRegistry(RegistryData registry) throws RegistryStorageConflictException {
requireNonNull(registry);
Optional<RegistryData> existing = empty();
if (registry.getId() != null) {
// TODO investigate using locks, such as optimistic locks
existing = registryRepository.findByIdOptional(registry.getId());
}
try {
final Instant now = Instant.now();
if (existing.isEmpty()) {
registry.setCreatedAt(now);
}
registry.setUpdatedAt(now);
registryRepository.persistAndFlush(registry);
} catch (PersistenceException ex) {
if (ex.getCause() instanceof ConstraintViolationException) {
throw new RegistryStorageConflictException();
} else {
throw ex;
}
}
return existing.isEmpty();
}
use of org.bf2.srs.fleetmanager.storage.RegistryStorageConflictException in project srs-fleet-manager by bf2fc6cc711aee1a0c2a.
the class StartDeprovisionRegistryWorker method execute.
@Transactional
@Override
public void execute(Task aTask, WorkerContext ctl) throws RegistryStorageConflictException {
StartDeprovisionRegistryTask task = (StartDeprovisionRegistryTask) aTask;
Optional<RegistryData> registryOptional = storage.getRegistryById(task.getRegistryId());
if (registryOptional.isPresent()) {
// FAILURE POINT 1
var registry = registryOptional.get();
var force = Instant.now().isAfter(registry.getCreatedAt().plus(props.getDeprovisionStuckInstanceTimeout()));
if (force) {
log.warn("Registry instance '{}' is forced to be deprovisioned.", registry);
}
var deprovision = force;
var status = RegistryStatusValueDto.of(registry.getStatus());
switch(status) {
case ACCEPTED:
case PROVISIONING:
if (!force) {
log.debug("Provisioning in progress. Retrying.");
ctl.retry();
}
break;
case READY:
case FAILED:
deprovision = true;
break;
case REQUESTED_DEPROVISIONING:
case DEPROVISIONING_DELETING:
if (!force) {
log.debug("Deprovisioning is already in progress. Stopping. Registry = {}", registry);
ctl.stop();
}
break;
default:
throw new IllegalStateException("Unexpected status value: " + status);
}
if (deprovision) {
registry.setStatus(RegistryStatusValueDto.DEPROVISIONING_DELETING.value());
// FAILURE POINT 2
storage.createOrUpdateRegistry(registry);
ctl.delay(() -> tasks.submit(DeprovisionRegistryTask.builder().registryId(registry.getId()).build()));
}
} else {
log.warn("Registry id='{}' not found. Stopping.", task.getRegistryId());
ctl.stop();
}
}
use of org.bf2.srs.fleetmanager.storage.RegistryStorageConflictException in project srs-fleet-manager by bf2fc6cc711aee1a0c2a.
the class RegistryServiceImpl method deleteRegistry.
@Override
@Audited(extractParameters = { "0", KEY_REGISTRY_ID })
@CheckDeletePermissions
public void deleteRegistry(String registryId) throws RegistryNotFoundException, RegistryStorageConflictException {
try {
// Verify preconditions - Registry exists
storage.getRegistryById(registryId).orElseThrow(() -> new RegistryNotFoundException(registryId));
tasks.submit(StartDeprovisionRegistryTask.builder().registryId(registryId).build());
} catch (NumberFormatException ex) {
throw new RegistryNotFoundException(registryId);
}
}
use of org.bf2.srs.fleetmanager.storage.RegistryStorageConflictException in project srs-fleet-manager by bf2fc6cc711aee1a0c2a.
the class RegistryServiceImpl method createRegistry.
@Audited
@Override
public RegistryDto createRegistry(RegistryCreateDto registryCreate) throws RegistryStorageConflictException, TermsRequiredException, ResourceLimitReachedException, EvalInstancesNotAllowedException, TooManyEvalInstancesForUserException, TooManyInstancesException, AccountManagementServiceException {
final AccountInfo accountInfo = authService.extractAccountInfo();
// Make sure we have more instances available (max capacity not yet reached).
long instanceCount = storage.getRegistryCountTotal();
if (instanceCount >= maxInstances) {
throw new TooManyInstancesException();
}
// Figure out if we are going to create a standard or eval instance.
ResourceType resourceType = evalInstancesOnlyEnabled ? ResourceType.REGISTRY_INSTANCE_EVAL : accountManagementService.determineAllowedResourceType(accountInfo);
if (resourceType == ResourceType.REGISTRY_INSTANCE_EVAL) {
// Are eval instances allowed?
if (!evalInstancesEnabled) {
throw new EvalInstancesNotAllowedException();
}
// Limit the # of eval instances per user. Need to check storage for list of eval registry instances.
List<RegistryData> registriesByOwner = storage.getRegistriesByOwner(accountInfo.getAccountUsername());
int evalInstanceCount = 0;
for (RegistryData registryData : registriesByOwner) {
// TODO Perform a dedicated query
if (RegistryInstanceTypeValueDto.EVAL.value().equals(registryData.getInstanceType())) {
evalInstanceCount++;
}
}
if (evalInstanceCount >= maxEvalInstancesPerUser) {
throw new TooManyEvalInstancesForUserException();
}
}
// Try to consume some quota from AMS for the appropriate resource type (standard or eval). If successful
// we'll get back a subscriptionId - if not we'll throw an exception.
String subscriptionId = accountManagementService.createResource(accountInfo, resourceType);
// Convert to registry data and persist it in the DB.
RegistryInstanceTypeValueDto instanceType = resourceTypeToInstanceType(resourceType);
RegistryData registryData = convertRegistry.convert(registryCreate, subscriptionId, accountInfo.getAccountUsername(), accountInfo.getOrganizationId(), accountInfo.getAccountId(), instanceType);
// Generate the ID
registryData.setId(UUID.randomUUID().toString());
storage.createOrUpdateRegistry(registryData);
tasks.submit(ScheduleRegistryTask.builder().registryId(registryData.getId()).build());
return convertRegistry.convert(registryData);
}
Aggregations