private void applyChanges(Run target, Run source) throws IOException { validateChanges(target, source); target.setAlias(source.getAlias()); target.setAccession(source.getAccession()); target.setDescription(source.getDescription()); target.setFilePath(source.getFilePath()); target.setHealth(source.getHealth()); target.setStartDate(source.getStartDate()); target.setCompletionDate(source.getCompletionDate()); target.setMetrics(source.getMetrics()); makeContainerChangesChangeLog(target, target.getSequencerPartitionContainers(), source.getSequencerPartitionContainers()); applyContainerChanges(target, source); target.setSequencingParameters(source.getSequencingParameters()); target.setSequencer(source.getSequencer()); if (isIlluminaRun(target)) { applyIlluminaChanges((IlluminaRun) target, (IlluminaRun) source); } else if (isLS454Run(target)) { applyLS454Changes((LS454Run) target, (LS454Run) source); } else if (isSolidRun(target)) { applySolidChanges((SolidRun) target, (SolidRun) source); } else if (isOxfordNanoporeRun(target)) { applyOxfordNanoporeChanges((OxfordNanoporeRun) target, (OxfordNanoporeRun) source); } }
/** * Determines which of two Runs was more recently modified * * @param run1 * @param run2 * @return the Run with the later lastModified date. Arbitrarily returns run1 if they are equal */ private Run lastModified(Run run1, Run run2) { return run1.getLastModified().before(run2.getLastModified()) ? run2 : run1; }
private boolean updateHealthFromNotification(Run notification, final Run managed, User user) { if (notification.getHealth() == null) { } else if (notification.getHealth() == HealthType.Unknown) { if (managed.getHealth() == null) { managed.setHealth(notification.getHealth()); managed.setCompletionDate(notification.getHealth().isDone() ? notification.getCompletionDate() : null); return true; if (!managed.didSomeoneElseChangeColumn("health", user) || (!managed.getHealth().isDone() && notification.getHealth().isDone())) { managed.setHealth(notification.getHealth()); Date completionDate = null; if (notification.getHealth().isDone()) { if (notification.getCompletionDate() != null) { completionDate = notification.getCompletionDate(); } else if (managed.getCompletionDate() != null) { completionDate = managed.getCompletionDate(); } else { completionDate = new Date(); managed.setCompletionDate(completionDate); return true;
public static RunDto asDto(@Nonnull Run from, boolean includeContainers, boolean includeContainerPartitions, boolean includePoolContents) { RunDto dto = new RunDto(); dto.setId(from.getId()); dto.setName(from.getName()); dto.setAlias(from.getAlias()); if (from.getHealth() != null) { dto.setStatus(from.getHealth().getKey()); } else { dto.setStatus(""); dto.setLastModified(formatDateTime(from.getLastModified())); if (from.getSequencer() != null) { dto.setPlatformType(from.getSequencer().getInstrumentModel().getPlatformType().getKey()); } else { dto.setPlatformType(""); if (from.getStartDate() != null) { dto.setStartDate(formatDate(from.getStartDate())); } else { dto.setStartDate(""); if (from.getCompletionDate() != null) { dto.setEndDate(formatDate(from.getCompletionDate())); if (from.getSequencingParameters() != null) { dto.setParameters(asDto(from.getSequencingParameters())); } else { SequencingParametersDto parametersDto = new SequencingParametersDto();
Run runFromDb = runDao.getByAlias(source.getAlias()); boolean isNew; target = source.getPlatformType().createRun(user); target.setCreationTime(now); target.setCreator(user); target.setName(generateTemporaryName()); target.setAlias(source.getAlias()); isNew = true; } else { target = runFromDb; if (source.getPlatformType() != target.getPlatformType()) { throw new IllegalStateException( "Run scanner detected a run from " + source.getPlatformType().name() + " and there is a save run from " + target.getPlatformType().name()); target.setLastModifier(user); boolean isMutated = false; isMutated |= updateMetricsFromNotification(source, target); isMutated |= updateField(source.getFilePath(), target.getFilePath(), target::setFilePath); isMutated |= updateField(source.getStartDate(), target.getStartDate(), target::setStartDate); target.setSequencer(sequencer); + " for run " + source.getAlias() + "; used fallback container model instead."); switch (source.getPlatformType()) { case ILLUMINA: isMutated |= updateIlluminaRunFromNotification((IlluminaRun) source, (IlluminaRun) target);
private void validateChanges(Run before, Run changed) throws IOException { List<ValidationError> errors = new ArrayList<>(); if (!changed.getHealth().isDone()) { changed.setCompletionDate(null); } else if (changed.getCompletionDate() == null) { errors.add(new ValidationError("completionDate", "Completion date must be provided for finished run")); } if (before != null) { if (before.getCompletionDate() != null && changed.getCompletionDate() != null && !changed.getCompletionDate().equals(before.getCompletionDate()) && !authorizationManager.isAdminUser()) { errors.add(new ValidationError("completionDate", "Only admin may change completion date")); } if (before.getStartDate() != null && changed.getStartDate() != null && !changed.getStartDate().equals(before.getStartDate()) && !authorizationManager.isAdminUser()) { errors.add(new ValidationError("completionDate", "Only admin may change start date")); } } InstrumentModel platform = changed.getSequencer().getInstrumentModel(); for (RunPosition position : changed.getRunPositions()) { if (position.getPosition() != null && !platform.getPositions().contains(position.getPosition())) { errors.add(new ValidationError( String.format("Platform %s does not have a position %s", platform.getAlias(), position.getPosition()))); } } if (!errors.isEmpty()) { throw new ValidationException(errors); } }
@Override public Long create(Run run) throws IOException { authorizationManager.throwIfNotWritable(run); validateChanges(null, run); saveContainers(run); run.setChangeDetails(authorizationManager.getCurrentUser()); loadChildEntities(run); run.setSecurityProfile(securityProfileStore.get(securityProfileStore.save(run.getSecurityProfile()))); run.setName(generateTemporaryName()); Run saved = save(run); makeContainerChangesChangeLog(saved, Collections.emptyList(), saved.getSequencerPartitionContainers()); return saved.getId(); }
@Override protected void populate(Element xml, Pair<PoolableElementView, Partition> entry) { Run r = entry.getValue().getSequencerPartitionContainer().getLastRun(); xml.setAttribute("alias", "L00" + entry.getValue().getPartitionNumber() + ":" + entry.getKey().getDilutionName() + ":" + r.getAlias()); xml.setAttribute("run_center", centreName); if (r.getHealth() == HealthType.Completed) { xml.setAttribute("run_date", DF_TIMESTAMP.format(r.getCompletionDate())); } xml.setAttribute("center_name", centreName); for (Experiment e : submission.getExperiments()) { Element experimentRef = xml.getOwnerDocument().createElementNS(null, "EXPERIMENT_REF"); experimentRef.setAttribute("refname", e.getAlias()); experimentRef.setAttribute("refcenter", centreName); xml.appendChild(experimentRef); } Element dataBlock = xml.getOwnerDocument().createElementNS(null, "DATA_BLOCK"); dataBlock.setAttribute("sector", Integer.toString(entry.getValue().getPartitionNumber())); if (entry.getValue().getPool().getPoolDilutions().size() > 1) { // multiplexed dataBlock.setAttribute("member_name", entry.getKey().getDilutionName()); } }
public static ContainerDto asDto(@Nonnull SequencerPartitionContainer from, boolean includePartitions, boolean includePoolContents) { ContainerDto dto = new ContainerDto(); dto.setId(from.getId()); dto.setIdentificationBarcode(from.getIdentificationBarcode()); dto.setModel(asDto(from.getModel())); Run lastRun = from.getLastRun(); if (lastRun != null) { dto.setLastRunAlias(lastRun.getAlias()); dto.setLastRunId(lastRun.getId()); dto.setLastSequencerId(lastRun.getSequencer().getId()); dto.setLastSequencerName(lastRun.getSequencer().getName()); } if (from.getLastModified() != null) { dto.setLastModified(formatDateTime(from.getLastModified())); } if (from.getClusteringKit() != null) { dto.setClusteringKit(asDto(from.getClusteringKit())); } if (from.getMultiplexingKit() != null) { dto.setMultiplexingKit(asDto(from.getMultiplexingKit())); } if (includePartitions) { dto.setPartitions(asPartitionDtos(from.getPartitions(), includePoolContents)); } return dto; }
if (run1.getStartDate().before(run2.getStartDate())) { return run2; } else if (run1.getStartDate().after(run2.getStartDate())) { return run1; if (run1.getCompletionDate() == null) { if (run2.getCompletionDate() == null) { return run1; } else if (run2.getCompletionDate() == null) { return run2; if (run1.getCompletionDate().before(run2.getCompletionDate())) { return run2; } else if (run1.getCompletionDate().after(run2.getCompletionDate())) { return run1;
InstrumentPosition position = null; if (!isStringEmptyOrNull(positionName)) { position = target.getSequencer().getInstrumentModel().getPositions().stream() .filter(pos -> positionName.equals(pos.getAlias())) .findFirst().orElseThrow(() -> new IllegalArgumentException(String.format("Unknown position '%s' for platform '%s'", positionName, target.getSequencer().getInstrumentModel().getAlias()))); newRunPos.setContainer(newContainer); newRunPos.setPosition(position); target.getRunPositions().clear(); target.getRunPositions().add(newRunPos); return true; case 1: containerSerialNumber, container.getPartitions().size(), laneCount)); if (target.getSequencerPartitionContainers().stream().noneMatch(c -> c.getId() == container.getId())) { target.addSequencerPartitionContainer(container, position); updatePartitionContents(getLaneContents, container); return true;
/** * Loads persisted objects into run fields. Should be called before saving or updating. Loads all fields except for: * <ul> * <li>creator/lastModifier User objects</li> * </ul> * * @param run the Run to load entities into. Must contain at least the IDs of the objects to load. * @throws IOException */ private void loadChildEntities(Run run) throws IOException { if (run.getSequencingParameters() != null) { run.setSequencingParameters(sequencingParametersService.get(run.getSequencingParameters().getId())); } run.setSequencer(instrumentService.get(run.getSequencer().getId())); }
private boolean updateMetricsFromNotification(Run source, Run target) { if (source.getMetrics() != null && source.getMetrics().equals(target.getMetrics())) return false; if (source.getMetrics() == null) { return false; if (source.getMetrics() != null && target.getMetrics() == null) { target.setMetrics(source.getMetrics()); return true; ArrayNode sourceMetrics; try { sourceMetrics = mapper.readValue(source.getMetrics(), ArrayNode.class); } catch (IOException e) { log.error("Impossible junk metrics were passed in for run " + target.getId(), e); return false; targetMetrics = mapper.readValue(target.getMetrics(), ArrayNode.class); } catch (IOException e) { log.error("The database is full of garbage metrics for run " + target.getId(), e); return false; combinedMetrics.addAll(targetMetricsMap.values()); try { target.setMetrics(mapper.writeValueAsString(combinedMetrics)); } catch (JsonProcessingException e) { log.error("Failed to save data just unserialised.", e);
@Override public void addNote(Run run, Note note) throws IOException { Run managed = runDao.get(run.getId()); authorizationManager.throwIfNotWritable(managed); note.setCreationDate(new Date()); note.setOwner(authorizationManager.getCurrentUser()); managed.addNote(note); managed.setLastModifier(authorizationManager.getCurrentUser()); runDao.save(managed); }
@Override public void deleteNote(Run run, Long noteId) throws IOException { if (noteId == null || noteId.equals(Note.UNSAVED_ID)) { throw new IllegalArgumentException("Cannot delete an unsaved Note"); } Run managed = runDao.get(run.getId()); authorizationManager.throwIfNotWritable(managed); Note deleteNote = null; for (Note note : managed.getNotes()) { if (note.getNoteId().equals(noteId)) { deleteNote = note; break; } } if (deleteNote == null) { throw new IOException("Note " + noteId + " not found for Run " + run.getId()); } authorizationManager.throwIfNonAdminOrMatchingOwner(deleteNote.getOwner()); managed.getNotes().remove(deleteNote); runDao.save(managed); }
@Override public void update(Run run) throws IOException { Run managed = get(run.getId()); authorizationManager.throwIfNotWritable(managed); loadChildEntities(run); saveContainers(run); applyChanges(managed, run); managed.setChangeDetails(authorizationManager.getCurrentUser()); save(managed); }
private Run save(Run run) throws IOException { try { Long id = runDao.save(run); Run saved = runDao.get(id); // post-save field generation boolean needsUpdate = false; if (hasTemporaryName(run)) { saved.setName(namingScheme.generateNameFor(saved)); validateNameOrThrow(saved, namingScheme); needsUpdate = true; } if (needsUpdate) { runDao.save(saved); saved = runDao.get(saved.getId()); } return saved; } catch (MisoNamingException e) { throw new IllegalArgumentException("Name generator failed to generate a valid name", e); } catch (ConstraintViolationException e) { // Send the nested root cause message to the user, since it contains the actual error. throw new ConstraintViolationException(e.getMessage() + " " + ExceptionUtils.getRootCauseMessage(e), e.getSQLException(), e.getConstraintName()); } }
@Override public Run getLastRun() { return getRunPositions().stream().map(RunPosition::getRun).filter(r -> r.getStartDate() != null) .max((a, b) -> a.getStartDate().compareTo(b.getStartDate())) .orElse(null); }