/** * {@inheritDoc} */ @Override public BucketList updateBucketAllocBatch(Experiment.ID experimentID, BucketList bucketList) { LOGGER.debug("Add Bucket: saving new allocation percentages for experiment" + experimentID); // Update both repositories cassandraRepository.updateBucketBatch(experimentID, bucketList); databaseRepository.updateBucketBatch(experimentID, bucketList); return buckets.getBuckets(experimentID, false /* don't check experiment again */); }
buckets.deleteBucket(experimentID, bucketLabel, user);
Bucket bucket = buckets.getBucket(experimentID, bucketLabel);
BucketList oldBuckets = buckets.getBuckets(experimentID, false /* don't check experiment again */); bucket.setControl(oldBucket.isControl()); buckets.validateBucketChanges(oldBucket, bucket); Bucket.Builder builder = buckets.getBucketBuilder(experimentID, bucket.getLabel()); List<Bucket.BucketAuditInfo> changeList = buckets.getBucketChangeList(oldBucket, bucket, builder); allBuckets = buckets.combineOldAndNewBuckets(oldBuckets, changeBucketList); validator.validateExperimentBuckets(allBuckets.getBuckets());
/** * {@inheritDoc} */ @Override public Bucket createBucket(Experiment.ID experimentID, Bucket newBucket, UserInfo user) { Experiment experiment = experiments.getExperiment(experimentID); if (experiment == null) { throw new ExperimentNotFoundException(experimentID); } validateExperimentState(experiment); checkBucketConstraint(experiment, newBucket); LOGGER.debug("Add Bucket: adding new bucket to running experiment" + experiment.getID()); cassandraRepository.createBucket(newBucket); try { databaseRepository.createBucket(newBucket); } catch (RepositoryException e) { cassandraRepository.deleteBucket(newBucket.getExperimentID(), newBucket.getLabel()); throw e; } //if we just created an experiment in a running experiment, update the remaining allocation percentages if (!Experiment.State.DRAFT.equals(experiment.getState())) { eventLog.postEvent(new BucketCreateEvent(user, experiment, newBucket)); BucketList updates = buckets.adjustAllocationPercentages(experiment, newBucket); buckets.updateBucketAllocBatch(experimentID, updates); } return getBucket(experimentID, newBucket.getLabel()); }
experiment.getApplicationName(), experiment.getLabel(), oldBucket); buckets.validateBucketChanges(bucket, updates); List<Bucket.BucketAuditInfo> changeList = buckets.getBucketChangeList(bucket, updates, builder);
BucketList bucketList1 = buckets.updateBucketBatch(experimentID, bucketList, user); Bucket bucket = buckets.updateBucket(experimentID, bucketLabel, bucketEntity, user);
Bucket bucket = buckets.createBucket(experimentID, newBucket, user);
return httpHeader.headers().entity(buckets.getBuckets(experimentID, true)).build(); } catch (Exception exception) { LOGGER.error("getBuckets failed for experimentID={} with error:", experimentID, exception);
/** * Queries the database to get additional information to the buckets for the provided * experiment, like the label and allocation percentage. For the analytics data per bucket * see {@link #getAnalyticData(List, Parameters)}. * * @param exp the experiment that should be enriched with bucket data * @return the same ExperimentDetail object but with additional information */ private ExperimentDetail getBucketData(ExperimentDetail exp) { List<Bucket> buckList = buckets.getBuckets(exp.getId(), false).getBuckets(); exp.addBuckets(buckList); return exp; }
.forEach(experiment -> { Experiment.ID experimentID = experiment.getID(); BucketList bucketList = buckets.getBuckets(experimentID, false); ExperimentList exclusionExperimentList = mutex.getExclusions(experimentID); List<Experiment> exclusionList = exclusionExperimentList.getExperiments();
/** * {@inheritDoc} */ @Override public void checkStateTransition(Experiment.ID experimentID, Experiment.State currentState, Experiment.State desiredState) { if (desiredState != null && !currentState.equals(desiredState)) { // Throw an exception if the StateTransition is invalid validator.validateStateTransition(currentState, desiredState); /* If moving from a DRAFT state to a RUNNING state a sanity-check is required on the experiment buckets. Fetch the bucket information if the experiment will be (or remain) in an active state (running, paused) because that info is used to create the KV-store entry. * */ if (currentState.equals(DRAFT) && desiredState.equals(RUNNING)) { // Throw an exception if the sanity-check fails BucketList bucketList = buckets.getBuckets(experimentID, false /* don't check experiment again */); validator.validateExperimentBuckets(bucketList.getBuckets()); } } }
/** * {@inheritDoc} */ @Override public BucketList adjustAllocationPercentages(Experiment experiment, Bucket newBucket) { double remainingAlloc = 1. - newBucket.getAllocationPercent(); BucketList bucketList = buckets.getBuckets(experiment.getID(), false /* don't check experiment again */); BucketList newBuckets = new BucketList(); for (Bucket bucket : bucketList.getBuckets()) { if (bucket.getLabel().equals(newBucket.getLabel())) { continue; } double newAlloc = roundToTwo(remainingAlloc * bucket.getAllocationPercent()); LOGGER.debug("Add Bucket: setting allocation percentage for bucket " + bucket.getLabel() + " in experiment " + experiment.getID() + " to: " + newAlloc); Bucket.Builder builder = Bucket.from(bucket).withAllocationPercent(newAlloc); Bucket updatedBucket = builder.build(); newBuckets.addBucket(updatedBucket); if (!Experiment.State.DRAFT.equals(experiment.getState()) && Double.compare(bucket.getAllocationPercent(), updatedBucket.getAllocationPercent()) != 0) { // this is a system event, so no user needed eventLog.postEvent(new BucketChangeEvent(experiment, updatedBucket, "allocation", String.valueOf(bucket.getAllocationPercent()), String.valueOf(updatedBucket.getAllocationPercent()))); } } return newBuckets; }