public ExperimentDTO versionExperiment()

in server/src/main/java/com/epam/indigoeln/core/service/experiment/ExperimentService.java [551:645]


    public ExperimentDTO versionExperiment(String experimentName, String projectId, String notebookId, User user) {
        if (StringUtils.isEmpty(experimentName)) {
            throw new IllegalArgumentException("Experiment name cannot be null.");
        }
        Project project = projectRepository.findById(projectId)
                .orElseThrow(() -> EntityNotFoundException.createWithProjectId(projectId));
        Notebook notebook = notebookRepository
                .findById(SequenceIdUtil.buildFullId(projectId, notebookId)).
                orElseThrow(() -> EntityNotFoundException.createWithNotebookId(notebookId));

        // check of EntityAccess (User must have "Create Sub-Entity" permission in notebook's access list,
        // or must have CONTENT_EDITOR authority)
        if (!PermissionUtil.hasEditorAuthorityOrPermissions(user, notebook.getAccessList(),
                UserPermission.CREATE_SUB_ENTITY)) {
            throw OperationDeniedException.createNotebookSubEntityCreateOperation(notebook.getId());
        }

        notebook.getExperiments().stream()
                .filter(e -> experimentName.equals(e.getName()) && ExperimentStatus.OPEN.equals(e.getStatus()))
                .findAny().ifPresent(e -> {
            throw OperationDeniedException.createVersionExperimentOperation(e.getId());
        });

        // Update previous version
        Experiment lastVersion = notebook.getExperiments().stream().filter(e -> e.isLastVersion()
                && experimentName.equals(e.getName()))
                .findFirst().orElseThrow(() -> EntityNotFoundException.createWithExperimentName(experimentName));
        lastVersion.setLastVersion(false);
        lastVersion = experimentRepository.save(lastVersion);

        int newExperimentVersion = lastVersion.getExperimentVersion() + 1;

        // Save new version
        Experiment newVersion = new Experiment();
        String id;
        if (lastVersion.getExperimentVersion() > 1) {
            id = lastVersion.getId().split("_")[0];
        } else {
            id = lastVersion.getId();
        }
        newVersion.setId(id + "_" + newExperimentVersion);
        newVersion.setName(experimentName);
        newVersion.setTemplate(lastVersion.getTemplate());
        newVersion.setStatus(ExperimentStatus.OPEN);
        final List<Component> components = lastVersion.getComponents();
        components.forEach(c -> c.setId(null));
        final List<Component> newComponents = updateComponents(Collections.emptyList(), components, newVersion.getId());
        newVersion.setComponents(newComponents);
        newVersion.setLastVersion(true);
        newVersion.setExperimentVersion(newExperimentVersion);
        newVersion.compileExperimentFullName(notebook.getName());
        Triple<PermissionChanges<Project>, PermissionChanges<Notebook>, PermissionChanges<Experiment>> changes =
                ExperimentPermissionHelper.fillNewExperimentsPermissions(project, notebook, newVersion, user);

        final Experiment savedNewVersion = experimentRepository.save(newVersion);
        notebook.getExperiments().add(savedNewVersion);
        Notebook savedNotebook = notebookRepository.save(notebook);

        Set<User> contentEditors = userService.getContentEditors();

        List<WebSocketUtil.DelayedNotificationRunnable> notifications = new ArrayList<>();

        //update lastVersion name and version
        notifications.add(
                webSocketUtil.getUpdateExperimentNotification(user, projectId, notebookId, lastVersion,
                        getEntityUpdateRecipients(contentEditors, lastVersion, null)));

        PermissionChanges<Project> projectPermissions = changes.getLeft();
        if (projectPermissions.hadChanged()) {
            Project savedProject = projectRepository.save(projectPermissions.getEntity());
            notifications.add(
                    webSocketUtil.getUpdateProjectNotification(user, savedProject,
                            getEntityUpdateRecipients(contentEditors, savedProject, null)));
        }

        notifications.add(
                webSocketUtil.getNewProjectNotification(user,
                        getSubEntityChangesRecipients(projectPermissions)));

        notifications.add(
                webSocketUtil.getProjectSubEntityNotification(user, project,
                        getSubEntityChangesRecipients(changes.getMiddle())));

        notifications.add(
                webSocketUtil.getUpdateNotebookNotification(user, projectId, savedNotebook,
                        getEntityUpdateRecipients(contentEditors, savedNotebook, null)));

        notifications.add(
                webSocketUtil.getNotebookSubEntityNotification(user, projectId, savedNotebook,
                        getSubEntityChangesRecipients(changes.getRight(), contentEditors)));

        webSocketUtil.sendAll(notifications);

        return new ExperimentDTO(savedNewVersion);
    }