Search in sources :

Example 1 with AbstractEditorOperation

use of org.alien4cloud.tosca.editor.operations.AbstractEditorOperation in project alien4cloud by alien4cloud.

the class EditorTopologyRecoveryHelperService method buildRecoveryOperations.

/**
 * Given a set of dependencies, analyse a given topology and build a list of {@link AbstractEditorOperation} to apply to the topology to make it synch
 * with the dependencies present in the repository
 *
 * @param topology The topology we want to recover
 * @param updatedDependencies The updated dependencies within the topology
 * @return a list of {@link AbstractEditorOperation} representing the operations to perform on the topology for recovery
 */
public List<AbstractEditorOperation> buildRecoveryOperations(Topology topology, Set<CSARDependency> updatedDependencies) {
    List<AbstractEditorOperation> recoveryOperations = Lists.newArrayList();
    if (!topology.isEmpty()) {
        for (CSARDependency updatedDependency : AlienUtils.safe(updatedDependencies)) {
            buildNodesRecoveryOperations(topology, updatedDependency, recoveryOperations);
            buildRelationshipsRecoveryOperations(topology, updatedDependency, recoveryOperations);
        }
    }
    return recoveryOperations;
}
Also used : AbstractEditorOperation(org.alien4cloud.tosca.editor.operations.AbstractEditorOperation) CSARDependency(org.alien4cloud.tosca.model.CSARDependency)

Example 2 with AbstractEditorOperation

use of org.alien4cloud.tosca.editor.operations.AbstractEditorOperation in project alien4cloud by alien4cloud.

the class EditionContextManager method setup.

@PostConstruct
public void setup() {
    // initialize the cache
    contextCache = CacheBuilder.newBuilder().expireAfterAccess(30, TimeUnit.MINUTES).removalListener(new RemovalListener<String, EditionContext>() {

        @Override
        public void onRemoval(RemovalNotification<String, EditionContext> removalNotification) {
            log.debug("Topology edition context with id {} has been evicted. {} pending operations are lost.", removalNotification.getKey(), removalNotification.getValue().getOperations().size());
            for (AbstractEditorOperation operation : removalNotification.getValue().getOperations()) {
                if (operation instanceof UpdateFileOperation) {
                    String fileId = ((UpdateFileOperation) operation).getTempFileId();
                    if (artifactRepository.isFileExist(fileId)) {
                        artifactRepository.deleteFile(fileId);
                    }
                }
            }
        }
    }).build(new CacheLoader<String, EditionContext>() {

        @Override
        public EditionContext load(String csarId) throws Exception {
            log.debug("Loading edition context for archive {}", csarId);
            Csar csar = csarService.getOrFail(csarId);
            Topology topology = topologyServiceCore.getOrFail(csarId);
            // check if the topology git repository has been created already
            Path topologyGitPath = repositoryService.createGitDirectory(csar);
            log.debug("Edition context for archive {} loaded", csar);
            return new EditionContext(csar, topology, topologyGitPath);
        }
    });
}
Also used : Path(java.nio.file.Path) Csar(org.alien4cloud.tosca.model.Csar) UpdateFileOperation(org.alien4cloud.tosca.editor.operations.UpdateFileOperation) AbstractEditorOperation(org.alien4cloud.tosca.editor.operations.AbstractEditorOperation) Topology(org.alien4cloud.tosca.model.templates.Topology) PostConstruct(javax.annotation.PostConstruct)

Example 3 with AbstractEditorOperation

use of org.alien4cloud.tosca.editor.operations.AbstractEditorOperation in project alien4cloud by alien4cloud.

the class EditorService method checkSynchronization.

/**
 * Ensure that the request is synchronized with the current state of the edition.
 *
 * @param operation, The operation under evaluation.
 */
private synchronized void checkSynchronization(AbstractEditorOperation operation) {
    // there is an operation being processed so just fail (nobody could get the notification)
    if (EditionContextManager.get().getCurrentOperation() != null) {
        throw new EditionConcurrencyException();
    }
    List<AbstractEditorOperation> operations = EditionContextManager.get().getOperations();
    // if someone performed some operations we have to ensure that the new operation is performed on top of a synchronized topology
    if (EditionContextManager.get().getLastOperationIndex() == -1) {
        if (operation.getPreviousOperationId() != null) {
            throw new EditionConcurrencyException();
        }
    } else if (!operations.get(EditionContextManager.get().getLastOperationIndex()).getId().equals(operation.getPreviousOperationId())) {
        throw new EditionConcurrencyException();
    }
    operation.setId(UUID.randomUUID().toString());
    EditionContextManager.get().setCurrentOperation(operation);
}
Also used : EditionConcurrencyException(org.alien4cloud.tosca.editor.exception.EditionConcurrencyException) AbstractEditorOperation(org.alien4cloud.tosca.editor.operations.AbstractEditorOperation)

Example 4 with AbstractEditorOperation

use of org.alien4cloud.tosca.editor.operations.AbstractEditorOperation in project alien4cloud by alien4cloud.

the class EditorService method undoRedo.

/**
 * Undo or redo operations until the given index (including)
 *
 * @param topologyId The id of the topology for which to undo or redo operations.
 * @param at The index on which to place the undo/redo cursor (-1 means no operations, then 0 is first operation etc.)
 * @param lastOperationId The last known operation id for client optimistic locking.
 * @return The topology DTO.
 */
public TopologyDTO undoRedo(String topologyId, int at, String lastOperationId) {
    try {
        initContext(topologyId, lastOperationId);
        if (-1 > at || at > EditionContextManager.get().getOperations().size()) {
            throw new NotFoundException("Unable to find the requested index for undo/redo");
        }
        checkTopologyRecovery();
        if (at == EditionContextManager.get().getLastOperationIndex()) {
            // nothing to change.
            return dtoBuilder.buildTopologyDTO(EditionContextManager.get());
        }
        // TODO Improve this by avoiding dao query for (deep) cloning topology and keeping cache for TOSCA types that are required.
        editionContextManager.reset();
        Topology topology = EditionContextManager.getTopology();
        Csar csar = EditionContextManager.getCsar();
        for (int i = 0; i < at + 1; i++) {
            AbstractEditorOperation operation = EditionContextManager.get().getOperations().get(i);
            IEditorOperationProcessor processor = processorMap.get(operation.getClass());
            processor.process(csar, topology, operation);
        }
        EditionContextManager.get().setLastOperationIndex(at);
        return dtoBuilder.buildTopologyDTO(EditionContextManager.get());
    } catch (IOException e) {
        // FIXME undo should be fail-safe...
        return null;
    } finally {
        EditionContextManager.get().setCurrentOperation(null);
        editionContextManager.destroy();
    }
}
Also used : Csar(org.alien4cloud.tosca.model.Csar) NotFoundException(alien4cloud.exception.NotFoundException) AbstractEditorOperation(org.alien4cloud.tosca.editor.operations.AbstractEditorOperation) Topology(org.alien4cloud.tosca.model.templates.Topology) IOException(java.io.IOException) EditorIOException(org.alien4cloud.tosca.editor.exception.EditorIOException) IEditorOperationProcessor(org.alien4cloud.tosca.editor.processors.IEditorOperationProcessor)

Example 5 with AbstractEditorOperation

use of org.alien4cloud.tosca.editor.operations.AbstractEditorOperation in project alien4cloud by alien4cloud.

the class EditorService method initContext.

/**
 * Call this method only for checking optimistic locking and initializing edition context for method that don't process an operation (save, undo etc.)
 *
 * @param topologyId The id of the topology under edition.
 * @param lastOperationId The id of the last operation.
 */
private void initContext(String topologyId, String lastOperationId) {
    // create a fake operation for optimistic locking
    AbstractEditorOperation optimisticLockOperation = new AbstractEditorOperation() {

        @Override
        public String commitMessage() {
            return "This operation will never be enqueued and never commited.";
        }
    };
    optimisticLockOperation.setPreviousOperationId(lastOperationId);
    // init the edition context with the fake operation.
    initContext(topologyId, optimisticLockOperation);
}
Also used : AbstractEditorOperation(org.alien4cloud.tosca.editor.operations.AbstractEditorOperation)

Aggregations

AbstractEditorOperation (org.alien4cloud.tosca.editor.operations.AbstractEditorOperation)8 Topology (org.alien4cloud.tosca.model.templates.Topology)3 Map (java.util.Map)2 IEditorOperationProcessor (org.alien4cloud.tosca.editor.processors.IEditorOperationProcessor)2 Csar (org.alien4cloud.tosca.model.Csar)2 EvaluationContext (org.springframework.expression.EvaluationContext)2 SpelParserConfiguration (org.springframework.expression.spel.SpelParserConfiguration)2 SpelExpressionParser (org.springframework.expression.spel.standard.SpelExpressionParser)2 StandardEvaluationContext (org.springframework.expression.spel.support.StandardEvaluationContext)2 NotFoundException (alien4cloud.exception.NotFoundException)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 Given (cucumber.api.java.en.Given)1 DataTableRow (gherkin.formatter.model.DataTableRow)1 IOException (java.io.IOException)1 Path (java.nio.file.Path)1 HashMap (java.util.HashMap)1 PostConstruct (javax.annotation.PostConstruct)1 EditionConcurrencyException (org.alien4cloud.tosca.editor.exception.EditionConcurrencyException)1 EditorIOException (org.alien4cloud.tosca.editor.exception.EditorIOException)1 UpdateFileOperation (org.alien4cloud.tosca.editor.operations.UpdateFileOperation)1