/** * {@inheritDoc} */ public Map<Experiment.ID, Integer> getPriorityPerID(Application.Name applicationName) { return getPriorities(applicationName, false) .getPrioritizedExperiments() .parallelStream() .collect(Collectors.toMap(PrioritizedExperiment::getID, PrioritizedExperiment::getPriority)); } }
/** * {@inheritDoc} */ @Override // Isolate the scope of this bucket retrieval public Bucket.Builder getBucketBuilder(Experiment.ID experimentID, Bucket.Label bucketLabel) { Bucket bucket = getBucket(experimentID, bucketLabel); if (bucket == null) { throw new BucketNotFoundException(bucketLabel); } return Bucket.from(bucket); }
/** * {@inheritDoc} */ @Override public PrioritizedExperimentList getPriorities(Application.Name applicationName, boolean verifyPriorityList) { if (verifyPriorityList) { List<Experiment.ID> priorityList = prioritiesRepository.getPriorityList(applicationName); List<Experiment> experimentList = experiments.getExperiments(applicationName); if ((priorityList != null ? priorityList.size() : 0) != experimentList.size()) { prioritiesRepository.createPriorities(applicationName, cleanPriorityList(applicationName, priorityList)); } } return prioritiesRepository.getPriorities(applicationName); }
Bucket bucket = getBucket(experimentID, bucketLabel); if (bucket == null) { throw new BucketNotFoundException(bucketLabel); desiredState == Bucket.State.EMPTY)) { BucketList bucketList = getBuckets(experimentID, false /* don't check experiment again */); Double bucketB = roundToTwo(bucket.getAllocationPercent()); newPct = roundToTwo(1. - totalAlloc); } else { newPct = roundToTwo(newPct); totalAlloc += newPct; Bucket.Builder builder = getBucketBuilder(experimentID, buck.getLabel()); builder.withAllocationPercent(newPct); builder.withState(newState);
/** * {@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()); }
/** * {@inheritDoc} */ @Override public void checkForIllegalPausedRunningUpdate(Experiment experiment, Experiment updates) { /* Throw an exception if the experiment is in RUNNING/PAUSED state and if applicationName or Label is being updated. Also, if startTime/endTime is being updated with a value that has already passed or when the established startTime/endTime has already passed. */ if (experiment.getState().equals(RUNNING) || experiment.getState().equals(PAUSED)) { if (updates.getApplicationName() != null && !updates.getApplicationName().equals(experiment.getApplicationName())) throw new IllegalArgumentException("Cannot change AppName when the experiment is not in DRAFT state"); if (updates.getLabel() != null && !updates.getLabel().equals(experiment.getLabel())) throw new IllegalArgumentException("Cannot change Label when the experiment is not in DRAFT state"); if (updates.getStartTime() != null && !updates.getStartTime().equals(experiment.getStartTime())) checkForIllegalExperimentStartTime(experiment, updates); if (updates.getEndTime() != null && !updates.getEndTime().equals(experiment.getEndTime())) checkForIllegalExperimentEndTime(experiment, updates); } }
Bucket bucket = getBucket(experimentID, bucketLabel); if (bucket == null) { throw new BucketNotFoundException(bucketLabel); Bucket.Builder builder = getBucketBuilder(experimentID, bucketLabel);
Experiment experiment = getExperiment(experimentID); boolean requiresUpdate = buildUpdatedExperiment(experiment, updates, builder, changeList);
/** * {@inheritDoc} */ @Override public void deletePage(Experiment.ID experimentID, Page.Name pageName, UserInfo user) { Application.Name applicationName = getApplicationNameForModifyingPages(experimentID); pagesRepository.deletePage(applicationName, experimentID, pageName); Experiment experiment = experiments.getExperiment(experimentID); if (experiment != null) { eventLog.postEvent(new ExperimentChangeEvent(user, experiment, "pages", pageName.toString(), null)); } LOGGER.info("event=EXPERIMENT_METADATA_CHANGE, message=PAGE_REMOVED, applicationName={}, experimentName={}, configuration=[pageName={}, userName={}]", experiment.getApplicationName(), experiment.getLabel(), pageName, user.getUsername()); }
/** * {@inheritDoc} */ public List<Experiment> getRecursiveMutualExclusions(Experiment experiment) { List<Experiment> visitedExperiments = new ArrayList<>(); Set<Experiment> unvisitedExperiments = new HashSet<>(); unvisitedExperiments.add(experiment); do { Set<Experiment> newUnvisitedExperiments = new HashSet<>(); for (Experiment tempExperiment : unvisitedExperiments) { visitedExperiments.add(tempExperiment); newUnvisitedExperiments.addAll( this.getExclusions(tempExperiment.getID()) .getExperiments() // Hack: We need to make experiments compatible, converting CassandraExperiments .parallelStream() .map(ce -> Experiment.from(ce).build()) .collect(Collectors.toList()) ); } unvisitedExperiments.addAll(newUnvisitedExperiments); unvisitedExperiments.removeAll(visitedExperiments); } while (!unvisitedExperiments.isEmpty()); return visitedExperiments; } }
/** * {@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; }
/** * {@inheritDoc} */ @Override public void createPriorities(Application.Name applicationName, ExperimentIDList experimentIDList, boolean verifyPriorityList) { // Throw an exception if application name is invalid if (applicationName == null) { throw new ApplicationNotFoundException((Application.Name) null); } if (verifyPriorityList) { prioritiesRepository.createPriorities(applicationName, cleanPriorityList(applicationName, experimentIDList.getExperimentIDs())); } else { prioritiesRepository.createPriorities(applicationName, experimentIDList.getExperimentIDs()); } }
/** * {@inheritDoc} */ @Override public void postPages(Experiment.ID experimentID, ExperimentPageList experimentPageList, UserInfo user) { Application.Name applicationName = getApplicationNameForModifyingPages(experimentID); pagesRepository.postPages(applicationName, experimentID, experimentPageList); Experiment experiment = experiments.getExperiment(experimentID); if (experiment != null) { List<String> pageNames = new ArrayList<>(); for (ExperimentPage experimentPage : experimentPageList.getPages()) { pageNames.add(experimentPage.getName().toString()); } String pageString = StringUtils.join(pageNames, ", "); eventLog.postEvent(new ExperimentChangeEvent(user, experiment, "pages", null, pageString)); LOGGER.info("event=EXPERIMENT_METADATA_CHANGE, message=PAGES_ADDED, applicationName={}, experimentName={}, configuration=[pages={}]", experiment.getApplicationName(), experiment.getLabel(), pageString); } }