public Bucket build() { Bucket result = new Bucket(); result.setControl(instance.isControl()); result.setState(instance.getState()); result.setLabel(instance.getLabel()); result.setPayload(instance.getPayload()); result.setAllocationPercent(instance.getAllocationPercent()); result.setDescription(instance.getDescription()); result.setExperimentID(instance.getExperimentID()); instance = null; return result; } }
private Builder(Bucket other) { instance = new Bucket(); instance.experimentID = other.getExperimentID(); instance.label = other.getLabel(); instance.control = other.isControl() == null ? Boolean.FALSE : other.isControl(); instance.allocationPercent = other.getAllocationPercent(); instance.description = other.getDescription(); instance.payload = other.getPayload(); instance.state = other.getState(); }
public void validateBucketStateTransition(Bucket.State oldState, Bucket.State desiredState) { Bucket bucket = new Bucket(); bucket.setState(oldState); if (!bucket.isStateTransitionValid(desiredState)) { throw new InvalidBucketStateTransitionException("Invalid switch from state \"" + oldState + "\" to invalid state \"" + desiredState + "\""); } }
/** * This method takes a list of buckets and transforms it to the {@link BucketDetail}s that are needed * for later extension. * * @param buckets a list of {@link Bucket}s */ public void addBuckets(List<Bucket> buckets) { List<BucketDetail> details = buckets.stream() .map(b -> new BucketDetail(b.getLabel(), b.isControl(), b.getAllocationPercent(), b.getState(), b.getDescription())) .collect(Collectors.toList()); setBuckets(details); }
@Override public void createBucket(Bucket newBucket) throws RepositoryException { final String SQL = "insert into bucket (" + "experiment_id, description, label, allocation_percent, is_control, payload, state) " + "values (?,?,?,?,?,?,?)"; try { newTransaction().insert( SQL, newBucket.getExperimentID(), newBucket.getDescription() != null ? newBucket.getDescription() : "", newBucket.getLabel().toString(), newBucket.getAllocationPercent(), newBucket.isControl() != null ? newBucket.isControl() : false, newBucket.getPayload() != null ? newBucket.getPayload() : "", Bucket.State.OPEN.toString()); } catch (WasabiException e) { throw e; } catch (Exception e) { throw new RepositoryException("Could not create bucket \"" + newBucket + "\"", e); } }
Bucket newBucket = Bucket.newInstance(experimentID, bucketLabel) .withAllocationPercent(bucket.getAllocationPercent()) .withControl(bucket.isControl()) .withDescription(bucket.getDescription()) .withPayload(bucket.getPayload()) .withState(bucket.getState()) .build(); cassandraRepository.createBucket(newBucket);
Bucket.BucketAuditInfo changeData; if (updates.isControl() != null && !updates.isControl().equals(bucket.isControl())) { builder.withControl(updates.isControl()); changeData = new Bucket.BucketAuditInfo("is_control", bucket.isControl().toString(), updates.isControl().toString()); changeList.add(changeData); if (updates.getAllocationPercent() != null && !updates.getAllocationPercent().equals(bucket.getAllocationPercent())) { builder.withAllocationPercent(updates.getAllocationPercent()); changeData = new Bucket.BucketAuditInfo("allocation", bucket.getAllocationPercent().toString(), updates.getAllocationPercent().toString()); changeList.add(changeData); if (updates.getDescription() != null && !updates.getDescription().equals(bucket.getDescription())) { builder.withDescription(updates.getDescription()); changeData = new Bucket.BucketAuditInfo("description", bucket.getDescription(), updates.getDescription()); changeList.add(changeData); if (updates.getPayload() != null && !updates.getPayload().equals(bucket.getPayload())) { builder.withPayload(updates.getPayload()); changeData = new Bucket.BucketAuditInfo("payload", bucket.getPayload(), updates.getPayload()); changeList.add(changeData);
/** * {@inheritDoc} */ @Override public Bucket updateBucketAllocationPercentage(Bucket bucket, Double desiredAllocationPercentage) { try { bucketAccessor.updateAllocation(desiredAllocationPercentage, bucket.getExperimentID().getRawID(), bucket.getLabel().toString()); } catch (Exception e) { throw new RepositoryException("Could not update bucket allocation percentage \"" + bucket.getExperimentID() + "\".\"" + bucket.getLabel() + "\"", e); } // return the bucket with the updated values bucket = getBucket(bucket.getExperimentID(), bucket.getLabel()); return bucket; }
public void validateExperimentBuckets(List<Bucket> buckets) { if ((buckets == null) || (buckets.isEmpty())) { throw new IllegalArgumentException("No experiment buckets specified"); } Double totalAllocation = 0.0; Integer numControl = 0; Integer nOpen = 0; for (Bucket bucket : buckets) { Double val = bucket.getAllocationPercent(); totalAllocation += val; if (bucket.getState() == Bucket.State.OPEN || bucket.getState() == null) { nOpen++; } if (bucket.isControl()) { numControl++; } } if ((nOpen > 0 && Math.abs(totalAllocation - 1.0) > 1e-12) || (nOpen == 0 && Double.doubleToRawLongBits(totalAllocation) != 0)) { throw new IllegalArgumentException("Total allocation must be 1.0 (or 0.0 if all buckets are closed/empty"); } if (numControl > 1) { throw new IllegalArgumentException("Only one bucket may be specified as a control bucket"); } }
/** * {@inheritDoc} */ @Override public void validateBucketChanges(Bucket bucket, Bucket updates) { if (updates.getExperimentID() != null && !updates.getExperimentID().equals(bucket.getExperimentID())) { throw new IllegalArgumentException("Invalid value for experimentID \"" + updates.getExperimentID() + " \"." + " Cannot update ExperimentID"); } if (updates.getLabel() != null && !updates.getLabel().equals(bucket.getLabel())) { throw new IllegalArgumentException("Invalid value for bucket label \"" + updates.getLabel() + " \". " + "Cannot update bucket label"); } if (updates.getState() != null && !updates.getState().equals(bucket.getState())) { throw new IllegalArgumentException("Cannot update the state of a bucket using this api"); } }
private void checkBucketConstraint(Experiment experiment, Bucket newBucket) { Bucket test = cassandraRepository.getBucket(newBucket.getExperimentID(), newBucket.getLabel()); if (test != null) { throw new ConstraintViolationException(ConstraintViolationException.Reason.UNIQUE_CONSTRAINT_VIOLATION, "Bucket label must be unique within an experiment", null); } if (!experiment.getState().equals(Experiment.State.DRAFT) && newBucket.isControl() != null && newBucket.isControl()) { throw new ConstraintViolationException(ConstraintViolationException.Reason.APPLICATION_CONSTRAINT_VIOLATION, "Bucket added to a running experiment may not be a control bucket", null); } }
/** * {@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; }
/** * Get the bucket based on experiment id and bucket label * If metadata cache is enabled then fetch from cache else fetch from database. * * @param experimentID * @param bucketLabel * @return */ protected Optional<Bucket> getBucketByLabel(Experiment.ID experimentID, Bucket.Label bucketLabel) { Optional<Bucket> rBucket = Optional.empty(); BucketList bucketList = null; if (metadataCacheEnabled) { bucketList = metadataCache.getBucketList(experimentID); } else { bucketList = repository.getBucketList(experimentID); } if (isNull(bucketList)) return rBucket; for (Bucket bucket : bucketList.getBuckets()) { if (bucket.getLabel().equals(bucketLabel)) { return Optional.of(bucket); } } return rBucket; }
for (Bucket bucket : bucketList.getBuckets()) { if (bucket.getLabel() == null) { throw new IllegalArgumentException("error, bucket label was null"); if (b.getLabel().equals(bucket.getLabel())) { oldBucket = b; throw new BucketNotFoundException(bucket.getLabel()); if (bucket.isControl() == null) { bucket.setControl(oldBucket.isControl()); Bucket.Builder builder = buckets.getBucketBuilder(experimentID, bucket.getLabel()); List<Bucket.BucketAuditInfo> changeList = buckets.getBucketChangeList(oldBucket, bucket, builder); cassandraRepository.logBucketChanges(experimentID, changeBucketList.getBuckets().get(i).getLabel(), allChanges.get(i));
bucketLabel = ((BucketEvent) event).getBucket().getLabel(); } else if (event instanceof BucketCreateEvent) { property = "allocation"; after = String.valueOf(((BucketCreateEvent) event).getBucket().getAllocationPercent());
@Override public int compare(Bucket b1, Bucket b2) { return b1.getAllocationPercent().compareTo( b2.getAllocationPercent()); } });
private Builder(Experiment.ID experimentID, Bucket.Label label) { instance = new Bucket(); instance.experimentID = experimentID; instance.label = label; instance.control = false; }
boolean isBucketEmpty = false; if (bucketLabel != null && experimentRepository.getBucket(experimentID, t.getBucketLabel()).getState().equals(Bucket.State.EMPTY)) { bucketLabel = null; isBucketEmpty = true;
/** * Get the bucket based on experiment id and bucket label * * @param experimentID * @param bucketLabel * @return */ protected String getBucketPayload(Experiment.ID experimentID, String bucketLabel) { if (isNull(bucketLabel) || bucketLabel.trim().isEmpty()) { return null; } Optional<Bucket> rBucket = getBucketByLabel(experimentID, Bucket.Label.valueOf(bucketLabel)); String payload = null; if (rBucket.isPresent()) { payload = rBucket.get().getPayload(); } return payload; }